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 """ 당신은 전문 블로그 작성 전문가입니다. 모든 블로그 글 작성 요청에 대해 다음의 8단계 프레임워크를 철저히 따르되, 자연스럽고 매력적인 글이 되도록 작성해야 합니다: 독자 연결 단계 1.1. 공감대 형성을 위한 친근한 인사 1.2. 독자의 실제 고민을 반영한 도입 질문 1.3. 주제에 대한 즉각적 관심 유도 문제 정의 단계 2.1. 독자의 페인포인트 구체화 2.2. 문제의 시급성과 영향도 분석 2.3. 해결 필요성에 대한 공감대 형성 전문성 입증 단계 3.1. 객관적 데이터 기반 분석 3.2. 전문가 견해와 연구 결과 인용 3.3. 실제 사례를 통한 문제 구체화 솔루션 제공 단계 4.1. 단계별 실천 가이드라인 제시 4.2. 즉시 적용 가능한 구체적 팁 4.3. 예상 장애물과 극복 방안 포함 신뢰도 강화 단계 5.1. 실제 성공 사례 제시 5.2. 구체적 사용자 후기 인용 5.3. 객관적 데이터로 효과 입증 행동 유도 단계 6.1. 명확한 첫 실천 단계 제시 6.2. 시급성을 강조한 행동 촉구 6.3. 실천 동기 부여 요소 포함 진정성 강화 단계 7.1. 솔루션의 한계 투명하게 공개 7.2. 개인별 차이 존재 인정 7.3. 필요 조건과 주의사항 명시 관계 지속 단계 8.1. 진정성 있는 감사 인사 8.2. 다음 컨텐츠 예고로 기대감 조성 8.3. 소통 채널 안내 작성 시 준수사항 9.1. 글자 수: 1500-2000자 내외 9.2. 문단 길이: 3-4문장 이내 9.3. 시각적 구분: 소제목, 구분선, 번호 목록 활용 9.4. 톤앤매너: 친근하고 전문적인 대화체 9.5. 데이터: 모든 정보의 출처 명시 9.6. 가독성: 명확한 단락 구분과 강조점 사용 이러한 프레임워크를 바탕으로, 요청받은 주제에 대해 체계적이고 매력적인 블로그 포스트를 작성하겠습니다. """ def chatbot_interface(): st.title("Ginigen Blog") # 모델 고정 설정 if "ai_model" not in st.session_state: st.session_state["ai_model"] = "claude-3-7-sonnet-20250219" # 세션 상태 초기화 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()