Stone164 commited on
Commit
d3b7d4e
·
verified ·
1 Parent(s): 11cb3d3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +298 -38
app.py CHANGED
@@ -1,76 +1,336 @@
1
  import gradio as gr
2
  from openai import OpenAI
3
  import os
 
4
 
5
- # 修复格式问题预测函数
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  def predict(message, history):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  try:
8
  # 初始化OpenAI客户端
9
  api_key = os.environ.get("API_TOKEN")
10
  if not api_key:
11
- return history + [["错误:API密钥未设置", ""]]
12
 
13
  client = OpenAI(api_key=api_key)
14
 
15
- # 构建消息列表,包含历史记录
16
- messages = [{"role": "system", "content": "你是一个有用的AI助手。"}]
17
 
18
- # 添加历史消息
19
- for user_msg, bot_msg in history:
20
- messages.append({"role": "user", "content": user_msg})
21
- messages.append({"role": "assistant", "content": bot_msg})
 
22
 
23
- # 添加当前户消息
24
- messages.append({"role": "user", "content": message})
25
-
26
- # 非流式调用
27
  response = client.chat.completions.create(
28
- model="gpt-4o",
29
  messages=messages,
30
- max_tokens=1000,
31
- temperature=0.7,
 
32
  stream=False
33
  )
34
 
35
- bot_response = response.choices[0].message.content
36
-
37
- # 返回新的历史记录,添加当前交互
38
- return history + [[message, bot_response]]
39
  except Exception as e:
40
- # 时也保持正确的格式
41
- return history + [[message, f"发生错误: {str(e)}"]]
42
 
43
- # 创建简化版界面
44
  with gr.Blocks(css="""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  #custom-send {
46
  background-color: #ec4899 !important;
47
  color: white !important;
48
  border-radius: 999px !important;
49
  padding: 10px 24px !important;
50
  font-weight: bold;
 
 
51
  }
52
-
 
 
 
 
 
 
 
 
 
 
 
53
  footer {
54
  display: none !important;
55
  }
56
  """) as demo:
57
- gr.HTML("""
58
- <div style='text-align: center; margin-bottom: 10px;'>
59
- <h1 style='color:white; font-size: 28px; margin-bottom: 6px;'>🎓 AI Career Assistant</h1>
60
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  """)
62
 
63
- chatbot = gr.Chatbot()
64
- msg = gr.Textbox(placeholder="输入你的问题...", show_label=False)
65
- clear = gr.Button("清除对话")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
- send_btn = gr.Button("发送", elem_id="custom-send")
 
 
 
 
 
68
 
69
- # 重要:正确处理输入和状态
70
- msg.submit(predict, [msg, chatbot], [chatbot]).then(
71
- lambda: "", None, msg)
72
- send_btn.click(predict, [msg, chatbot], [chatbot]).then(
73
- lambda: "", None, msg)
74
- clear.click(lambda: None, None, chatbot)
75
 
76
- demo.launch()
 
 
1
  import gradio as gr
2
  from openai import OpenAI
3
  import os
4
+ import time
5
 
