import os import gradio as gr from dotenv import load_dotenv from openai import OpenAI import logging import time import uuid # 로깅 설정 - INFO 레벨로 변경 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # 환경 변수 로드 load_dotenv() # API 키 설정 OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") logger.info("API 키 설정 완료") # OpenAI 클라이언트 설정 openai_client = OpenAI(api_key=OPENAI_API_KEY) # 모델별 프롬프트 정의 GPT_PROMPTS = { "문법 교정": """ 1. 주어진 텍스트의 문법을 검토하고 교정하라 2. 반드시 원본 텍스트를 유지하면서 문법적인 부분에서만 수정하라 3. 맞춤법, 띄어쓰기, 문장 부호 등을 한국어 문법에 맞게 정확하게 수정하라 4. 절대 원본 텍스트 이외의 다른 부가적인 설명을 출력하지 말 것 - '수정된 텍스트', '개선된 텍스트'등 출력금지 """, "문장 다듬기": """ ## 문장 구조 검토 - **불필요한 문구 제거:** 필수적이지 않은 표현을 삭제하여 문장을 간결하게 유지합니다. - **주어-서술어 명확성:** 문장의 주어와 서술어를 명확히 하여 의미 전달이 실수 없이 이루어지도록 합니다. - **긴 문장 분리:** 지나치게 긴 문장은 읽기 쉽게 여러 문장으로 나눕니다. ## 단락 구성 점검 - **핵심 주제 확인:** 각 단락이 명확한 핵심 주제나 중심 생각을 가지고 있는지 확인합니다. - **자연스러운 연결:** 단락 간의 흐름이 자연스럽도록 연결어를 적절히 사용합니다. - **단락 길이 조절:** 너무 길거나 짧은 단락은 조정하여 균형을 맞춥니다. ## 어휘 개선 - **외래어 순화:** 불필요한 외래어를 한국어로 대체합니다. - **단어 구체화:** 모호한 표현은 보다 명확한 용어로 바꿉니다. - **중복 표현 삭제:** 의미가 중복되는 단어를 제거하여 문장의 효율성을 높입니다. ## 전달력 강화 - **핵심 메시지 부각:** 문장에서 가장 중요한 메시지가 잘 드러나도록 조정합니다. - **논리적 흐름 개선:** 전체 문단의 논리적인 흐름이 자연스럽도록 만듭니다. - **독자 이해 고려:** 독자가 쉽게 이해할 수 있는지 고려하여 표현합니다. ## 일관성 확보 - **문체 통일:** 문장의 톤과 스타일이 일정한지 유지합니다. - **용어 통일:** 동일한 용어를 일관성 있게 사용합니다. - **시제 일관성:** 시제가 일정하게 유지되도록 합니다. # Output Format - 원본과 동일한 말투와 어조를 유지하여, 필요한 부분만을 다듬은 텍스트로 출력합니다. - 부가적인 설명 없이 단순히 개선된 텍스트만을 제공합니다. """, "명언인용하여 다듬기": """ 1. 주어진 텍스트의 문장에 적절한 명언이나 격언을 딱한번 인용하여 더 설득력 있고 인상적인 내용으로 발전시켜라 2. 인용구를 문맥에 맞게 자연스럽게 녹아들게 작성하라 3. 원본 텍스트의 내용과 분위기를 최대한 반영하라 4. 절대 원본 텍스트 이외의 다른 부가적인 설명을 출력하지 말 것 - '수정된 텍스트', '개선된 텍스트'등 출력금지 """, "내 마음대로 다듬기": """ 1. 사용자가 제공한 페르소나와 목적에 맞게 텍스트를 다듬어라 2. 텍스트의 전반적인 톤과 분위기를 사용자가 설정한 방향에 맞추어 수정하라 3. 명확성, 일관성, 독창성을 유지하며 개선하라 4. 반드시 사용자 지정 지침에 따라 수정하라 5. 절대 다른 부가적인 설명을 출력하지 말 것 - '수정된 텍스트', '개선된 텍스트'등 출력금지 """, } def process_text(input_text, improvement_type, custom_purpose, persona, temperature, top_p): """GPT 모델용 텍스트 처리 함수""" try: print("텍스트 처리 시작") request_id = str(uuid.uuid4())[:8] timestamp_micro = int(time.time() * 1000000) % 1000 if improvement_type == "내 마음대로 다듬기": purpose = f"다음 페르소나를 가지고 텍스트를 다듬으세요: {persona}\n\n목적: {custom_purpose}" else: purpose = GPT_PROMPTS[improvement_type] response = openai_client.chat.completions.create( model="gpt-4o-mini", messages=[ { "role": "system", "content": f"REQ-{request_id}-{timestamp_micro}" }, { "role": "user", "content": f"다음 텍스트를 목적에 맞게 다듬어라.\n\n텍스트: {input_text}\n\n목적: {purpose}" } ], max_tokens=2000, temperature=temperature, top_p=top_p ) print("텍스트 처리 완료") return response.choices[0].message.content except Exception as e: print("텍스트 처리 실패") logger.error(f"처리 중 오류 발생: {str(e)}") return f"오류 발생: {str(e)}" def create_interface(): css = """ footer { visibility: hidden; } """ with gr.Blocks(theme=gr.themes.Soft( primary_hue=gr.themes.Color( c50="#FFF7ED", # 가장 밝은 주황 c100="#FFEDD5", c200="#FED7AA", c300="#FDBA74", c400="#FB923C", c500="#F97316", # 기본 주황 c600="#EA580C", c700="#C2410C", c800="#9A3412", c900="#7C2D12", # 가장 어두운 주황 c950="#431407", ), secondary_hue="zinc", # 모던한 느낌의 회색 계열 neutral_hue="zinc", font=("Pretendard", "sans-serif") ), css=css) as demo: gr.Markdown( """ # ✨ 텍스트 개선 도구 ### 텍스트를 목적에 맞게 개선해보세요 """, elem_classes="text-3xl" ) with gr.Row(): with gr.Column(scale=1): input_text = gr.Textbox( label="원본 텍스트", placeholder="여기에 개선하고 싶은 텍스트를 입력하세요...1,000자 이상은 모델에 따라 퀄리티가 떨어질 수 있습니다", lines=6 ) improvement_type = gr.Radio( choices=["문법 교정", "문장 다듬기", "명언인용하여 다듬기", "내 마음대로 다듬기"], label="개선 방향", value="문법 교정" ) custom_purpose = gr.Textbox( label="개선 목적/방향성", placeholder="텍스트를 어떤 방향으로 개선하고 싶으신지 설명해주세요...", lines=4, visible=False ) persona = gr.Textbox( label="페르소나 적용하기", placeholder="어떤 역할, 성격을 가지고 텍스트를 다듬길 원하시나요? (예: 유머러스한 개그맨, 진지한 교수 등)", lines=4, visible=False ) with gr.Row(visible=False) as generation_settings: temperature = gr.Slider( minimum=0.0, maximum=1.0, value=0.7, step=0.1, label="Temperature", info="높을수록 더 창의적인 결과가 생성됩니다" ) top_p = gr.Slider( minimum=0.0, maximum=1.0, value=0.9, step=0.1, label="Top P", info="높을수록 더 다양한 단어를 사용합니다" ) submit_btn = gr.Button( "✨ 텍스트 개선하기", variant="primary", size="lg" ) gr.Markdown(""" ### 💡 사용 가이드 1. 개선하고 싶은 텍스트를 입력하세요 2. 개선 방향을 선택하세요 3. '내 마음대로 다듬기' 선택 시: - 개선 목적/방향성을 입력하세요 - 페르소나를 설정하세요 - Temperature, Top-p를 설정해보세요 4. '텍스트 개선하기' 버튼을 클릭하세요 """) with gr.Column(scale=1): output_text = gr.Textbox( label="개선된 텍스트", lines=35, show_copy_button=True ) def update_custom_inputs_visibility(choice): is_custom = choice == "내 마음대로 다듬기" return { custom_purpose: gr.update(visible=is_custom), persona: gr.update(visible=is_custom), generation_settings: gr.update(visible=is_custom) } improvement_type.change( fn=update_custom_inputs_visibility, inputs=[improvement_type], outputs=[custom_purpose, persona, generation_settings] ) submit_btn.click( fn=process_text, inputs=[input_text, improvement_type, custom_purpose, persona, temperature, top_p], outputs=output_text, api_name="improve_text" ) return demo if __name__ == "__main__": logger.info("애플리케이션 시작") demo = create_interface() demo.queue() demo.launch()