HelenaXH commited on
Commit
d2d5c74
·
verified ·
1 Parent(s): 49c7b41

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -234
app.py CHANGED
@@ -6,11 +6,11 @@ import os
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 +20,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 模式问题 ============================
@@ -47,7 +49,7 @@ 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
@@ -58,7 +60,7 @@ 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 "未知专业"
@@ -66,7 +68,6 @@ def do_time_roadmap():
66
  ps = user_profile["personality_summary"] or "暂无"
67
  dd = user_profile["dream_day"] or "暂无"
68
 
69
- # 生成路线图的prompt
70
  prompt_roadmap = f"""
71
  学生信息:
72
  - 学术背景:{bg_info}
@@ -84,31 +85,10 @@ def do_time_roadmap():
84
 
85
  请用Markdown分段写作,结合学生当前背景合理推断要点,写得具体些。
86
  """
87
- try:
88
- api_key = os.environ.get("API_TOKEN")
89
- if not api_key:
90
- return "错误:API_TOKEN 未设置"
91
- client = OpenAI(api_key=api_key)
92
 
93
- msgs = [
94
- {"role":"system","content":"你是一位专业的职业规划顾问,会生成时间轴式路线图"},
95
- {"role":"user","content": prompt_roadmap}
96
- ]
97
- resp = client.chat.completions.create(
98
- model=model_default,
99
- messages=msgs,
100
- max_tokens=token_default,
101
- temperature=temp_default,
102
- top_p=top_p_default,
103
- stream=False
104
- )
105
- return resp.choices[0].message.content
106
- except Exception as e:
107
- return f"生成路线图时出错: {str(e)}"
108
-
109
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 深度分析函数(3个具体职业) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110
  def do_deep_analysis():
111
- # 读取 user_profile
112
  direction = user_profile["forward_direction_choice"] or "尚未选择"
113
  bg_info = user_profile["bg_info"] or "未知背景"
114
  wv = user_profile["work_value"] or "无"
@@ -123,39 +103,19 @@ def do_deep_analysis():
123
  理想工作: {dd}
124
 
125
  请你再深入分析,为学生推荐3个更具体的职业,并说明:
126
- 1. 这些职业对学生背景的契合度(机械工程/心理学/商科等都可)
127
  2. 日常工作内容
128
  3. 需要哪些课程或考试
129
- 4. 本校资源如何利用
130
- 5. 实习 & 经验积累建议
131
  6. 简历优化思路
132
 
133
  用中文分段写作,字数500+。
134
  """
135
- try:
136
- api_key = os.environ.get("API_TOKEN")
137
- if not api_key:
138
- return "错误:API_TOKEN 未设置"
139
- client = OpenAI(api_key=api_key)
140
- msgs = [
141
- {"role":"system","content": "你是一位专业职业顾问,会深度分析并列出3个具体职业。"},
142
- {"role":"user","content": deep_prompt}
143
- ]
144
- resp = client.chat.completions.create(
145
- model=model_default,
146
- messages=msgs,
147
- max_tokens=token_default,
148
- temperature=temp_default,
149
- top_p=top_p_default,
150
- stream=False
151
- )
152
- return resp.choices[0].message.content
153
- except Exception as e:
154
- return f"深度分析出错: {str(e)}"
155
 
156
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 推荐大方向函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
  def recommend_3directions():
158
- # 读取 user_profile
159
  bg_info = user_profile["bg_info"] or "未知"
160
  wv = user_profile["work_value"] or "无"
161
  ps = user_profile["personality_summary"] or "不详"
@@ -171,20 +131,25 @@ def recommend_3directions():
171
  分两部分:
172
  [一、人物画像]:1) 学术背景 2) 价值观 3) 性格 4) 理想工作
173
  [二、推荐3个大方向]:每个方向(1~2段文字)
 
174
  最后用如下结尾:
175
  1. XXX方向
176
  2. XXX方向
177
  3. XXX方向
178
  如都不满意,可输入'换'。
179
  """
 
 
 
 
180
  try:
181
  api_key = os.environ.get("API_TOKEN")
