TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 Gen AI>

[Gen AI] 그라디오로 챗봇 제작하기 - 3 (소설봇)

by 기록자_Recordian 2024. 12. 12.
728x90
반응형
이전 내용
 

[Gen AI] 그라디오로 챗봇 제작하기 - 1 (상담봇)

이전 내용 [Gen AI] 그라디오(Gradio)이전 내용 [Gen AI] OpenAI API 사용해보기 (로컬, 주피터노트북)이전 내용 [Gen AI] OpenAI API 키 발급하기Open AI API란? OpenAI에서 개발한 인공지능 모델을 프로그래밍 인

puppy-foot-it.tistory.com

 

[Gen AI] 그라디오로 챗봇 제작하기 - 2 (번역봇)

이전 내용 [Gen AI] 그라디오로 챗봇 제작하기 - 1 (상담봇)이전 내용 [Gen AI] 그라디오(Gradio)이전 내용 [Gen AI] OpenAI API 사용해보기 (로컬, 주피터노트북)이전 내용 [Gen AI] OpenAI API 키 발급하기Open AI

puppy-foot-it.tistory.com


소설봇 기능 추가하기

 

5) 소설봇 기능 추가하기

소설봇은 몇 가지 설정만 잡아 주면 자동으로 소설을 작성해주는 기능을 수행한다.

코드는 이전에 작성해둔 코드 중 '소설봇' 탭에서 pass를 삭제하고 작성한다.

 

5-1) 레이아웃 구현하기

탭을 제외한 소설봇의 레이아웃은 세로로 4블록이 쌓여 있고, 2번째 블록에는 가로로 2블록이 나뉘어있다. 또한 그 안에서 첫 번째 블록이 2개로 나뉘어 있다.

    with gr.Tab("소설봇"):
        gr.Markdown()
        with gr.Accordion():
            with gr.Row():
                with gr.Column():
                    gr.Dropdown()
                    gr.Slider()
                gr.Text()
        gr.Button()
        gr.Text()

▶ Accordion(빨간 네모)으로 묶여 있는 부분은 해당 기능을 접었다 폈다 하면서 사용자 설정 기능을 숨길 수 있다.

Accordion 내부는 가로로 Dropdown, Slider 한 묶음과 Textbox 로 나뉘어 있다. 가로로 나뉜 부분은 Row로 묶어주고, Dropdown과 Slider는 세로로 나뉘어 있기 때문에 Column으로 묶어준다.

 

- 타이틀 및 설명: 어떤 역할을 하는지 나타내는 타이틀 레이아웃 구현

    with gr.Tab("소설봇"):
        gr.Markdown(
            value="""
            # <center>소설봇</center>
            <center>소설을 생성해 주는 봇입니다.</center>
            """)
        with gr.Accordion():

 

- 모델 선택: 하위 레이아웃을 숨길 수 있는 Accordion과 GPT 모델을 선택할 수 있는 드롭다운 기능 구현

        with gr.Accordion(label="사용자 설정"):
            with gr.Row():
                with gr.Column(scale=1):
                    gr.Dropdown(
                        label="모델 선택",
                        choices=["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4",
                                 "gpt-4-32k", "gpt-4-1106-preview"],
                        value="gpt-4-1106-preview",
                        interactive=True
                    )
                    gr.Slider()

  • with gr.Accordion(label="사용자 설정"): label의 값 설정. Accordion이 있는 그룹의 상단에 이름 표시
  • gr.Dropdown: 드롭다운 세부 옵션 설정
  • choices: 챗GPT의 대표적인 모델을 리스트로 만들어 바인딩
  • value: 기본 모델의 값 설정
  • value 매개변수를 지정하면 자동으로 interactive가 비활성화되기 때문에 직접 True로 활성화

- 창의성 조절 기능: GPT의 창의성을 담당하는 슬라이드 구현. OpenAI API로 GPT를 호출할 때 설정할 수 있는 매개변수 중 창의성에 관련된 성능을 조절하는 기능을 말한다.