6
+ # 存储用户回答全局字典
7
+ user_profile = {
8
+ "mode": None,
9
+ "age": None,
10
+ "degree": None,
11
+ "interests": None,
12
+ "mbti": None,
13
+ "specific_career": None # 用于Backward模式时存储具体职业方向
14
+ }
15
+
16
+ # 问题列表
17
+ base_questions = [
18
+ ("mode", "你是否有心仪的职业方向?\n- 如果有,请回复'是'(Backward模式:我们将帮你设计实现该目标的路径)\n- 如果没有,请回复'否'(Forward模式:我们将根据你的背景推荐合适的职业)"),
19
+ ("age", "你的年龄范围是?(例如:'18岁以下','18-21岁','21-25岁','25-29岁','30岁以上')"),
20
+ ("degree", "你目前的学历是什么?(例如:'本科在读','本科毕业','硕士在读','博士')"),
21
+ ("interests", "请列出几个你的兴趣爱好,用逗号分隔。(例如:编程,心理学,设计)"),
22
+ ("mbti", "你的MBTI人格类型是什么?(例如:INFP,INTJ,ENFP等)如果不知道,可以回复'不知道'")
23
+ ]
24
+
25
+ # 全局变量存储当前问题索引和问题列表
26
+ current_q_index = 0
27
+ questions = base_questions.copy()
28
+
29
+ # 默认值
30
+ system_prompt_default = "你是一位专业的职业规划顾问,帮助学生规划他们的职业路径。"
31
+ model_default = "gpt-4o"
32
+ temp_default = 0.7
33
+ top_p_default = 0.95
34
+ token_default = 2000
35
+
36
+ # 函数:生成系统提示
37
+ def generate_system_prompt():
38
+ mode = user_profile["mode"]
39
+ age = user_profile["age"]
40
+ degree = user_profile["degree"]
41
+ interests = user_profile["interests"]
42
+ mbti = user_profile["mbti"]
43
+ specific_career = user_profile.get("specific_career")
44
+
45
+ if mode and "是" in mode: # Backward 模式
46
+ prompt = f"""
47
+ 你是一位专业的职业规划顾问,使用"Backward Design"方法帮助学生规划他们的职业路径。
48
+
49
+ 学生个人资料:
50
+ - 年龄: {age}
51
+ - 学历: {degree}
52
+ - 兴趣爱好: {interests}
53
+ - MBTI类型: {mbti}
54
+ - 目标职业: {specific_career}
55
+
56
+ 请分析学生提出的职业方向:
57
+ 1. 提供该职业的简要分析
58
+ 2. 列出该领域排名靠前的组织/公司
59
+ 3. 分析该职业所需的技能和能力
60
+ 4. 描述职业发展和上升空间
61
+
62
+ 然后,基于学生的学术背景,请提供以下方面的具体建议:
63
+ 1. 专业选择建议(是否需要转专业、双学位等)
64
+ 2. 推荐的选课方向及理由
65
+ 3. 需要学习的关键技能
66
+ 4. 必要的资格认证或考试
67
+ 5. 如何利用学校资源(社团、项目、教授等)
68
+ 6. 实习和经验积累策略(包括人脉拓展建议)
69
+ 7. 简历优化建议
70
+
71
+ 最后,请用Markdown格式提供清晰的职业路线图,格式如下:
72
+ ```
73
+ 📍 现在: [当前状态]
74
+ 🎓 [时间点]: [建议行动,如选修特定课程]
75
+ 💼 [时间点]: [建议行动,如申请实习]
76
+ 📄 [时间点]: [建议行动,如获取认证]
77
+ 🚀 [时间点]: [建议行动,如目标职位申请]
78
+ ```
79
+ """
80
+ else: # Forward 模式
81
+ prompt = f"""
82
+ 你是一位专业的职业规划顾问,使用"Forward Design"方法帮助学生探索适合的职业路径。
83
+
84
+ 学生个人资料:
85
+ - 年龄: {age}
86
+ - 学历: {degree}
87
+ - 兴趣爱好: {interests}
88
+ - MBTI类型: {mbti}
89
+
90
+ 请根据学生的背景和个人资料进行分析:
91
+ 1. 总结学生的优势和劣势
92
+ 2. 分析学生的性格特点和职业适配性
93
+ 3. 基于学生的学历背景、兴趣爱好和性格特点,推荐6个可能适合的职业大方向
94
+
95
+ 请以对话形式呈现,让学生从这6个方向中选择1-2个他们最感兴趣的方向。
96
+
97
+ 当学生选择了特定方向后,请进一步推荐3个具体职业,并针对每个职业提供:
98
+ 1. 职业描述和日常工作内容
99
+ 2. 该职业对学生的适合度分析
100
+ 3. 入行门槛和要求
101
+ 4. 详细的准备步骤,包括:
102
+ - 推荐的选课方向
103
+ - 必要的技能培训
104
+ - 资格认证或考试
105
+ - 如何利用学校资源
106
+ - 实习和经验积累建议
107
+ - 简历优化方向
108
+
109
+ 最后,为学生选择的职业方向提供一个清晰的Markdown格式职业路线图:
110
+ ```
111
+ 📍 现在: [当前状态]
112
+ 🎓 [时间点]: [建议行动,如选修特定课程]
113
+ 💼 [时间点]: [建议行动,如申请实习]
114
+ 📄 [时间点]: [建议行动,如获取认证]
115
+ 🚀 [时间点]: [建议行动,如目标职位申请]
116
+ ```
117
+ """
118
+ return prompt
119
+
120
+ # 预测函数
121
  def predict(message, history):