182
  if not api_key:
183
  return "错误:API_TOKEN 未设置"
184
  client = OpenAI(api_key=api_key)
185
  msgs = [
186
- {"role":"system","content":"你是一位职业顾问,擅长根据用户资料推荐3大方向"},
187
- {"role":"user","content":rec_prompt}
188
  ]
189
  resp = client.chat.completions.create(
190
  model=model_default,
@@ -196,9 +161,49 @@ def recommend_3directions():
196
  )
197
  return resp.choices[0].message.content
198
  except Exception as e:
199
- return f"多方向推荐出错: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ predict ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202
  def predict(message, history):
203
  global current_q_index, questions
204
  global in_forward_flow, in_backward_flow
@@ -209,12 +214,12 @@ def predict(message, history):
209
  global forward_deep_dive_done
210
  global roadmap_offered, roadmap_done
211
 
212
- # 第一对话重置
213
  if not history:
214
  current_q_index = 0
215
  questions = base_questions[:]
216
- for key in user_profile:
217
- user_profile[key] = None
218
 
219
  in_forward_flow = in_backward_flow = False
220
  forward_index = backward_index = 0
@@ -225,7 +230,7 @@ def predict(message, history):
225
  roadmap_offered = False
226
  roadmap_done = False
227
 
228
- # ~~~~~~~~~~ 存储 base_questions 回答 ~~~~~~~~~~
229
  if 0 < current_q_index <= len(questions):
230
  key = questions[current_q_index - 1][0]
231
  user_profile[key] = message.strip()
@@ -238,7 +243,6 @@ def predict(message, history):
238
  # Forward
239
  in_forward_flow = True
240
 
241
- # 如果 base_questions 还没问完,就继续问
242
  if current_q_index < len(questions):
243
  nxt = questions[current_q_index][1]
244
  current_q_index += 1
@@ -246,15 +250,14 @@ def predict(message, history):
246
 
247
  mode = user_profile.get("mode") or ""
248
 
249
- # ======== Backward 流程 ========
250
  if "是" in mode:
251
  if in_backward_flow and not backward_done:
252
- # 存储上一回答
253
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
254
  prev_key = backward_additional_questions[backward_index - 1][0]
255
  user_profile[prev_key] = message.strip()
256
 
257
- # 下一个问题
258
  if backward_index < len(backward_additional_questions):
259
  k, prompt_text = backward_additional_questions[backward_index]
260
  backward_index += 1
@@ -262,76 +265,51 @@ def predict(message, history):
262
  else:
263
  backward_done = True
264
 
265
- # 如果 backward_done
266
  if backward_done:
267
- # 直接进入最终
268
- try:
269
- api_key = os.environ.get("API_TOKEN")
270
- if not api_key:
271
- return "错误:API密钥未设置"
272
- client = OpenAI(api_key=api_key)
273
- system_prompt = generate_system_prompt()
274
-
275
- msgs = [
276
- {"role":"system","content": system_prompt},
277
- {"role":"user","content": f"请根据信息{user_profile}给出完整规划"}
278
- ]
279
- resp = client.chat.completions.create(
280
- model=model_default,
281
- messages=msgs,
282
- max_tokens=token_default,
283
- temperature=temp_default,
284
- top_p=top_p_default,
285
- stream=False
286
- )
287
- return resp.choices[0].message.content
288
- except Exception as e:
289
- return f"发生错误: {str(e)}"
290
-
291
- # ======== Forward 流程 ========
292
  else:
293
  if in_forward_flow and not forward_done and not forward_deep_dive_done and not roadmap_done:
294
- # 存储上一回答
295
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
296
  prev_key = forward_additional_questions[forward_index - 1][0]
297
  user_profile[prev_key] = message.strip()
298
 
299
- # 若还有 Forward问题
300
  if forward_index < len(forward_additional_questions):
301
  k, prompt_text = forward_additional_questions[forward_index]
302
  forward_index += 1
303
  return prompt_text
304
-
305
- # 如果4个Forward问完,还没推荐
306
  elif not forward_recommendation_given:
