IDEA-DESIGN / app.py
ginipick's picture
Update app.py
0228286 verified
raw
history blame
6.09 kB
import os
import streamlit as st
import json
import anthropic
# API ์„ค์ •
api_key = os.environ.get("API_KEY")
client = anthropic.Anthropic(api_key=api_key)
# ์ตœ๋Œ€ ํ† ํฐ ์ˆ˜ ์„ค์ • (Claude-3 Sonnet์˜ ์ตœ๋Œ€ ํ† ํฐ ์ˆ˜)
MAX_TOKENS = 7999
def get_system_prompt():
return """์ œ ์ด๋ฆ„์€ Mouse-II์ž…๋‹ˆ๋‹ค.
[๋ชฉ์ ๊ณผ ์ „๋ฌธ์„ฑ]
- AI ์„œ๋น„์Šค ๊ฐœ๋ฐœ์— ํŠนํ™”๋œ ์ „๋ฌธ ์–ด์‹œ์Šคํ„ดํŠธ๋กœ์„œ, Python๊ณผ Gradio ๊ธฐ๋ฐ˜ AI ์„œ๋น„์Šค ๊ฐœ๋ฐœ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค
- Hugging Face๋ฅผ ์ฃผ์š” ๋ฐฐํฌ ํ”Œ๋žซํผ์œผ๋กœ ํ•˜๋Š” ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค
[๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค ์ง€์›]
1. ์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„
- ์‚ฌ์šฉ์ž์˜ AI ์„œ๋น„์Šค ๊ฐœ๋ฐœ ๋‹ˆ์ฆˆ ํŒŒ์•…
- ๊ตฌํ˜„ ๊ฐ€๋Šฅ์„ฑ ๋ฐ ๊ธฐ์ˆ  ์Šคํƒ ๊ฒ€ํ† 
- Hugging Face ๋ฐฐํฌ ์ ํ•ฉ์„ฑ ํ‰๊ฐ€
2. ์„ค๊ณ„ ๋‹จ๊ณ„
- Gradio UI/UX ์„ค๊ณ„
- ํ•„์š”ํ•œ AI ๋ชจ๋ธ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ์ •
- ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ์„ค๊ณ„
- ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ์˜ˆ์™ธ ์ƒํ™ฉ ๋Œ€์‘ ๋ฐฉ์•ˆ
3. ๊ตฌํ˜„ ๊ฐ€์ด๋“œ
- Python ์ฝ”๋“œ ์ž‘์„ฑ ์ง€์›
- Gradio ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„
- requirements.txt ์ƒ์„ธ ๋ช…์„ธ
- ํ™˜๊ฒฝ ์„ค์ • ๊ฐ€์ด๋“œ
4. ํ…Œ์ŠคํŠธ ๋ฐ ๊ฒ€์ฆ
- ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ œ๊ณต
- ์„ฑ๋Šฅ ์ตœ์ ํ™” ์ œ์•ˆ
- ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ถ„์„
- ์‘๋‹ต ์‹œ๊ฐ„ ๊ฐœ์„  ๋ฐฉ์•ˆ
5. ๋ฐฐํฌ ์ง€์›
- Hugging Face Spaces ๋ฐฐํฌ ์ ˆ์ฐจ ์•ˆ๋‚ด
- ๋ณด์•ˆ ์„ค์ • ๊ฐ€์ด๋“œ
- ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ์ตœ์ ํ™”
- ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐฉ์•ˆ ์ œ์‹œ
[์ฝ”๋“œ ์ƒ์„ฑ ๊ทœ์น™]
- ๋ชจ๋“  ์ฝ”๋“œ ์ƒ์„ฑ์‹œ requirements.txt ๋‚ด์šฉ ํ•„์ˆ˜ ํฌํ•จ
- ๋ฒ„์ „ ํ˜ธํ™˜์„ฑ์„ ๊ณ ๋ คํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ช…์„ธ
- ์‹คํ–‰ ํ™˜๊ฒฝ ์ œ์•ฝ์‚ฌํ•ญ ๋ช…์‹œ
- ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๊ณ ๋ ค์‚ฌํ•ญ ํ‘œ๊ธฐ
[์‘๋‹ต ์›์น™]
- ์ •ํ™•ํ•˜๊ณ  ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ ์ œ๊ณต
- ๋ช…ํ™•ํ•œ ์„ค๋ช…๊ณผ ์ฃผ์„ ํฌํ•จ
- ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ์˜ˆ์™ธ ์ƒํ™ฉ ๊ณ ๋ ค
- ๋‹จ๊ณ„๋ณ„ ๊ตฌํ˜„ ๊ฐ€์ด๋“œ ์ œ๊ณต
- ํ•œ๊ตญ์–ด๋กœ ์ž์—ฐ์Šค๋Ÿฌ์šด ์†Œํ†ต
- ๋ณด์•ˆ ๋ฐ ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ ์ค€์ˆ˜
[ํ’ˆ์งˆ ๋ณด์ฆ]
- ์ฝ”๋“œ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์ œ๊ณต
- ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ์•ˆ ์ œ์‹œ
- ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ถ„์„
- ์‘๋‹ต์‹œ๊ฐ„ ์ธก์ • ๊ฒฐ๊ณผ
- ์—๋Ÿฌ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ ๊ฒ€ํ† 
์ €๋Š” ํ•ญ์ƒ Mouse-II๋กœ์„œ ์ „๋ฌธ์ ์ด๊ณ  ์ •ํ™•ํ•œ AI ์„œ๋น„์Šค ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ๋ฅผ ์ œ๊ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค."""
def chatbot_interface():
st.title("Ginigen Blog")
# ๋ชจ๋ธ ๊ณ ์ • ์„ค์ •
if "ai_model" not in st.session_state:
st.session_state["ai_model"] = "claude-3-5-sonnet-20241022"
# ์„ธ์…˜ ์ƒํƒœ ์ดˆ๊ธฐํ™”
if "messages" not in st.session_state:
st.session_state.messages = []
# ์ž๋™ ์ €์žฅ ๊ธฐ๋Šฅ
if "auto_save" not in st.session_state:
st.session_state.auto_save = True
# ๋Œ€ํ™” ๊ธฐ๋ก ๊ด€๋ฆฌ (์‚ฌ์ด๋“œ๋ฐ”)
st.sidebar.title("๋Œ€ํ™” ๊ธฐ๋ก ๊ด€๋ฆฌ")
# ์ž๋™ ์ €์žฅ ํ† ๊ธ€
st.session_state.auto_save = st.sidebar.toggle("์ž๋™ ์ €์žฅ", value=st.session_state.auto_save)
# ๋Œ€ํ™” ๊ธฐ๋ก ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
uploaded_file = st.sidebar.file_uploader("๋Œ€ํ™” ๊ธฐ๋ก ๋ถˆ๋Ÿฌ์˜ค๊ธฐ", type=['json'])
if uploaded_file is not None:
try:
content = uploaded_file.getvalue().decode()
if content.strip():
st.session_state.messages = json.loads(content)
st.sidebar.success("๋Œ€ํ™” ๊ธฐ๋ก์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค!")
else:
st.sidebar.warning("์—…๋กœ๋“œ๋œ ํŒŒ์ผ์ด ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค.")
except json.JSONDecodeError:
st.sidebar.error("์˜ฌ๋ฐ”๋ฅธ JSON ํ˜•์‹์˜ ํŒŒ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค.")
except Exception as e:
st.sidebar.error(f"ํŒŒ์ผ ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}")
# ๋Œ€ํ™” ๊ธฐ๋ก ์ดˆ๊ธฐํ™” ๋ฒ„ํŠผ
if st.sidebar.button("๋Œ€ํ™” ๊ธฐ๋ก ์ดˆ๊ธฐํ™”"):
st.session_state.messages = []
st.sidebar.success("๋Œ€ํ™” ๊ธฐ๋ก์ด ์ดˆ๊ธฐํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
# ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# ์‚ฌ์šฉ์ž ์ž…๋ ฅ
if prompt := st.chat_input("๋ฌด์—‡์„ ๋„์™€๋“œ๋ฆด๊นŒ์š”?"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# AI ์‘๋‹ต ์ƒ์„ฑ
with st.chat_message("assistant"):
message_placeholder = st.empty()
full_response = ""
# API ํ˜ธ์ถœ
with client.messages.stream(
max_tokens=MAX_TOKENS,
system=get_system_prompt(),
messages=[{"role": m["role"], "content": m["content"]} for m in st.session_state.messages],
model=st.session_state["ai_model"]
) as stream:
for text in stream.text_stream:
full_response += str(text) if text is not None else ""
message_placeholder.markdown(full_response + "โ–Œ")
message_placeholder.markdown(full_response)
st.session_state.messages.append({"role": "assistant", "content": full_response})
# ์ž๋™ ์ €์žฅ ๊ธฐ๋Šฅ
if st.session_state.auto_save:
try:
with open('chat_history_auto_save.json', 'w', encoding='utf-8') as f:
json.dump(st.session_state.messages, f, ensure_ascii=False, indent=4)
except Exception as e:
st.sidebar.error(f"์ž๋™ ์ €์žฅ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
# ๋Œ€ํ™” ๊ธฐ๋ก ๋‹ค์šด๋กœ๋“œ
if st.sidebar.button("๋Œ€ํ™” ๊ธฐ๋ก ๋‹ค์šด๋กœ๋“œ"):
json_history = json.dumps(st.session_state.messages, indent=4, ensure_ascii=False)
st.sidebar.download_button(
label="๋Œ€ํ™” ๊ธฐ๋ก ์ €์žฅํ•˜๊ธฐ",
data=json_history,
file_name="chat_history.json",
mime="application/json"
)
def main():
chatbot_interface()
if __name__ == "__main__":
main()