File size: 5,767 Bytes
62197bc
6892e38
 
0a0002d
 
40eafe3
0a0002d
40eafe3
 
 
 
 
0a0002d
40eafe3
0a0002d
40eafe3
 
 
0a0002d
3f2c65f
6892e38
9af2f27
 
010780b
9af2f27
010780b
62197bc
e3dbd7b
 
 
62197bc
e3dbd7b
62197bc
 
 
 
 
e652a1b
62197bc
e652a1b
 
 
 
e3dbd7b
5852990
62197bc
0a0002d
bfe3411
e652a1b
 
 
9af2f27
5852990
e59426c
9972d5c
e483831
bfe3411
5852990
e483831
 
 
 
e59426c
 
ce381eb
e59426c
 
 
 
5852990
40eafe3
5852990
 
 
0db006a
0a0002d
0db006a
 
5852990
 
 
40eafe3
0a0002d
5852990
 
 
 
0a0002d
e59426c
40eafe3
 
0a0002d
 
 
 
 
 
40eafe3
0a0002d
 
 
 
 
 
 
 
 
 
 
4f4c601
40eafe3
0a0002d
 
 
010780b
e652a1b
9af2f27
d3be36d
010780b
0a0002d
62197bc
 
 
 
4f4c601
010780b
 
 
 
e483831
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
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 "未設定")