""" Gemini 챗봇 - Gradio 버전 Google Search로 최신 정보를 검색하는 AI 챗봇 """ import os import json import datetime from google import genai from google.genai import types import gradio as gr # ============================================================ # 1. Gemini에게 메시지 보내기 # ============================================================ def send_message(user_message, chat_history, api_key, system_prompt, use_search): """사용자 메시지를 Gemini에게 보내고 응답을 받습니다.""" # API Key 확인 if not api_key or not api_key.strip(): chat_history.append({"role": "user", "content": user_message}) chat_history.append({"role": "assistant", "content": "⚠️ API Key를 입력해주세요."}) return "", chat_history # 빈 메시지 확인 if not user_message or not user_message.strip(): return "", chat_history # 클라이언트 생성 client = genai.Client(api_key=api_key.strip()) # 현재 날짜를 시스템 프롬프트에 추가 today = datetime.date.today().strftime("%Y-%m-%d") base_instruction = f"오늘 날짜는 {today}입니다. 최신 정보를 기준으로 답변하세요." if system_prompt and system_prompt.strip(): full_instruction = f"{base_instruction}\n{system_prompt.strip()}" else: full_instruction = base_instruction # 도구 설정 (Google Search) tools = [] if use_search: tools = [types.Tool(google_search=types.GoogleSearch())] # 설정 config = types.GenerateContentConfig( system_instruction=full_instruction, tools=tools if tools else None, ) # 대화 기록을 Gemini 형식으로 변환 contents = [] for msg in chat_history: content = msg["content"] if isinstance(content, list): content = "".join(part["text"] for part in content if "text" in part) role = "user" if msg["role"] == "user" else "model" contents.append(types.Content(role=role, parts=[types.Part(text=content)])) contents.append(types.Content(role="user", parts=[types.Part(text=user_message)])) # 메시지 전송 try: response = client.models.generate_content( model="gemini-2.5-flash-lite", contents=contents, config=config, ) reply = response.text except Exception as e: reply = f"❌ 오류 발생: {str(e)}" # 대화 기록에 추가 chat_history.append({"role": "user", "content": user_message}) chat_history.append({"role": "assistant", "content": reply}) return "", chat_history # ============================================================ # 2. 대화 기록 저장 # ============================================================ def save_chat(chat_history): """대화 기록을 JSON 파일로 저장합니다.""" if not chat_history: return gr.update(value=None) now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"chat_{now}.json" filepath = os.path.join("saved_chats", filename) os.makedirs("saved_chats", exist_ok=True) with open(filepath, "w", encoding="utf-8") as f: json.dump(chat_history, f, ensure_ascii=False, indent=2) return gr.update(value=filepath) def clear_chat(): """대화 기록을 초기화합니다.""" return [] # ============================================================ # 3. Gradio UI 만들기 # ============================================================ with gr.Blocks( title="Gemini 챗봇", ) as app: gr.Markdown("# Gemini 챗봇") gr.Markdown("Google Gemini API를 사용하는 AI 챗봇입니다.") with gr.Row(): # --- 왼쪽: 설정 패널 --- with gr.Column(scale=1): gr.Markdown("## 설정") api_key = gr.Textbox( label="Gemini API Key", placeholder="API Key를 입력하세요", type="password", ) system_prompt = gr.Textbox( label="시스템 프롬프트", placeholder="예: 당신은 친절한 한국어 AI 비서입니다.", lines=3, ) use_search = gr.Checkbox( label="Google Search 사용", value=True, ) gr.Markdown("---") gr.Markdown("## 대화 관리") save_btn = gr.Button("대화 저장", variant="secondary") save_output = gr.File(label="저장된 파일") # --- 오른쪽: 채팅 영역 --- with gr.Column(scale=3): chatbot = gr.Chatbot( label="대화", height=500, ) with gr.Row(): msg = gr.Textbox( label="메시지 입력", placeholder="메시지를 입력하세요...", scale=4, show_label=False, ) send_btn = gr.Button("전송", variant="primary", scale=1) clear_btn = gr.Button("대화 초기화") # --- 이벤트 연결 --- send_btn.click( fn=send_message, inputs=[msg, chatbot, api_key, system_prompt, use_search], outputs=[msg, chatbot], ) msg.submit( fn=send_message, inputs=[msg, chatbot, api_key, system_prompt, use_search], outputs=[msg, chatbot], ) clear_btn.click(fn=clear_chat, outputs=[chatbot]) save_btn.click(fn=save_chat, inputs=[chatbot], outputs=[save_output]) # ============================================================ # 4. 앱 실행 # ============================================================ if __name__ == "__main__": app.launch(server_name="0.0.0.0", server_port=7860)