HelenaXH commited on
Commit
2e5b1f6
·
verified ·
1 Parent(s): 925113b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +180 -62
app.py CHANGED
@@ -11,9 +11,12 @@ user_profile = {
11
  "personality_summary": None,
12
  "dream_day": None,
13
  "forward_direction_choice": None,
14
- # 新增:存储3个推荐方向 + 最终选择的方向
15
- "recommended_directions": [],
16
- "final_choice": None
 
 
 
17
  }
18
 
19
  # ============================ 基础问题 ============================
@@ -51,34 +54,43 @@ forward_deep_dive_done = False
51
  roadmap_offered = False
52
  roadmap_done = False
53
 
 
 
 
 
 
54
  # ============================ 模型设置 ============================
55
  model_default = "gpt-4o"
56
  token_default = 2000
57
  temp_default = 0.7
58
  top_p_default = 0.95
59
 
60
-
61
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 新增:选择后更详细介绍的函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62
- def do_selected_career_detail(selected_direction, bg_info, wv, ps, dd):
63
  """
64
- 当用户在3大方向中择了某一个后,自动生成更详细的分析
65
- 包括薪资水平、工作环境、晋升难度、关键技能、工作节奏等。
 
 
 
 
66
  """
67
  prompt = f"""
68
  你是一位专业的职业规划顾问。
69
- 用户的具体方向: {selected_direction}
70
  学生背景: {bg_info}
71
- 工作价值: {wv}
72
  性格: {ps}
73
  理想工作: {dd}
74
 
75
- 请写一份更详细的方向说明,至少包含:
76
  1. 行业平均薪资(初级/中级/高级)
77
  2. 工作环境(远程/混合/办公室,团队规模等)
78
  3. 晋升难度(需要什么资历或条件)
79
  4. 关键技能和考证
80
  5. 日常工作节奏
81
- 请用分段Markdown格式,字数不少于300字。
 
82
  """
83
  try:
84
  api_key = os.environ.get("API_TOKEN")
@@ -87,7 +99,7 @@ def do_selected_career_detail(selected_direction, bg_info, wv, ps, dd):
87
  client = OpenAI(api_key=api_key)
88
 
89
  msgs = [
90
- {"role": "system", "content": "你是一位专业职业顾问,会为用户选定方向提供详细的分析。"},
91
  {"role": "user", "content": prompt}
92
  ]
93
  resp = client.chat.completions.create(
@@ -105,8 +117,8 @@ def do_selected_career_detail(selected_direction, bg_info, wv, ps, dd):
105
 
106
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 路线图生成函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107
  def do_time_roadmap():
108
- # 修改:优先使用 final_choice
109
- direction = user_profile.get("final_choice") or user_profile.get("forward_direction_choice") or user_profile.get("specific_career")
110
  bg_info = user_profile["bg_info"] or "未知专业"
111
  wv = user_profile["work_value"] or "暂无"
112
  ps = user_profile["personality_summary"] or "暂无"
@@ -115,16 +127,18 @@ def do_time_roadmap():
115
  prompt_roadmap = f"""
116
  学生信息:
117
  - 学术背景:{bg_info}
118
- - 职业方向:{direction}
119
  - 工作价值:{wv}
120
  - 性格:{ps}
121
  - 理想工作:{dd}
 
122
  请你使用时间轴方式,给出一个职业路线图,如:
123
  📍 Now: [当前阶段做什么]
124
  🎓 Year X: [需要选的课/要做的项目]
125
  💼 下个暑假: [申请什么实习、参加什么活动]
126
  📄 毕业前: [考什么证书、准备材料]
127
  🚀 毕业后: [目标岗位、如何申请]
 
128
  请用Markdown分段写作,结合学生当前背景合理推断要点,写得具体些。
129
  """
130
  try:
@@ -150,8 +164,67 @@ def do_time_roadmap():
150
  return f"生成路线图时出错: {str(e)}"
151
 
152
 
153
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 深度分析函数 (可保留备用) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  def do_deep_analysis():
 
155
  direction = user_profile["forward_direction_choice"] or "尚未选择"
156
  bg_info = user_profile["bg_info"] or "未知背景"
157
  wv = user_profile["work_value"] or "无"
@@ -235,15 +308,13 @@ def recommend_3directions():
235
  stream=False
236
  )
237
 
238
- # 这里是真实的大模型返回文本
239
  output_text = resp.choices[0].message.content
240
 
241
- # ---- 关键:给 user_profile["recommended_directions"] 赋值 ----
242
- # 如果你想自动化解析返回的方向,可用正则或提取逻辑。这里演示写死3个示例:
243
  user_profile["recommended_directions"] = [
244
- "远程工程咨询",
245
- "在线教育和辅导",
246
- "远程研发项目管理"
247
  ]
