Update app.py
Browse files
app.py
CHANGED
|
@@ -41,30 +41,25 @@ backward_additional_questions = [
|
|
| 41 |
# ============================ 状态控制变量 ============================
|
| 42 |
current_q_index = 0
|
| 43 |
questions = base_questions[:]
|
| 44 |
-
|
| 45 |
-
# Forward模式状态
|
| 46 |
in_forward_flow = False
|
|
|
|
| 47 |
forward_index = 0
|
|
|
|
| 48 |
forward_done = False
|
|
|
|
| 49 |
forward_recommendation_given = False
|
| 50 |
-
direction_chosen = False # 是否已经选定大方向
|
| 51 |
-
jobs_recommended = False # 是否已给出3个具体职业
|
| 52 |
-
job_chosen = False # 是否选定了具体职业
|
| 53 |
recommendation_round = 0
|
| 54 |
forward_deep_dive_done = False
|
|
|
|
|
|
|
| 55 |
|
| 56 |
-
#
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
backward_done = False
|
| 60 |
-
backward_analysis_given = False # 是否已经提供职业分析
|
| 61 |
-
backward_job_chosen = False # Backward模式是否已选定职业
|
| 62 |
|
| 63 |
-
#
|
| 64 |
post_career_detail_asked = False # 是否已询问用户要看A/B/C
|
| 65 |
post_career_detail_done = False # 是否已回答完A/B/C
|
| 66 |
-
roadmap_offered = False
|
| 67 |
-
roadmap_done = False
|
| 68 |
|
| 69 |
# ============================ 模型设置 ============================
|
| 70 |
model_default = "gpt-4o"
|
|
@@ -76,7 +71,7 @@ top_p_default = 0.95
|
|
| 76 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 77 |
# 动态函数:根据用户选择的 A/B/C,让 OpenAI 生成相应分析
|
| 78 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 79 |
-
def answer_abc_questions(selected, bg_info, wv
|
| 80 |
desired_parts = []
|
| 81 |
if "a" in selected.lower():
|
| 82 |
desired_parts.append("A")
|
|
@@ -88,18 +83,13 @@ def answer_abc_questions(selected, bg_info, wv=None, ps=None, dd=None):
|
|
| 88 |
if not desired_parts:
|
| 89 |
return "好的,你暂时不需要查看A/B/C的专项信息。"
|
| 90 |
|
| 91 |
-
# 处理可能为None的参数
|
| 92 |
-
work_value = wv if wv is not None else "未提供"
|
| 93 |
-
personality = ps if ps is not None else "未提供"
|
| 94 |
-
dream_day = dd if dd is not None else "未提供"
|
| 95 |
-
|
| 96 |
prompt_text = f"""
|
| 97 |
你是一位专业的职业规划顾问。以下是学生背景信息,请根据他选择的模块(A/B/C)给出详细分析和建议。
|
| 98 |
学生背景:
|
| 99 |
- 学术背景: {bg_info}
|
| 100 |
-
- 工作意义: {
|
| 101 |
-
- 性格: {
|
| 102 |
-
- 理想工作: {
|
| 103 |
|
| 104 |
学生目前想要的额外信息模块:{', '.join(desired_parts)}
|
| 105 |
请分别按顺序为每个模块写一段分析和建议,可以使用Markdown分段形式。
|
|
@@ -132,19 +122,14 @@ def answer_abc_questions(selected, bg_info, wv=None, ps=None, dd=None):
|
|
| 132 |
|
| 133 |
|
| 134 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 职业详细介绍 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 135 |
-
def do_selected_career_detail(selected_career, bg_info, wv
|
| 136 |
-
# 对于Backward模式,某些参数可能为None
|
| 137 |
-
wv_text = f"工作意义: {wv}" if wv else ""
|
| 138 |
-
ps_text = f"性格: {ps}" if ps else ""
|
| 139 |
-
dd_text = f"理想工作: {dd}" if dd else ""
|
| 140 |
-
|
| 141 |
prompt = f"""
|
| 142 |
你是一位专业的职业规划顾问。
|
| 143 |
学生最终选择的具体职业: {selected_career}
|
| 144 |
学生背景: {bg_info}
|
| 145 |
-
{
|
| 146 |
-
{
|
| 147 |
-
{
|
| 148 |
请写一份更详细的职业说明,至少包含:
|
| 149 |
1. 行业平均薪资(初级/中级/高级)
|
| 150 |
2. 工作环境(远程/混合/办公室,团队规模等)
|
|
@@ -179,18 +164,12 @@ def do_selected_career_detail(selected_career, bg_info, wv=None, ps=None, dd=Non
|
|
| 179 |
|
| 180 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 时间轴式规划 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 181 |
def do_time_roadmap():
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
direction = user_profile.get("specific_career", "未指定职业")
|
| 185 |
-
else: # Forward模式
|
| 186 |
-
direction = user_profile.get("final_choice") or user_profile.get("selected_direction", "未指定方向")
|
| 187 |
-
|
| 188 |
bg_info = user_profile["bg_info"] or "未知专业"
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
ps = user_profile.get("personality_summary", "暂无")
|
| 193 |
-
dd = user_profile.get("dream_day", "暂无")
|
| 194 |
|
| 195 |
prompt_roadmap = f"""
|
| 196 |
学生信息:
|
|
@@ -230,52 +209,6 @@ def do_time_roadmap():
|
|
| 230 |
return f"生成路线图时出错: {str(e)}"
|
| 231 |
|
| 232 |
|
| 233 |
-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Backward模���专用:生成职业分析 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 234 |
-
def generate_backward_career_analysis():
|
| 235 |
-
career = user_profile.get("specific_career") or "未指定职业"
|
| 236 |
-
bg_info = user_profile.get("bg_info") or "未知背景"
|
| 237 |
-
|
| 238 |
-
prompt = f"""
|
| 239 |
-
你是一位专业的职业规划顾问,使用Backward Design方法帮助学生达成职业目标。
|
| 240 |
-
目标职业: {career}
|
| 241 |
-
学生背景: {bg_info}
|
| 242 |
-
|
| 243 |
-
请提供一份详细的职业分析报告,包括以下内容:
|
| 244 |
-
1. 该职业的基本介绍和行业现状
|
| 245 |
-
2. 该领域排名前列的组织或公司
|
| 246 |
-
3. 从业所需的核心技能和能力
|
| 247 |
-
4. 典型的职业发展路径
|
| 248 |
-
5. 针对学生背景的具体建议:
|
| 249 |
-
- 学术课程建议
|
| 250 |
-
- 技能培养重点
|
| 251 |
-
- 实习和实践经验积累方向
|
| 252 |
-
- 专业证书和资格认证
|
| 253 |
-
|
| 254 |
-
请使用Markdown格式,保持专业性和具体性。
|
| 255 |
-
"""
|
| 256 |
-
try:
|
| 257 |
-
api_key = os.environ.get("API_TOKEN")
|
| 258 |
-
if not api_key:
|
| 259 |
-
return "错误:API_TOKEN 未设置"
|
| 260 |
-
client = OpenAI(api_key=api_key)
|
| 261 |
-
|
| 262 |
-
msgs = [
|
| 263 |
-
{"role": "system", "content": "你是一位专业职业顾问,擅长分析特定职业的要求和发展路径。"},
|
| 264 |
-
{"role": "user", "content": prompt}
|
| 265 |
-
]
|
| 266 |
-
resp = client.chat.completions.create(
|
| 267 |
-
model=model_default,
|
| 268 |
-
messages=msgs,
|
| 269 |
-
max_tokens=token_default,
|
| 270 |
-
temperature=temp_default,
|
| 271 |
-
top_p=top_p_default,
|
| 272 |
-
stream=False
|
| 273 |
-
)
|
| 274 |
-
return resp.choices[0].message.content
|
| 275 |
-
except Exception as e:
|
| 276 |
-
return f"生成职业分析时出错: {str(e)}"
|
| 277 |
-
|
| 278 |
-
|
| 279 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 推荐具体职业 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 280 |
def recommend_3jobs_for_direction(direction, bg_info, wv, ps, dd):
|
| 281 |
prompt = f"""
|
|
@@ -413,10 +346,10 @@ def generate_system_prompt():
|
|
| 413 |
mode = user_profile["mode"]
|
| 414 |
sc = user_profile["specific_career"]
|
| 415 |
bg = user_profile["bg_info"]
|
| 416 |
-
wv = user_profile
|
| 417 |
-
ps = user_profile
|
| 418 |
-
dd = user_profile
|
| 419 |
-
fwd = user_profile
|
| 420 |
|
| 421 |
if mode == "是":
|
| 422 |
return f"""
|
|
@@ -458,7 +391,6 @@ def predict(message, history):
|
|
| 458 |
global forward_recommendation_given
|
| 459 |
global recommendation_round
|
| 460 |
global forward_deep_dive_done
|
| 461 |
-
global backward_analysis_given, backward_job_chosen
|
| 462 |
global roadmap_offered, roadmap_done
|
| 463 |
global direction_chosen, jobs_recommended, job_chosen
|
| 464 |
global post_career_detail_asked, post_career_detail_done
|
|
@@ -470,84 +402,112 @@ def predict(message, history):
|
|
| 470 |
for k in user_profile:
|
| 471 |
user_profile[k] = None
|
| 472 |
|
| 473 |
-
# 重置Forward模式状态
|
| 474 |
in_forward_flow = False
|
|
|
|
| 475 |
forward_index = 0
|
|
|
|
| 476 |
forward_done = False
|
|
|
|
| 477 |
forward_recommendation_given = False
|
| 478 |
-
direction_chosen = False
|
| 479 |
-
jobs_recommended = False
|
| 480 |
-
job_chosen = False
|
| 481 |
recommendation_round = 0
|
| 482 |
forward_deep_dive_done = False
|
| 483 |
-
|
| 484 |
-
# 重置Backward模式状态
|
| 485 |
-
in_backward_flow = False
|
| 486 |
-
backward_index = 0
|
| 487 |
-
backward_done = False
|
| 488 |
-
backward_analysis_given = False
|
| 489 |
-
backward_job_chosen = False
|
| 490 |
-
|
| 491 |
-
# 重置共用状态
|
| 492 |
roadmap_offered = False
|
| 493 |
roadmap_done = False
|
|
|
|
|
|
|
|
|
|
|
|
|
| 494 |
post_career_detail_asked = False
|
| 495 |
post_career_detail_done = False
|
| 496 |
|
| 497 |
-
# ======================== 先处理
|
| 498 |
-
if current_q_index =
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
in_backward_flow = False
|
| 512 |
-
# 设置下一个问题为Forward模式的第一个问题
|
| 513 |
-
questions = forward_additional_questions[:]
|
| 514 |
-
current_q_index = 0
|
| 515 |
-
|
| 516 |
-
# 如果还在基本问题中,就继续提问
|
| 517 |
if current_q_index < len(questions):
|
| 518 |
nxt = questions[current_q_index][1]
|
| 519 |
current_q_index += 1
|
| 520 |
return nxt
|
| 521 |
-
|
| 522 |
-
# 收集上一个问题的答案
|
| 523 |
-
if current_q_index > 0 and current_q_index <= len(questions):
|
| 524 |
-
key = questions[current_q_index - 1][0]
|
| 525 |
-
user_profile[key] = message.strip()
|
| 526 |
|
| 527 |
# ======================== 分模式处理 =========================
|
|
|
|
|
|
|
| 528 |
# ~~~~~~~~~ Backward模式 ~~~~~~~~~
|
| 529 |
-
if
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 549 |
|
| 550 |
-
# 处理 A/B/C 答疑
|
| 551 |
elif post_career_detail_asked and not post_career_detail_done:
|
| 552 |
user_choice = message.strip().lower()
|
| 553 |
if user_choice in ["不需要", "no", "n"]:
|
|
@@ -566,8 +526,12 @@ def predict(message, history):
|
|
| 566 |
roadmap_offered = True
|
| 567 |
return abc_text + "\n\n以上是你所选的A/B/C专项信息。需要一个时间轴式职业路线图吗?如需,则回复【要】,否则回复【不要】。"
|
| 568 |
|
| 569 |
-
# 处理是否需要时间轴路线图
|
| 570 |
-
elif
|
|
|
|
|
|
|
|
|
|
|
|
|
| 571 |
ans = message.strip().lower()
|
| 572 |
if ans in ["要", "yes", "y"]:
|
| 573 |
roadmap_done = True
|
|
@@ -578,7 +542,7 @@ def predict(message, history):
|
|
| 578 |
backward_done = True
|
| 579 |
return "好的,不生成时间轴,本次规划结束。"
|
| 580 |
|
| 581 |
-
# 最终收尾
|
| 582 |
if backward_done:
|
| 583 |
try:
|
| 584 |
api_key = os.environ.get("API_TOKEN")
|
|
@@ -603,11 +567,21 @@ def predict(message, history):
|
|
| 603 |
return f"发生错误: {str(e)}"
|
| 604 |
|
| 605 |
# ~~~~~~~~~ Forward模式 ~~~~~~~~~
|
| 606 |
-
|
| 607 |
# 前期处理:收集信息和推荐大方向
|
| 608 |
-
if not direction_chosen:
|
| 609 |
-
# 收集
|
| 610 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 611 |
forward_recommendation_given = True
|
| 612 |
return recommend_3directions()
|
| 613 |
|
|
@@ -687,7 +661,7 @@ def predict(message, history):
|
|
| 687 |
else:
|
| 688 |
return "请回复1/2/3选择具体职业,或输入'换'来重新推荐"
|
| 689 |
|
| 690 |
-
# 处理 A/B/C 答疑
|
| 691 |
elif post_career_detail_asked and not post_career_detail_done:
|
| 692 |
user_choice = message.strip().lower()
|
| 693 |
if user_choice in ["不需要", "no", "n"]:
|
|
@@ -883,4 +857,4 @@ footer {
|
|
| 883 |
return [{"role":"assistant","content": questions[0][1]}]
|
| 884 |
|
| 885 |
demo.load(auto_first, outputs=chatbot)
|
| 886 |
-
demo.launch()
|
|
|
|
| 41 |
# ============================ 状态控制变量 ============================
|
| 42 |
current_q_index = 0
|
| 43 |
questions = base_questions[:]
|
|
|
|
|
|
|
| 44 |
in_forward_flow = False
|
| 45 |
+
in_backward_flow = False
|
| 46 |
forward_index = 0
|
| 47 |
+
backward_index = 0
|
| 48 |
forward_done = False
|
| 49 |
+
backward_done = False
|
| 50 |
forward_recommendation_given = False
|
|
|
|
|
|
|
|
|
|
| 51 |
recommendation_round = 0
|
| 52 |
forward_deep_dive_done = False
|
| 53 |
+
roadmap_offered = False
|
| 54 |
+
roadmap_done = False
|
| 55 |
|
| 56 |
+
direction_chosen = False # 是否已经选定大方向
|
| 57 |
+
jobs_recommended = False # 是否已给出3个具体职业
|
| 58 |
+
job_chosen = False # 是否选定了具体职业
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
+
# ========== 用于 A/B/C 专项问题的标记 ==========
|
| 61 |
post_career_detail_asked = False # 是否已询问用户要看A/B/C
|
| 62 |
post_career_detail_done = False # 是否已回答完A/B/C
|
|
|
|
|
|
|
| 63 |
|
| 64 |
# ============================ 模型设置 ============================
|
| 65 |
model_default = "gpt-4o"
|
|
|
|
| 71 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 72 |
# 动态函数:根据用户选择的 A/B/C,让 OpenAI 生成相应分析
|
| 73 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 74 |
+
def answer_abc_questions(selected, bg_info, wv, ps, dd):
|
| 75 |
desired_parts = []
|
| 76 |
if "a" in selected.lower():
|
| 77 |
desired_parts.append("A")
|
|
|
|
| 83 |
if not desired_parts:
|
| 84 |
return "好的,你暂时不需要查看A/B/C的专项信息。"
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
prompt_text = f"""
|
| 87 |
你是一位专业的职业规划顾问。以下是学生背景信息,请根据他选择的模块(A/B/C)给出详细分析和建议。
|
| 88 |
学生背景:
|
| 89 |
- 学术背景: {bg_info}
|
| 90 |
+
- 工作意义: {wv}
|
| 91 |
+
- 性格: {ps}
|
| 92 |
+
- 理想工作: {dd}
|
| 93 |
|
| 94 |
学生目前想要的额外信息模块:{', '.join(desired_parts)}
|
| 95 |
请分别按顺序为每个模块写一段分析和建议,可以使用Markdown分段形式。
|
|
|
|
| 122 |
|
| 123 |
|
| 124 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 职业详细介绍 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 125 |
+
def do_selected_career_detail(selected_career, bg_info, wv, ps, dd):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
prompt = f"""
|
| 127 |
你是一位专业的职业规划顾问。
|
| 128 |
学生最终选择的具体职业: {selected_career}
|
| 129 |
学生背景: {bg_info}
|
| 130 |
+
工作意义: {wv}
|
| 131 |
+
性格: {ps}
|
| 132 |
+
理想工作: {dd}
|
| 133 |
请写一份更详细的职业说明,至少包含:
|
| 134 |
1. 行业平均薪资(初级/中级/高级)
|
| 135 |
2. 工作环境(远程/混合/办公室,团队规模等)
|
|
|
|
| 164 |
|
| 165 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 时间轴式规划 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 166 |
def do_time_roadmap():
|
| 167 |
+
direction = user_profile.get("final_choice") or user_profile.get("selected_direction") or \
|
| 168 |
+
user_profile.get("forward_direction_choice") or user_profile.get("specific_career")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
bg_info = user_profile["bg_info"] or "未知专业"
|
| 170 |
+
wv = user_profile["work_value"] or "暂无"
|
| 171 |
+
ps = user_profile["personality_summary"] or "暂无"
|
| 172 |
+
dd = user_profile["dream_day"] or "暂无"
|
|
|
|
|
|
|
| 173 |
|
| 174 |
prompt_roadmap = f"""
|
| 175 |
学生信息:
|
|
|
|
| 209 |
return f"生成路线图时出错: {str(e)}"
|
| 210 |
|
| 211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 推荐具体职业 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 213 |
def recommend_3jobs_for_direction(direction, bg_info, wv, ps, dd):
|
| 214 |
prompt = f"""
|
|
|
|
| 346 |
mode = user_profile["mode"]
|
| 347 |
sc = user_profile["specific_career"]
|
| 348 |
bg = user_profile["bg_info"]
|
| 349 |
+
wv = user_profile["work_value"]
|
| 350 |
+
ps = user_profile["personality_summary"]
|
| 351 |
+
dd = user_profile["dream_day"]
|
| 352 |
+
fwd = user_profile["forward_direction_choice"]
|
| 353 |
|
| 354 |
if mode == "是":
|
| 355 |
return f"""
|
|
|
|
| 391 |
global forward_recommendation_given
|
| 392 |
global recommendation_round
|
| 393 |
global forward_deep_dive_done
|
|
|
|
| 394 |
global roadmap_offered, roadmap_done
|
| 395 |
global direction_chosen, jobs_recommended, job_chosen
|
| 396 |
global post_career_detail_asked, post_career_detail_done
|
|
|
|
| 402 |
for k in user_profile:
|
| 403 |
user_profile[k] = None
|
| 404 |
|
|
|
|
| 405 |
in_forward_flow = False
|
| 406 |
+
in_backward_flow = False
|
| 407 |
forward_index = 0
|
| 408 |
+
backward_index = 0
|
| 409 |
forward_done = False
|
| 410 |
+
backward_done = False
|
| 411 |
forward_recommendation_given = False
|
|
|
|
|
|
|
|
|
|
| 412 |
recommendation_round = 0
|
| 413 |
forward_deep_dive_done = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
roadmap_offered = False
|
| 415 |
roadmap_done = False
|
| 416 |
+
|
| 417 |
+
direction_chosen = False
|
| 418 |
+
jobs_recommended = False
|
| 419 |
+
job_chosen = False
|
| 420 |
post_career_detail_asked = False
|
| 421 |
post_career_detail_done = False
|
| 422 |
|
| 423 |
+
# ======================== 先处理基础问题 =========================
|
| 424 |
+
if 0 < current_q_index <= len(questions):
|
| 425 |
+
key = questions[current_q_index - 1][0]
|
| 426 |
+
# 第一个问题决定是 / 否
|
| 427 |
+
if key == "mode" and current_q_index == 1:
|
| 428 |
+
ans = message.strip()
|
| 429 |
+
user_profile["mode"] = ans
|
| 430 |
+
if "是" in ans:
|
| 431 |
+
in_backward_flow = True
|
| 432 |
+
else:
|
| 433 |
+
in_forward_flow = True
|
| 434 |
+
else:
|
| 435 |
+
user_profile[key] = message.strip()
|
| 436 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
if current_q_index < len(questions):
|
| 438 |
nxt = questions[current_q_index][1]
|
| 439 |
current_q_index += 1
|
| 440 |
return nxt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 441 |
|
| 442 |
# ======================== 分模式处理 =========================
|
| 443 |
+
mode = user_profile.get("mode") or ""
|
| 444 |
+
|
| 445 |
# ~~~~~~~~~ Backward模式 ~~~~~~~~~
|
| 446 |
+
if mode == "是":
|
| 447 |
+
if in_backward_flow and not backward_done:
|
| 448 |
+
if backward_index > 0 and backward_index <= len(backward_additional_questions):
|
| 449 |
+
prev_key = backward_additional_questions[backward_index - 1][0]
|
| 450 |
+
user_profile[prev_key] = message.strip()
|
| 451 |
+
|
| 452 |
+
if backward_index < len(backward_additional_questions):
|
| 453 |
+
k, prompt_text = backward_additional_questions[backward_index]
|
| 454 |
+
backward_index += 1
|
| 455 |
+
return prompt_text
|
| 456 |
+
else:
|
| 457 |
+
# 修改这里,不要直接设置backward_done为True
|
| 458 |
+
# 而是需要生成职业详情并询问是否需要A/B/C专项信息
|
| 459 |
+
try:
|
| 460 |
+
api_key = os.environ.get("API_TOKEN")
|
| 461 |
+
if not api_key:
|
| 462 |
+
return "错误:API_TOKEN 未设置"
|
| 463 |
+
client = OpenAI(api_key=api_key)
|
| 464 |
+
|
| 465 |
+
# 先生成职业详情
|
| 466 |
+
career_detail_prompt = f"""
|
| 467 |
+
你是一位专业的职业规划顾问。
|
| 468 |
+
学生目标职业: {user_profile.get('specific_career') or '未知'}
|
| 469 |
+
学生背景: {user_profile.get('bg_info') or '未知'}
|
| 470 |
+
请写一份详细的职业说明,至少包含:
|
| 471 |
+
1. 行业平均薪资(初级/中级/高级)
|
| 472 |
+
2. 工作环境(远程/混合/办公室,团队规模等)
|
| 473 |
+
3. 晋升难度(需要什么资历或条件)
|
| 474 |
+
4. 关键技能和考证
|
| 475 |
+
5. 日常工作节奏
|
| 476 |
+
6. 行业前景
|
| 477 |
+
用分段Markdown格式,字数不少于300字。
|
| 478 |
+
"""
|
| 479 |
+
msgs = [
|
| 480 |
+
{"role": "system", "content": "你是一位专业职业顾问,会为用户的目标职业提供详细分析。"},
|
| 481 |
+
{"role": "user", "content": career_detail_prompt}
|
| 482 |
+
]
|
| 483 |
+
resp = client.chat.completions.create(
|
| 484 |
+
model=model_default,
|
| 485 |
+
messages=msgs,
|
| 486 |
+
max_tokens=token_default,
|
| 487 |
+
temperature=temp_default,
|
| 488 |
+
top_p=top_p_default,
|
| 489 |
+
stream=False
|
| 490 |
+
)
|
| 491 |
+
detail_msg = resp.choices[0].message.content
|
| 492 |
+
|
| 493 |
+
# 设置状态,与Forward模式保持一致
|
| 494 |
+
user_profile["final_choice"] = user_profile.get("specific_career")
|
| 495 |
+
job_chosen = True
|
| 496 |
+
forward_deep_dive_done = True
|
| 497 |
+
post_career_detail_asked = True
|
| 498 |
+
|
| 499 |
+
# 返回职业详情并询问A/B/C
|
| 500 |
+
return detail_msg + "\n\n我还可以针对以下三方面提供更深入的分析建议:" \
|
| 501 |
+
"\n- A:专业/选课 & 求职方向" \
|
| 502 |
+
"\n- B:本校资源利用建议" \
|
| 503 |
+
"\n- C:实习 & networking 积累" \
|
| 504 |
+
"\n如果你想查看其中一个或多个,请输入 A / B / C / AB / BC / AC / ABC" \
|
| 505 |
+
"\n如果都不需要,请回复'不需要'。"
|
| 506 |
+
|
| 507 |
+
except Exception as e:
|
| 508 |
+
return f"生成职业详情时出错: {str(e)}"
|
| 509 |
|
| 510 |
+
# 处理 A/B/C 答疑 (复用Forward模式的逻辑)
|
| 511 |
elif post_career_detail_asked and not post_career_detail_done:
|
| 512 |
user_choice = message.strip().lower()
|
| 513 |
if user_choice in ["不需要", "no", "n"]:
|
|
|
|
| 526 |
roadmap_offered = True
|
| 527 |
return abc_text + "\n\n以上是你所选的A/B/C专项信息。需要一个时间轴式职业路线图吗?如需,则回复【要】,否则回复【不要】。"
|
| 528 |
|
| 529 |
+
# 处理是否需要时间轴路线图 (复用Forward模式的逻辑)
|
| 530 |
+
elif job_chosen and not roadmap_offered and not roadmap_done:
|
| 531 |
+
roadmap_offered = True
|
| 532 |
+
return "需要一个时间轴式职业路线图吗?如需,则回复【要】,否则回复【不要】。"
|
| 533 |
+
|
| 534 |
+
elif roadmap_offered and not roadmap_done:
|
| 535 |
ans = message.strip().lower()
|
| 536 |
if ans in ["要", "yes", "y"]:
|
| 537 |
roadmap_done = True
|
|
|
|
| 542 |
backward_done = True
|
| 543 |
return "好的,不生成时间轴,本次规划结束。"
|
| 544 |
|
| 545 |
+
# 最终收尾 (仅在所有流程都完成时才会触发)
|
| 546 |
if backward_done:
|
| 547 |
try:
|
| 548 |
api_key = os.environ.get("API_TOKEN")
|
|
|
|
| 567 |
return f"发生错误: {str(e)}"
|
| 568 |
|
| 569 |
# ~~~~~~~~~ Forward模式 ~~~~~~~~~
|
| 570 |
+
else:
|
| 571 |
# 前期处理:收集信息和推荐大方向
|
| 572 |
+
if in_forward_flow and not direction_chosen:
|
| 573 |
+
# 收集 4个基础问题
|
| 574 |
+
if forward_index > 0 and forward_index <= len(forward_additional_questions):
|
| 575 |
+
prev_key = forward_additional_questions[forward_index - 1][0]
|
| 576 |
+
user_profile[prev_key] = message.strip()
|
| 577 |
+
|
| 578 |
+
if forward_index < len(forward_additional_questions):
|
| 579 |
+
k, prompt_text = forward_additional_questions[forward_index]
|
| 580 |
+
forward_index += 1
|
| 581 |
+
return prompt_text
|
| 582 |
+
|
| 583 |
+
# 问完 4个问题 -> 推荐3方向
|
| 584 |
+
elif not forward_recommendation_given:
|
| 585 |
forward_recommendation_given = True
|
| 586 |
return recommend_3directions()
|
| 587 |
|
|
|
|
| 661 |
else:
|
| 662 |
return "请回复1/2/3选择具体职业,或输入'换'来重新推荐"
|
| 663 |
|
| 664 |
+
# 处理 A/B/C 答疑
|
| 665 |
elif post_career_detail_asked and not post_career_detail_done:
|
| 666 |
user_choice = message.strip().lower()
|
| 667 |
if user_choice in ["不需要", "no", "n"]:
|
|
|
|
| 857 |
return [{"role":"assistant","content": questions[0][1]}]
|
| 858 |
|
| 859 |
demo.load(auto_first, outputs=chatbot)
|
| 860 |
+
demo.launch()
|