gr.Slider(
                        label="창의성",
                        info="숫자가 높을수록 창의적",
                        minimum=0,
                        maximum=2,
                        step=0.1,
                        value=1,
                        interactive=True
                    )

  • 이 컴포넌트의 역할은 챗GPT API를 호출할 때 temperature 매개변수 입력값을 설정하는 것이다.
  • step은 0.1로 설정하여 minimum 0부터 maximum 2 사이에서 유의미한 변화의 폭 만큼 움직이게 한다.
  • 초깃값 value를 1로 설정하여 temperature의 기본값으로 맞춰준다.
  • value에 값을 지정할 경우, interactive가 False의 값을 가지게 되므로, True로 수정

- 소설 세부 설정: 소설의 세부적인 사항을 적는 공간으로, 어떤 구조로 소설을 작성할 것인지, 어떤 소재가 사용될 것인지 등의 세부적인 사항을 적을 수 있다.

                gr.Text(
                    container=False,
                    placeholder="소설의 세부적인 설정을 작성합니다.",
                    lines=8,
                    scale=4
                )

  • container=False: container를 없애 공간을 확보한다.
  • lines=8: lines가 2 이상이어야 Enter를 이용한 줄 넘기기가 가능하다.

- [생성하기] 버튼과 출력 화면: 버튼을 클릭해 프로그램을 실행하고 출력된 텍스트를 출력할 수 있다.

        gr.Button(
            value="생성하기",
            variant="primary"
        )
        gr.Text(
            label="",
            placeholder="이곳에 소설의 내용이 출력됩니다.",
            lines=10,
            max_lines=200,
            show_copy_button=True

▶ 불필요한 label의 값을 없애고 show_copy_button을 True로 하여 내용을 쉽게 복사할 수 있도록 한다.

lines를 10, max_lines를 200으로 하여 동적인 UI를 만든다.

 

5-2) 소설봇 기능 구현하기

[생성하기] 버튼을 클릭하면 '모델 선택'과 '창의성', 소설 세부 사항을 참고해 챗GPT로 값을 받아 화면에 출력하는 기능을 구현해 본다.

함수 코드는 #소설봇 코드와 #레이아웃 사이에 추가해준다.

def novel_bot(model, temperature, detail):
    completion= openai.chat.completions.create(
        model=model,
        temperature=temperature,
        messages=[
            {"role": "system", "content": "당신은 소설가입니다. 요청하는 조건에 맞춰 소설을 작성해 주세요."},
            {"role": "user", "content": detail}
        ])
    return completion.choices[0].message.content

novel_bot의 매개변수는 총 세 가지로, 각각의 매개변수가 받아올 값은 다음과 같다.

  • model: 사용할 언어 모델 종류
  • temperature: 0~2 사이의 창의성을 조절한 값
  • detail: 소설의 세부 사항

5-3) 변수에 컴포넌트 바인딩하기

앞서 작성한 함수에 참조하기 위한 기능들을 변수에 바인딩해 준다.

 

5-4) 이벤트 리스너 추가하기

nb_submit 변수에 클릭 이벤트 리스너를 추가한다.

        # 보내기
        nb_submit.click(
            fn=novel_bot,
            inputs=[nb_model, nb_temperature, nb_detail],
            outputs=nb_output
        )

▶ 버튼의 이벤트 리스너인 click을 추가하고 인수를 추가해준다. (앞서 정의한 함수 novel_bot / inputs에는 3개의 매개변수 / outputs에는 최종 출력할 값)

 

5-5) 실행하고 확인하기

소설봇에게 주인공으로 아기와 엄마가 등장하는 300자의 짧은 단편 소설을 써달라고 요청했다.

내용은 다음과 같다.

