企业级AI面试官实战:基于Agent Harness与证据链的架构设计
发布时间:2026/9/8 17:46:45 锦皓数字建站

不是写个 Prompt 就能做 AI 面试官去年我接过一个 AI Recruiting 相关的系统重构需求对方最初的设想非常简单把 2.2 万道面试题塞进大模型写好一套 system prompt然后让模型自动出题、自动追问、自动判定候选人。我当时看着那份需求文档心里就清楚这个方案在真实生产环境中撑不过三个星期。后来事实也印证了这一点单靠 prompt 驱动的面试 Agent 在早期 Demo 阶段表现得还挺像回事但一进入真实候选人测试问题从四面八方涌出来——模型幻觉造成的误判、题库检索不到导致的“凭空出题”、同一份答案在不同会话里打出完全不同的分数、候选人不服结果时你根本拿不出让人信服的依据。这篇文章要把我在这个项目里摸爬滚打出来的东西彻底拆一遍。核心不是“怎么调 prompt”而是“为什么 AI 面试官不能只靠 prompt”以及我们用 Agent Harness 加代码证据链这套架构怎么把 2.2 万道题的题库、追问策略、评分逻辑、反作弊校验全部串起来。内容会比较硬核涉及提示词工程的实际边界、Agent 编排框架的设计取舍、证据链数据结构的落地细节适合正在做 AI 面试、AI 测评、或者任何想用大模型做高确定性决策系统的团队参考。1. 项目整体设计与思路拆解1.1 为什么单独靠 Prompt 撑不住 AI 面试官先把一件事说清楚如果你只需要做一个“能聊天”的面试模拟器那一条精心编写的 prompt 确实够了。但“AI 面试官”和“AI 聊天机器人”是两种完全不同的东西。面试官的核心是评估评估的前提是标准、证据和可复核性。一个 worker 的回答是“好”还是“不好”不能靠模型当天的心情决定。我总结过单 prompt 方案在实际应用中的四个致命伤幻觉出题模型在自由生成模式下很容易偏离题库。你以为它是在从 2.2 万道题里抽题实际它可能在自创一道听起来很专业、但跟岗位技能模型完全不匹配的题。一次两次还好规模化后题库就失控了。评分不稳同一份答案换两次会话可能一个给 4 分一个给 2 分。大模型的采样随机性在这里完全暴露没有显式的评分 rubrics 和约束条件分数就是玄学。无据可查出题依据是什么为什么追问那三个问题为什么最终判定不通过单人、单条 prompt 的体系下这些东西全部是黑盒候选人质疑时你连过程记录都拿不出来。扩展性差2.2 万道题要按岗位、职级、技能标签动态筛选要接反作弊逻辑要控制追问深度要结合候选人历史答题轨迹动态调难度这些东西塞进一条 prompt 里prompt 会膨胀到几千 token然后触发模型上下文窗口崩坏。这些不是靠“优化一下 prompt 技巧”就能解决的问题。你得把“出题—追问—评估”这个流程从大模型的自由生成里拆出来用一套外部的编排框架去约束它这个框架就是 Agent Harness。1.2 Agent Harness 在项目里到底扮演什么角色很多人分不清 Agent 和 Agent Harness 的关系。简单来说Agent 是那个“干活的人”Harness 是“装 Agent 的支架”——它决定 Agent 什么时候被调用、以什么顺序被调用、输入输出用什么格式、中途出错怎么处理、结束之后产出什么工件。在我们的系统里Agent Harness 承担了几项光靠 prompt 根本干不了的职责流程控制把整个面试分成多个 stage包括开场、基础能力考察、项目深挖、算法评估、综合评定每个 stage 可以动态选择调用不同能力的 Agent。策略注入Harness 可以从题库服务里动态拉取当前候选人的考查策略把策略连同题目组合成结构化 context 丢给 Agent而不是让 Agent 自己决定问什么。知识库桥接Agent 无法直接访问 MySQL 里的题库表和候选人履历库Harness 负责通过向量检索和 SQL 查询把结果拿回来并“喂”给 Agent。输出约束与校验Agent 的原始输出会先经过 Harness 的格式校验层如果是非法 JSON 或缺失必填字段Harness 会决定是重试一次还是走兜底逻辑。证据链归档每轮交互后Harness 会把题目来源、模型调用参数、评分过程、命中规则全部记录下来生成一份结构化的证据文件。第一阶段项目上线后我最深刻的体会就是真正稳定的是 Harness 的规则层而不是大模型的智力层。模型负责它擅长的语言理解和生成Harness 负责所有需要确定性的事情。1.3 从“prompt 工程”到“harness 工程”的思维转换我见过很多团队做类似项目时还在用“写一个大 prompt”的思路去推动这实际上是用旧地图找新大陆。Prompt 工程的核心是把所有指令塞进一个上下文窗口里让模型自主学习而 Harness 工程的核心是把任务拆成多个可独立控制、可独立验证的环节大模型只是其中一个环节的组件。做这个转换时团队里最大的阻力其实是心理上的总觉得“把任务拆给多个 Agent 会不会更不可控”。但实际上只要 Harness 的接口契约做得够清晰每个 Agent 只做一件事反而比让一个模型又出题又追问又打分要稳得多。模块化带来的最大收益是容错某一个 Agent 失败了Harness 可以降级到规则逻辑整个面试不会崩。所以我在设计文档里反复强调一句话Prompt 管的是“怎么说得更好”Harness 管的是“怎么做得更对”。AI 面试官这种场景后者才是决定着系统能不能被 HR 业务方接受的关键。2. 题库侧的结构化设计与数据组织2.1 2.2 万道题的分类体系面试题和普通语料不一样它不是丢进向量库就算完事的。2.2 万道题要能支撑动态出题首先得有一套结构化程度足够高的分类体系。我们在最初清洗 Tita 题库时用了双维度标签模型维度一考查方向基础理论语言基础、框架原理、数据库范式、网络协议项目经验架构设计、技术选型、问题排查、团队协作软性素质沟通表达、目标管理、抗压能力、学习能力思维能力逻辑推理、归纳总结、创造性思维维度二难度梯度L1 入门级概念记忆、基础语法、简单场景判断L2 进阶级多知识点的组合运用、常见场景问题定位L3 高级性能优化、架构取舍、复杂场景设计每道题在入库时都要同时挂上这两个维度的标签再加上岗位映射、关键词、参考答案和判分要点。你可以想一下如果没有这套结构只是往向量库里“灌”两万道题后续出题时你只能做相似度召回题目难度和岗位贴合度完全不可控。而有了标签体系后出题策略可以做成完全确定性的规则比如“找 3 道 L1 基础理论 2 道 L2 项目经验 1 道 L3 思维能力”再结合向量检索做精细排序效果完全不在一个量级。2.2 题库索引与动态出题策略动态出题的过程拆开来看是三步粗筛根据候选人的目标岗位、简历关键词、当前面试阶段从数据库里用 SQL 做标签过滤把候选题目范围压缩到 500 道以内。细排把简历中的技术关键词做向量化和题目的 embedding 做相似度检索排序后取出最相关的 20 道候选。选优将这 20 道题连同题目标签、难度、考查方向交给 Harness 的调度 Agent让它结合候选人前面几轮的答题表现最终选中 6-8 道题并规划出追问方向。注意这里有一个非常关键的工程决策选优这一步绝不直接交给大模型的“自由意志”而是在 prompt 里给出明确的排序 JSON 输出要求同时 Harness 层有严格的 schema 校验。不满足 schema 时直接重试。这一步是整个出题链路中机器规则和大模型能力之间平衡的典型案例。2.3 题库内容本身的“提示词化”改造这一步可能很多人没意识到—题库里的题目原始状态是给人类面试官看的比如题目后一般只有参考答案。但你要让大模型基于这道题灵活追问、准确评分就得给每道题补上一套结构化的“AI 元信息”。这包括考查点列表这道题到底想测什么不能只写“考察对索引的理解”要细化到“考察联合索引最左前缀原则、覆盖索引优化场景、索引失效的典型场景”追问集预置 3 到 5 个可能的追问方向帮助 Agent 在候选人回答不完整时给出正确引导评分锚点描述不同水平回答的典型特征比如“优秀回答会主动提及回表查询代价并对比两种索引方案的 IO 开销中等回答会提到联合索引顺序但无法解释原理较差回答只会背诵概念”常见陷阱标注这个领域中候选人容易混淆的知识点让 Agent 在评估时留意这套改造工程量很大两万道题不可能全部靠人工处理我们同步采用了大模型批量生成初稿 专家抽检修正的方式把每道题的平均处理成本控制在 3-4 分钟。坦白讲这是一个苦活累活但它决定了后面 Agent 评估能力的上限。你喂给模型什么水平的“评分锚点”它就能给出什么水平的反馈。3. Harness 架构与关键实现细节3.1 一套可落地的 Harness 分层模型我们的 Agent Harness 从逻辑上分成了四层。这个分层不一定对你适用但可以作为一个参考骨架后续完全可以根据业务场景调整。第一层调度编排层负责维护面试流程的状态机。面试一共有多少个阶段、每阶段调哪个 Agent、什么条件往下走、什么条件需要回溯这些都是调度编排层用代码写死的确定性逻辑。这一层绝对不用 prompt 控制因为流程本身就不该有随机性。第二层上下文组装层负责从各个数据源读取数据并组装为 Agent 的输入。这一层要解决的核心问题是“Agent 看到的上下文是什么样”。我们会在这一层把候选人的简历精华、当前题目内容、之前的答题转录、预设的评分标准整合成一个格式完全统一的 context。第三层Agent 执行层这是真正调用大模型的地方。我们项目里不同 Agent 使用的模型不完全相同用于追问的小模型响应速度更快用于综合评分的模型需要更强的推理能力所以会用更大的模型。第四层校验与恢复层负责检查 Agent 的输出是否合法。非法则重试或降级。这个层级决定了系统的鲁棒性因为大模型输出一定会有不稳定的时候你不能让它直接崩溃。3.2 Manifold 设计一个 Manifold 管理多个 Prompt在开发中我们采用了 Manifold 机制来管理 Agent 的多套 prompt。如果你用 OpenAI 或 Claude 的 API 做过开发应该对“一个人话的 prompt 序列”不陌生但实际场景里一个 Agent 往往有多个 prompt 变体。比如追问 Agent 在候选人回答模糊、回答正确但不够深入、答非所问三种情境下需要使用完全不同的追问策略。我之前会把这些变体全部塞进同一个 system prompt 里让模型“自己结合情况判断”。这种做法的好处是模型上下文大能综合理解全局坏处是 prompt 一旦叠了太多分支模型的遵循率会显著下降今天走这个分支明天可能就走偏。后来改成 Manifold 模式每个 Agent 下面挂多个独立命名的 promptHarness 根据当前会话状态先选出对应的 prompt 再调用模型。说白了就是把“让模型自己判断”这件事逐步收拢为“Harness 先用规则判断再让模型执行”。下面是当时我们内部用的一份伪配置用来管理“追问 Agent”的三个 Prompt 变体agent: followup_agent model: gpt-4o-mini manifolds: - name: clarify_ambiguity trigger: candidate_answer.confidence 0.4 system_prompt: 你是一名面试官候选人对问题的回答比较含糊。请用中文提出一个问题限定在原始问题相关的知识范围内目的是澄清候选人真实掌握程度。不要直接给出答案或者提示。 - name: deep_dive trigger: candidate_answer.confidence 0.4 AND candidate_answer.depth 0.7 system_prompt: 你已经得到候选人基本正确的回答。请从你得到的该题考查点列表中挑选一个候选人尚未深入展开的子知识点做针对性的深入追问。 - name: scenario_probe trigger: candidate_answer.depth 0.7 system_prompt: 候选人对该题掌握情况较好。请设计一个贴近真实项目的场景问题考察其在工程实践中的迁移能力。这套配置的核心价值在哪里在于 trigger 条件是代码逻辑它根据上一轮候选人的回答质量让 Harness 去选择该用哪个 promise。这不是大模型自己“悟”出来的而是我们通过规则显式控制的结果。它带来的直接好处是同样的回答模式百分之百会触发同样的策略不会再出现同一道题、同一种回答两次问出不同追问的尴尬局面。3.3 上下文组装中的 Embedding 检索细节实际操作中我建议把题目检索的 embedding 独立出来单独维护。我们给每道题生成了一组独立的向量维度是 1536。生成向量时用的不是题目的原始文本而是“题目 考查点列表 参考答案要点”拼接后的组合文本。这种做法的效果远比只用题目本身要好我实测过检索的相关性有差不多 15% 到 20% 的提升。检索时机和处理流程上有几个值得一提的关键点候选人进入面试间时Harness 通过消息队列触发简历分析任务。简历文本被解析为 JSON 后抽取技能标签和关键经验字段再用同样的 embedding 模型把结构化文本向量化。向量化完成之后去题库向量库做 ANN 检索取回 Top 50 题目。这 50 道题再回到 MySQL 里做一次 SQL 精细过滤把岗位类型、职级等硬性条件过滤掉。最后把满分 50 题交给调度 Agent进入前面提到的“选优”环节。向量检索不是万能的所以在后期我们做了一个非常关键的调整把纯向量召回改成了“向量 标签 规则”的混合召回。具体来说如果某个候选人的简历里明确写了“熟悉 Redis”那么 Redis 相关题目会通过标签直接命中即使它的 embedding 相似度不高。这样做极大减少了模型“看不懂简历隐含信息”造成的漏召回问题。3.4 代码证据链让每一次判定都无懈可击这是整个项目里我认为最值得拿出来讲的模块。AI 面试系统如果只输出一个“通过/不通过”业务方绝对不放心。HR 会把候选人申诉场景直接抛过来“你们说他不通过证据呢”所以我们必须把评估过程做成代码层面的证据链。我一直觉得用代码生成证据比用自然语言描述证据要可靠得多。代码是精确的、可校验的、不依赖于文本解析稳定性的。证据链的 JSON 结构大体是这样的{ candidate_id: cand_1024, interview_id: itv_2048, overall_score: 3.2, stages: [ { stage: project_experience, question_id: q_55821, question_source: RESUME_KEYWORD_HIT, matched_keywords: [Redis], evaluator_agent: deep_dive_agent, model_used: gpt-4o, temperature: 0.2, prompt_version: 20250115_v3, raw_answer_excerpt: 候选人提到使用 Redis 做缓存但在高并发场景下未提及缓存穿透处理, score_anchor_hit: [ { anchor_id: q_55821_anchor_2, description: 中等回答能提到 Redis 缓存的使用场景但缺乏异常与边界情况处理 } ], score: 3, reasoning: 候选人在追问中依然未主动提出缓存穿透与击穿的解决方案因此判定其掌握处于中等偏下 } ] }这份 JSON 不是给人看的文档而是给审计系统吃的原料。它有多重用途可追溯候选人质疑时直接把编码证据导出哪道题、命中什么锚点、当时调的是什么模型温度参数一目了然无从辩驳。可复现把同样的证据 JSON 喂回评估 Agent理论上应该得到同样的评分。这样我们就可以做回归测试防止某次模型更新后评分逻辑漂移。可优化分析证据链中大量“score_anchor_hit 为空”的样本说明题目评分锚点写得不到位指导后续模板迭代。如果你只做一个自娱自乐的本地 Demo证据链确实是“听起来很专业但没必要”的东西。但你的系统一旦要面对真实的 HR 业务和候选人这一层就是你和“玩具”之间的分水岭。我们后期花了将近 30% 的开发时间在证据链的完善上但我认为是整个项目里最值的一笔投入。4. Prompt 的设计原则与评测方法4.1 核心 Prompt 的结构设计虽然我说“不能只靠 Prompt”但 Prompt 仍然是 Agent 能力的重要组成部分。只是它从“控制全局的角色”退化成了“约束单次行为的一份配置”。在实际编写中我总结了一套适合面试 Agent 场景的 Prompt 结构套用在很多 Agent 上效果都不错角色边界明确 Agent 的身份和限制如“你是一名只负责对候选人答案进行追问的技术面试官你不负责评分评分由另一个模块完成”。把职责边界划清楚可以极大减少模型在做 A 任务时顺手把 B 任务也干了的问题。输入描述描述你会拿到什么数据。告诉模型输入的结构例如“你将收到一道题目、该题的考查点列表、候选人的上轮回答文字记录”。任务目标描述这一轮要具体实现什么。用一句话说清楚越具体越好。约束条件通常我们会加硬性约束比如“不得透露你正在评估候选人”“不得直接告知答案”“只用中文提问”。输出格式对所有需要程序解析的 Agent必须约定严格 JSON 格式并加一句“不要输出任何其他解释文字”。回退指令如果模型对某题非常不熟悉允许它触发一个固定的回退动作比如返回“{‘fallback’: ‘question_unclear’}”而不是让它硬编一道题。这套结构并不神奇它核心解决的问题是让同一个 Agent 在多次运行中保持输出行为的一致性和可解析性。4.2 随机性与参数设置对面试质量的影响面试质量里我们最关心的就是“同样的问题同样的答案会不会被打成不同的分数”。光有 prompt 约束还不够模型采样参数必须严格固定temperature评分和评估类任务统一调至 0.10.2几乎不引入随机性。top_p固定为 0.9 左右避免过度采样尾部低概率 token。max_tokens设置合理上限防止 Agent 在追问时突然“话痨”。比如追问任务我们一般限制在 256 tokens 以内最终综合评分任务可以放到 1024。seed如果 API 支持指定 seed配合固定 prompt 可以在多次请求中保持稳定的输出模式。快照机制也是我强烈建议做的。每次上线新的 prompt 版本、模型版本或参数配置时Harness 会记录一套完整的工件。为什么因为大模型服务商推新模型接口是常态今天用的 gpt-4o 好使月底它出了个新快照版你不会希望线上评分结果无声无息地漂移。我们在项目中提供了对单个 Agent 的 “回滚” 能力。比如发现某个追问 Agent 换新模型后追问质量明显下降一键切回上个版本其他 Agent 不受影响。这种机制不用太复杂本质上就是记录当前线上版本号 代码仓库 tag 关联。4.3 评测集与回归测试没有测评就没有优化面试 Agent 的迭代如果没有一套固定的评测集你根本不知道这次改动是变好了还是变坏了。我花了不少时间搭建了一套离线评测集方案这里直接分享出来数据构成从历史真实面试记录中抽取 200 组题目 候选人回答 人工判定分数覆盖 30 个不同岗位方向保证多样性包含 20 组边界样本如回答特别简短、回答前后矛盾、答非所问评测指标评分准确性Agent 给出的分数和人工判定分数的绝对差是否在 1 分以内追问合理性由 5 名资深面试官人工打分1-5 分判断追问是否抓住回答中的漏洞结构化通过率Agent 输出的 JSON 是否能通过 Harness 的 schema 校验幻觉率Agent 出题内容是否出现在题库知识范围之外这套评测集每周跑一次。任何 prompt 改动、模型升级、题库规则变化都要先过评测集分数不达标就不允许上线。效果非常显著系统的可靠性就是这么一点点“磨”出来的。5. 常见问题与实操避坑5.1 模型“幻觉出题”怎么控制幻觉问题是 AI 面试系统里最致命的问题。模型在自由发挥时可能出一道上看起来像“计算机网络”的题但知识点已在题库里不存在。这会导致候选人质疑题目权威性。我们的解法是多层拦截第一层出题 Agent 的 prompt 里硬性要求“只能在提供的候选题目列表中做选择不得自创题目”同时提供候选列表完整 ID 列表要求输出时带回题目 ID。第二层Harness 校验 Agent 输出的 JSON看题目 ID 是否真实存在于本次面试允许的题目名单中。如果不存在直接判为幻觉输出丢弃并重试一次。第三层在证据链中记录“题目命中方式 AGENT_SELECTED_FROM_STRATEGY”方便后期追溯。这套拦截组合拳的效果是非常实在的。上线最初两周幻觉出题率大概有 5%三周后降到了 0.3% 以下。5.2 长文本对话中上下文被冲掉AI 面试往往会进行多轮追问候选人回答原文可能很长。如果你想从头到尾保持全量上下文tokens 消耗会直线上升并且会触及大模型的上下文窗口限制。你说你希望模型记住所有内容其实它到后面根本记不住前面的关键细节。我们的解决方案是做上下文压缩 关键信息提取每轮对话结束后Harness 同步调用一个“信息提取 Agent”把对话内容压缩成结构化要点比如“候选人提到‘做过秒杀项目’使用 Redis 预扣库存未提及最终一致性方案”。后续 Agent 调用时传入的不再是全部对话原稿而是压缩后的要点 当前题目 最新回答。只有在最终综合评估阶段才会调取完整对话记录来做最终裁决。这套方案大大降低了 token 消耗同时保留了评估所需的关键信息。实测下来单场面试的 token 成本下降了约 40%而且评分稳定性反而更高了。5.3 小模型的“答非所问”问题为了让追问延迟更低我们原本想让小模型负责实时候追问。实际测下来的效果并不够理想尤其在多轮追问中容易跑偏——上一秒问候选人 Redis 持久化下一秒开始纠结 RDB 文件格式的字节细节完全偏离了考查点。我们的调整方案是把追问职责拆成两部分规则判定部分通过代码判定候选人是否触及了隐藏红线。比如当回答与标准考点的余弦相似度低于某个阈值时直接判定为“跑题”Harness 触发一个预设的引导话术。生成部分只有在规则判定确认“确实需要追问”的情况下才调用模型生成新的追问问题并对追问题目本身用关键词匹配做一次“是否偏离考查点”的校验。这里也顺带解释了“为什么我们要用 Harness 做这么多约束”如果模型有 90% 的时间表现正常那剩下 10% 的错误在招聘场景里就是不可接受的。作为系统设计者你要做的是把这 10% 用代码兜住而不是指望模型自己改正。5.4 大题库下响应延迟过高2.2 万道题的检索响应延迟是一个绕不开的工程问题。如果每次交互都实时 Embedding 简历和题目响应时间会非常难看。我们优化后的大致时间分布摆出来给你参考题目预检索候选人进入面试间后立刻异步进行先对简历做向量化并完成 Top 50 初步检索结果缓存到 Rediskey 有效期设为 30 分钟。动态选优调度 Agent 只需要在 50 道候选题目里做排序选择单次推理耗时约 1 秒。追问响应小模型 压缩上下文单次追问生成在 1.5 秒以内。面试全程的平均“Agent 响应延迟”控制在 2 秒内真实对话节奏基本够用。如果是那种现场实时抽题的场景那就没办法缓存了只能加一层接口限流和降级策略。6. 关于落地效果和经验反思系统上线后我们拿真实的候选人数据集做了一轮 A/B 对比。一组用纯 prompt 方案的旧版系统一组用 Harness 架构的新系统。在 1 个月的测试周期里新系统的评分与人工终面结果的相关系数有明显提升。更直观的是 HR 团队的反馈旧版系统收到过 3 次候选人申诉质疑评分合理性新版系统上线至今保持零申诉因为每次评分都能导出一份完整证据链明细。从这个项目里提炼几条真正有价值的心得别信“one prompt to rule them all”。单条 prompt 在复杂决策类 AI 应用里天花板非常低越早拆成多 Agent 编排结构后期越省力。确定性逻辑交给代码不确定性判断交给模型。这句话是 Agent Harness 架构的纲。面试官系统里有大量流程应该用代码硬编码模型只做生成和判断的环节否则就是给自己的系统埋雷。证据链不是附加项是核心功能。做面向业务、面向人的决策系统让系统“会做决策”和“能解释决策”至少要三思而后行其实根本不给你选择权。评测集是护城河。没有评测集AI 系统的迭代就是一场“你觉得好了我也觉得好了但生产环境翻车了”的悲剧。对这个方向后续的演进我个人看好两个点。一是把证据链从“事后可追溯”升级为“实时反馈”即在前一轮对话刚结束时就触发规则引擎对回答质量做快速预评估动态调整后续追问方向这会进一步提升面试的效率和灵敏性。二是基于大量历史面试数据构建岗位能力模型让出题策略不再依赖人工配置而是通过聚类自动生成岗位技能权重分布。做 AI 面试官系统本质上做的是“如何用 AI 替代掉人工面试最不稳定的环节同时用工程手段兜住 AI 自己最不稳定的一面”。这条路上没有银弹但 Agent Harness 加证据链这套组合至少让我现在夜里能睡得踏实一点——大多数情况下它可以告诉你每一步决策是怎么做出来的哪怕 AI 出了错你也能指出它具体错在哪、为什么错。这不就是 AI 落地时最需要的掌控感么。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。