248
 
249
  return output_text
@@ -303,7 +374,9 @@ def predict(message, history):
303
  global forward_deep_dive_done
304
  global roadmap_offered, roadmap_done
305
 
306
- # ========== 初始化 ==========
 
 
307
  if not history:
308
  current_q_index = 0
309
  questions[:] = base_questions
@@ -314,14 +387,19 @@ def predict(message, history):
314
  in_backward_flow = False
315
  forward_index = 0
316
  backward_index = 0
317
- forward_done = backward_done = False
 
318
  forward_recommendation_given = False
319
  recommendation_round = 0
320
  forward_deep_dive_done = False
321
  roadmap_offered = False
322
  roadmap_done = False
323
 
324
- # ========== 先处理基础问题 ==========
 
 
 
 
325
  if 0 < current_q_index <= len(questions):
326
  key = questions[current_q_index - 1][0]
327
  # 第一个问题决定是 / 否
@@ -340,7 +418,7 @@ def predict(message, history):
340
  current_q_index += 1
341
  return nxt
342
 
343
- # ========== 分模式处理 ==========
344
  mode = user_profile.get("mode") or ""
345
 
346
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -348,7 +426,7 @@ def predict(message, history):
348
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
349
  if mode == "是":
350
  if in_backward_flow and not backward_done:
351
- # 补充回答
352
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
353
  prev_key = backward_additional_questions[backward_index - 1][0]
354
  user_profile[prev_key] = message.strip()
@@ -388,66 +466,98 @@ def predict(message, history):
388
  # Forward模式处理
389
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
390
  else:
391
- if in_forward_flow and not forward_done and not forward_deep_dive_done and not roadmap_done:
392
- # 收集 Forward 问题回答
393
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
394
  prev_key = forward_additional_questions[forward_index - 1][0]
395
  user_profile[prev_key] = message.strip()
396
 
397
- # 如果还有 Forward 的问题没问完
398
  if forward_index < len(forward_additional_questions):
399
  k, prompt_text = forward_additional_questions[forward_index]
400
  forward_index += 1
401
  return prompt_text
402
 
403
- # 如果 4 个问题都问完 -> 推荐3方向
404
  elif not forward_recommendation_given:
405
  forward_recommendation_given = True
406
  return recommend_3directions()
407
 
408
  else:
409
- # 学生选1/2/3 or ''
410
  choice = message.strip().lower()
411
  if choice in ["1","2","3"]:
412
- # 将数字保存在 forward_direction_choice
413
- user_profile["forward_direction_choice"] = choice
414
-
415
- # 先找到选的是哪一个实际方向
416
- idx = int(choice) - 1 # 0,1,2
417
- # 如果 recommended_directions 有存储,拿到
418
- # 如果为空,就简单用 '未知方向'
419
- final_dir = "未知方向"
420
- if user_profile["recommended_directions"]:
421
- if 0 <= idx < len(user_profile["recommended_directions"]):
422
- final_dir = user_profile["recommended_directions"][idx]
423
-
424
- # 存下来,后续生成路线图用
425
- user_profile["final_choice"] = final_dir
426
-
427
- # 生成更详细的分析
428
- detail_msg = do_selected_career_detail(
429
- selected_direction=final_dir,
430
- bg_info=user_profile["bg_info"] or "",
431
- wv=user_profile["work_value"] or "",
432
- ps=user_profile["personality_summary"] or "",
433
- dd=user_profile["dream_day"] or ""
434
- )
435
-
436
- forward_deep_dive_done = True
437
- return detail_msg
438
-
439
  elif choice == "换":
440
  recommendation_round += 1
441
  if recommendation_round > 2:
442
  forward_done = True
443
  return "已多次换方向,结束推荐。"
444
  else:
 
445
  return recommend_3directions()
446
  else:
447
  return "请回复1/2/3选择方向,或输入'换'来重新推荐"
448
 
449
- # 详细方向介绍结束后 -> 问时间轴
450
- elif forward_deep_dive_done and not roadmap_offered:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  roadmap_offered = True
452
  return "需要一个时间轴式职业路线图吗?如需,则回复【要】,否则回复【不要】。"
453
 
@@ -486,6 +596,7 @@ def predict(message, history):
486
  except Exception as e:
487
  return f"发生错误: {str(e)}"
488
 
 
489
  return "信息收集完毕,如还未得到最终回复,请再输入任意文字继续。"
490
 
491
 