307
  forward_recommendation_given = True
308
  return recommend_3directions()
309
-
310
- # 已推荐过方向,等待学生选1/2/3 or '换'
311
  else:
 
312
  choice = message.strip().lower()
313
- # 如果是1/2/3 => 深度分析
314
  if choice in ["1","2","3"]:
315
  user_profile["forward_direction_choice"] = choice
316
- # 进入深度分析
317
  forward_deep_dive_done = True
318
  return do_deep_analysis()
319
  elif "换" in choice:
320
  recommendation_round += 1
321
- if recommendation_round > 2: # 最多换2次
322
  forward_done = True
323
  return "已多次换方向,先进入下个阶段吧。"
324
- # 再次推荐
325
- return recommend_3directions()
326
  else:
327
  return "请回复1/2/3选择方向,或输入'换'来请求新的推荐"
328
 
329
- # 当深度分析完,才问路线图
330
  elif forward_deep_dive_done and not roadmap_offered:
 
331
  roadmap_offered = True
332
  return "需要一个时间轴式的职业路线图吗?如果需要,请回复“是”,否则回复“否”。"
333
 
334
  elif roadmap_offered and not roadmap_done:
 
335
  ans = message.strip().lower()
336
  if ans == "是":
337
  roadmap_done = True
@@ -342,135 +320,46 @@ def predict(message, history):
342
  forward_done = True
343
  return "好的,不生成路线图,本次规划到此结束。"
344
 
345
- # 如果 forward_done
346
  if forward_done:
347
- # 最终生成 or结束
348
- try:
349
- api_key = os.environ.get("API_TOKEN")
350
- if not api_key:
351
- return "错误:API密钥未设置"
352
- client = OpenAI(api_key=api_key)
353
- system_prompt = generate_system_prompt()
354
-
355
- msgs = [
356
- {"role":"system","content": system_prompt},
357
- {"role":"user","content": f"以下是学生资料: {user_profile}. 如需更详细方案可再次输入问题"}
358
- ]
359
- resp = client.chat.completions.create(
360
- model=model_default,
361
- messages=msgs,
362
- max_tokens=token_default,
363
- temperature=temp_default,
364
- top_p=top_p_default,
365
- stream=False
366
- )
367
- return resp.choices[0].message.content
368
- except Exception as e:
369
- return f"发生错误: {str(e)}"
370
 
371
  return "信息收集完毕,若尚未得到最终回复,请输入任意文字以继续。"
372
 
373
-
374
  # ============================ Gradio UI ============================
375
- with gr.Blocks(css="""
376
- body {
377
- background-color: #1e1e1e;
378
- color: #ffffff;
379
- }
380
- .gradio-container {
381
- font-family: 'Segoe UI', sans-serif;
382
- }
383
- .message.user {
384
- background-color: #cce6ff !important;
385
- color: #000000 !important;
386
- border-radius: 10px !important;
387
- padding: 10px;
388
- margin: 6px;
389
- }
390
- .message.bot {
391
- background-color: #5599ff !important;
392
- color: #000000 !important;
393
- border-radius: 10px !important;
394
- padding: 10px;
395
- margin: 6px;
396
- }
397
- .gradio-container .chat-msg.bot-msg .message.bot p {
398
- color: #000000 !important;
399
- }
400
- .gr-button {
401
- border-radius: 8px;
402
- }
403
- #custom-send {
404
- background-color: #ec4899 !important;
405
- color: white !important;
406
- border-radius: 999px !important;
407
- padding: 10px 24px !important;
408
- font-weight: bold;
409
- box-shadow: 0 0 10px #ec4899;
410
- transition: all 0.3s ease-in-out;
411
- }
412
- #custom-send:hover {
413
- background-color: #d63384 !important;
414
- box-shadow: 0 0 12px #ec4899;
415
- }
416
- textarea, input {
417
- background-color: #ffe4f1 !important;
418
- color: #5e2c49 !important;
419
- border: 1px solid #ec4899 !important;
420
- }
421
- footer {
422
- display: none !important;
423
- }
424
- """) as demo:
425
-
426
- with gr.Row():
427
- gr.HTML("""
428
- <div style='display: flex; align-items: center; justify-content: center; gap: 20px; margin-bottom: 10px;'>
429
- <img src='https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmFucGwxbmNsd3J5NXV0Y282NXNtMzNsZW5jMm4wNWh6c2dqbXIwdiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l41m18LjqpzxUr2WA/giphy.gif' width='200' style='border-radius: 12px; box-shadow: 0 0 10px #ec4899;'>
430
- <div style='text-align: left;'>
431
- <h1 style='color:white; font-size: 36px; margin-bottom: 6px;'>🎓 多步职业规划助手</h1>
432
- <p style='font-size: 18px; font-weight:bold; color:#ec4899; margin-top: 0;'>Forward三步:推荐大方向→深度分析→可选时间轴路线图</p>
433
- </div>
434
- </div>
435
- """)
436
-
437
  gr.Markdown("""
438
- **📝 Forward / Backward 轮交互,附带换方向、深度分析、以及可选时间轴路线图**
439
- 1. 如果你已有明确职业目标 => 回答“是”(Backward
440
- 2. 如果还在探索 => 回答“否”(Forward
441
- 3. Forward模式下:先问4个问题→推荐3大方向→可换→选定后深度分析→询问是否要路线图
 
442
  """)
