import streamlit as st import os from groq import Groq import re # コードブロックを抽出し、プレースホルダーに置き換える関数 def extract_code_blocks(text): code_blocks = re.findall(r'```.*?```', text, re.DOTALL) for i, block in enumerate(code_blocks): placeholder = f"<CODE_BLOCK_{i+1}>" text = text.replace(block, placeholder) return text, code_blocks # プレースホルダーを実際のコードブロックに置き換える関数 def reinsert_code_blocks(translated_text, code_blocks): for i, block in enumerate(code_blocks): placeholder = f"<CODE_BLOCK_{i+1}>" translated_text = translated_text.replace(placeholder, block) return translated_text # APIキーの設定 try: client = Groq(api_key=st.secrets["GROQ_API_KEY"]) st.success("APIクライアントが正常に設定されました。") except Exception as e: st.error(f"APIクライアントの設定に失敗しました: {e}") # Streamlitアプリケーションのタイトルと説明 st.title("Groq APIによるAIチャットボット") st.subheader("生成されたテキストがリアルタイムで表示されます") # 会話履歴の初期化(セッションごとに維持) if 'conversation_history' not in st.session_state: st.session_state['conversation_history'] = [] # 過去の会話履歴を表示 for entry in st.session_state['conversation_history']: st.chat_message(entry['role']).markdown(entry['content']) # ユーザー入力の受付 if prompt := st.chat_input("質問を入力してください:"): st.session_state['conversation_history'].append({"role": "user", "content": prompt}) st.chat_message("user").markdown(prompt) translated_prompt = "" response_text = "" translated_response_text = "" with st.chat_message("assistant"): message_placeholder = st.empty() # 応答の一時表示用の空要素 try: # 日本語の質問を英語に翻訳(gemma2-9b-itを使用) translation_response = client.chat.completions.create( model="gemma2-9b-it", messages=[ {"role": "system", "content": "Translate the following Japanese text to English accurately without adding or omitting any details."}, {"role": "user", "content": prompt} ], stream=True, temperature=0.8, top_p=0.92 ) # 英語に翻訳された質問を蓄積 for chunk in translation_response: if hasattr(chunk.choices[0].delta, 'content'): chunk_text = chunk.choices[0].delta.content if chunk_text: translated_prompt += chunk_text # 英語に翻訳された質問をllama3-70b-8192で応答生成 response = client.chat.completions.create( model="llama3-70b-8192", messages=[ {"role": "system", "content": "Provide a detailed response including code examples."}, {"role": "user", "content": translated_prompt} ], stream=True ) # 応答の処理とコードブロックの抽出 full_response_text = "" for chunk in response: if hasattr(chunk.choices[0].delta, 'content'): chunk_text = chunk.choices[0].delta.content if chunk_text: full_response_text += chunk_text # コードブロックを抽出し、プレースホルダーを挿入 text_with_placeholders, code_blocks = extract_code_blocks(full_response_text) # 非コード部分を日本語に翻訳 final_translation_response = client.chat.completions.create( model="gemma2-9b-it", messages=[ {"role": "system", "content": "Translate the following English text to Japanese, keeping all code blocks in their original form."}, {"role": "user", "content": text_with_placeholders} ], stream=True, temperature=0.8, top_p=0.92 ) for chunk in final_translation_response: if hasattr(chunk.choices[0].delta, 'content'): chunk_text = chunk.choices[0].delta.content if chunk_text: translated_response_text += chunk_text # コードブロックをプレースホルダーの位置に再挿入 final_output = reinsert_code_blocks(translated_response_text, code_blocks) message_placeholder.markdown(final_output) st.session_state['conversation_history'].append({"role": "assistant", "content": final_output}) st.success("APIからの応答が正常に処理されました。") except Exception as e: error_message = f"APIリクエストの処理中にエラーが発生しました: {e}" st.error(error_message) st.write("Error:", error_message) # エラーの表示 # 会話履歴をリセットするボタン if st.button("会話をリセット"): st.session_state['conversation_history'] = [] st.rerun() # デバッグ情報の表示(開発中のみ使用) if st.checkbox("デバッグ情報を表示"): st.write("会話履歴:", st.session_state['conversation_history']) st.write("API Key設定状況:", "設定済み" if "GROQ_API_KEY" in st.secrets else "未設定")