☰
从上传简历到生成面试题:简历驱动出题链路怎么走
2026/10/27 2:04:26 网站建设 项目流程

本文基于「码上面试平台」当前代码整理。这里分析的是简历提题链路,不展示工作流配置中的凭证或敏感参数。

简历上传成功,不等于面试已经准备好

从页面看,这个功能像是“选一个 PDF,点上传,等题目出来”。从服务端看,它至少包含会话状态更新、Agent 配置解析、文件上传、模型调用、结果解析、缓存初始化和结构化持久化。

我会把它看成一个有明确成功条件的业务流程:只有题目、流程状态和后续需要的会话材料都准备到能继续答题的程度,接口才应该告诉前端提取成功。

先从 Controller 之后追入口

接口进入InterviewSessionFacade.extractInterviewQuestions后,先把会话标为RESUME_UPLOADING,然后创建InterviewQuestionReqDTO并委托给InterviewWorkflowService。实际实现InterviewAgentOrchestrationService再把调用交给InterviewQuestionExtractionService。

拆成这几层有一个实际好处:Controller 处理 HTTP 入口,Facade 维护会话级规则,Orchestration 选择业务能力,Extraction Service 承担外部 AI 与结果处理。读代码时顺着这条线追,比从某个 SDK 调用往回猜业务目的更快。

提取服务里有哪些关键步骤?

1. 解析业务 Agent 并准备幂等材料

服务根据INTERVIEW_QUESTION_EXTRACTION场景查找对应 Agent。它会在加锁前计算上传文件内容的 SHA-256 摘要;同一会话的简历提取属于重操作,会获取会话级锁,避免并发请求同时跑完整的提取链路。

这里的摘要不是文件 URL:同一份文件重复上传时,外部存储可能给出不同 URL,用内容摘要作为 AI Single-flight key 更接近“同一份输入”。但文件上传发生在 AI 调用之前,所以不要把 AI 结果复用误解成“整个上传流程完全没有重复动作”。

2. 上传文件并调用工作流

拿到锁后,服务先通过XingChenAIClient.uploadFile上传简历,再调用统一 AI Invoker,使用简历文件 URL 和提取场景请求模型。AI 调用受 Guard 和 Single-flight 保护;失败时会记录错误响应,最后在finally释放会话锁。

题目提取 Prompt 期望返回题目、建议、面试方向和简历评分等结构化字段。但工作流实际输出和 Java DTO 之间不是自动绑定的:字段名、嵌套层级和数组类型都要由解析器显式处理。

3. 先留原始响应,再尝试结构化解析

模型返回后,代码会先尝试将原始响应写入 Mongo 的面试题记录,再提取实际内容并解析结构化字段。这样做的思路是:结构化解析失败时,至少还有机会检查原始模型响应,定位是工作流返回错误、响应形状变化,还是字段本身缺失。

解析成功后,服务会:

  • 校验并缓存题目列表。
  • 初始化 Redis flow,当前题从第 1 题开始。
  • 缓存建议、简历评分、面试方向和可复用的简历上下文。
  • 将结构化材料回写到面试题文档,供缓存恢复和报告使用。
  • 重置会话分数,避免旧运行态分数污染新一轮面试。

只有当结构化处理成功,提取响应才会设置成功标记。Facade 看到成功后才把会话改为READY并刷新运行态快照;失败则把会话退回DRAFT,让用户保留重新提取的入口。

这条链路最容易踩的坑

工作流字段是接口契约

当前提取代码读取questions、sugest、suggestions、resumeScore和type等字段;建议字段里保留了历史拼写sugest,面试方向还兼容多个名称。这里不能只改 Prompt 或工作流字段,还要核对 Java 解析、缓存、DTO 和持久化字段。

我倾向于把字段兼容集中在边界解析器,而不是让每个业务方法各自猜一遍别名。兼容字段也应该有淘汰条件,否则“兼容历史数据”会慢慢变成永久的隐式协议。

Redis 有题,不代表后续恢复材料完整

题目、flow、简历上下文和评分材料不一定在同一时刻写完。当前代码会同时维护 Redis 热态和 Mongo 中的原始/结构化记录,目的是让缓存丢失后还有恢复来源。复盘时需要分别确认:接口是否返回成功、Redis 是否可继续答题、Mongo 是否留有足够材料,而不能只验证页面上出现了题目。

还有一个值得做故障验证的边界:原始响应持久化和结构化字段回写的方法会捕获异常并记录日志;如果 Redis 侧已经准备成功而 Mongo 回写失败,当前提取仍可能返回成功。短期答题也许能继续,但后续缓存恢复的材料可能不完整。这里需要明确业务选择:是允许缓存短期可用,还是必须等持久化成功后才进入READY。

我的复盘:Agent 的结果只是中间产物

这条链路让我更愿意用“业务就绪”定义成功,而不是把 HTTP 200 或模型返回非空当成成功。简历提取不仅要问模型,还要把题目转成系统能推进的流程状态,并留下可恢复的数据。

代价也很直接:一次提题横跨外部文件服务、模型、Redis 和 Mongo,严格原子提交并不存在。设计重点就变成了哪些步骤必须成功、哪些失败可以降级、以及降级后能否清楚地恢复或重试。

源码入口

  • 会话状态和提取委托:admin/src/main/java/com/hewei/hzyjy/xunzhi/interview/flow/session/InterviewSessionFacade.java
  • 工作流编排:admin/src/main/java/com/hewei/hzyjy/xunzhi/interview/flow/session/InterviewAgentOrchestrationService.java
  • 上传、AI 调用和字段组装:admin/src/main/java/com/hewei/hzyjy/xunzhi/interview/flow/extraction/InterviewQuestionExtractionService.java
  • 原始响应和结构化字段持久化:admin/src/main/java/com/hewei/hzyjy/xunzhi/interview/service/impl/InterviewQuestionServiceImpl.java
  • AI 响应提取和兼容解析:admin/src/main/java/com/hewei/hzyjy/xunzhi/interview/shared/InterviewResponseParser.java

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询