443
 
444
- chatbot = gr.Chatbot(height=500, show_label=False, show_copy_button=True, type="messages")
445
-
446
- with gr.Row():
447
- with gr.Column(scale=8):
448
- msg = gr.Textbox(placeholder="请在这里输入你的回答...", show_label=False, container=False)
449
- with gr.Column(scale=1):
450
- submit_btn = gr.Button("🚀 发送", elem_id="custom-send")
451
 
452
- with gr.Row():
453
- reset_btn = gr.Button("🔄 重新开始")
 
 
454
 
455
- def add_message(message, history):
456
- history = history or []
457
- history.append({"role": "user", "content": message})
458
- return "", history
 
459
 
460
- def bot_response(history):
461
- history = history or []
462
- user_message = history[-1]["content"]
463
- bot_message = predict(user_message, history[:-1] if len(history) > 1 else [])
464
- history.append({"role": "assistant", "content": bot_message})
465
- return history
466
 
467
- submit_btn.click(fn=add_message, inputs=[msg, chatbot], outputs=[msg, chatbot]) \
468
- .then(fn=bot_response, inputs=[chatbot], outputs=[chatbot])
469
 
470
- msg.submit(fn=add_message, inputs=[msg, chatbot], outputs=[msg, chatbot]) \
471
- .then(fn=bot_response, inputs=[chatbot], outputs=[chatbot])
472
-
473
- def reset_state():
474
  global current_q_index, questions
475
  global in_forward_flow, in_backward_flow
476
  global forward_index, backward_index