@@ -579,6 +690,8 @@ footer {
579
  global forward_deep_dive_done
580
  global roadmap_offered, roadmap_done
581
 
 
 
582
  current_q_index = 0
583
  questions[:] = base_questions
584
  for k in user_profile:
@@ -595,6 +708,11 @@ footer {
595
  forward_deep_dive_done = False
596
  roadmap_offered = False
597
  roadmap_done = False
 
 
 
 
 
598
  return []
599
 
600
  reset.click(reset_state, outputs=chatbot)
 
11
  "personality_summary": None,
12
  "dream_day": None,
13
  "forward_direction_choice": None,
14
+
15
+ # 新增:用于 Forward 模式下的更多状态
16
+ "recommended_directions": [], # 3个大方向
17
+ "selected_direction": None, # 学生最终选定的大方向
18
+ "recommended_jobs": [], # 3个具体职业
19
+ "final_choice": None # 学生最终选定的具体职业
20
  }
21
 
22
  # ============================ 基础问题 ============================
 
54
  roadmap_offered = False
55
  roadmap_done = False
56
 
57
+ # 新增:控制大方向→具体职业的流程
58
+ direction_chosen = False # 是否已经选定大方向
59
+ jobs_recommended = False # 是否已给出3个具体职业
60
+ job_chosen = False # 是否选定了具体职业
61
+
62
  # ============================ 模型设置 ============================
63
  model_default = "gpt-4o"
64
  token_default = 2000
65
  temp_default = 0.7
66
  top_p_default = 0.95
67
 
68
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 提供具体职业后,再深入介绍 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69
+ def do_selected_career_detail(selected_career, bg_info, wv, ps, dd):
 
70
  """
71
+ 学生在3个具体职业里某一个后,详细介绍
72
+ 1. 薪资水平
73
+ 2. 工作环境
74
+ 3. 晋升难度
75
+ 4. 关键技能和考证
76
+ 5. 日常工作节奏
77
  """
78
  prompt = f"""
79
  你是一位专业的职业规划顾问。
80
+ 学生最终的具体职业: {selected_career}
81
  学生背景: {bg_info}
82
+ 工作意义: {wv}
83
  性格: {ps}
84
  理想工作: {dd}
85
 
86
+ 请写一份更详细的职业说明,至少包含:
87
  1. 行业平均薪资(初级/中级/高级)
88
  2. 工作环境(远程/混合/办公室,团队规模等)
89
  3. 晋升难度(需要什么资历或条件)
90
  4. 关键技能和考证
91
  5. 日常工作节奏
92
+
93
+ 用分段Markdown格式,字数不少于300字。
94
  """
95
  try:
96
  api_key = os.environ.get("API_TOKEN")
 
99
  client = OpenAI(api_key=api_key)
100
 
101
  msgs = [
102
+ {"role": "system", "content": "你是一位专业职业顾问,会为用户选定的具体职业提供详细的分析。"},
103
  {"role": "user", "content": prompt}
104
  ]
105
  resp = client.chat.completions.create(
 
117
 
118
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 路线图生成函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119
  def do_time_roadmap():
120
+ # 优先 final_choice
121
+ direction = user_profile.get("final_choice") or user_profile.get("selected_direction") or user_profile.get("forward_direction_choice") or user_profile.get("specific_career")
122
  bg_info = user_profile["bg_info"] or "未知专业"
123
  wv = user_profile["work_value"] or "暂无"
124
  ps = user_profile["personality_summary"] or "暂无"
 
127
  prompt_roadmap = f"""
128
  学生信息:
129
  - 学术背景:{bg_info}
130
+ - 职业方向/具体职业:{direction}
131
  - 工作价值:{wv}
132
  - 性格:{ps}
133
  - 理想工作:{dd}
134
+
135
  请你使用时间轴方式,给出一个职业路线图,如:
136
  📍 Now: [当前阶段做什么]
137
  🎓 Year X: [需要选的课/要做的项目]
138
  💼 下个暑假: [申请什么实习、参加什么活动]
139
  📄 毕业前: [考什么证书、准备材料]
140
  🚀 毕业后: [目标岗位、如何申请]
141
+
142
  请用Markdown分段写作,结合学生当前背景合理推断要点,写得具体些。
143
  """
144
  try:
 
164
  return f"生成路线图时出错: {str(e)}"
165
 
166
 
167
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 给定大方向后,再给3个具体职业 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168
+ def recommend_3jobs_for_direction(direction, bg_info, wv, ps, dd):
169
+ """
170
+ 当学生选定了某个大方向后,AI再推荐3个该方向下的具体职业
171
+ """
172
+ prompt = f"""
173
+ 你是一位专��的职业规划顾问。
174
+ 学生选定的大方向:{direction}
175
+ 学生背景:{bg_info}
176
+ 工作意义:{wv}
177
+ 性格:{ps}
178
+ 理想工作:{dd}
179
+
180
+ 请为该方向推荐3个更具体的职业岗位,并分点说明:
181
+ 1) 为什么适合这个大方向
182
+ 2) 典型工作职责
183
+ 3) 技能/证书要求
184
+ 4) 未来发展前景
185
+
186
+ 最后再用如下格式提示学生选择:
187
+ 1. XXX职业
188
+ 2. XXX职业
189
+ 3. XXX职业
190
+ 如都不满意,可输入'换'。
191
+ """
192
+ try:
193
+ api_key = os.environ.get("API_TOKEN")
194
+ if not api_key:
195
+ return "错误:API_TOKEN 未设置"
196
+ client = OpenAI(api_key=api_key)
197
+
198
+ msgs = [
199
+ {"role": "system", "content": "你是一位专业职业顾问,会根据用户选定的大方向再推荐3个具体职业。"},
200
+ {"role": "user", "content": prompt}
201
+ ]
202
+ resp = client.chat.completions.create(
203
+ model=model_default,
204
+ messages=msgs,
205
+ max_tokens=token_default,
206
+ temperature=temp_default,
207
+ top_p=top_p_default,
208
+ stream=False
209
+ )
210
+ # 模型返回的文本
211
+ output_text = resp.choices[0].message.content
212
+
213
+ # 这里可以固定或基于返回文本做解析,我这边演示先手动赋值。
214
+ user_profile["recommended_jobs"] = [
215
+ f"{direction} - 职业A",
216
+ f"{direction} - 职业B",
217
+ f"{direction} - 职业C"
218
+ ]
219
+ return output_text
220
+
221
+ except Exception as e:
222
+ return f"推荐具体职业时出错: {str(e)}"
223
+
224
+
225
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 深度分析函数(可做备用) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
226
  def do_deep_analysis():
227
+ # 保留原有,若后续需要也可用
228
  direction = user_profile["forward_direction_choice"] or "尚未选择"
229
  bg_info = user_profile["bg_info"] or "未知背景"
230
  wv = user_profile["work_value"] or "无"
 
308
  stream=False
309
  )
310
 
 
311
  output_text = resp.choices[0].message.content
312
 
313
+ # 这里演示写死3个大方向,真实场景可再解析大模型返回
 
314
  user_profile["recommended_directions"] = [
315
+ "方向A:工程咨询",
316
+ "方向B:在线教育",
317
+ "方向C:研发管理"
318
  ]
319
 
320
  return output_text
 
374
  global forward_deep_dive_done
375
  global roadmap_offered, roadmap_done
376
 
377
+ global direction_chosen, jobs_recommended, job_chosen
378
+
379
+ # ======================== 初始化 =========================
380
  if not history:
381
  current_q_index = 0
382
  questions[:] = base_questions
 
387
  in_backward_flow = False
388
  forward_index = 0
389
  backward_index = 0
390
+ forward_done = False
391
+ backward_done = False
392
  forward_recommendation_given = False
393
  recommendation_round = 0
394
  forward_deep_dive_done = False
395
  roadmap_offered = False
396
  roadmap_done = False
397
 
398
+ direction_chosen = False
399
+ jobs_recommended = False
400
+ job_chosen = False
401
+
402
+ # ======================== 先处理基础问题 =========================
403
  if 0 < current_q_index <= len(questions):
404
  key = questions[current_q_index - 1][0]
405
  # 第一个问题决定是 / 否
 
418
  current_q_index += 1
419
  return nxt
420
 
421
+ # ======================== 分模式处理 =========================
422
  mode = user_profile.get("mode") or ""
423
 
424
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
426
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
427
  if mode == "是":
428
  if in_backward_flow and not backward_done:
429
+ # 录入回答
430
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
431
  prev_key = backward_additional_questions[backward_index - 1][0]
432
  user_profile[prev_key] = message.strip()
 
466
  # Forward模式处理
467
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
468
  else:
469
+ # 1) 先问 forward_additional_questions
470
+ if in_forward_flow and not forward_done and not direction_chosen and not jobs_recommended and not job_chosen and not roadmap_done:
471
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
472
  prev_key = forward_additional_questions[forward_index - 1][0]
473
  user_profile[prev_key] = message.strip()
474
 
 
475
  if forward_index < len(forward_additional_questions):
476
  k, prompt_text = forward_additional_questions[forward_index]
477
  forward_index += 1
478
  return prompt_text
479
 
480
+ # 已完成4个问题,准备推荐3方向
481
  elif not forward_recommendation_given:
482
  forward_recommendation_given = True
483
  return recommend_3directions()
484
 
485
  else:
486
+ # 学生选择大方向 or 换
487
  choice = message.strip().lower()
488
  if choice in ["1","2","3"]:
489
+ idx = int(choice) - 1
490
+ if idx < len(user_profile["recommended_directions"]):
491
+ # 选定的大方向
492
+ sel_dir = user_profile["recommended_directions"][idx]
493
+ user_profile["selected_direction"] = sel_dir
494
+ direction_chosen = True
495
+ # 进入:给出该方向下的3个具体职业
496
+ return recommend_3jobs_for_direction(
497
+ direction=sel_dir,
498
+ bg_info=user_profile["bg_info"] or "",
499
+ wv=user_profile["work_value"] or "",
500
+ ps=user_profile["personality_summary"] or "",
501
+ dd=user_profile["dream_day"] or ""
502
+ )
503
+ else:
504
+ return "无效选项,请重新输入1/2/3或'换'"
 
 
 
 
 
 
 
 
 
 
 
505
  elif choice == "换":
506
  recommendation_round += 1
507
  if recommendation_round > 2:
508
  forward_done = True
509
  return "已多次换方向,结束推荐。"
510
  else:
511
+ # 再次推荐3大方向
512
  return recommend_3directions()
513
  else:
514
  return "请回复1/2/3选择方向,或输入'换'来重新推荐"
515
 
516
+ # 2) 已选定大方向 -> 推荐了3个具体职业
517
+ elif direction_chosen and not jobs_recommended and not job_chosen:
518
+ # 此时 message 应该是“AI 给出3个具体职业”后,用户的输入
519
+ # 学生现在选“1/2/3”或“换”
520
+ choice = message.strip().lower()
521
+ if choice in ["1","2","3"]:
522
+ idx = int(choice) - 1
523
+ if idx < len(user_profile["recommended_jobs"]):
524
+ final_job = user_profile["recommended_jobs"][idx]
525
+ user_profile["final_choice"] = final_job
526
+ job_chosen = True
527
+
528
+ # 生成详细介绍
529
+ detail_msg = do_selected_career_detail(
530
+ selected_career=final_job,
531
+ bg_info=user_profile["bg_info"] or "",
532
+ wv=user_profile["work_value"] or "",
533
+ ps=user_profile["personality_summary"] or "",
534
+ dd=user_profile["dream_day"] or ""
535
+ )
536
+ forward_deep_dive_done = True
537
+ return detail_msg
538
+ else:
539
+ return "无效的选项,请重新输入1/2/3或'换'"
540
+ elif choice == "换":
541
+ # 学生对这3个具体职业不满意
542
+ recommendation_round += 1
543
+ if recommendation_round > 2:
544
+ forward_done = True
545
+ return "已多次换职业,结束推荐。"
546
+ else:
547
+ # 重新推荐3个具体职业
548
+ sel_dir = user_profile.get("selected_direction") or "未知方向"
549
+ return recommend_3jobs_for_direction(
550
+ direction=sel_dir,
551
+ bg_info=user_profile["bg_info"] or "",
552
+ wv=user_profile["work_value"] or "",
553
+ ps=user_profile["personality_summary"] or "",
554
+ dd=user_profile["dream_day"] or ""
555
+ )
556
+ else:
557
+ return "请回复1/2/3选择具体职业,或输入'换'来重新推荐"
558
+
559
+ # 3) 已选定具体职业 -> 问是否需要时间轴
560
+ elif job_chosen and not roadmap_offered and not roadmap_done:
561
  roadmap_offered = True
562
  return "需要一个时间轴式职业路线图吗?如需,则回复【要】,否则回复【不要】。"
563
 
 
596
  except Exception as e:
597
  return f"发生错误: {str(e)}"
598
 
599
+ # 如果都没被return,执行这里:
600
  return "信息收集完毕,如还未得到最终回复,请再输入任意文字继续。"
601
 
602
 
 
690
  global forward_deep_dive_done
691
  global roadmap_offered, roadmap_done
692
 
693
+ global direction_chosen, jobs_recommended, job_chosen
694
+
695
  current_q_index = 0
696
  questions[:] = base_questions
697
  for k in user_profile:
 
708
  forward_deep_dive_done = False
709
  roadmap_offered = False
710
  roadmap_done = False
711
+
712
+ direction_chosen = False
713
+ jobs_recommended = False
714
+ job_chosen = False
715
+
716
  return []
717
 
718
  reset.click(reset_state, outputs=chatbot)