import os import time import google.generativeai as genai import streamlit as st import re from streamlit_chat import message # Google Generative AI API 설정 genai.configure(api_key=os.environ["GEMINI_API_KEY"]) # 모델 설정 generation_config = { "temperature": 1, "top_p": 0.95, "top_k": 40, "max_output_tokens": 8192, "response_mime_type": "text/plain", } safety_settings = [ {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, ] # 전역 변수로 chat_session 초기화 chat_session = None def start_new_chat_session(): global chat_session chat_session = ( genai.GenerativeModel( model_name="gemini-2.0-flash", safety_settings=safety_settings, generation_config=generation_config, system_instruction="""당신은 뛰어난 전문성을 갖춘 과학자이다. 또 초등학교 교사이기도 하다. 과학 교과 내용 전문가입니다. 학생이 과학적 개념이나 원리에 대해 질문하면 구체적인 예시를 들어 친절하게 설명해주세요. 학생들이 자신들의 탐구 계획이나 실험 방법 등에 대한 질문을 하면 탐구 과정이나 실험 절차나 팁을 알려주세요.""", ) .start_chat(history=[]) ) # 초기 세션 시작 start_new_chat_session() # Streamlit 앱 설정 st.set_page_config(page_title="AI 과학자", layout="centered") st.markdown( """
AI 과학자
과학에 대해 궁금한 점을 AI 과학자에게 질문하세요, 자유탐구에 대한 조언을 구하세요.
""", unsafe_allow_html=True ) # 채팅 히스토리 관리 if "history" not in st.session_state: st.session_state.history = [] # 채팅 세션 초기화 if "chat_session" not in st.session_state: st.session_state.chat_session = chat_session # 채팅 메시지 출력 섹션 chat_container = st.container() # 사용자 입력 받기 user_input = st.text_input( "입력", key="user_input", placeholder="여기에 질문을 입력하세요...", help="과학적 개념이나 탐구 방법에 대한 질문을 입력하세요." ) def respond(user_input): st.session_state.history.append({"user": user_input, "ai": ""}) try: response = st.session_state.chat_session.send_message(user_input, stream=True) full_text = "" # 스트리밍 응답 처리 for chunk in response: chunk_text = chunk.text # 문장 단위로 분리하여 실시간 출력 for sentence in chunk_text.split("."): sentence = sentence.strip() + ". " # 숫자 또는 * 로 시작하는 경우 줄 바꿈 추가 if re.match(r"^\d+\.", sentence) or sentence.startswith("* "): full_text += "\n" + sentence else: full_text += sentence # 히스토리 최신 항목 업데이트 st.session_state.history[-1]["ai"] = full_text time.sleep(0.03) # 출력 속도 조절 except Exception as e: st.session_state.history[-1]["ai"] = f"에러 발생: {str(e)}" # 응답 생성 및 출력 if user_input: respond(user_input) # 채팅 메시지 출력 with chat_container: st.markdown("
", unsafe_allow_html=True) for chat in st.session_state.history: if "user" in chat: message(chat["user"], is_user=True, key=f"user_{chat['user']}") if "ai" in chat: message(chat["ai"], is_user=False, key=f"ai_{chat['ai']}") st.markdown("
", unsafe_allow_html=True) # 초기화 버튼 클릭 시 if st.button("초기화"): start_new_chat_session() st.session_state.history = []