@@ -482,8 +371,8 @@ footer {
482
 
483
  current_q_index = 0
484
  questions = base_questions[:]
485
- for key in user_profile:
486
- user_profile[key] = None
487
 
488
  in_forward_flow = in_backward_flow = False
489
  forward_index = backward_index = 0
@@ -493,13 +382,13 @@ footer {
493
  forward_deep_dive_done = False
494
  roadmap_offered = False
495
  roadmap_done = False
496
-
497
  return []
498
 
499
- reset_btn.click(fn=reset_state, inputs=None, outputs=chatbot, queue=False)
 
 
 
500
 
501
- def auto_first_question():
502
- return [{"role": "assistant", "content": questions[0][1]}]
503
 
504
- demo.load(auto_first_question, inputs=None, outputs=chatbot)
505
- demo.launch()
 
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 # 学生在3大方向中选哪一个
14
  }
15
 
16
  # ============================ 基础问题 ============================
 
20
 
21
  # ============================ Forward 模式问题 ============================
22
  forward_additional_questions = [
23
+ ("bg_info", """那么接下来我会需要你提供一些你的资料,并分享一些你的性格和喜好。
24
+ 请先告诉我,你的学校、年级、专业,和主修课程是什么?如果能提供你的选课表或resume就更好啦。"""),
25
 
26
+ ("work_value", """非常好!那你认为“工作”的意义是什么?你觉得一份理想的工作,应该带来哪些价值或满足感?
27
+ (例如:帮助他人、赚大钱、自由时间、个人成长、创意空间等)"""),
28
 
29
+ ("personality_summary", """用几句话总结你的性格:比如外向/内向?喜欢挑战?注重细节?讨厌重复吗?"""),
30
 
31
+ ("dream_day", """再描述一下你理想工作的一天是什么样:在哪工作?做什么?和谁合作?忙还是闲?更自由还是更有秩序?""")
32
  ]
33
 
34
  # ============================ Backward 模式问题 ============================
 
49
  forward_recommendation_given = False
50
 
51
  # 新增:多次换方向、深度分析、路线图
52
+ recommendation_round = 0 # 记录已换几次大方向
53
  forward_deep_dive_done = False
54
  roadmap_offered = False
55
  roadmap_done = False
 
60
  temp_default = 0.7
61
  top_p_default = 0.95
62
 
63
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 路线图函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64
  def do_time_roadmap():
65
  direction = user_profile["forward_direction_choice"] or user_profile["specific_career"]
66
  bg_info = user_profile["bg_info"] or "未知专业"
 
68
  ps = user_profile["personality_summary"] or "暂无"
69
  dd = user_profile["dream_day"] or "暂无"
70
 
 
71
  prompt_roadmap = f"""
72
  学生信息:
73
  - 学术背景:{bg_info}
 
85
 
86
  请用Markdown分段写作,结合学生当前背景合理推断要点,写得具体些。
87
  """
88
+ return call_openai(prompt_roadmap, "你是一位专业的职业规划顾问,会生成时间轴式路线图")
 
 
 
 
89
 
90
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 深度分析:3个具体职业 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  def do_deep_analysis():
 
92
  direction = user_profile["forward_direction_choice"] or "尚未选择"
93
  bg_info = user_profile["bg_info"] or "未知背景"
94
  wv = user_profile["work_value"] or "无"
 
103
  理想工作: {dd}
104
 
105
  请你再深入分析,为学生推荐3个更具体的职业,并说明:
106
+ 1. 这些职业对学生背景的契合度
107
  2. 日常工作内容
108
  3. 需要哪些课程或考试
109
+ 4. 利用本校资源建议
110
+ 5. 实习 & 经验积累
111
  6. 简历优化思路
112
 
113
  用中文分段写作,字数500+。
114
  """
115
+ return call_openai(deep_prompt, "你是一位专业职业顾问,会深度分析并列出3个具体职业。")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 推荐3大方向 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
  def recommend_3directions():
 
119
  bg_info = user_profile["bg_info"] or "未知"
120
  wv = user_profile["work_value"] or "无"
121
  ps = user_profile["personality_summary"] or "不详"
 
131
  分两部分:
132
  [一、人物画像]:1) 学术背景 2) 价值观 3) 性格 4) 理想工作
133
  [二、推荐3个大方向]:每个方向(1~2段文字)
134
+
135
  最后用如下结尾:
136
  1. XXX方向
137
  2. XXX方向
138
  3. XXX方向
139
  如都不满意,可输入'换'。
140
  """
141
+ return call_openai(rec_prompt, "你是一位职业顾问,擅长根据用户资料推荐3大方向")
142
+
143
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Call OpenAI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144
+ def call_openai(user_prompt, system_text):
145
  try:
146
  api_key = os.environ.get("API_TOKEN")
147
  if not api_key:
148
  return "错误:API_TOKEN 未设置"
149
  client = OpenAI(api_key=api_key)
150
  msgs = [
151
+ {"role":"system","content": system_text},
152
+ {"role":"user","content": user_prompt}
153
  ]
154
  resp = client.chat.completions.create(
155
  model=model_default,
 
161
  )
162
  return resp.choices[0].message.content
163
  except Exception as e:
164
+ return f"出错: {str(e)}"
165
+
166
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ generate_system_prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167
+ def generate_system_prompt():
168
+ mode = user_profile["mode"]
169
+ specific_career = user_profile["specific_career"]
170
+ bg_info = user_profile["bg_info"]
171
+ wv = user_profile["work_value"]
172
+ ps = user_profile["personality_summary"]
173
+ dd = user_profile["dream_day"]
174
+ fwd_choice = user_profile["forward_direction_choice"]
175
+
176
+ if "是" in (mode or ""):
177
+ return f"""
178
+ 你是一位专业的职业规划顾问,使用Backward Design方法帮助学生达成他们的职业目标。
179
+ 目标职业: {specific_career}
180
+ 背景信息: {bg_info}
181
+ 请提供:
182
+ 1. 该职业的简要分析
183
+ 2. 排名前列的组织或公司
184
+ 3. 所需技能和能力
185
+ 4. 职业发展路径
186
+ 5. 学术/课程建议、技能培养、资源使用、实习规划、简历优化等
187
+ 最后请用Markdown格式输出职业路径图:
188
+ 📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
189
+ """
190
+ else:
191
+ return f"""
192
+ 你是一位专业的职业规划顾问,使用Forward Design方法帮助学生探索合适的职业路径。
193
+ 学生背景: {bg_info}
194
+ 工作意义: {wv}
195
+ 性格总结: {ps}
196
+ 理想工作: {dd}
197
+ 学生选择方向: {fwd_choice}
198
+
199
+ 请输出:
200
+ 1. 学生的优势、性格、价值观分析
201
+ 2. 推荐3个具体职业,并说明日常工作内容、适配性、要求、准备路径
202
+ 3. 最后输出职业路径图:
203
+ 📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
204
+ """
205
 
206
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 主逻辑函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207
  def predict(message, history):
208
  global current_q_index, questions
209
  global in_forward_flow, in_backward_flow
 
214
  global forward_deep_dive_done
215
  global roadmap_offered, roadmap_done
216
 
217
+ # 第一���对话 -> 重置
218
  if not history:
219
  current_q_index = 0
220
  questions = base_questions[:]
221
+ for k in user_profile:
222
+ user_profile[k] = None
223
 
224
  in_forward_flow = in_backward_flow = False
225
  forward_index = backward_index = 0
 
230
  roadmap_offered = False
231
  roadmap_done = False
232
 
233
+ # 如果还在问 base_questions
234
  if 0 < current_q_index <= len(questions):
235
  key = questions[current_q_index - 1][0]
236
  user_profile[key] = message.strip()
 
243
  # Forward
244
  in_forward_flow = True
245
 
 
246
  if current_q_index < len(questions):
247
  nxt = questions[current_q_index][1]
248
  current_q_index += 1
 
250
 
251
  mode = user_profile.get("mode") or ""
252
 
253
+ # ~~~~~~~ Backward模式 ~~~~~~~
254
  if "是" in mode:
255
  if in_backward_flow and not backward_done:
256
+ # 存储上一回答
257
  if backward_index > 0 and backward_index <= len(backward_additional_questions):
258
  prev_key = backward_additional_questions[backward_index - 1][0]
259
  user_profile[prev_key] = message.strip()
260
 
 
261
  if backward_index < len(backward_additional_questions):
262
  k, prompt_text = backward_additional_questions[backward_index]
263
  backward_index += 1
 
265
  else:
266
  backward_done = True
267
 
 
268
  if backward_done:
269
+ sprompt = generate_system_prompt()
270
+ return call_openai(f"请根据{user_profile}给出完整规划", sprompt)
271
+
272
+ # ~~~~~~~ Forward模式 ~~~~~~~
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  else:
274
  if in_forward_flow and not forward_done and not forward_deep_dive_done and not roadmap_done:
275
+ # 存储上一回答
276
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
277
  prev_key = forward_additional_questions[forward_index - 1][0]
278
  user_profile[prev_key] = message.strip()
279
 
280
+ # 若还有Forward问题没问完
281
  if forward_index < len(forward_additional_questions):
282
  k, prompt_text = forward_additional_questions[forward_index]
283
  forward_index += 1
284
  return prompt_text
285
+ # 若4个问完 -> 推荐3方向
 
286
  elif not forward_recommendation_given:
287
  forward_recommendation_given = True
288
  return recommend_3directions()
 
 
289
  else:
290
+ # 用户输入 1/2/3 或 '换'
291
  choice = message.strip().lower()
 
292
  if choice in ["1","2","3"]:
293
  user_profile["forward_direction_choice"] = choice
 
294
  forward_deep_dive_done = True
295
  return do_deep_analysis()
296
  elif "换" in choice:
297
  recommendation_round += 1
298
+ if recommendation_round > 2:
299
  forward_done = True
300
  return "已多次换方向,先进入下个阶段吧。"
301
+ else:
302
+ return recommend_3directions()
303
  else:
304
  return "请回复1/2/3选择方向,或输入'换'来请求新的推荐"
305
 
 
306
  elif forward_deep_dive_done and not roadmap_offered:
307
+ # 深度分析完 -> 问要不要路线图
308
  roadmap_offered = True
309
  return "需要一个时间轴式的职业路线图吗?如果需要,请回复“是”,否则回复“否”。"
310
 
311
  elif roadmap_offered and not roadmap_done:
312
+ # 生成 or 不生成
313
  ans = message.strip().lower()
314
  if ans == "是":
315
  roadmap_done = True
 
320
  forward_done = True
321
  return "好的,不生成路线图,本次规划到此结束。"
322
 
 
323
  if forward_done:
324
+ # 最终or结束
325
+ sprompt = generate_system_prompt()
326
+ return call_openai(f"以下是学生资料: {user_profile}, 如需更多建议可再次输入问题", sprompt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
 
328
  return "信息收集完毕,若尚未得到最终回复,请输入任意文字以继续。"
329
 
 
330
  # ============================ Gradio UI ============================
331
+ with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  gr.Markdown("""
333
+ # 🎓步职业规划助手
334
+ Forward / Backward多轮问答,支持:
335
+ 1. Forward可换3大方向
336
+ 2. 学生选定方向深度分析3个具体职业
337
+ 3. 可选时间轴规划
338
  """)
339
 
340
+ chatbot = gr.Chatbot()
341
+ msg = gr.Textbox()
342
+ send = gr.Button("发送")
343
+ reset = gr.Button("重置")
 
 
 
344
 
345
+ def add_user_message(m, h):
346
+ h = h or []
347
+ h.append({"role":"user","content":m})
348
+ return "", h
349
 
350
+ def add_bot_response(h):
351
+ user_m = h[-1]["content"]
352
+ bot_m = predict(user_m, h[:-1])
353
+ h.append({"role":"assistant","content":bot_m})
354
+ return h
355
 
356
+ send.click(add_user_message, [msg, chatbot], [msg, chatbot]) \
357
+ .then(add_bot_response, chatbot, chatbot)
 
 
 
 
358
 
359
+ msg.submit(add_user_message, [msg, chatbot], [msg, chatbot]) \
360
+ .then(add_bot_response, chatbot, chatbot)
361
 
362
+ def reset_all():
 
 
 
363
  global current_q_index, questions
364
  global in_forward_flow, in_backward_flow
365
  global forward_index, backward_index
 
371
 
372
  current_q_index = 0
373
  questions = base_questions[:]
374
+ for k in user_profile:
375
+ user_profile[k] = None
376
 
377
  in_forward_flow = in_backward_flow = False
378
  forward_index = backward_index = 0
 
382
  forward_deep_dive_done = False
383
  roadmap_offered = False
384
  roadmap_done = False
 
385
  return []
386
 
387
+ reset.click(reset_all, outputs=chatbot)
388
+
389
+ def start_q():
390
+ return [{"role":"assistant","content": questions[0][1]}]
391
 
392
+ demo.load(start_q, outputs=chatbot)
 
393
 
394
+ demo.launch()