어느 추운 겨울날, 작은 아기가 태어났다. 아기는 엄마의 따뜻한 품에 안기고 천사처럼 웃었다. 엄마는 아기를 보며 눈물을 흘렸다. 그 순간, 아기는 마치 빛나는 별처럼 보였다. 엄마는 아기에게 사랑을 가득 전했다. 아기는 엄마의 미소에 안심하며 자라갔다. 엄마는 밤낮없이 아기를 돌봐주었지만, 피로한 일상에도 미소를 잃지 않았다. 어느 날, 아기는 첫 발을 내딛었다. 엄마는 눈물을 글썽이며 기뻐했다. 아기는 더 이상 작은 존재가 아니었다. 엄마의 작은 아기는 이제 세상을 앞으로 향해 모험을 떠날 준비를 하는 중이었다. 아기는 첫 발소리와 함께 엄마의 손을 꽉 잡았다. 엄마는 아기의 손을 꼭 쥐며 웃었다. 이제 둘은 함께 세상을 만나기 위해 첫 걸음을 내딛었다. 함께라면 두렵지 않다는 것을 알았기에, 아기와 엄마는 행복한 여정을 시작했다. 이들의 이야기는 세대를 넘어 전해질 아름다운 추억으로 남을 것이다.

 

그렇다면 똑같은 주제를 창의성을 뜻하는 temperature를 maximum인 2로 올려서 재요청하면 어떻게 될까?

한 나머지 벚나무 숲속에 작은 오두막 한 채가 조용히 서 있다. 익어가는 가을에서 다 얽쌀줄도 모르는 바보 scootermobiledir_COMM_pid323_a356822.wwwsgiAWwg_); 흰 탄생

▶ 독특한 발상의 이야기를 기대했건만, 우리가 정의하는 창의성과 인공지능이 정의하는 창의성이라는 개념이 다른 듯하다.

temperature는 0.7에서 1 사이가 적절하다고 한다.


전체 코드 (상담봇, 번역봇, 소설봇)

 

import gradio as gr
import os
from openai import OpenAI

# OpenAI 클라이언트 설정
client = OpenAI(
    api_key=os.environ['OPENAI_API_KEY'])

# 상담봇 - 채팅 및 답변
def counseling_bot_chat(message, chat_history):
    if message == "":
        return "", chat_history
    else:
        completion = openai.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "당신은 DUDE의 상담원입니다. 쇼핑몰 상품과 관련되지 않은 질문에는 정중히 거절하세요."},
                {"role": "user", "content": message}
            ]
        )
        chat_history.append([message, completion.choices[0].message.content])
        return "", chat_history

# 상담봇 - 되돌리기
def counseling_bot_undo(chat_history):
    if len(chat_history) > 1:
        chat_history.pop()
    return chat_history

# 상담봇 - 초기화
def counseling_bot_reset(chat_hisotry):
    chat_history=[[None, "안녕하세요, DUDE 입니다. 상담을 도와드리겠습니다."]]
    return chat_history

# 번역봇
def translate_bot(output_conditions, output_language, input_text):
    if input_text == "":
        return ""
    else:
        if output_conditions == "":
            output_conditions=""
        else:
            output_conditions="번역할 때의 조건은 다음과 같습니다." + output_conditions

        completion = openai.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "당신은 번역가입니다. 입력한 언어를 설명 없이 곧바로 {0}로 번역해서 알려 주세요.\
                번역이 불가능한 언어라면 번역이 불가하다고 말한 후 그 이유를 설명해 주세요. {1}".format(output_language, output_conditions)},
                {"role": "user", "content":input_text}
            ])

        return completion.choices[0].message.content

# 소설봇
def novel_bot(model, temperature, detail):
    completion = openai.chat.completions.create(
        model=model,
        temperature=temperature,
        messages=[
            {"role": "system", "content": "당신은 소설가입니다. 요청하는 조건에 맞춰 소설을 작성해 주세요."},
            {"role": "user", "content": detail}
        ])
    return completion.choices[0].message.content