122
+ global current_q_index, questions
123
+
124
+ # 如果是第一次交互,重置问题索引和用户资料
125
+ if not history:
126
+ current_q_index = 0
127
+ for key in user_profile:
128
+ user_profile[key] = None
129
+ questions = base_questions.copy()
130
+
131
+ # 处理当前问题的回答
132
+ if current_q_index > 0 and current_q_index <= len(questions):
133
+ key = questions[current_q_index - 1][0]
134
+ user_profile[key] = message.strip()
135
+
136
+ # 如果模式是Backward(是)且刚刚回答了模式��题,添加额外的具体职业方向问题
137
+ if key == "mode" and "是" in user_profile["mode"]:
138
+ questions.insert(1, ("specific_career", "请具体描述你想要从事的职业方向。"))
139
+
140
+ # 如果还有问题要问
141
+ if current_q_index < len(questions):
142
+ question = questions[current_q_index][1]
143
+ current_q_index += 1
144
+ return question
145
+
146
+ # 所有问题都回答完了,生成个性化回复
147
  try:
148
  # 初始化OpenAI客户端
149
  api_key = os.environ.get("API_TOKEN")
150
  if not api_key:
151
+ return "错误:API密钥未设置,请在Space设置中添加名为API_TOKEN的Secret。"
152
 
153
  client = OpenAI(api_key=api_key)
154
 
155
+ # 生成系统提示
156
+ system_prompt = generate_system_prompt()
157
 
158
+ # 构建消息
159
+ messages = [
160
+ {"role": "system", "content": system_prompt},
161
+ {"role": "user", "content": f"根据我提供的信息,请给我职业规划建议。我的回答是:{user_profile}. {message}"}
162
+ ]
163
 
164
+ # API
 
 
 
165
  response = client.chat.completions.create(
166
+ model=model_default,
167
  messages=messages,
168
+ max_tokens=token_default,
169
+ temperature=temp_default,
170
+ top_p=top_p_default,
171
  stream=False
172
  )
173
 
174
+ return response.choices[0].message.content
 
 
 
175
  except Exception as e:
176
+ return f"发生误: {str(e)}"
 
177
 
178
+ # 创建自定义界面
179
  with gr.Blocks(css="""
180
+ body {
181
+ background-color: #1e1e1e;
182
+ color: #ffffff;
183
+ }
184
+
185
+ .gradio-container {
186
+ font-family: 'Segoe UI', sans-serif;
187
+ }
188
+
189
+ .gr-chatbot {
190
+ background-color: transparent !important;
191
+ }
192
+
193
+ .message.user {
194
+ background-color: #cce6ff !important; /* Much lighter blue */
195
+ color: #000000 !important;
196
+ border-radius: 10px !important;
197
+ padding: 10px;
198
+ margin: 6px;
199
+ }
200
+
201
+ .message.bot {
202
+ background-color: #99ccff !important; /* Lighter blue */
203
+ color: #000000 !important;
204
+ border-radius: 10px !important;
205
+ padding: 10px;
206
+ margin: 6px;
207
+ }
208
+
209
+ .gr-button {
210
+ border-radius: 8px;
211
+ }
212
+
213
  #custom-send {
214
  background-color: #ec4899 !important;
215
  color: white !important;
216
  border-radius: 999px !important;
217
  padding: 10px 24px !important;
218
  font-weight: bold;
219
+ box-shadow: 0 0 10px #ec4899;
220
+ transition: all 0.3s ease-in-out;
221
  }
222
+
223
+ #custom-send:hover {
224
+ background-color: #d63384 !important;
225
+ box-shadow: 0 0 12px #ec4899;
226
+ }
227
+
228
+ textarea, input {
229
+ background-color: #ffe4f1 !important;
230
+ color: #5e2c49 !important;
231
+ border: 1px solid #ec4899 !important;
232
+ }
233
+
234
  footer {
235
  display: none !important;
236
  }
237
  """) as demo:
