HelenaXH commited on
Commit
2f69958
·
verified ·
1 Parent(s): 2773ed3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -118
app.py CHANGED
@@ -4,13 +4,14 @@ import os
4
 
5
  # ============================ 用户信息结构 ============================
6
  user_profile = {
7
- "mode": None, # 是 / 否 (Backward / Forward)
8
- "specific_career": None, # Backward 目标职业
9
- "bg_info": None, # 学术背景
10
- "work_value": None, # 工作意义
11
- "personality_summary": None, # 性格总结
12
- "dream_day": None, # 理想工作一天
13
- "forward_direction_choice": None # 选的大方向
 
14
  }
15
 
16
  # ============================ 基础问题 ============================
@@ -20,13 +21,15 @@ base_questions = [
20
 
21
  # ============================ Forward 模式问题 ============================
22
  forward_additional_questions = [
23
- ("bg_info", """那么接下来我会需要你提供一些你的资料,并分享一些你的性格和喜好。请先告诉我,你的学校、年级、专业,和主修课程是什么?如果能提供你的选课表或resume就更好啦。"""),
 
24
 
25
- ("work_value", """非常好!那你认为“工作”的意义是什么?你觉得一份理想的工作,应该带来哪些价值或满足感?(例如:帮助他人、赚大钱、自由时间、个人成长、创意空间等)"""),
 
26
 
27
- ("personality_summary", "用几句话总结你的性格:比如外向/内向?喜欢挑战?注重细节?讨厌重复吗?"),
28
 
29
- ("dream_day", "描述一下你理想工作的一天是什么样:在哪工作?做什么?和谁合作?忙还是闲?更自由还是更有秩序?")
30
  ]
31
 
32
  # ============================ Backward 模式问题 ============================
@@ -46,11 +49,13 @@ forward_done = False
46
  backward_done = False
47
  forward_recommendation_given = False
48
 
49
- # 新增:多次换方向深度分析路线图
50
- recommendation_round = 0 # 换方向轮数
51
- forward_deep_dive_done = False # 是否已进行“深度分析”
52
- roadmap_offered = False # 是否已询问要不要时间轴
53
- roadmap_done = False # 是否已生成或放弃时间轴
 
 
54
 
55
  # ============================ 模型设置 ============================
56
  model_default = "gpt-4o"
@@ -58,13 +63,14 @@ token_default = 2000
58
  temp_default = 0.7
59
  top_p_default = 0.95
60
 
61
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 路线图生成函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62
  def do_time_roadmap():
63
  direction = user_profile["forward_direction_choice"] or user_profile["specific_career"]
64
  bg_info = user_profile["bg_info"] or "未知专业"
65
  wv = user_profile["work_value"] or "暂无"
66
  ps = user_profile["personality_summary"] or "暂无"
67
  dd = user_profile["dream_day"] or "暂无"
 
68
 
69
  prompt_roadmap = f"""
70
  学生信息:
@@ -73,15 +79,16 @@ def do_time_roadmap():
73
  - 工作价值:{wv}
74
  - 性格:{ps}
75
  - 理想工作:{dd}
 
76
 
77
- 使用时间轴,给出一个职业路线图,如:
78
  📍 Now: [当前阶段做什么]
79
  🎓 Year X: [需要选的课/要做的项目]
80
- 💼 下个暑假: [申请什么实习、参加什么活动]
81
- 📄 毕业前: [考什么书、准备材料]
82
- 🚀 毕业后: [目标岗位如何申请]
83
 
84
- 请用Markdown分段写作,结合学生当前背景合理推断,写得具体些
85
  """
86
  try:
87
  api_key = os.environ.get("API_TOKEN")
@@ -90,8 +97,8 @@ def do_time_roadmap():
90
  client = OpenAI(api_key=api_key)
91
 
92
  msgs = [
93
- {"role": "system", "content": "你是一位专业职业规划顾问,会生成时间轴式路线图"},
94
- {"role": "user", "content": prompt_roadmap}
95
  ]
96
  resp = client.chat.completions.create(
97
  model=model_default,
@@ -121,11 +128,11 @@ def do_deep_analysis():
121
  理想工作: {dd}
122
 
123
  请你再深入分析,为学生推荐3个更具体的职业,并说明:
124
- 1. 这些职业对学生背景的契合度(机械工程/心理学/商科等都可)
125
  2. 日常工作内容
126
  3. 需要哪些课程或考试
127
  4. 本校资源如何利用
128
- 5. 实习 & 经验积累建议
129
  6. 简历优化思路
130
 
131
  用中文分段写作,字数500+。
@@ -136,8 +143,8 @@ def do_deep_analysis():
136
  return "错误:API_TOKEN 未设置"
137
  client = OpenAI(api_key=api_key)
138
  msgs = [
139
- {"role": "system", "content": "你是一位专业职业顾问,会深度分析并列出3个具体职业。"},
140
- {"role": "user", "content": deep_prompt}
141
  ]
142
  resp = client.chat.completions.create(
143
  model=model_default,
@@ -159,9 +166,9 @@ def recommend_3directions():
159
  dd = user_profile["dream_day"] or "无"
160
 
161
  rec_prompt = f"""
162
- 请根据以下信息,写一份条理清晰的人物画像+3个大方向,并结尾让学生选1~3或
163
  - 学术背景: {bg_info}
164
- - 工作价值: {wv}
165
  - 性格: {ps}
166
  - 理想工作: {dd}
167
  分两部分:
@@ -179,8 +186,8 @@ def recommend_3directions():
179
  return "错误:API_TOKEN 未设置"
180
  client = OpenAI(api_key=api_key)
181
  msgs = [
182
- {"role": "system", "content": "你是一位职业顾问,擅长根据用户资料推荐3大方向"},
183
- {"role": "user", "content": rec_prompt}
184
  ]
185
  resp = client.chat.completions.create(
186
  model=model_default,
@@ -194,7 +201,6 @@ def recommend_3directions():
194
  except Exception as e:
195
  return f"多方向推荐出错: {str(e)}"
196
 
197
-
198
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ generate_system_prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199
  def generate_system_prompt():
200
  mode = user_profile["mode"]
@@ -216,7 +222,7 @@ def generate_system_prompt():
216
  3. 所需技能和能力
217
  4. 职业发展路径
218
  5. 学术/课程建议、技能培养、资源使用、实习规划、简历优化等
219
- 最后请用Markdown格式输出职业路图:
220
  📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
221
  """
222
  else:
@@ -231,11 +237,10 @@ def generate_system_prompt():
231
  请输出:
232
  1. 学生的优势、性格、价值观分析
233
  2. 推荐3个具体职业,并说明日常工作内容、适配性、要求、准备路径
234
- 3. 最后输出职业路图:
235
  📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
236
  """
237
 
238
-
239
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 主逻辑函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240
  def predict(message, history):
241
  global current_q_index, questions
@@ -245,24 +250,24 @@ def predict(message, history):
245
  global forward_recommendation_given
246
  global recommendation_round
247
  global forward_deep_dive_done
 
248
  global roadmap_offered, roadmap_done
249
 
250
  # 第一次对话 -> 重置
251
  if not history:
252
  current_q_index = 0
253
  questions = base_questions[:]
254
- for key in user_profile:
255
- user_profile[key] = None
256
 
257
- in_forward_flow = False
258
- in_backward_flow = False
259
- forward_index = 0
260
- backward_index = 0
261
- forward_done = False
262
- backward_done = False
263
  forward_recommendation_given = False
264
  recommendation_round = 0
265
  forward_deep_dive_done = False
 
 
266
  roadmap_offered = False
267
  roadmap_done = False
268
 
@@ -289,7 +294,6 @@ def predict(message, history):
289
  # ~~~~~~~ Backward模式 ~~~~~~~
290
  if "是" in mode:
291
  if in_backward_flow and not backward_done:
292
- # 存储上一轮回答
293
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
294
  prev_key = backward_additional_questions[backward_index - 1][0]
295
  user_profile[prev_key] = message.strip()
@@ -302,17 +306,16 @@ def predict(message, history):
302
  backward_done = True
303
 
304
  if backward_done:
305
- # 直接进入最终
306
  try:
307
  api_key = os.environ.get("API_TOKEN")
308
  if not api_key:
309
  return "错误:API_TOKEN 未设置"
310
  client = OpenAI(api_key=api_key)
311
- system_prompt = generate_system_prompt()
312
-
313
  msgs = [
314
- {"role":"system","content": system_prompt},
315
- {"role":"user","content": f"请根据信息{user_profile}给出完整规划"}
316
  ]
317
  resp = client.chat.completions.create(
318
  model=model_default,
@@ -334,40 +337,61 @@ def predict(message, history):
334
  prev_key = forward_additional_questions[forward_index - 1][0]
335
  user_profile[prev_key] = message.strip()
336
 
337
- # Forward问题
338
  if forward_index < len(forward_additional_questions):
339
  k, prompt_text = forward_additional_questions[forward_index]
340
  forward_index += 1
341
  return prompt_text
342
 
343
- # 如果4个Forward问完,还没推荐
344
  elif not forward_recommendation_given:
345
  forward_recommendation_given = True
346
  return recommend_3directions()
347
 
348
- # 已推荐过方向,等待学生选1/2/3 or '换'
349
  else:
350
  choice = message.strip().lower()
351
  if choice in ["1","2","3"]:
352
  user_profile["forward_direction_choice"] = choice
353
- # 进入深度分析
354
  forward_deep_dive_done = True
355
  return do_deep_analysis()
356
- elif "换" in choice:
357
  recommendation_round += 1
358
- if recommendation_round > 2: # 最多换2次
359
  forward_done = True
360
- return "已多次换方向,先进入下个阶段吧。"
361
- # 再次推荐
362
- return recommend_3directions()
363
  else:
364
  return "请回复1/2/3选择方向,或输入'换'来请求新的推荐"
365
 
366
- elif forward_deep_dive_done and not roadmap_offered:
367
- # 深度分析完 -> 问要不要路线图
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  roadmap_offered = True
369
- return "需要一个时间轴式的职业路线���吗?如果需要,请回复“是”,否则回复“否”。"
370
 
 
371
  elif roadmap_offered and not roadmap_done:
372
  ans = message.strip().lower()
373
  if ans == "是":
@@ -377,20 +401,20 @@ def predict(message, history):
377
  else:
378
  roadmap_done = True
379
  forward_done = True
380
- return "好的,不生成路线图,本次规划到此结束"
381
 
 
382
  if forward_done:
383
- # 最终生成 or 就结束
384
  try:
385
  api_key = os.environ.get("API_TOKEN")
386
  if not api_key:
387
  return "错误:API_TOKEN 未设置"
388
  client = OpenAI(api_key=api_key)
389
- system_prompt = generate_system_prompt()
390
-
391
  msgs = [
392
- {"role":"system","content": system_prompt},
393
- {"role":"user","content": f"以下是学生资料: {user_profile}.需更详细方案可输入问题"}
394
  ]
395
  resp = client.chat.completions.create(
396
  model=model_default,
@@ -404,7 +428,7 @@ def predict(message, history):
404
  except Exception as e:
405
  return f"发生错误: {str(e)}"
406
 
407
- return "信息收集完毕,若尚未得到最终回复,请输入任意文字以继续。"
408
 
409
 
410
  # ============================ Gradio UI ============================
@@ -459,54 +483,31 @@ footer {
459
  }
460
  """) as demo:
461
 
462
- with gr.Row():
463
- gr.HTML("""
464
- <div style='display: flex; align-items: center; justify-content: center; gap: 20px; margin-bottom: 10px;'>
465
- <img src='https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFucGwxbmNsd3J5NXV0Y282NXNtMzNsZW5jMm4wNWh6c2dqbXIwdiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l41m18LjqpzxUr2WA/giphy.gif' width='200' style='border-radius: 12px; box-shadow: 0 0 10px #ec4899;'>
466
- <div style='text-align: left;'>
467
- <h1 style='color:white; font-size: 36px; margin-bottom: 6px;'>🎓 多步职业规划助手</h1>
468
- <p style='font-size: 18px; font-weight:bold; color:#ec4899; margin-top: 0;'>Forward三步:推荐大方向→深度分析→可选时间轴路线图</p>
469
- </div>
470
- </div>
471
- """)
472
-
473
- gr.Markdown("""
474
- **📝 Forward / Backward 多轮交互,附带换方向、深度分析、以及可选时间轴路线图**
475
- 1. 如果你已有明确职业目标 => 回答“是”(Backward)
476
- 2. 如果还在探索 => 回答“否”(Forward)
477
- 3. Forward模式下:先问4个问题→推荐3大方向→可换→选定后深度分析→询问是否要路线图
478
- """)
479
 
480
  chatbot = gr.Chatbot(height=500, show_label=False, show_copy_button=True, type="messages")
 
 
 
481
 
482
- with gr.Row():
483
- with gr.Column(scale=8):
484
- msg = gr.Textbox(placeholder="请在这里输入你的回答...", show_label=False, container=False)
485
- with gr.Column(scale=1):
486
- submit_btn = gr.Button("🚀 发送", elem_id="custom-send")
487
 
488
- with gr.Row():
489
- reset_btn = gr.Button("🔄 重新开始")
 
 
 
490
 
491
- def add_message(message, history):
492
- history = history or []
493
- history.append({"role": "user", "content": message})
494
- return "", history
495
 
496
- def bot_response(history):
497
- history = history or []
498
- user_message = history[-1]["content"]
499
- bot_message = predict(user_message, history[:-1] if len(history) > 1 else [])
500
- history.append({"role": "assistant", "content": bot_message})
501
- return history
502
 
503
- submit_btn.click(fn=add_message, inputs=[msg, chatbot], outputs=[msg, chatbot]) \
504
- .then(fn=bot_response, inputs=[chatbot], outputs=[chatbot])
505
-
506
- msg.submit(fn=add_message, inputs=[msg, chatbot], outputs=[msg, chatbot]) \
507
- .then(fn=bot_response, inputs=[chatbot], outputs=[chatbot])
508
-
509
- def reset_state():
510
  global current_q_index, questions
511
  global in_forward_flow, in_backward_flow
512
  global forward_index, backward_index
@@ -514,12 +515,13 @@ footer {
514
  global forward_recommendation_given
515
  global recommendation_round
516
  global forward_deep_dive_done
 
517
  global roadmap_offered, roadmap_done
518
 
519
  current_q_index = 0
520
  questions = base_questions[:]
521
- for key in user_profile:
522
- user_profile[key] = None
523
 
524
  in_forward_flow = False
525
  in_backward_flow = False
@@ -530,17 +532,20 @@ footer {
530
  forward_recommendation_given = False
531
  recommendation_round = 0
532
  forward_deep_dive_done = False
 
 
533
  roadmap_offered = False
534
  roadmap_done = False
535
 
536
  return []
537
 
538
- reset_btn.click(fn=reset_state, inputs=None, outputs=chatbot, queue=False)
 
 
 
 
 
539
 
540
- def auto_first_question():
541
- # 启动时自动问第一个问题
542
- return [{"role": "assistant", "content": questions[0][1]}]
543
 
544
- demo.load(auto_first_question, inputs=None, outputs=chatbot)
545
- demo.launch()
546
 
 
4
 
5
  # ============================ 用户信息结构 ============================
6
  user_profile = {
7
+ "mode": None, # 是 / 否 (Backward / Forward)
8
+ "specific_career": None, # Backward 目标职业
9
+ "bg_info": None, # Forward/Backward共用,学术背景
10
+ "work_value": None, # Forward:工作意义
11
+ "personality_summary": None, # Forward:性格
12
+ "dream_day": None, # Forward:理想一天
13
+ "forward_direction_choice": None, # Forward的大方向
14
+ "extra_info": None # 新增,用于存放补充信息
15
  }
16
 
17
  # ============================ 基础问题 ============================
 
21
 
22
  # ============================ Forward 模式问题 ============================
23
  forward_additional_questions = [
24
+ ("bg_info", """那么接下来我会需要你提供一些你的资料,并分享一些你的性格和喜好。
25
+ 请先告诉我,你的学校、年级、专业,和主修课程是什么?如果能提供选课表或resume就更好啦。"""),
26
 
27
+ ("work_value", """非常好!那你认为“工作”的意义是什么?你觉得一份理想的工作,应该带来哪些价值或满足感?
28
+ 例如:帮助他人、赚大钱、自由时间、个人成长、创意空间等"""),
29
 
30
+ ("personality_summary", """再用几句话总结你的性格:比如外向/内向?喜欢挑战?注重细节?讨厌重复吗?"""),
31
 
32
+ ("dream_day", """描述一下你理想工作的一天:在哪工作?做什么?和谁合作?忙还是闲?更自由还是更有秩序?""")
33
  ]
34
 
35
  # ============================ Backward 模式问题 ============================
 
49
  backward_done = False
50
  forward_recommendation_given = False
51
 
52
+ # 新增:多次换方向/深度分析/路线图 + 补充信息
53
+ recommendation_round = 0
54
+ forward_deep_dive_done = False
55
+ ask_additional_info = False # 是否问学生补充信息
56
+ extra_info_done = False # 学生是否成或放弃补充
57
+ roadmap_offered = False # 是否已询问是否要路线图
58
+ roadmap_done = False # 是否已生成或放弃路线图
59
 
60
  # ============================ 模型设置 ============================
61
  model_default = "gpt-4o"
 
63
  temp_default = 0.7
64
  top_p_default = 0.95
65
 
66
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 路线图函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67
  def do_time_roadmap():
68
  direction = user_profile["forward_direction_choice"] or user_profile["specific_career"]
69
  bg_info = user_profile["bg_info"] or "未知专业"
70
  wv = user_profile["work_value"] or "暂无"
71
  ps = user_profile["personality_summary"] or "暂无"
72
  dd = user_profile["dream_day"] or "暂无"
73
+ extra = user_profile["extra_info"] or "未补充更多实习信息"
74
 
75
  prompt_roadmap = f"""
76
  学生信息:
 
79
  - 工作价值:{wv}
80
  - 性格:{ps}
81
  - 理想工作:{dd}
82
+ - 补充信息:{extra}
83
 
84
+ 请使用时间轴一个职业路线图,如:
85
  📍 Now: [当前阶段做什么]
86
  🎓 Year X: [需要选的课/要做的项目]
87
+ 💼 下个暑假: [实习/活动]
88
+ 📄 毕业前: [考证/准备材料]
89
+ 🚀 毕业后: [目标岗位/如何申请]
90
 
91
+ 请用Markdown写作,结合学生当前背景合理推断点。
92
  """
93
  try:
94
  api_key = os.environ.get("API_TOKEN")
 
97
  client = OpenAI(api_key=api_key)
98
 
99
  msgs = [
100
+ {"role":"system","content":"你是一位专业职业顾问,会生成时间轴式路线图"},
101
+ {"role":"user","content": prompt_roadmap}
102
  ]
103
  resp = client.chat.completions.create(
104
  model=model_default,
 
128
  理想工作: {dd}
129
 
130
  请你再深入分析,为学生推荐3个更具体的职业,并说明:
131
+ 1. 对学生背景的契合度
132
  2. 日常工作内容
133
  3. 需要哪些课程或考试
134
  4. 本校资源如何利用
135
+ 5. 实习 & 经验积累
136
  6. 简历优化思路
137
 
138
  用中文分段写作,字数500+。
 
143
  return "错误:API_TOKEN 未设置"
144
  client = OpenAI(api_key=api_key)
145
  msgs = [
146
+ {"role":"system","content":"你是一位专业职业顾问,会深度分析3个具体职业。"},
147
+ {"role":"user","content":deep_prompt}
148
  ]
149
  resp = client.chat.completions.create(
150
  model=model_default,
 
166
  dd = user_profile["dream_day"] or "无"
167
 
168
  rec_prompt = f"""
169
+ 请根据以下信息,写一份条理清晰的人物画像+3个大方向,并结尾让学生选1~3或''
170
  - 学术背景: {bg_info}
171
+ - 工作意义: {wv}
172
  - 性格: {ps}
173
  - 理想工作: {dd}
174
  分两部分:
 
186
  return "错误:API_TOKEN 未设置"
187
  client = OpenAI(api_key=api_key)
188
  msgs = [
189
+ {"role":"system","content":"你是一位职业顾问,擅长根据用户资料推荐3大方向"},
190
+ {"role":"user","content":rec_prompt}
191
  ]
192
  resp = client.chat.completions.create(
193
  model=model_default,
 
201
  except Exception as e:
202
  return f"多方向推荐出错: {str(e)}"
203
 
 
204
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ generate_system_prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
205
  def generate_system_prompt():
206
  mode = user_profile["mode"]
 
222
  3. 所需技能和能力
223
  4. 职业发展路径
224
  5. 学术/课程建议、技能培养、资源使用、实习规划、简历优化等
225
+ 最后请用Markdown格式输出职业路线图:
226
  📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
227
  """
228
  else:
 
237
  请输出:
238
  1. 学生的优势、性格、价值观分析
239
  2. 推荐3个具体职业,并说明日常工作内容、适配性、要求、准备路径
240
+ 3. 最后输出职业路线图:
241
  📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
242
  """
243
 
 
244
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 主逻辑函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245
  def predict(message, history):
246
  global current_q_index, questions
 
250
  global forward_recommendation_given
251
  global recommendation_round
252
  global forward_deep_dive_done
253
+ global ask_additional_info, extra_info_done
254
  global roadmap_offered, roadmap_done
255
 
256
  # 第一次对话 -> 重置
257
  if not history:
258
  current_q_index = 0
259
  questions = base_questions[:]
260
+ for k in user_profile:
261
+ user_profile[k] = None
262
 
263
+ in_forward_flow = in_backward_flow = False
264
+ forward_index = backward_index = 0
265
+ forward_done = backward_done = False
 
 
 
266
  forward_recommendation_given = False
267
  recommendation_round = 0
268
  forward_deep_dive_done = False
269
+ ask_additional_info = False
270
+ extra_info_done = False
271
  roadmap_offered = False
272
  roadmap_done = False
273
 
 
294
  # ~~~~~~~ Backward模式 ~~~~~~~
295
  if "是" in mode:
296
  if in_backward_flow and not backward_done:
 
297
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
298
  prev_key = backward_additional_questions[backward_index - 1][0]
299
  user_profile[prev_key] = message.strip()
 
306
  backward_done = True
307
 
308
  if backward_done:
309
+ # 直接最终规划
310
  try:
311
  api_key = os.environ.get("API_TOKEN")
312
  if not api_key:
313
  return "错误:API_TOKEN 未设置"
314
  client = OpenAI(api_key=api_key)
315
+ sprompt = generate_system_prompt()
 
316
  msgs = [
317
+ {"role":"system","content": sprompt},
318
+ {"role":"user","content": f"请根据{user_profile}给出最终规划"}
319
  ]
320
  resp = client.chat.completions.create(
321
  model=model_default,
 
337
  prev_key = forward_additional_questions[forward_index - 1][0]
338
  user_profile[prev_key] = message.strip()
339
 
340
+ # 1) 在问 Forward问题
341
  if forward_index < len(forward_additional_questions):
342
  k, prompt_text = forward_additional_questions[forward_index]
343
  forward_index += 1
344
  return prompt_text
345
 
346
+ # 2) 4个问完 -> 推荐3大方向
347
  elif not forward_recommendation_given:
348
  forward_recommendation_given = True
349
  return recommend_3directions()
350
 
351
+ # 3) 用户可选1/2/3'换'
352
  else:
353
  choice = message.strip().lower()
354
  if choice in ["1","2","3"]:
355
  user_profile["forward_direction_choice"] = choice
 
356
  forward_deep_dive_done = True
357
  return do_deep_analysis()
358
+ elif choice == "换":
359
  recommendation_round += 1
360
+ if recommendation_round > 2:
361
  forward_done = True
362
+ return "已多次换方向,先结束推荐吧。"
363
+ else:
364
+ return recommend_3directions()
365
  else:
366
  return "请回复1/2/3选择方向,或输入'换'来请求新的推荐"
367
 
368
+ # 深度分析完成后 -> 先问有没有要补充的信息
369
+ elif forward_deep_dive_done and not ask_additional_info and not extra_info_done and not roadmap_done:
370
+ ask_additional_info = True
371
+ return "你还有其他想补充的信息吗?比如实习经历、社团活动、项目经验。如果有,请回复“是”,否则回复“否”。"
372
+
373
+ # 学生回答是否要补充信息
374
+ elif ask_additional_info and not extra_info_done and not roadmap_done:
375
+ ans = message.strip().lower()
376
+ if ans == "是":
377
+ extra_info_done = True
378
+ return "请告诉我你的实习经历或其他背景信息:"
379
+ else:
380
+ # 学生说没有要补充 -> 直接问要不要路线图
381
+ ask_additional_info = False
382
+ extra_info_done = True
383
+ return "需要一个时间轴式的职业路线图吗?若需要,请回复“是”,否则回复“否”。"
384
+
385
+ # 如果学生要补充信息 -> 存入 user_profile["extra_info"] -> 再问路线图
386
+ elif extra_info_done and not roadmap_offered and not roadmap_done:
387
+ # 把用户刚刚补充的一段信息写进 user_profile
388
+ if user_profile["extra_info"] is None:
389
+ user_profile["extra_info"] = message.strip()
390
+ # 现在再问路线图
391
  roadmap_offered = True
392
+ return "好的,补充信息收到。需要一个时间轴式的职业路线吗?需要,请回复“是”,否则回复“否”。"
393
 
394
+ # 学生回答要或不要路线图
395
  elif roadmap_offered and not roadmap_done:
396
  ans = message.strip().lower()
397
  if ans == "是":
 
401
  else:
402
  roadmap_done = True
403
  forward_done = True
404
+ return "好的,本次规划到此结束,祝你一切顺利!"
405
 
406
+ # 如果 forward_done
407
  if forward_done:
408
+ # 最终收尾
409
  try:
410
  api_key = os.environ.get("API_TOKEN")
411
  if not api_key:
412
  return "错误:API_TOKEN 未设置"
413
  client = OpenAI(api_key=api_key)
414
+ sprompt = generate_system_prompt()
 
415
  msgs = [
416
+ {"role":"system","content": sprompt},
417
+ {"role":"user","content": f"当前资料: {user_profile},果还想进一步咨询请再输入"}
418
  ]
419
  resp = client.chat.completions.create(
420
  model=model_default,
 
428
  except Exception as e:
429
  return f"发生错误: {str(e)}"
430
 
431
+ return "信息收集完毕,如还未得到最终回复,请输入任意文字以继续。"
432
 
433
 
434
  # ============================ Gradio UI ============================
 
483
  }
484
  """) as demo:
485
 
486
+ gr.HTML("<h1 style='color:white;'>Forward / Backward 多轮交互 + 可换方向 + 深度分析 + 补充信息 + 时间轴路线图</h1>")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
 
488
  chatbot = gr.Chatbot(height=500, show_label=False, show_copy_button=True, type="messages")
489
+ msg = gr.Textbox(placeholder="请输入你的回答...")
490
+ send = gr.Button("🚀 发送", elem_id="custom-send")
491
+ reset = gr.Button("🔄 重新开始")
492
 
493
+ def add_user_message(m, h):
494
+ h = h or []
495
+ h.append({"role":"user","content":m})
496
+ return "", h
 
497
 
498
+ def add_bot_response(h):
499
+ user_m = h[-1]["content"]
500
+ bot_m = predict(user_m, h[:-1])
501
+ h.append({"role":"assistant","content":bot_m})
502
+ return h
503
 
504
+ send.click(add_user_message, [msg, chatbot], [msg, chatbot]) \
505
+ .then(add_bot_response, chatbot, chatbot)
 
 
506
 
507
+ msg.submit(add_user_message, [msg, chatbot], [msg, chatbot]) \
508
+ .then(add_bot_response, chatbot, chatbot)
 
 
 
 
509
 
510
+ def reset_all():
 
 
 
 
 
 
511
  global current_q_index, questions
512
  global in_forward_flow, in_backward_flow
513
  global forward_index, backward_index
 
515
  global forward_recommendation_given
516
  global recommendation_round
517
  global forward_deep_dive_done
518
+ global ask_additional_info, extra_info_done
519
  global roadmap_offered, roadmap_done
520
 
521
  current_q_index = 0
522
  questions = base_questions[:]
523
+ for k in user_profile:
524
+ user_profile[k] = None
525
 
526
  in_forward_flow = False
527
  in_backward_flow = False
 
532
  forward_recommendation_given = False
533
  recommendation_round = 0
534
  forward_deep_dive_done = False
535
+ ask_additional_info = False
536
+ extra_info_done = False
537
  roadmap_offered = False
538
  roadmap_done = False
539
 
540
  return []
541
 
542
+ reset.click(reset_all, outputs=chatbot)
543
+
544
+ def start_q():
545
+ return [{"role":"assistant","content": questions[0][1]}]
546
+
547
+ demo.load(start_q, outputs=chatbot)
548
 
549
+ demo.launch()
 
 
550
 
 
 
551