Jiangxz commited on
Commit
37086cb
·
verified ·
1 Parent(s): d6a9cf8

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +208 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ # 財政部財政資訊中心 江信宗
3
+
4
+ import gradio as gr
5
+ import openai
6
+ import time
7
+ import re
8
+ import os
9
+
10
+ MODELS = [
11
+ "Meta-Llama-3.1-405B-Instruct",
12
+ "Meta-Llama-3.1-70B-Instruct",
13
+ "Meta-Llama-3.1-8B-Instruct"
14
+ ]
15
+
16
+ API_BASE = "https://api.sambanova.ai/v1"
17
+
18
+ def create_client(api_key=None):
19
+ """Creates an OpenAI client instance."""
20
+ if api_key:
21
+ openai.api_key = api_key
22
+ else:
23
+ openai.api_key = os.getenv("YOUR_API_TOKEN")
24
+ return openai.OpenAI(api_key=openai.api_key, base_url=API_BASE)
25
+
26
+ def chat_with_ai(message, chat_history, system_prompt):
27
+ """Formats the chat history for the API call."""
28
+ # 初始化訊息列表,首先新增系統提示詞
29
+ messages = [{"role": "system", "content": system_prompt}]
30
+ # 遍歷聊天歷史,將使用者和AI機器人的對話新增到訊息列表中
31
+ for tup in chat_history:
32
+ # 獲取字典的第一個鍵(通常是使用者的訊息)
33
+ first_key = list(tup.keys())[0]
34
+ # 獲取字典的最後一個鍵(通常是AI機器人的回應)
35
+ last_key = list(tup.keys())[-1]
36
+ # 將使用者的訊息新增到messages列表中
37
+ messages.append({"role": "user", "content": tup[first_key]})
38
+ # 將AI機器人的回應新增到messages列表中
39
+ messages.append({"role": "assistant", "content": tup[last_key]})
40
+ # 新增當前使用者的訊息
41
+ messages.append({"role": "user", "content": message})
42
+ return messages
43
+
44
+ def respond(message, chat_history, model, system_prompt, thinking_budget, api_key):
45
+ """Sends the message to the API and gets the response."""
46
+ # 建立OpenAI客戶端
47
+ client = create_client(api_key)
48
+ # 格式化聊天歷史
49
+ messages = chat_with_ai(message, chat_history, system_prompt.format(budget=thinking_budget))
50
+ # 記錄開始時間
51
+ start_time = time.time()
52
+ try:
53
+ # 呼叫API獲取回應
54
+ completion = client.chat.completions.create(model=model, messages=messages)
55
+ response = completion.choices[0].message.content
56
+ # 計算思考時間
57
+ thinking_time = time.time() - start_time
58
+ return response, thinking_time
59
+ except Exception as e:
60
+ # 捕獲並返回錯誤資訊
61
+ error_message = f"Error: {str(e)}"
62
+ return error_message, time.time() - start_time
63
+
64
+ def parse_response(response):
65
+ """Parses the response from the API."""
66
+ # 使用正規表示式提取回答部分
67
+ answer_match = re.search(r'<answer>(.*?)</answer>', response, re.DOTALL)
68
+ # 使用正規表示式提取反思部分
69
+ reflection_match = re.search(r'<reflection>(.*?)</reflection>', response, re.DOTALL)
70
+ # 提取答案和反思內容,如果沒有匹配則設爲空字串
71
+ answer = answer_match.group(1).strip() if answer_match else ""
72
+ reflection = reflection_match.group(1).strip() if reflection_match else ""
73
+ # 提取所有步驟
74
+ steps = re.findall(r'<step>(.*?)</step>', response, re.DOTALL)
75
+ # 如果沒有提取到答案,則返回原始回應
76
+ if answer == "":
77
+ return response, "", ""
78
+ return answer, reflection, steps
79
+
80
+ def generate(message, history, model, system_prompt, thinking_budget, api_key):
81
+ """Generates the chatbot response."""
82
+ # 獲取AI回應和思考時間
83
+ response, thinking_time = respond(message, history, model, system_prompt, thinking_budget, api_key)
84
+ # 如果回應是錯誤資訊,直接返回
85
+ if response.startswith("Error:"):
86
+ return history + [({"role": "system", "content": response},)], ""
87
+ # 解析AI的回應
88
+ answer, reflection, steps = parse_response(response)
89
+ # 初始化訊息列表
90
+ messages = []
91
+ # 新增使用者的輸入
92
+ messages.append({"role": "user", "content": f'<div style="text-align: left;">{message}</div>'})
93
+ # 格式化AI回應的步驟和反思
94
+ formatted_steps = [f"Step {i}:{step}" for i, step in enumerate(steps, 1)]
95
+ all_steps = "<br>".join(formatted_steps) + f"<br><br>Reflection:{reflection}"
96
+ # 新增AI的推理過程和思考時間
97
+ messages.append({
98
+ "role": "assistant",
99
+ "content": f'<div style="text-align: left;">{all_steps}</div>',
100
+ "metadata": {"title": f"推理過程時間: {thinking_time:.2f} 秒"}
101
+ })
102
+ # 新增AI的最終答案
103
+ messages.append({"role": "assistant", "content": f"<b>{answer}</b>"})
104
+ # 返回更新後的歷史記錄和空字串(用於清空輸入框)
105
+ return history + messages, ""
106
+
107
+ DEFAULT_SYSTEM_PROMPT = """You are a helpful assistant in normal conversation.
108
+ When given a problem to solve, you are an expert problem-solving assistant.
109
+ Your task is to provide a detailed, step-by-step solution to a given question.
110
+ Follow these instructions carefully:
111
+ 1. Read the given question carefully and reset counter between <count> and </count> to {budget}
112
+ 2. Generate a detailed, logical step-by-step solution.
113
+ 3. Enclose each step of your solution within <step> and </step> tags.
114
+ 4. You are allowed to use at most {budget} steps (starting budget),
115
+ keep track of it by counting down within tags <count> </count>,
116
+ STOP GENERATING MORE STEPS when hitting 0, you don't have to use all of them.
117
+ 5. Do a self-reflection when you are unsure about how to proceed,
118
+ based on the self-reflection and reward, decides whether you need to return
119
+ to the previous steps.
120
+ 6. After completing the solution steps, reorganize and synthesize the steps
121
+ into the final answer within <answer> and </answer> tags.
122
+ 7. Provide a critical, honest and subjective self-evaluation of your reasoning
123
+ process within <reflection> and </reflection> tags.
124
+ 8. Assign a quality score to your solution as a float between 0.0 (lowest
125
+ quality) and 1.0 (highest quality), enclosed in <reward> and </reward> tags.
126
+ Example format:
127
+ <count> [starting budget] </count>
128
+ <step> [Content of step 1] </step>
129
+ <count> [remaining budget] </count>
130
+ <step> [Content of step 2] </step>
131
+ <reflection> [Evaluation of the steps so far] </reflection>
132
+ <reward> [Float between 0.0 and 1.0] </reward>
133
+ <count> [remaining budget] </count>
134
+ <step> [Content of step 3 or Content of some previous step] </step>
135
+ <count> [remaining budget] </count>
136
+ ...
137
+ <step> [Content of final step] </step>
138
+ <count> [remaining budget] </count>
139
+ <answer> [Final Answer] </answer> (must give final answer in this format)
140
+ <reflection> [Evaluation of the solution] </reflection>
141
+ <reward> [Float between 0.0 and 1.0] </reward>
142
+ """
143
+
144
+ custom_css = """
145
+ .custom-button {
146
+ border-radius: 10px !important;
147
+ }
148
+ .natural-bg {
149
+ background-color: #e8f5e9 !important;
150
+ padding: 15px !important;
151
+ border-radius: 10px !important;
152
+ }
153
+ .pink-bg {
154
+ background-color: #ff4081 !important;
155
+ border-radius: 10px !important;
156
+ }
157
+ .pink-bg label, .pink-bg .label-wrap {
158
+ color: white !important;
159
+ }
160
+ .pink-bg textarea {
161
+ color: black !important;
162
+ }
163
+ .user-message .message.user {
164
+ background-color: #ffe0b2 !important;
165
+ border-radius: 10px !important;
166
+ padding: 10px !important;
167
+ margin: 0 !important;
168
+ }
169
+ .assistant-message .message.bot {
170
+ background-color: #e3f2fd !important;
171
+ border-radius: 5px !important;
172
+ padding: 10px !important;
173
+ margin: 0 !important;
174
+ }
175
+ """
176
+
177
+ with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as demo:
178
+ gr.Markdown("# Reasoning Chains using Llama-3.1-Instruct. Deployed by 江信宗")
179
+
180
+ with gr.Row(elem_classes="natural-bg"):
181
+ model = gr.Dropdown(choices=MODELS, label="選擇模型", value=MODELS[0])
182
+ thinking_budget = gr.Slider(minimum=1, maximum=100, value=20, step=1, label="思維規劃", info="模型所能進行的最大思考次數")
183
+ api_key = gr.Textbox(label="API Key", type="password", placeholder="API authentication key for large language models")
184
+
185
+ chatbot = gr.Chatbot(
186
+ label="Chat",
187
+ show_label=False,
188
+ show_share_button=False,
189
+ show_copy_button=True,
190
+ likeable=True,
191
+ layout="panel",
192
+ type="messages",
193
+ elem_classes=["user-message", "assistant-message"]
194
+ )
195
+ msg = gr.Textbox(label="在此輸入您的問題:", placeholder="輸入完成後直接按 Enter 開始執行......", elem_classes="pink-bg")
196
+ clear_button = gr.Button("清除聊天記錄", elem_classes="custom-button")
197
+ clear_button.click(lambda: ([], ""), inputs=None, outputs=[chatbot, msg])
198
+ # system_prompt = gr.Textbox(label="System Prompt", value=DEFAULT_SYSTEM_PROMPT, lines=15, interactive=True)
199
+ system_prompt = gr.Textbox(label="System Prompt", value=DEFAULT_SYSTEM_PROMPT, visible=False)
200
+ msg.submit(generate, inputs=[msg, chatbot, model, system_prompt, thinking_budget, api_key], outputs=[chatbot, msg])
201
+
202
+ demo.load(js=None)
203
+
204
+ if __name__ == "__main__":
205
+ if "SPACE_ID" in os.environ:
206
+ demo.launch()
207
+ else:
208
+ demo.launch(share=True, show_api=False)
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ openai