Kims12's picture
Update app.py
f7cddc9 verified
import gradio as gr
import openai
import os
def respond_chatgpt_qna(
question: str,
system_message: str,
max_tokens: int,
temperature: float,
top_p: float
):
"""
OpenAI의 gpt-4o-mini 모델을 이용해 질문에 대한 답변을 반환하는 함수.
"""
openai_token = os.getenv("OPENAI_TOKEN")
if not openai_token:
return "OpenAI API 토큰이 필요합니다."
openai.api_key = openai_token
messages = [
{"role": "system", "content": system_message},
{"role": "user", "content": question}
]
try:
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=messages,
max_tokens=max_tokens,
temperature=temperature,
top_p=top_p,
)
assistant_message = response.choices[0].message['content']
return assistant_message
except Exception as e:
return f"오류가 발생했습니다: {str(e)}"
def merge_and_call(tone: str, ref1: str, ref2: str, ref3: str):
"""
사용자가 선택한 말투와 참조글들을 하나의 프롬프트로 합쳐 gpt-4o-mini 모델에 전달하는 함수.
각 말투에 따라 고유의 system_message(프롬프트)가 적용되며, 아래의 기본 프롬프트 규칙을 반드시 준수한다.
"""
# 기본 프롬프트 규칙 (모든 말투에 공통 적용)
base_prompt = (
"너는 가장 주목받는 마케터이며 블로그 마케팅 전문가이다. "
"특히 너는 '정보성(Informative)' 전문 블로그 마케팅 전문가로서, 정보 제공에 초점을 맞추어 작성해야 한다.\n"
"다음 텍스트 작성 규칙을 반드시 준수하라:\n"
"1. 소주제를 5개로 구분하여 2000자 이상 작성하라.\n"
"2. 전체 맥락을 이해하고 문장의 일관성을 유지하라.\n"
"3. 절대로 참고글을 한 문장 이상 그대로 출력하지 말라.\n"
"4. 주제와 상황에 맞는 적절한 어휘를 선택하라.\n"
"5. 한글 어휘의 난이도는 쉽게 작성하라.\n"
"6. 절대 문장의 끝에 '답니다'를 사용하지 말라.\n"
"정보성 블로그 작성 규칙:\n"
"1. 독자가 얻고자 하는 유용하고 흥미로운 정보를 제공하라.\n"
"2. 독자의 공감을 이끌어내고 궁금증을 해결하라.\n"
"3. 독자의 관심사를 충족시키라.\n"
"4. 독자에게 이득이 되는 정보를 제공하라.\n"
"제외 규칙:\n"
"1. 반드시 비속어 및 욕설은 제외하라.\n"
"2. 반드시 참고글의 링크(URL)는 제외하라.\n"
"3. '링크를 확인해주세요' 등의 문구는 제외하라.\n"
"4. 참고글에 있는 작성자, 화자, 유튜버, 기자의 이름, 애칭, 닉네임은 반드시 제외하라.\n"
"5. 문장의 끝부분에 어색한 표현(예: '예요', '답니다', '해요', '해주죠', '됐죠', '됐어요', '고요' 등)은 사용하지 말라."
)
# 말투별 추가 프롬프트 설정
if tone == "친근하게":
tone_prompt = (
"친근하게:\n"
"1. 톤과 어조: 대화하듯 편안하고 친근한 말투를 사용하라.\n"
"2. 문장 및 어투: 반드시 '해요체'로 작성하며, '습니다'체나 '~다'로 끝나지 않도록 하라. 구어체 표현(예: '~했어요', '~인 것 같아요')을 사용하라.\n"
"3. 용어 및 설명: 전문 용어 대신 쉬운 단어를 사용하고, 비유나 은유를 통해 복잡한 개념을 설명하라.\n"
"4. 독자와의 상호작용: 독자의 의견을 묻는 질문과 댓글을 유도하는 문구를 포함하라.\n"
"주의: 너무 가벼운 톤은 피하되 주제의 중요성을 해치지 말라."
)
elif tone == "일반적인":
tone_prompt = (
"일반적인:\n"
"1. 톤과 어조: 중립적이고 객관적인 톤을 유지하며, 적절한 존댓말(예: '~합니다', '~입니다')을 사용하라.\n"
"2. 내용 구조: 명확한 주제 제시와 논리적인 전개, 소제목 및 단락 구분을 활용하라.\n"
"3. 용어 및 설명: 이해하기 쉬운 용어와 간단한 설명을 사용하고, 객관적인 정보를 제공하라.\n"
"4. 독자 상호작용: 독자의 생각을 묻는 질문과 추가 정보를 제공하는 키워드를 포함하라.\n"
"5. 마무리: 주요 내용을 간략히 요약하고 추가 정보를 안내하라."
)
elif tone == "전문적인":
tone_prompt = (
"전문적인:\n"
"1. 톤과 구조: 공식적이고 학술적인 톤을 사용하며, 명확한 서론, 본론, 결론 구조로 체계적으로 전개하라.\n"
"2. 내용 구성: 복잡한 개념을 정확하게 전달할 수 있도록 전문 용어와 심층 분석을 활용하라.\n"
"3. 데이터 활용: 통계, 연구 결과, 전문가 의견 등을 인용하여 신뢰성을 높이라.\n"
"4. 텍스트 구조화: 번호 매기기, 기울임꼴, 들여쓰기를 활용하여 논리적 구조를 강조하라.\n"
"5. 마무리: 핵심 논점을 재강조하고 향후 연구나 실무적 함의를 제시하라."
)
else:
tone_prompt = "아래의 참조글들을 참고하여 블로그 글을 생성하라."
# 최종 system_message는 tone_prompt와 base_prompt를 결합하여 구성
system_message = tone_prompt + "\n" + base_prompt
# 프롬프트에 참조글 내용을 반영 (참고글은 직접 출력하지 않도록 주의)
question = f"참조글 1: {ref1}\n참조글 2: {ref2}\n참조글 3: {ref3}\n위 내용을 참고하여 주제와 상황에 맞는 블로그 글을 작성하라. 단, 참고글의 내용을 그대로 인용하지 말라."
# 고급 설정은 코드 내부 기본값으로 지정
max_tokens = 2000
temperature = 0.7
top_p = 0.95
return respond_chatgpt_qna(
question=question,
system_message=system_message,
max_tokens=max_tokens,
temperature=temperature,
top_p=top_p
)
with gr.Blocks() as demo:
gr.Markdown("# 블로그 생성기")
tone_radio = gr.Radio(
choices=["친근하게", "일반적인", "전문적인"],
label="말투바꾸기",
value="일반적인"
)
ref1_text = gr.Textbox(label="참조글 1", lines=5)
ref2_text = gr.Textbox(label="참조글 2", lines=5)
ref3_text = gr.Textbox(label="참조글 3", lines=5)
answer_output = gr.Textbox(label="결과", lines=10, interactive=False)
submit_button = gr.Button("전송")
submit_button.click(
fn=merge_and_call,
inputs=[tone_radio, ref1_text, ref2_text, ref3_text],
outputs=answer_output
)
if __name__ == "__main__":
demo.launch()