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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +239 -87
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, # 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,15 +20,13 @@ base_questions = [
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,10 +47,10 @@ backward_done = False
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
56
 
57
  # ============================ 模型设置 ============================
58
  model_default = "gpt-4o"
@@ -60,7 +58,7 @@ token_default = 2000
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 "未知专业"
@@ -85,9 +83,29 @@ def do_time_roadmap():
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 "未知背景"
@@ -103,18 +121,37 @@ def do_deep_analysis():
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 "无"
@@ -127,29 +164,23 @@ def recommend_3directions():
127
  - 工作价值: {wv}
128
  - 性格: {ps}
129
  - 理想工作: {dd}
130
-
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,7 +192,8 @@ def call_openai(user_prompt, system_text):
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():
@@ -203,6 +235,7 @@ def generate_system_prompt():
203
  📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
204
  """
205
 
 
206
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 主逻辑函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207
  def predict(message, history):
208
  global current_q_index, questions
@@ -218,12 +251,15 @@ def predict(message, history):
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
226
- forward_done = backward_done = False
 
 
 
227
  forward_recommendation_given = False
228
  recommendation_round = 0
229
  forward_deep_dive_done = False
@@ -253,7 +289,7 @@ def predict(message, history):
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()
@@ -266,40 +302,64 @@ def predict(message, history):
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
 
@@ -309,7 +369,6 @@ def predict(message, history):
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
@@ -321,45 +380,133 @@ def predict(message, history):
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,24 +518,29 @@ with gr.Blocks() as demo:
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
379
- forward_done = backward_done = False
 
 
 
380
  forward_recommendation_given = False
381
  recommendation_round = 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()
 
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
 
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
  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
  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 "未知专业"
 
83
 
84
  请用Markdown分段写作,结合学生当前背景合理推断要点,写得具体些。
85
  """
86
+ try:
87
+ api_key = os.environ.get("API_TOKEN")
88
+ if not api_key:
89
+ return "错误:API_TOKEN 未设置"
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,
98
+ messages=msgs,
99
+ max_tokens=token_default,
100
+ temperature=temp_default,
101
+ top_p=top_p_default,
102
+ stream=False
103
+ )
104
+ return resp.choices[0].message.content
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 "未知背景"
 
121
  理想工作: {dd}
122
 
123
  请你再深入分析,为学生推荐3个更具体的职业,并说明:
124
+ 1. 这些职业对学生背景的契合度(机械工程/心理学/商科等都可)
125
  2. 日常工作内容
126
  3. 需要哪些课程或考试
127
+ 4. 本校资源如何利用
128
+ 5. 实习 & 经验积累建议
129
  6. 简历优化思路
130
 
131
  用中文分段写作,字数500+。
132
  """
133
+ try:
134
+ api_key = os.environ.get("API_TOKEN")
135
+ if not api_key:
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,
144
+ messages=msgs,
145
+ max_tokens=token_default,
146
+ temperature=temp_default,
147
+ top_p=top_p_default,
148
+ stream=False
149
+ )
150
+ return resp.choices[0].message.content
151
+ except Exception as e:
152
+ return f"深度分析出错: {str(e)}"
153
 
154
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 推荐大方向函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155
  def recommend_3directions():
156
  bg_info = user_profile["bg_info"] or "未知"
157
  wv = user_profile["work_value"] or "无"
 
164
  - 工作价值: {wv}
165
  - 性格: {ps}
166
  - 理想工作: {dd}
 
167
  分两部分:
168
  [一、人物画像]:1) 学术背景 2) 价值观 3) 性格 4) 理想工作
169
  [二、推荐3个大方向]:每个方向(1~2段文字)
 
170
  最后用如下结尾:
171
  1. XXX方向
172
  2. XXX方向
173
  3. XXX方向
174
  如都不满意,可输入'换'。
175
  """
 
 
 
 
176
  try:
177
  api_key = os.environ.get("API_TOKEN")
178
  if not api_key:
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,
 
192
  )
193
  return resp.choices[0].message.content
194
  except Exception as e:
195
+ return f"多方向推荐出错: {str(e)}"
196
+
197
 
198
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ generate_system_prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199
  def generate_system_prompt():
 
235
  📍 现在 → 🎓 学习建议 → 💼 实践建议 → 📄 认证建议 → 🚀 求职建议
236
  """
237
 
238
+
239
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 主逻辑函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240
  def predict(message, history):
241
  global current_q_index, questions
 
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
 
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
  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,
319
+ messages=msgs,
320
+ max_tokens=token_default,
321
+ temperature=temp_default,
322
+ top_p=top_p_default,
323
+ stream=False
324
+ )
325
+ return resp.choices[0].message.content
326
+ except Exception as e:
327
+ return f"发生错误: {str(e)}"
328
 
329
  # ~~~~~~~ Forward模式 ~~~~~~~
330
  else:
331
  if in_forward_flow and not forward_done and not forward_deep_dive_done and not roadmap_done:
332
+ # 存储上一回答
333
  if forward_index > 0 and forward_index <= len(forward_additional_questions):
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
 
 
369
  return "需要一个时间轴式的职业路线图吗?如果需要,请回复“是”,否则回复“否”。"
370
 
371
  elif roadmap_offered and not roadmap_done:
 
372
  ans = message.strip().lower()
373
  if ans == "是":
374
  roadmap_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,
397
+ messages=msgs,
398
+ max_tokens=token_default,
399
+ temperature=temp_default,
400
+ top_p=top_p_default,
401
+ stream=False
402
+ )
403
+ return resp.choices[0].message.content
404
+ except Exception as e:
405
+ return f"发生错误: {str(e)}"
406
 
407
  return "信息收集完毕,若尚未得到最终回复,请输入任意文字以继续。"
408
 
409
+
410
  # ============================ Gradio UI ============================
411
+ with gr.Blocks(css="""
412
+ body {
413
+ background-color: #1e1e1e;
414
+ color: #ffffff;
415
+ }
416
+ .gradio-container {
417
+ font-family: 'Segoe UI', sans-serif;
418
+ }
419
+ .message.user {
420
+ background-color: #cce6ff !important;
421
+ color: #000000 !important;
422
+ border-radius: 10px !important;
423
+ padding: 10px;
424
+ margin: 6px;
425
+ }
426
+ .message.bot {
427
+ background-color: #5599ff !important;
428
+ color: #000000 !important;
429
+ border-radius: 10px !important;
430
+ padding: 10px;
431
+ margin: 6px;
432
+ }
433
+ .gradio-container .chat-msg.bot-msg .message.bot p {
434
+ color: #000000 !important;
435
+ }
436
+ .gr-button {
437
+ border-radius: 8px;
438
+ }
439
+ #custom-send {
440
+ background-color: #ec4899 !important;
441
+ color: white !important;
442
+ border-radius: 999px !important;
443
+ padding: 10px 24px !important;
444
+ font-weight: bold;
445
+ box-shadow: 0 0 10px #ec4899;
446
+ transition: all 0.3s ease-in-out;
447
+ }
448
+ #custom-send:hover {
449
+ background-color: #d63384 !important;
450
+ box-shadow: 0 0 12px #ec4899;
451
+ }
452
+ textarea, input {
453
+ background-color: #ffe4f1 !important;
454
+ color: #5e2c49 !important;
455
+ border: 1px solid #ec4899 !important;
456
+ }
457
+ footer {
458
+ display: none !important;
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
 
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
526
+ forward_index = 0
527
+ backward_index = 0
528
+ forward_done = False
529
+ backward_done = False
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