import streamlit as st from together import Together import os from typing import Iterator from PIL import Image import base64 from PyPDF2 import PdfReader API_KEY = os.getenv("TOGETHER_API_KEY") if not API_KEY: raise ValueError("API key is missing! Make sure TOGETHER_API_KEY is set in the Secrets.") # Initialize the Together client @st.cache_resource def get_client(): return Together(api_key=API_KEY) def process_file(file) -> str: """Process uploaded file and return its content""" if file is None: return "" try: if file.type == "application/pdf": text = "" pdf_reader = PdfReader(file) for page in pdf_reader.pages: text += page.extract_text() + "\n" return text elif file.type.startswith("image/"): return base64.b64encode(file.getvalue()).decode("utf-8") else: return file.getvalue().decode('utf-8') except Exception as e: st.error(f"파일 처리 중 오류 발생: {str(e)}") return "" def generate_response( message: str, history: list[tuple[str, str]], system_message: str, max_tokens: int, temperature: float, top_p: float, files=None ) -> Iterator[str]: client = get_client() try: # 메시지 형식 수정 messages = [{"role": "system", "content": system_message}] # 히스토리 추가 for user_msg, assistant_msg in history: messages.append({"role": "user", "content": user_msg}) messages.append({"role": "assistant", "content": assistant_msg}) # 현재 메시지와 파일 내용 추가 current_content = message if files: file_contents = [] for file in files: content = process_file(file) if content: file_contents.append(f"파일 내용:\n{content}") if file_contents: current_content = current_content + "\n\n" + "\n\n".join(file_contents) messages.append({"role": "user", "content": current_content}) # API 호출 시도 try: stream = client.chat.completions.create( model="deepseek-ai/DeepSeek-R1", messages=messages, max_tokens=max_tokens, temperature=temperature, top_p=top_p, stream=True ) for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: yield chunk.choices[0].delta.content except Exception as e: if "rate limit" in str(e).lower(): yield "죄송합니다. API 호출 한도에 도달했습니다. 잠시 후 다시 시도해주세요." else: yield f"API 호출 중 오류가 발생했습니다: {str(e)}" except Exception as e: yield f"오류가 발생했습니다: {str(e)}" def main(): st.set_page_config(page_title="DeepSeek 채팅", page_icon="💭", layout="wide") if "messages" not in st.session_state: st.session_state.messages = [] st.title("DeepSeek 채팅") st.markdown("DeepSeek AI 모델과 대화하세요. 필요한 경우 파일을 업로드할 수 있습니다.") with st.sidebar: st.header("설정") system_message = st.text_area( "시스템 메시지", value="당신은 깊이 있게 생각하는 AI입니다. 문제를 깊이 고려하고 체계적인 추론 과정을 통해 올바른 해결책을 도출하기 위해 매우 긴 사고 체인을 사용할 수 있습니다. 반드시 한글로 답변하세요.", height=100 ) max_tokens = st.slider("최대 토큰 수", 1, 8192, 8192) temperature = st.slider("온도", 0.1, 4.0, 0.0, 0.1) top_p = st.slider("Top-p", 0.1, 1.0, 0.95, 0.05) uploaded_file = st.file_uploader( "파일 업로드 (선택사항)", type=['txt', 'py', 'md', 'pdf', 'png', 'jpg', 'jpeg'], accept_multiple_files=True ) for message in st.session_state.messages: with st.chat_message(message["role"]): st.write(message["content"]) if prompt := st.chat_input("무엇을 알고 싶으신가요?"): st.session_state.messages.append({"role": "user", "content": prompt}) with st.chat_message("user"): st.write(prompt) with st.chat_message("assistant"): response_placeholder = st.empty() full_response = "" history = [(msg["content"], next_msg["content"]) for msg, next_msg in zip(st.session_state.messages[::2], st.session_state.messages[1::2])] for response_chunk in generate_response( prompt, history, system_message, max_tokens, temperature, top_p, uploaded_file ): full_response += response_chunk response_placeholder.markdown(full_response + "▌") response_placeholder.markdown(full_response) st.session_state.messages.append({"role": "assistant", "content": full_response}) if __name__ == "__main__": main()