HelenaXH commited on
Commit
c6753f9
·
verified ·
1 Parent(s): 9561784

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -67
app.py CHANGED
@@ -21,11 +21,8 @@ base_questions = [
21
  # ============================ Forward 模式问题 ============================
22
  forward_additional_questions = [
23
  ("bg_info", """那么接下来我会需要你提供一些你的资料,并分享一些你的性格和喜好。请先告诉我,你的学校、年级、专业,和主修课程是什么?如果能提供你的选课表或resume就更好啦。"""),
24
-
25
  ("work_value", """非常好!那你认为“工作”的意义是什么?你觉得一份理想的工作,应该带来哪些价值或满足感?(例如:帮助他人、赚大钱、自由时间、个人成长、创意空间等)"""),
26
-
27
  ("personality_summary", "用几句话总结你的性格:比如外向/内向?喜欢挑战?注重细节?讨厌重复吗?"),
28
-
29
  ("dream_day", "再描述一下你理想工作的一天是什么样:在哪工作?做什么?和谁合作?忙还是闲?更自由还是更有秩序?")
30
  ]
31
 
@@ -46,7 +43,6 @@ 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
@@ -105,7 +101,7 @@ def do_time_roadmap():
105
  except Exception as e:
106
  return f"生成路线图时出错: {str(e)}"
107
 
108
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 深度分析(3个具体职业) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109
  def do_deep_analysis():
110
  direction = user_profile["forward_direction_choice"] or "尚未选择"
111
  bg_info = user_profile["bg_info"] or "未知背景"
@@ -161,7 +157,7 @@ def recommend_3directions():
161
  rec_prompt = f"""
162
  请根据以下信息,写一份条理清晰的人物画像+3个大方向,并结尾让学生选1~3或'换':
163
  - 学术背景: {bg_info}
164
- - 工作价值: {wv}
165
  - 性格: {ps}
166
  - 理想工作: {dd}
167
  分两部分:
@@ -204,7 +200,7 @@ def generate_system_prompt():
204
  dd = user_profile["dream_day"]
205
  fwd = user_profile["forward_direction_choice"]
206
 
207
- if mode == "是": # 只有当base question回答“是”时 -> backward
208
  return f"""
209
  你是一位专业的职业规划顾问,使用Backward Design方法帮助学生达成他们的职业目标。
210
  目标职业: {sc}
@@ -265,15 +261,11 @@ def predict(message, history):
265
  # ===== 如果在base_questions环节 =====
266
  if 0 < current_q_index <= len(questions):
267
  key = questions[current_q_index - 1][0]
268
- # 仅当 key == "mode" 且我们还在问第1题 时, 才存回答到 user_profile["mode"]
269
  if key == "mode" and current_q_index == 1:
270
- # 这是回答第一个问题 => 决定 forward/backward
271
- user_profile["mode"] = message.strip()
272
  else:
273
- # 其他base问题(目前没别的), 可以存到 user_profile 也行
274
  user_profile[key] = message.strip()
275
 
276
- # 如果 base_questions 没问完 -> 问下一道
277
  if current_q_index < len(questions):
278
  nxt = questions[current_q_index][1]
279
  current_q_index += 1
@@ -281,7 +273,7 @@ def predict(message, history):
281
 
282
  mode = user_profile.get("mode") or ""
283
 
284
- # ~~~~~~~~~~~~ Backward 模式 ~~~~~~~~~~~~
285
  if mode == "是":
286
  if in_backward_flow and not backward_done:
287
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
@@ -296,15 +288,14 @@ def predict(message, history):
296
  backward_done = True
297
 
298
  if backward_done:
299
- # 生成backward结果
300
- import_text = generate_system_prompt()
301
  try:
302
  api_key = os.environ.get("API_TOKEN")
303
  if not api_key:
304
  return "错误:API_TOKEN 未设置"
305
  client = OpenAI(api_key=api_key)
 
306
  msgs = [
307
- {"role":"system","content": import_text},
308
  {"role":"user","content": f"请根据{user_profile}给出最终规划"}
309
  ]
310
  resp = client.chat.completions.create(
@@ -319,25 +310,21 @@ def predict(message, history):
319
  except Exception as e:
320
  return f"发生错误: {str(e)}"
321
 
322
- # ~~~~~~~~~~~~ Forward 模式 ~~~~~~~~~~~~
323
  else:
324
  if in_forward_flow and not forward_done and not forward_deep_dive_done and not roadmap_done:
325
- # 存储上一回答(不影响mode)
326
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
327
  prev_key = forward_additional_questions[forward_index - 1][0]
328
  user_profile[prev_key] = message.strip()
329
 
330
- # 如果还有forward附加问题没问完
331
  if forward_index < len(forward_additional_questions):
332
  k, prompt_text = forward_additional_questions[forward_index]
333
  forward_index += 1
334
  return prompt_text
335
- # 问完4个问题 -> 推荐3方向
336
  elif not forward_recommendation_given:
337
  forward_recommendation_given = True
338
  return recommend_3directions()
339
  else:
340
- # 用户选1/2/3或 '换'
341
  choice = message.strip().lower()
342
  if choice in ["1","2","3"]:
343
  user_profile["forward_direction_choice"] = choice
@@ -347,19 +334,17 @@ def predict(message, history):
347
  recommendation_round += 1
348
  if recommendation_round > 2:
349
  forward_done = True
350
- return "已多次换方向,结束推荐吧。"
351
  else:
352
  return recommend_3directions()
353
  else:
354
- return "请回复1/2/3选择方向,或输入'换'来重新推荐"
355
 
356
  elif forward_deep_dive_done and not roadmap_offered:
357
- # 深度分析完 -> 问路线图
358
  roadmap_offered = True
359
- return "需要一个时间轴式职业路线图吗?如果是,请回复“是”,否则回复“否”。"
360
 
361
  elif roadmap_offered and not roadmap_done:
362
- # 学生答 “是” or “否”
363
  ans = message.strip().lower()
364
  if ans == "是":
365
  roadmap_done = True
@@ -368,19 +353,18 @@ def predict(message, history):
368
  else:
369
  roadmap_done = True
370
  forward_done = True
371
- return "好的,不生成路线图,本次规划结束了~"
372
 
373
  if forward_done:
374
- # 最终输出
375
- sprompt = generate_system_prompt()
376
  try:
377
  api_key = os.environ.get("API_TOKEN")
378
  if not api_key:
379
  return "错误:API_TOKEN 未设置"
380
  client = OpenAI(api_key=api_key)
 
381
  msgs = [
382
  {"role":"system","content":sprompt},
383
- {"role":"user","content": f"以下学生资料: {user_profile}. 需要更多咨询请提问。"}
384
  ]
385
  resp = client.chat.completions.create(
386
  model=model_default,
@@ -394,8 +378,7 @@ def predict(message, history):
394
  except Exception as e:
395
  return f"发生错误: {str(e)}"
396
 
397
- return "信息收集完毕,尚未得到最终回复,请输入任意内容以继续。"
398
-
399
 
400
  # ============================ Gradio UI ============================
401
  with gr.Blocks(css="""
@@ -455,19 +438,20 @@ footer {
455
  <img src='https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFucGwxbmNsd3J5NXV0Y282NXNtMzNsZW5jMm4wNWh6c2dqbXIwdiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l41m18LjqpzxUr2WA/giphy.gif' width='200' style='border-radius: 12px; box-shadow: 0 0 10px #ec4899;'>
456
  <div style='text-align: left;'>
457
  <h1 style='color:white; font-size: 36px; margin-bottom: 6px;'>🎓 多步职业规划助手</h1>
458
- <p style='font-size: 18px; font-weight:bold; color:#ec4899; margin-top: 0;'>Forward三步:推荐大方向→深度分析→可选时间轴路线图</p>
459
  </div>
460
  </div>
461
  """)
462
- gr.Markdown("""
463
- **📝 Forward / Backward 多轮交互,附带换方向深度分析、以及可选时间轴路线图**
464
- 1. 如果你已有明确职业目标 => 回答“是”(Backward)
465
- 2. 如果还在探索 => 回答“否”(Forward)
466
- 3. Forward模式下:先问4个问题→推荐3大方向→可换→选定后深度分析→询问是否要路线图
467
- """)
468
-
469
- chatbot = gr.Chatbot(height=500, show_label=False, show_copy_button=True, type="messages")
470
-
 
471
  with gr.Row():
472
  with gr.Column(scale=8):
473
  msg = gr.Textbox(placeholder="请在这���输入你的回答...", show_label=False, container=False)
@@ -476,25 +460,25 @@ footer {
476
 
477
  with gr.Row():
478
  reset_btn = gr.Button("🔄 重新开始")
479
-
480
- def add_user_message(m, h):
481
- h = h or []
482
- h.append({"role":"user","content":m})
483
- return "", h
484
 
485
- def add_bot_response(h):
486
- user_m = h[-1]["content"]
487
- bot_m = predict(user_m, h[:-1])
488
- h.append({"role":"assistant","content":bot_m})
489
- return h
490
 
491
- send.click(add_user_message, [msg, chatbot], [msg, chatbot]) \
492
- .then(add_bot_response, chatbot, chatbot)
 
 
 
 
493
 
494
- msg.submit(add_user_message, [msg, chatbot], [msg, chatbot]) \
495
- .then(add_bot_response, chatbot, chatbot)
 
 
496
 
497
- def reset_all():
498
  global current_q_index, questions
499
  global in_forward_flow, in_backward_flow
500
  global forward_index, backward_index
@@ -509,21 +493,23 @@ footer {
509
  for k in user_profile:
510
  user_profile[k] = None
511
 
512
- in_forward_flow = in_backward_flow = False
513
- forward_index = backward_index = 0
514
- forward_done = backward_done = False
 
 
 
515
  forward_recommendation_given = False
516
  recommendation_round = 0
517
  forward_deep_dive_done = False
518
  roadmap_offered = False
519
  roadmap_done = False
520
- return []
521
-
522
- reset.click(reset_all, outputs=chatbot)
523
 
524
- def start():
525
- return [{"role":"assistant","content": questions[0][1]}]
526
 
527
- demo.load(start, outputs=chatbot)
 
528
 
529
- demo.launch()
 
 
21
  # ============================ Forward 模式问题 ============================
22
  forward_additional_questions = [
23
  ("bg_info", """那么接下来我会需要你提供一些你的资料,并分享一些你的性格和喜好。请先告诉我,你的学校、年级、专业,和主修课程是什么?如果能提供你的选课表或resume就更好啦。"""),
 
24
  ("work_value", """非常好!那你认为“工作”的意义是什么?你觉得一份理想的工作,应该带来哪些价值或满足感?(例如:帮助他人、赚大钱、自由时间、个人成长、创意空间等)"""),
 
25
  ("personality_summary", "用几句话总结你的性格:比如外向/内向?喜欢挑战?注重细节?讨厌重复吗?"),
 
26
  ("dream_day", "再描述一下你理想工作的一天是什么样:在哪工作?做什么?和谁合作?忙还是闲?更自由还是更有秩序?")
27
  ]
28
 
 
43
  backward_done = False
44
  forward_recommendation_given = False
45
 
 
46
  recommendation_round = 0
47
  forward_deep_dive_done = False
48
  roadmap_offered = False
 
101
  except Exception as e:
102
  return f"生成路线图时出错: {str(e)}"
103
 
104
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 深度分析函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105
  def do_deep_analysis():
106
  direction = user_profile["forward_direction_choice"] or "尚未选择"
107
  bg_info = user_profile["bg_info"] or "未知背景"
 
157
  rec_prompt = f"""
158
  请根据以下信息,写一份条理清晰的人物画像+3个大方向,并结尾让学生选1~3或'换':
159
  - 学术背景: {bg_info}
160
+ - 工作意义: {wv}
161
  - 性格: {ps}
162
  - 理想工作: {dd}
163
  分两部分:
 
200
  dd = user_profile["dream_day"]
201
  fwd = user_profile["forward_direction_choice"]
202
 
203
+ if mode == "是":
204
  return f"""
205
  你是一位专业的职业规划顾问,使用Backward Design方法帮助学生达成他们的职业目标。
206
  目标职业: {sc}
 
261
  # ===== 如果在base_questions环节 =====
262
  if 0 < current_q_index <= len(questions):
263
  key = questions[current_q_index - 1][0]
 
264
  if key == "mode" and current_q_index == 1:
265
+ user_profile["mode"] = message.strip() # 只这里写 mode
 
266
  else:
 
267
  user_profile[key] = message.strip()
268
 
 
269
  if current_q_index < len(questions):
270
  nxt = questions[current_q_index][1]
271
  current_q_index += 1
 
273
 
274
  mode = user_profile.get("mode") or ""
275
 
276
+ # ~~~~~~~~~~~~ Backward模式 ~~~~~~~~~~~~
277
  if mode == "是":
278
  if in_backward_flow and not backward_done:
279
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
 
288
  backward_done = True
289
 
290
  if backward_done:
 
 
291
  try:
292
  api_key = os.environ.get("API_TOKEN")
293
  if not api_key:
294
  return "错误:API_TOKEN 未设置"
295
  client = OpenAI(api_key=api_key)
296
+ sprompt = generate_system_prompt()
297
  msgs = [
298
+ {"role":"system","content": sprompt},
299
  {"role":"user","content": f"请根据{user_profile}给出最终规划"}
300
  ]
301
  resp = client.chat.completions.create(
 
310
  except Exception as e:
311
  return f"发生错误: {str(e)}"
312
 
313
+ # ~~~~~~~~~~~~ Forward模式 ~~~~~~~~~~~~
314
  else:
315
  if in_forward_flow and not forward_done and not forward_deep_dive_done and not roadmap_done:
 
316
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
317
  prev_key = forward_additional_questions[forward_index - 1][0]
318
  user_profile[prev_key] = message.strip()
319
 
 
320
  if forward_index < len(forward_additional_questions):
321
  k, prompt_text = forward_additional_questions[forward_index]
322
  forward_index += 1
323
  return prompt_text
 
324
  elif not forward_recommendation_given:
325
  forward_recommendation_given = True
326
  return recommend_3directions()
327
  else:
 
328
  choice = message.strip().lower()
329
  if choice in ["1","2","3"]:
330
  user_profile["forward_direction_choice"] = choice
 
334
  recommendation_round += 1
335
  if recommendation_round > 2:
336
  forward_done = True
337
+ return "已多次换方向,结束推荐了~"
338
  else:
339
  return recommend_3directions()
340
  else:
341
+ return "请回复1/2/3选择方向,或输入'换'来重"
342
 
343
  elif forward_deep_dive_done and not roadmap_offered:
 
344
  roadmap_offered = True
345
+ return "需要一个时间轴式职业路线图吗?如果是,请回复“是”,否则回复“否”。"
346
 
347
  elif roadmap_offered and not roadmap_done:
 
348
  ans = message.strip().lower()
349
  if ans == "是":
350
  roadmap_done = True
 
353
  else:
354
  roadmap_done = True
355
  forward_done = True
356
+ return "好的,不生成时间轴,本次就到这里。"
357
 
358
  if forward_done:
 
 
359
  try:
360
  api_key = os.environ.get("API_TOKEN")
361
  if not api_key:
362
  return "错误:API_TOKEN 未设置"
363
  client = OpenAI(api_key=api_key)
364
+ sprompt = generate_system_prompt()
365
  msgs = [
366
  {"role":"system","content":sprompt},
367
+ {"role":"user","content": f"最终资料: {user_profile}, 如果还需要帮助请提问。"}
368
  ]
369
  resp = client.chat.completions.create(
370
  model=model_default,
 
378
  except Exception as e:
379
  return f"发生错误: {str(e)}"
380
 
381
+ return "信息收集完毕,如果尚未得到最终回复,请输入任意文字继续。"
 
382
 
383
  # ============================ Gradio UI ============================
384
  with gr.Blocks(css="""
 
438
  <img src='https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFucGwxbmNsd3J5NXV0Y282NXNtMzNsZW5jMm4wNWh6c2dqbXIwdiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l41m18LjqpzxUr2WA/giphy.gif' width='200' style='border-radius: 12px; box-shadow: 0 0 10px #ec4899;'>
439
  <div style='text-align: left;'>
440
  <h1 style='color:white; font-size: 36px; margin-bottom: 6px;'>🎓 多步职业规划助手</h1>
441
+ <p style='font-size: 18px; font-weight:bold; color:#ec4899; margin-top: 0;'>Forward三步:推荐大方向→深度分析→可选时间轴</p>
442
  </div>
443
  </div>
444
  """)
445
+ gr.Markdown("""
446
+ **Forward / Backward** 多轮交互;Forward可换方向+深度分析+时间轴;Backward直接问目标职业+背景
447
+ """)
448
+
449
+ chatbot = gr.Chatbot(
450
+ height=500,
451
+ show_label=False,
452
+ show_copy_button=True,
453
+ type="messages"
454
+ )
455
  with gr.Row():
456
  with gr.Column(scale=8):
457
  msg = gr.Textbox(placeholder="请在这���输入你的回答...", show_label=False, container=False)
 
460
 
461
  with gr.Row():
462
  reset_btn = gr.Button("🔄 重新开始")
 
 
 
 
 
463
 
464
+ def add_message(m, hist):
465
+ hist = hist or []
466
+ hist.append({"role":"user","content":m})
467
+ return "", hist
 
468
 
469
+ def bot_response(hist):
470
+ hist = hist or []
471
+ user_m = hist[-1]["content"]
472
+ bot_m = predict(user_m, hist[:-1])
473
+ hist.append({"role":"assistant","content":bot_m})
474
+ return hist
475
 
476
+ submit_btn.click(add_message, [msg, chatbot], [msg, chatbot]) \
477
+ .then(bot_response, chatbot, chatbot)
478
+ msg.submit(add_message, [msg, chatbot], [msg, chatbot]) \
479
+ .then(bot_response, chatbot, chatbot)
480
 
481
+ def reset_state():
482
  global current_q_index, questions
483
  global in_forward_flow, in_backward_flow
484
  global forward_index, backward_index
 
493
  for k in user_profile:
494
  user_profile[k] = None
495
 
496
+ in_forward_flow = False
497
+ in_backward_flow = False
498
+ forward_index = 0
499
+ backward_index = 0
500
+ forward_done = False
501
+ backward_done = False
502
  forward_recommendation_given = False
503
  recommendation_round = 0
504
  forward_deep_dive_done = False
505
  roadmap_offered = False
506
  roadmap_done = False
 
 
 
507
 
508
+ return []
509
+ reset_btn.click(reset_state, outputs=chatbot)
510
 
511
+ def auto_first():
512
+ return [{"role": "assistant", "content": questions[0][1]}]
513
 
514
+ demo.load(auto_first, outputs=chatbot)
515
+ demo.launch()