项目实训(4)ai的流程控制初探
“经历深挖”那边算是有了个初步的框架,虽然AI时不时还是有点“人工智障”,但勉强能针对一个点聊几句了。现在,我想把摊子铺大一点,搞真正的“模拟面试”模式。
这个模式下,AI 不再局限于单个经历,而是可能基于用户的整个简历(如果能上传或输入的话),或者用户指定的一个目标职位描述,来进行一场更全面的面试。
挑战升级:
-
更复杂的角色扮演:AI 不仅要当面试官,可能还要根据不同的面试阶段(开场、技术提问、行为面试、反问环节)调整提问风格和重点。
-
信息源的多样性:
- 如果基于简历:怎么把简历内容有效地喂给AI?整个文本扔过去?还是提取关键信息?
- 如果基于职位描述 (JD):AI 需要理解 JD 里的要求,并据此提问。
-
流程控制:一场面试总有个大致流程。怎么引导 AI 按流程走?比如,先做个开场白,然后围绕技能和经历提问,再问问行为问题,最后让用户提问。
-
AI 的“个性” :能不能让用户选择面试官的风格?比如“友善型”、“压力型”、“技术钻研型”?这个有点超前了,但想想就觉得好玩。
初步的流程设计与 Prompt 构思:
假设我们先从“基于职位描述的面试”开始。
System Prompt v2 (模拟面试模式):
你是一位经验丰富的人力资源与技术招聘主管,现在将对候选人进行一场技术与综合素质的模拟面试。
候选人提供的职位描述如下:
---
[这里插入用户输入的职位描述文本]
---
你的任务是:
1. 开场:简单介绍自己(AI面试官),说明面试流程(例如:技术提问、项目经验、行为问题、候选人提问)。
2. 技术提问:根据职位描述中的技术要求,提出3-5个相关的技术问题,考察候选人的掌握程度。问题可以由浅入深。
3. 项目经验:挑选职位描述中提到的某类项目经验,让候选人详细阐述一个相关项目,并进行追问。
4. 行为问题:提出1-2个常见的行为面试问题(例如:团队合作、压力应对、遇到的最大挑战等)。
5. 候选人提问:告知候选人现在可以向你提问。
6. 结束:感谢候选人参与。
请严格按照以上流程进行。一次只进行一个环节的提问。在每个环节开始前,可以简要说明当前是什么环节。
你的语气应保持专业、客观、礼貌。
请先从“开场”环节开始。
实现思路与遇到的坎:
-
阶段管理:我需要在前端维护一个当前面试阶段的状态 (e.g.,
currentStage: 'introduction' | 'technical' | 'project' | 'behavioral' | 'user_questions' | 'closing')。- 当AI完成一个阶段的提问(或者用户回答完毕),我判断是否需要进入下一阶段,如果需要,就在下一次请求API时,悄悄在用户的回答后面,或者作为新的 system message (如果API支持多条system message 或者允许中途插入),加入一个指令,比如 "现在请进入技术提问环节。" 或者修改主 system prompt 的一部分。这块感觉很 tricky。
-
解析AI的回复以判断阶段完成:AI 说了一堆话,我怎么知道它这个环节的提问是不是结束了?比如我让它问3-5个技术问题,它问完第5个了,我是不是该主动引导它进入下一环节?还是等它自己说“技术问题问完了,接下来我们聊聊项目经验”?
- 想法1:让 AI 在每个环节结束时,明确说出类似“关于技术方面的问题就到这里”的句子。前端通过关键词匹配来判断。感觉不可靠。
- 想法2:前端维护每个阶段预计的交互轮次(比如技术提问3轮)。但AI可能一轮问多个问题,用户也可能一轮回答多个。也不好控制。
- 想法3 (目前倾向) :在 System Prompt 里强化指示,比如“每个环节的问题请一次性提完,或者明确告知候选人你将继续就此环节提问”。然后,在 AI 回复后,前端可以提供一个按钮“下一个问题/进入下一环节”,由用户主动点击来推进。这样控制权在用户手里一部分,AI 也被引导了。
-
如何把JD动态插入Prompt? 这个简单,就是字符串拼接。在调用API前,读取用户输入的JD,替换掉System Prompt里的占位符。
-
处理AI的“自由发挥” :万一AI不按套路出牌,直接跳过某个环节,或者在一个环节问个没完没了怎么办?
- 这是 Prompt Engineering 的核心难点。除了优化 Prompt,可能还需要前端做一些“兜底”逻辑。比如,如果AI在一个环节停留太久(比如超过N轮对话),可以给用户一个“跳过此环节”或“强制进入下一环节”的选项,点击后,前端强行构造一个指向下一环节的指令发给AI。
代码层面的思考(片段):
// AIChatWindow.vue or a new AIInterviewFlowManager.ts
const interviewStages = ['introduction', 'technical', 'project', 'behavioral', 'user_questions', 'closing'] as const;
type InterviewStage = typeof interviewStages[number];
const currentInterviewStage = ref<InterviewStage>('introduction');
// ... (API 调用逻辑) ...
// 在处理AI回复后,可能需要更新 currentInterviewStage
// 或者提供按钮让用户点击进入下一阶段
const advanceToNextStage = () => {
const currentIndex = interviewStages.indexOf(currentInterviewStage.value);
if (currentIndex < interviewStages.length - 1) {
currentInterviewStage.value = interviewStages[currentIndex + 1];
// 可能需要发一条消息给AI,告诉它新阶段开始了
// e.g., sendSystemMessageToAI(`Now, let's move to the ${currentInterviewStage.value} stage.`);
// 或者,在下一次用户输入后,构造的 apiMessages 里包含新的指示性内容。
// 这块是最头疼的,怎么自然地让AI跟着我的节奏走。
}
};
// System Prompt 构造可能变成一个函数
const getSystemPromptForInterview = (jobDescription: string, stage: InterviewStage) => {
let basePrompt = `你是一位经验丰富的人力资源与技术招聘主管... 职位描述:\n${jobDescription}\n---`;
// 根据 stage 添加不同的指令
switch (stage) {
case 'introduction':
basePrompt += `\n你的任务是:1. 开场... 请先从“开场”环节开始。`;
break;
case 'technical':
basePrompt += `\n现在是技术提问环节。请根据职位描述中的技术要求,提出3-5个相关的技术问题。`;
break;
// ... 其他 stages
}
return basePrompt;
};
// 每次调用API时,都用最新的 stage 去生成 system prompt,或者想办法只在 stage 切换时注入关键指令。
// 后者可能更高效,避免重复发送大量文本。
// 我倾向于只在对话开始和关键转折点(如用户点击“下一环节”)时,强化 system prompt 或发送特定指令。
当前感受: 这个“模拟面试”模式比“经历深挖”要复杂一个数量级。控制一个能进行多轮、多阶段对话的AI,让它既能像人一样自然交流,又能严格遵守流程,太难了。 Prompt 的设计、上下文的维护、流程的控制,每一个点都够喝一壶的。 目前还只是非常表层的思考,代码也只是伪代码。真要实现出来,估计要不断试错,不断和AI“斗智斗勇”。
感觉自己不像在写代码,更像在当个蹩脚的木偶戏导演,AI就是那个时不时想自己加戏的木偶。
#AI模拟面试 #角色扮演AI #流程控制 #Prompt设计 #Vue3 #前端架构 #感觉要秃