# 레이아웃
with gr.Blocks(theme=gr.themes.Default()) as app:
    with gr.Tab("상담봇"):
        gr.Markdown(
            value="""
            #  <center>상담봇</center>
            <center> DUDE 상담봇입니다. 판매하는 상품과 관련된 질문에 답변 드립니다.</center>
        """)
        cb_chatbot=gr.Chatbot(
            value=[[None, "안녕하세요, DUDE 입니다. 상담을 도와드리겠습니다."]],
            show_label=False
        )
        with gr.Row():
            cb_user_input=gr.Text(
                lines=1,
                placeholder="입력 창",
                container=False,
                scale=9
            )
            cb_send_btn=gr.Button(
                value="보내기",
                scale=1,
                variant="primary",
                icon="https://cdn-icons-png.flaticon.com/128/12439/12439334.png"
            )
        with gr.Row():
            gr.Button(value="↪️되돌리기").click(fn=counseling_bot_undo, inputs=cb_chatbot, outputs=cb_chatbot)
            gr.Button(value="🔄️초기화").click(fn=counseling_bot_reset, inputs=cb_chatbot, outputs=cb_chatbot)
            # 보내기1
            cb_send_btn.click(fn=counseling_bot_chat, inputs=[cb_user_input, cb_chatbot], outputs=[cb_user_input, cb_chatbot])
            # 보내기2
            cb_user_input.submit(fn=counseling_bot_chat, inputs=[cb_user_input, cb_chatbot], outputs=[cb_user_input, cb_chatbot])
    with gr.Tab("번역봇"):
        gr.Markdown(
            value="""
            # <center>번역봇</center>
            <center>다국어 번역봇입니다.</center>
            """)
        with gr.Row():
            tb_output_conditions=gr.Text(
                label="번역 조건",
                placeholder="예시: 자연스럽게",
                lines=1,
                max_lines=3
            )
            tb_output_language=gr.Dropdown(
                label="출력 언어",
                choices=["한국어", "영어", "일본어", "중국어"],
                value="한국어",
                allow_custom_value=True,
                interactive=True
            )
        tb_submit=gr.Button(
            value="번역 하기",
            variant="primary"
        )
        with gr.Row():
            tb_input_text=gr.Text(
                placeholder="번역할 내용을 적어 주세요.",
                lines=10,
                max_lines=20,
                show_copy_button=True,
                label=""
            )
            tb_output_text=gr.Text(
                lines=10,
                max_lines=20,
                show_copy_button=True,
                label="",
                interactive=False
            )
        tb_submit.click(
            fn=translate_bot,
            inputs=[tb_output_conditions,
                    tb_output_language,
                    tb_input_text],
            outputs=tb_output_text
        )
    with gr.Tab("소설봇"):
        gr.Markdown(
            value="""
            # <center>소설봇</center>
            <center>소설을 생성해 주는 봇입니다.</center>
            """)
        with gr.Accordion(label="사용자 설정"):
            with gr.Row():
                with gr.Column(scale=1):
                    nb_model=gr.Dropdown(
                        label="모델 선택",
                        choices=["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4",
                                 "gpt-4-32k", "gpt-4-1106-preview"],
                        value="gpt-4-1106-preview",
                        interactive=True
                    )
                    nb_temperature=gr.Slider(
                        label="창의성",
                        info="숫자가 높을수록 창의적",
                        minimum=0,
                        maximum=2,
                        step=0.1,
                        value=1,
                        interactive=True
                    )
                nb_detail=gr.Text(
                    container=False,
                    placeholder="소설의 세부적인 설정을 작성합니다.",
                    lines=8,
                    scale=4
                )
        nb_submit=gr.Button(
            value="생성하기",
            variant="primary"
        )
        nb_output=gr.Text(
            label="",
            placeholder="이곳에 소설의 내용이 출력됩니다.",
            lines=10,
            max_lines=200,
            show_copy_button=True
        )
        # 보내기
        nb_submit.click(
            fn=novel_bot,
            inputs=[nb_model, nb_temperature, nb_detail],
            outputs=nb_output
        )

app.launch()

 

이제 만들어진 챗봇 프로그램을 허깅 페이스에 업로드해 본다.


다음 내용

 

[Gen AI] 그라디오로 제작한 챗봇 허깅 페이스에 업로드하기

이전 내용 [Gen AI] 그라디오로 챗봇 제작하기 - 3 (소설봇)이전 내용 [Gen AI] 그라디오로 챗봇 제작하기 - 1 (상담봇)이전 내용 [Gen AI] 그라디오(Gradio)이전 내용 [Gen AI] OpenAI API 사용해보기 (로컬,

puppy-foot-it.tistory.com


[출처]

Hey, 파이썬! 생성형 AI 활용 앱 만들어줘

Stack Overflow

728x90
반응형