山东大学项目实训个人博客(4)设计模拟面试流程控制引擎
模拟面试是一个多环节、有状态的复杂流程。本文将分享我如何为AlgoTutor设计一个基于状态机(State Machine)的面试流程控制引擎,来管理长达30-45分钟的面试会话。
模拟面试是AlgoTutor的亮点,它需要模拟真实面试的完整流程:开场白、技术问答、在线编码、项目深挖、反向提问。如何优雅地管理这个流程的状态流转?我选择使用状态机模型。
1. 状态机模型设计
我将一次面试会话抽象为一系列状态和转移条件:
[等待开始] --(用户点击开始)--> [进行中:自我介绍]
--(AI/用户结束本环节)--> [进行中:技术问答]
--(...)--> [进行中:在线编码]
--(...)--> [进行中:项目深挖]
--(...)--> [进行中:反向提问]
--(用户结束/超时)--> [已结束]
每个“进行中”状态都对应着不同的后端处理逻辑和前端界面。状态数据(如当前环节、已用时长、历史对话记录、编写的代码等)需要被持久化,因为会话可能长达45分钟。
2. 后端API与状态管理
我设计了以下核心REST API来驱动状态机:
POST /api/interview/sessions:创建新的面试会话,选择面试官角色(压力面、引导型等),初始状态为等待开始。
POST /api/interview/sessions/{id}/start:开始面试,状态变为进行中:自我介绍。
POST /api/interview/sessions/{id}/next:用户或AI驱动,切换到下一个环节(如从“技术问答”切换到“在线编码”)。
POST /api/interview/sessions/{id}/end:结束面试,状态变为已结束,触发生成复盘报告。
GET /api/interview/sessions/{id}:获取面试当前状态、历史记录等信息,用于前端渲染和断线重连。
状态、对话记录、用户代码等内容存储在Redis中,利用其过期特性可以自动清理过期会话。数据库MySQL中则存储最终的面试元数据和报告。
3. 与AI的协同
在不同的状态,后端调用AI的策略不同:
技术问答状态:当用户回答完一个问题,后端将整个对话历史发送给大模型,并提示“请根据用户的上一个回答,提出一个后续的、更深入的技术问题”。
在线编码状态:此状态下,用户在前端(德豪开发)编码,后端需要将用户提交的代码通过MCP工具调用沙箱执行,并将结果返回给前端和AI面试官,以便其进行追问或点评。
4. 个人实践与思考
我使用Spring的State Machine框架(Spring Statemachine)来初步实现这个模型。首先定义了InterviewEvent(开始、下一步、结束等)和InterviewState(如上所述)。
然后,我重点处理了“在线编码”状态。在这个状态下,前端会通过WebSocket与我建立长连接,实时推送代码变更。我维护一个sessionId -> WebSocketSession的映射。当用户触发“运行”时,前端通过WebSocket发送代码,我调用沙箱MCP工具执行,再将结果通过同一条WebSocket连接推回前端。同时,我也会将代码和结果附加到面试的“上下文”中,供AI面试官后续分析。
这个设计确保了面试流程的可控、可扩展和可持久化。接下来,我将与德豪紧密合作,定义清晰的WebSocket消息协议,确保前后端在面试流程控制上同步一致。