238
+
239
+ with gr.Row():
240
+ gr.HTML("""
241
+ <div style='display: flex; align-items: center; justify-content: center; gap: 20px; margin-bottom: 10px;'>
242
+ <!-- 左侧动图 -->
243
+ <img src='https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFucGwxbmNsd3J5NXV0Y282NXNtMzNsZW5jMm4wNWh6c2dqbXIwdiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l41m18LjqpzxUr2WA/giphy.gif' width='200' style='border-radius: 12px; box-shadow: 0 0 10px #ec4899;'>
244
+
245
+ <!-- 右侧标题 -->
246
+ <div style='text-align: left;'>
247
+ <h1 style='color:white; font-size: 36px; margin-bottom: 6px;'>🎓 AI职业规划助手</h1>
248
+ <p style='font-size: 18px; font-weight:bold; color:#ec4899; margin-top: 0;margin-left: 150px'>让梦想照进现实 💖</p>
249
+ </div>
250
+ </div>
251
+ """)
252
+
253
+ # 添加说明文本
254
+ gr.Markdown("""
255
+ **📝 个性化职业规划助手**
256
+
257
+ 我将通过5个简单问题了解你的背景,然后为你提供量身定制的职业规划建议。
258
+
259
+ **两种模式:**
260
+ - **Forward模式**:如果你还不确定职业方向,我会根据你的背景推荐合适的职业
261
+ - **Backward模式**:如果你已有明确职业目标,我会帮你规划实现该目标的路径
262
+
263
+ 请回答下面的问题,开始你的职业规划之旅!
264
  """)
265
 
266
+ # 创建聊天界面
267
+ chatbot = gr.Chatbot(
268
+ height=500,
269
+ bubble_full_width=False,
270
+ show_label=False,
271
+ show_copy_button=True
272
+ )
273
+
274
+ # 输入框和按钮
275
+ with gr.Row():
276
+ with gr.Column(scale=8):
277
+ msg = gr.Textbox(
278
+ placeholder="请在这里输入你的回答...",
279
+ show_label=False,
280
+ container=False
281
+ )
282
+
283
+ with gr.Column(scale=1):
284
+ submit_btn = gr.Button("🚀 发送", elem_id="custom-send")
285
+
286
+ # 重置按钮
287
+ with gr.Row():
288
+ reset_btn = gr.Button("🔄 重新开始")
289
+
290
+ # 处理事件
291
+ submit_btn.click(
292
+ fn=lambda message, history: ("", history + [[message, None]]),
293
+ inputs=[msg, chatbot],
294
+ outputs=[msg, chatbot],
295
+ queue=False
296
+ ).then(
297
+ fn=predict,
298
+ inputs=[chatbot.get_value()[-1][0], chatbot.get_value()[:-1]],
299
+ outputs=[chatbot.get_value()[-1][1]]
300
+ )
301
+
302
+ msg.submit(
303
+ fn=lambda message, history: ("", history + [[message, None]]),
304
+ inputs=[msg, chatbot],
305
+ outputs=[msg, chatbot],
306
+ queue=False
307
+ ).then(
308
+ fn=predict,
309
+ inputs=[chatbot.get_value()[-1][0], chatbot.get_value()[:-1]],
310
+ outputs=[chatbot.get_value()[-1][1]]
311
+ )
312
+
313
+ # 重置功能
314
+ def reset_conversation():
315
+ global current_q_index, questions
316
+ current_q_index = 0
317
+ questions = base_questions.copy()
318
+ for key in user_profile:
319
+ user_profile[key] = None
320
+ return []
321
 
322
+ reset_btn.click(
323
+ fn=reset_conversation,
324
+ inputs=None,
325
+ outputs=chatbot,
326
+ queue=False
327
+ )
328
 
329
+ # 当页面加载时自动触发第一个问题
330
+ def auto_first_question():
331
+ global current_q_index
332
+ current_q_index = 1 # 设为1因为会返回第0个问题
333
+ return questions[0][1]
 
334
 
335
+ # 自动触发第一个问题
336
+ demo.load(auto_first_question, inputs=None, outputs=chatbot, show_progress=False)