File size: 4,644 Bytes
1d355ad
f74a421
22032f3
c93bda6
90eca96
c93bda6
1d355ad
c93bda6
22032f3
 
217a78d
22032f3
85cbf3c
4790879
7fbfbed
1693242
4790879
22032f3
85cbf3c
 
 
 
 
 
 
 
c7f7960
bcd0d54
85cbf3c
c7f7960
85cbf3c
 
6e044c7
85cbf3c
 
9321a7b
 
 
85cbf3c
 
 
 
 
 
d335f3a
c93bda6
6728150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07f9b67
c93bda6
 
 
ceb5c50
c93bda6
 
 
 
57336d1
 
 
c93bda6
6728150
 
 
 
c93bda6
 
 
ceb5c50
c93bda6
ceb5c50
90eca96
 
 
 
ceb5c50
90eca96
 
 
 
 
 
 
 
 
c93bda6
 
90eca96
 
ceb5c50
c93bda6
d335f3a
c93bda6
 
 
c7f7960
c93bda6
57336d1
6728150
57336d1
 
 
 
 
6728150
d335f3a
c93bda6
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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(
    """
    <style>
    .main {
        background-color: #f0f2f6;
        padding: 20px;
        border-radius: 10px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }
    .chat-container {
        max-height: 500px;
        overflow-y: auto;
        padding: 10px;
        background-color: #ffffff;
        border-radius: 10px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
    </style>
    <div style='font-size: 30px; font-weight: bold; text-align: center;'>AI 과학자</div>
    <div style='text-align: center; margin-bottom: 20px;'>과학에 대해 궁금한 점을 AI 과학자에게 질문하세요, 자유탐구에 대한 조언을 구하세요.</div>
    """,
    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("<div class='chat-container'>", 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("</div>", unsafe_allow_html=True)

# 초기화 버튼 클릭 시
if st.button("초기화"):
    start_new_chat_session()
    st.session_state.history = []