AI 面试系统实施研究报告

阅读说明与证据等级

【事实】仅指固定 HEAD、审计或实际验证直接支持;【未验证】指源码存在但真实集成、性能或质量未获验证;【建议】是目标架构。除明确写为源码事实值外,全文性能、容量、阈值和 SLO 均为“建议初始目标”。

AI 面试产品交付:从练习工具到可审计系统

证据基线:2026-09-07。DeepInterview 固定 HEAD 为 241799b39e781737ccec30157d8201bcc572064c,GrillKit 固定 HEAD 为 15a400afb08349ad9b73f31a0c92ba147032164c。文中 【事实】 仅指两份审计或固定源码直接支持的结论;【建议】 是面向拟建产品的交付主张;【未验证】 表示虽有源码或项目自述,但审计未完成真实集成、性能或质量验证。README 只用于理解作者意图,不作为测试通过证据。

1. 执行摘要

【建议】AI 面试首先是一条业务闭环,不是一个“会问答的模型”。 它从候选人材料和岗位要求出发,把岗位拆成可观察的能力,把能力映射为有依据的题目,再通过语音、文本或代码收集证据。系统随后按预先发布的评分标尺解释证据,生成带出处、覆盖范围和不确定性的反馈。用户纠错、人工复核、申诉和线上质量数据又回到题库、评分标尺和发布流程,推动下一版改进。只有材料、能力、题目、对话、证据、评分、反馈和复盘首尾相接,产品才是可管理系统;只让模型自然地问几句话,只能证明一次演示能进行。

这条闭环直接决定产品能否经营。材料必须说明来源,题目必须说明为什么被选中,追问必须受轮次和范围约束,分数必须指向回答或测试结果,技术故障必须与能力不足分开,旧报告必须能还原当时使用的题库、模型和规则。这样,团队才能回答三个基本问题:这次结果依据什么;如果错了,影响到谁;修复后怎样恢复而不改写历史。第一版因此应先交付“可重复、可解释、出错后可恢复的练习与反馈链路”,再逐步增加语音、检索、代码执行和更高风险用途。

【事实】 DeepInterview 是以实时语音为主要交互方式的模拟面试系统。固定源码覆盖网页体验、简历与职位描述解析、公司信息检索、问题规划、实时对话、逐字稿、结构化评分、报告和数据保存,并非单纯的界面样机;但真实媒体、语音识别与合成、模型、完整知识检索、云端数据库和对象存储并未在本次审计中完成端到端运行。报告页在若干尚未就绪的状态使用样例评分卡,所以页面可显示不能证明真实面试评分成功(DeepInterview 审计报告页源码)。

【事实】 GrillKit 是单用户、本地优先的技术面试训练器。固定源码覆盖理论题、编码题、组合会话、计时、最多两轮追问、结构化 AI 评价、本地数据库、离线语音和可选的隔离代码执行。它定义了候选人可见的公开测试、仅服务端可见的隐藏测试及相应执行流程;但固定题库中 44/44 道编码题均为 AI 模式,测试执行模式、公开测试和隐藏测试的数量都为 0。因此项目说明中的“运行公开测试、提交后运行隐藏测试”是能力描述,不是当前题库已验证的体验(GrillKit 审计task specrun tests)。

【建议】 第一版应定位为候选人自主练习与形成性反馈工具,而非自动录用、淘汰、排名或远程监考系统。应组合 DeepInterview 的上下文准备和语音闭环,与 GrillKit 的确定性状态机、题目快照和代码执行边界;不应照搬两者的默认信任网络、未校准模型分数或不完整数据治理。招聘评估必须作为独立高风险产品线重新完成岗位效度、法律审查、公平性校准、人工复核和申诉机制。产品明确排除真实面试中的隐蔽监听、实时提词、代答、伪造身份和规避监考。

A. 一场 AI 面试如何真正完成

结论:一场面试真正完成,不是页面出现“已结束”,而是每个结论都能沿着材料、计划、回答和评分一路查回去。 以下用一个贯穿案例解释建议流程。人物、岗位、回答和数值均为示例,不代表两个参考项目已经实现或达到相同质量;引用的工程切片则来自固定源码与两份审计。

01读材料保留简历/职位描述出处
02定能力写成可观察信号
03选题目冻结题目与标尺
04收回答语音、文本与代码
05固证据确认转写与测试
06做评分规则校验模型判断
07再改进复核申诉回到发布

候选人林晨申请“中级后端工程师”。他的简历(CV)写到自己负责过订单服务,使用消息队列处理异步任务;职位描述(JD)要求能够设计高并发服务、排查线上故障,并解释数据一致性的取舍。系统不应从这两份材料直接跳到“给林晨打分”。CV 是候选人的自述,JD 是岗位要求,两者都不是已经证明的能力。系统要先把它们变成一份可检查、可冻结的面试计划。

A.1 从材料到能力:先确认要测什么

结论:材料解析的产物不是候选人画像,而是带出处的待验证假设。 系统分别读取 CV 和 JD,保留原文位置、解析版本和内容指纹(用于确认内容没有被替换的哈希值)。它从 JD 提取岗位目标、级别、必备能力和限制条件,再从 CV 提取经历、项目、时间和候选人声称使用过的技术。随后形成三项待测能力:并发与容量设计、故障诊断、数据一致性。

每项能力还要写成“可观察信号”。这意味着系统不评价“聪明”“有潜力”之类模糊标签,而是说明要在回答中看到什么。例如,并发与容量设计可以观察是否给出流量假设、瓶颈、保护顺序和验证方法;故障诊断可以观察是否从现象提出假设,再用指标或日志排除;数据一致性可以观察是否识别失败边界、补偿办法和用户影响。

为什么需要。 如果没有能力模型,选题只能依赖关键词相似或模型即兴判断。CV 里出现“Kafka”可能只是参与过项目,不能自动证明候选人理解消息可靠性;JD 里出现“沟通能力”也不能授权系统用口音或语速评分。带出处的能力项把“岗位需要什么”和“候选人已经证明什么”分开。

失败会怎样。 扫描版 CV 可能解析为空,JD 可能缺少级别,技能同义词可能被漏掉,模型也可能把自述当事实。【建议】 输入不完整时停在“需要补充材料”,说明缺什么;不允许为了维持流程而自动补全岗位要求。无法从材料支持的推断要标为“待确认”,不能进入正式评分。

【事实】 DeepInterview 的准备流程会并行处理 CV、JD 和公司资料,再做差距匹配与问题规划;其结构化对象包括候选人、岗位、差距、计划问题和面试上下文。这为“先结构化、再匹配、后规划”提供了源码依据,但复杂版式、多语言和真实岗位上的抽取准确率仍属 【未验证】DeepInterview Prep 审计准备流程源码)。

A.2 从能力到题目:把有限时间花在关键证据上

结论:题目规划不是让模型自由出题,而是在已发布题库中做受约束选择。 系统为三项能力选择主问题、评分标尺和允许的追问范围,并记录每题的选择理由。

系统先确认什么 本场怎样选择 回答中要看到什么 失败时立即做什么
并发与容量设计 “订单流量增长十倍,你会先估算和保护哪些环节?” 容量假设、简单计算、瓶颈、限流与降级顺序 若题目难度不匹配级别,停止发布该题并回到上一版本
故障诊断 “消费积压但数据库负载正常,你会怎样定位?” 排查顺序、可验证假设、指标和依赖关系 若问题与 JD 无关,标记计划缺陷,不把回答差异算到候选人
数据一致性 “库存扣减和订单创建不能同时成功时,你怎样取舍?” 失败场景、幂等、补偿、一致性边界和用户影响 若评分标尺与题目不配套,该题不能进入正式会话

“评分标尺(rubric)”是把“答得好”拆成不同等级的可观察标准、示例和反例。题目开始前,系统发布“计划快照”:把题目修订、rubric、语言、允许追问次数、材料版本和模型策略固定下来。之后题库即使更新,这场面试仍按原快照解释。

为什么需要。 固定主问题保证不同场次有共同基线;受约束追问允许澄清回答,却不能临时改变考试范围。计划快照还能解释为什么两个候选人收到不同问题,以及差异是否来自岗位相关信息。

失败会怎样。 自由生成问题会出现难度漂移、重复覆盖、遗漏关键能力或泄露不当内容。旧题被覆盖后,历史报告还可能按新 rubric 解释,造成同一答案“今天三分、下月四分”却找不到原因。【建议】 题库采用不可变修订;会话保存题目和 rubric 快照;动态追问只补充原能力证据,并受次数、时长与禁区约束。

【事实】 GrillKit 会在创建会话时快照题目、rubric、代码和任务规格,历史结果不必依赖当前题库;会话阶段和追问深度由领域规则控制,而不是由模型随意推进(GrillKit 数据模型会话阶段源码)。

A.3 从提问到回答:实时系统的任务是收集证据

结论:实时对话可以自然,但被保存和评分的事实必须稳定。 林晨进入面试后,系统读出第一题。他先回答:“我们会先扩容,再看数据库。”语音识别(STT,把声音转换为文字的服务)持续显示临时转写。临时文字会随着后续音频修正,只供即时反馈;只有一轮结束并通过检查后,才生成“已确认回答”。

系统发现回答没有容量假设,于是在原题范围内追问:“你会用哪些数据估算扩多少?扩容失败时先保护什么?”林晨补充峰值订单量、单实例吞吐、队列积压阈值,并提出先限制非核心查询、保护下单写入。模型可以建议这句追问,但能否追问、最多追问几次、何时结束,由会话状态机决定。状态机可以理解为一张不允许随意跳步的流程表:系统清楚知道当前处于准备、连接、答题、评分还是完成,只有满足规则才能进入下一步。

为什么需要。 实时链路同时处理音频、转写、模型输出、语音播放、计时和断线重连。任何消息都可能迟到或重复。如果把临时转写直接评分,后续修正不会反映到分数;如果让模型决定“本题已完成”,同一句话在不同模型版本下可能推进到不同状态。

失败会怎样。 第二题回答时网络中断,浏览器重连后重新发送上一条提交。如果没有“幂等键”(同一请求重复到达也只产生一次结果的标识),系统可能保存两份答案、调用两次模型并重复计费。【建议】 每个提交带幂等键和预期会话版本;服务端发现已处理后返回原结果,版本不匹配则重新读取状态,不允许旧页面把第三题退回第二题。

语音不是能力本身。设备或语音服务异常时,系统应转为文本,并记录“为何降级、从何时开始、哪些回答受影响”。“降级”是高级能力不可用时保留核心任务的备用方式,例如语音合成失败后继续显示问题文本。降级状态进入报告,但不进入能力分数。

【事实】 DeepInterview 的实时工作进程保存已确认转写,SessionGuard 限制时长和轮次,TranscriptFlusher 周期保存转写;GrillKit 的理论评价最多两轮追问。这些是可复用的恢复和边界意识,但真实设备、口音、噪声及供应商时延在本次审计中仍属 【未验证】DeepInterview Live 审计GrillKit 模型与语音)。

A.4 从文字和代码到证据:让确定性结果优先说话

结论:开放式回答需要解释,代码执行需要事实,两者不能混成一个“AI 感觉”。 理论题保存题目、已确认回答、追问、引用片段和 rubric 对应项。编码题还要保存候选人的代码版本、编译结果、公开测试、隐藏测试和资源使用。

林晨编写库存扣减函数。点击“运行”时只执行公开测试;点击“正式提交”时,服务端执行不向浏览器暴露的隐藏测试。编译是否成功、通过多少测试属于确定性信号。模型可以解释代码可读性、边界意识和取舍,却不能把测试失败改写为通过,也不能在没有测试时假装“已验证正确”。

为什么需要。 理论题适合观察推理过程,测试适合验证具体行为。二者组合,既避免只看输出忽略思路,也避免只听解释不验证代码。基础设施失败、候选代码失败和未运行必须是三个状态:INFRA_ERRORTEST_FAILEDNOT_RUN,不能都折叠成 false。

失败会怎样。 隐藏测试进入浏览器会泄题;执行环境若与应用共享网络和秘密,恶意代码可能扫描内网;没有参考解与错误解的题目即使“有测试字段”也可能无效。【建议】 测试由服务端按题目版本装配;执行环境默认无外网、无生产密钥、限 CPU/内存/进程/输出,完成后销毁工作区;基础设施失败只触发重跑或人工处理,不产生负向能力分。

【事实】 GrillKit 已实现公开与隐藏测试的数据结构、客户端隐藏边界以及 Run/Submit 流程;但固定题库中 44/44 道编码题全部为 AI 模式,tests 模式、public tests、hidden tests 均为 0。因此当前证据只证明判题框架存在,不能证明题库已具备真实判题体验(GrillKit 题库与判题任务规格源码)。

A.5 从证据到报告:没有测到,不等于能力差

结论:报告的核心不是总分,而是“哪项判断由哪段证据支持,哪些地方还不能判断”。 会后系统先冻结本场输入:题目版本、已确认转写、文本修订、代码、测试结果、rubric、模型和规则版本。随后逐项评分。

以并发能力为例,报告应同时展示:候选人给出的容量假设;该片段对应 rubric 的哪一项;仍缺少什么,例如数据库与消息队列如何分别压测;规则确认了哪些事实;模型给出什么解释;证据范围有多大。覆盖率(coverage)表示计划内容中有多少取得有效证据。三项能力只完成两项时,报告应写“覆盖不足,数据一致性暂不能判断”,而不是给缺失项填零再生成完整画像。

为什么需要。 分数把复杂证据压缩成一个数字,很容易制造过度确定。证据、覆盖和不确定性让用户知道分数适用于哪里,也让复核者能够修改具体环节,而不是争论模型是否“聪明”。

失败会怎样。 如果转写修正后仍引用旧文本,或者单题评分失败却继续汇总总分,报告会显得完整但事实已经断裂。【建议初始目标】 100% 的分项判断至少带一个可定位回答片段或确定性测试;没有有效证据的分项 100% 显示“未覆盖”“尚未判定”或“需复核”,不得自动填低分。用户修订转写时保留原文、修改人、时间和原因,只重算受影响题,不覆盖旧报告。

【事实】 DeepInterview 把能力名称绑定计划目标,把分数限制在 0–5,由代码派生等级;未回答题不记零分,而由 coverage 表达;单题失败也不会抹掉其他题。这些实现支持“局部可用、缺失不补零”的方向,但招聘效度和真实评分质量仍属 【未验证】DeepInterview 会后评分评分源码)。

本场最终形成一条可复核链:CV/JD 原文 → 能力项 → 题目修订 → 主问题与追问 → 已确认回答/代码 → 测试与引用 → rubric → 模型与规则版本 → 反馈 → 纠错或复核记录。只要其中一个箭头断开,争议处理就会退化成“相信模型”或“相信截图”。

B. 为什么 AI 会不稳定,以及系统如何变得稳定

结论:模型不稳定,不等于系统必须不稳定。 概率模型可能因上下文顺序、版本、参数和供应商路由给出不同表达;输入还会受材料解析、网络、语音和题库质量影响。可靠系统不要求每个组件永不失败,而是用七层保障让错误在形成不利结论前被发现、隔离和纠正。

B.1 先理解不稳定从哪里来

输入可能失真:CV 是扫描件,JD 缺关键要求,麦克风漏字,语音识别把否定词听反。流程可能竞争:重连重复提交,两个工作进程同时追加答案,上一轮迟到的模型输出污染下一轮。模型可能波动:输出字段缺失、超时、截断、被回答中的指令干扰,或供应商静默升级。评价也可能不稳:rubric 含糊,人工评审之间尚未达成一致,小语种或特定设备的误差被总体均值掩盖。运行环境还会引入队列积压、数据库冲突、预算耗尽和迁移失败。

所以“接口返回 200”“对话很流畅”“报告成功生成”都不是充分证据。稳定至少意味着:该保存的不能丢;同一提交不能重复算;听不清时不能猜;供应商超时不能嫁祸给候选人;每项结论必须拿得出依据;高影响结果可以暂停和复核。

B.2 七层保障怎样相互兜底

结论:七层保障不是七份独立清单,而是前一层漏过错误时,后一层继续阻断传播。

先守住哪一层 用什么白话机制 重点发现什么 异常后马上做什么
输入 材料、题库和音频先过安检 空解析、缺字段、无测试题、低置信转写、错误语言 停止准备、提示补充、切文本、标记证据待核对
流程 由规则决定现在到哪一步 重复提交、越过阶段、迟到消息、并发覆盖 返回首次结果、拒绝非法迁移、从检查点恢复
模型 把模型放进有字段、有版本、有超时的盒子 非法结构、分数越界、超时、截断、注入和版本漂移 有限重试、熔断、切已校准备份或转人工
证据 每个结论指向原话、测试和版本 引用丢失、旧转写、未运行测试、覆盖不足 撤回受影响分项,显示尚未判定,不补零
质量 用固定样本和人工共同标尺检查 重复波动、严重高低估、题目失效、群体误差 阻断发布、修 rubric、缩小适用范围
运行 用服务目标、预算和告警控制影响范围 队列积压、供应商故障、重试风暴、成本失控 停止扩量、保存事实、透明降级、列出受影响场次
治理 明确谁能发布、复核、撤回和申诉 未批准版本、高风险用途、供应商政策变化 暂停结果消费、人工复核、批量纠正或回滚

输入层先防止“坏材料进系统”。材料要有来源、类型、大小、解析结果和版本;编码题要有参考解、公开/隐藏测试和代表性错误解;关键语音片段低置信时先核对。流程层随后固定“发生了什么”。状态机只接受允许的迁移,浏览器不能自行宣告超时或完成,模型也不能直接修改会话状态。

模型层只让 AI 做受约束的语义任务。结构化输出(用固定字段传递结果的格式)要求题目 ID、rubric 项、证据位置、分数、缺失项和拒绝原因都符合契约;代码再检查分数范围、题目身份和引用边界。模型、提示词、参数、供应商和结构定义全部版本化。格式错误只允许有限修复,超时达到截止时间后熔断,不无限重试。

证据层回答“凭什么”。检索增强生成(RAG,先从获准资料找到相关片段,再让模型依据片段回答)必须返回可定位引用、内容指纹和索引版本。检索文本始终是不可信数据,不能覆盖系统指令,也不能调用未授权工具。版本冻结则确保历史报告仍使用当时的题库、rubric、模型、提示词、转写修订和测试集解释。

质量层回答“这种判断是否长期站得住”。固定质量集(golden set,一套由人认真判断过、每次升级都要重考的标准样本)覆盖岗位、级别、语言、口音、设备、回答长度、无答案和攻击输入。先确认受训评审按 rubric 能达到基本一致,再比较模型。运行层用服务等级目标(SLO,对关键用户结果设定的可靠性目标)、错误预算、熔断和故障演练控制影响范围。治理层最后决定哪个版本可以发布、哪些结果必须人工复核、申诉成立后怎样撤回和批量纠正。

这些机制互相补位。结构化输出只能保证结果形状正确,不能保证内容真实;检索引用只能说明来源,不能证明推理正确;版本冻结能解释差异,不能自动消除偏差;规则校验能拦住越界分数,不能替代人工标尺;幂等能防止重复评分,不能修复错误转写;人工复核能处理边界案例,不能代替日常自动监测。稳定来自组合,而不是押注某一个“更强模型”。

B.3 完整异常案例:三种故障同时发生时怎样不误伤

结论:当语音识别错误、模型超时和覆盖不足同时发生,系统的正确结果是“暂不能完整判断”,不是低分。 假设一场后端面试计划 6 题。第三题讨论数据库事务,林晨说:“可重复读并不能完全解决幻读,具体还取决于数据库实现。”背景噪声和断流让 STT 转成“可重复读能完全解决幻读”,恰好改变了技术含义。随后评分模型连续超时;第五、六题又因会话中断没有完成。最终只有 3/6 题有回答,其中只有 2 题形成可靠评分证据。

用户首先看到的是可理解的处置,而不是内部错误码。第三题关键句被高亮为“转写可能有误,请核对或改用文字”;计时在建议允许范围内暂停;模型超时后页面显示“回答已保存,评分稍后完成”,不会出现样例分数。会话结束后,报告明确写“回答覆盖 3/6,可靠评分覆盖 2/6,证据不足,暂不生成整体等级”。前两题已经核验的反馈仍可查看。用户可以修正第三题文本、补答未完成题,或申请人工复核;平台故障造成的补答不消耗用户次数。

系统内部保留更精确的事实。原始已确认音频轮次、机器转写、置信度、丢包情况和候选人修订分别保存;修订以新版本追加,不覆盖原文。第三题先进入 TRANSCRIPT_UNVERIFIED,禁止负向结论提交。主模型达到截止时间后只进行一次受预算约束的短重试;再次失败记录 provider、model、deadline、错误类型和调用费用,再切换经过同一 rubric 校准的备用模型。备用仍失败时进入 SCORING_PENDING,不回 mock,不写零分。

覆盖率要分开计算:回答覆盖说明完成了多少题,可靠评分覆盖说明多少题取得可用评分,rubric 覆盖说明关键评价项是否都获得证据。任一覆盖低于发布门槛,就阻止总体等级、排名和录用倾向。系统同时把 STT_LOW_CONFIDENCEMODEL_TIMEOUTSESSION_INTERRUPTED 写入不可追加修改的事件记录,并通过事务 outbox(数据库提交事实时,同事务登记待发送事件的机制)通知评分队列和事故看板。

当同一语言或区域的低置信率与同一模型的超时率一起升高,运行层按能力熔断:新会话默认转文本或备用 STT,评分转异步,已开始会话保存检查点。恢复后先用探针和小流量验证,再按幂等键重放 SCORING_PENDING。如果用户已经修正转写,只重算第三题;前两题不重复调用、不重复收费。旧的降级报告保留为历史版本,并以“已撤回”连接到新报告,不能静默覆盖。

复盘时不把三种故障合并成“模型表现差”。输入侧检查噪声、断流和关键术语核对;模型侧检查超时、重试、备用路由和费用;流程侧补充“可靠评分覆盖不足时禁止总体结论”的契约测试;治理侧查找同版本、同语言、同区域的全部受影响场次并确认纠正。这个案例体现的是“体验尽量继续,结论必须谨慎”:服务可以柔性降级,高影响判断必须严格关闭。

B.4 承诺什么,不承诺什么

结论:可信承诺应描述系统怎样发现和处理错误,而不是声称 AI 永不出错。

我们承诺怎样做 我们不承诺什么 用什么证明承诺兑现
每项分数都连接题目、rubric、回答片段、测试和版本 AI 分数等于一个人的真实能力或未来绩效 证据记录、引用抽检、版本快照和人工复核
低 STT 置信、模型超时和基础设施失败不自动变成低分 所有语言、口音、噪声和设备下语音识别永不出错 转写核对、文本替代、错误分类和分语言质量集
覆盖不足时显示证据不足,不制造完整画像 每场面试一定生成完整分数、排名或录用建议 多层 coverage、报告发布门槛和降级状态
相同提交重复到达只产生一次业务结果 网络、设备和第三方服务永不失败 幂等键、唯一约束、对账和恢复演练
模型、题库、rubric 和提示词变更经过版本化回归 概率模型对同一输入永远逐字一致 golden set、重复运行方差、发布清单和回滚记录
real、mock、sample、degraded 在页面、接口、导出和分析中一致标识 页面能展示或 README 写明支持,就代表生产链路已验证 来源状态字段、数据域隔离和下游契约测试
不把口音、停顿、流畅度、摄像头或设备质量直接等同岗位能力 AI 天然客观无偏,或一次校准永久有效 岗位相关 rubric、公平性切片、置信区间和申诉记录
高影响结果可以复核、纠错、撤回和恢复 自动评分可以替代招聘责任或成为唯一淘汰依据 复核时限、申诉审计、用途控制和独立 Go/No-Go

【事实】 DeepInterview 在缺少密钥或未知 provider 时可能使用 MockLLM,报告页在若干状态使用 sample scorecard;GrillKit 虽有 public/hidden tests 框架,但固定题库 44/44 道编码题的 tests/public/hidden 均为 0。这些事实说明 demo、README 和框架存在都不能替代真实生产验证(DeepInterview 审计限制GrillKit 审计限制)。

C. 怎样判断它是否真的靠谱并可持续经营

结论:“靠谱”至少有四种,必须分别测量、分别处置;可持续经营还要求题库、模型、供应商、申诉和成本形成固定节奏。 系统可用只说明用户大多能完成流程;回答质量说明问题与反馈是否有用;评分可信说明证据能否稳定映射到共同标尺;公平合规说明技术误差、数据处理和使用方式是否合理。一个维度达标不能替代另一个维度。

C.1 四种靠谱:指标必须连接异常动作

下表所有数值均为 【建议初始目标】,不是两个参考项目的实测结果。P95 表示 95% 的请求应快于该值,用于观察少数用户遇到的长等待;正式阈值必须用试点、压测、校准和法律审查修订。

先判断什么 持续看哪些信号 越界后立即采取什么行动 何时允许恢复
系统可用 API 月可用性 99.9%;会话建立成功率不低于 99.5%;已确认答案丢失数 0;重复计费数 0;说完到首个回应 P95 不高于 1.5 秒 切文本或异步评分;熔断故障供应商;暂停新会话;核对受影响场次 探针、小流量和恢复演练通过,错误预算回到计划内
回答质量 结构化输出成功率不低于 99.5%;引用可定位率 100%;严重无依据主张率低于 0.5%;人工抽检可执行反馈通过率不低于 90% 隔离问题或提示词版本;撤回无依据反馈;切换已验证模型 固定质量集和线上抽样重新达标
评分可信 确定性字段一致率 100%;100% 分项分数附证据与覆盖状态;重复运行跨越两个等级的比例低于 1%;核心 rubric 达到预登记人工一致性门槛 停止展示受影响分数;扩大人工复核;回滚评分版本 双评校准、题族切片和版本对照达到预登记门槛
公平合规 技术故障导致自动低分数 0;低置信转人工或核对率 100%;删除请求在承诺期限内完成率 100%;跨租户泄漏数 0;关键群体误差低于预登记门槛 暂停相关语言、题型或用途;提供文本替代、重新评估和通知;启动法律或安全流程 受影响结果纠正,独立复核确认风险降到允许范围

每类指标都要有负责人、看板和停用开关。总体满意度不能掩盖某个语言持续受损,低投诉也不能证明公平,因为受影响者可能不会申诉。样本不足时必须显示“尚不足以判断”和置信区间,不能把空白单元格涂成绿色。

C.2 从指标到经营节奏:把线上信号变成下一版改进

结论:上线后最重要的能力,是稳定地把故障、申诉和质量样本变成可验证改进。 日常循环应是“收集信号 → 归因 → 版本化修改 → 离线验证 → 小流量发布 → 观察 → 扩大或回滚”。每次变化都记录原因、负责人、审批人、评测结果、发布时间和回滚位置。

持续经营什么 平时采取什么动作 变更前必须拿出什么 发布后重点观察什么
题库 新题编写、旧题复审、难度与覆盖分析、泄露处置、本地化 岗位相关说明、rubric、参考答案;编码题正确解全过且代表错误解失败 完成率、用时、跳题、分布、申诉和异常相似答案
Rubric 补充可观察信号、等级锚点、反例和证据不足条件 至少两名受训评审独立标注并仲裁,达到预登记一致性 人工改判率、等级混淆、低覆盖和切片误差
模型与提示词 评估新版本、固定参数、维护已校准备份 golden set、注入、安全、成本、延迟和公平性切片通过 超时、格式失败、无依据主张、分数漂移和单场成本
质量样本 收集获准真实样本、合成边界样本、故障样本和人工标准 来源、许可、去标识、岗位与语言标签完整;训练和测试隔离 样本覆盖缺口、评审分歧和新场景退化
反馈与申诉 接收转写纠错、解释请求和正式申诉,追踪根因 处理时限、证据访问权限、升级标准和批量影响查询 处理时间、成立率、改判原因和重复问题
供应商与成本 对账调用、质量、区域、失败、账单与替换能力 数据条款、限流、预算、版本通知、退出和迁移方案 每场分项成本、重试浪费、集中度、降级率和账单差异
发布节奏 合并变更、影子验证、小流量、逐级放量和回滚 自动回归通过;高风险专项审查;完整发布清单与回滚包 SLO、质量、分数分布、申诉、人工积压和版本采用率

【建议初始目标】 题库和 rubric 至少每季度系统复审一次,高使用量题目每月抽检;模型或提示词每次变化都运行固定质量集,不跟随供应商默认日期自动升级;线上样本每周抽取;重大申诉在 1 个工作日内确认受理、5 个工作日内给出初步结论;供应商质量与成本每周对账,至少每季度演练一次备用路径;常规发布采用每两周一个可回滚窗口,高风险评分变化单独发布并延长观察。所有频率和时限均为建议初始目标,应按业务量、适用法律和团队能力调整。

一次发布不是换一个模型名称,而是形成不可变的发布清单:题库 release、rubric、模型、提示词、转写供应商、规则、数据结构、评测报告、已知限制和回滚位置。变更先绑定真实问题或样本;自动检查状态、权限、幂等和历史兼容;再跑 golden set 与公平性切片;随后进入影子流量或小流量。异常指标越界就回滚,旧场次保留原版本,新结果以修订存在,绝不静默改写历史。

C.3 把申诉、供应商和成本当作产品传感器

结论:申诉不是外围客服,供应商也不是不可见黑盒;它们都是质量和经营风险的实时传感器。 转写纠错集中在某类口音,可能说明 STT 质量退化;同一道题经常被误解,可能是题面含糊;人工频繁把三级改为二级,可能是 rubric 锚点不清;某区域晚间超时,可能是容量或路由问题。

每条反馈要归因到材料解析、题目、追问、转写、代码执行、模型、rubric、规则、报告展示、数据权利或系统故障。处理结果保留原始与修订结果、证据、责任人和影响版本。同一根因影响多场时,应主动查找范围并批量纠正,而不是等待每个人分别投诉。人工复核者看到题目、rubric、回答证据、技术状态和版本,不能只看到模型总分后进行确认式点击。

供应商看板按 provider、模型、区域、语言和 release 展示调用量、超时、P95/P99、结构成功率、fallback 去向、单位成本和版本启停时间。供应商价格具有时效性,当前报告不虚构单价;PoC 后按实际报价和压测填写 100、1,000、10,000 场三档成本模型。成本异常可能来自重试放大、上下文过长、未取消的语音合成或人工复核积压,不能只看每百万 token 的标价。

C.4 用同一张表决定可扩量、暂缓还是回滚

结论:扩量应采用“关键条件全部满足”,不能让漂亮的加权平均抵消一项高风险失败。

当前观察到什么 现在采取什么决定 接下来必须完成什么
连续两个观察窗口达到核心 SLO;当前 release 的状态、证据、安全和 golden 门禁全过;可靠评分覆盖没有下降;关键切片达标;人工与成本有余量;2 倍目标峰值演练通过 可扩量:按预先设定阶梯逐步增加流量,不一次全开 继续观察最差切片、错误预算、申诉、人工积压与单位成本;保留随时回滚能力
系统基本可用,但样本量不足、评分可信未达门槛,或只在部分语言/岗位稳定 暂缓正式扩量:可增加内部或影子流量;按能力矩阵限制语言、岗位或题型 补样本、校准 rubric、修复题库或供应商路径;达到预登记门槛后重新评审
出现跨租户数据问题、样例混入正式结果、技术故障导致自动低分、隐藏测试泄露、严重评分漂移、未关闭 P0/P1,或错误预算快速燃烧 立即回滚或停用相关能力:先停止结果发布和下游消费,再保全证据 列出受影响场次,通知、复核、重算或撤回;完成根因修复、回归和小流量验证后再恢复
SLO 达标,但每场成本、重试放大或人工复核积压不可持续 冻结流量:不以技术可用掩盖经营不可持续 调整上下文、模型路由、缓存和复核门槛;完成成本对账与容量验证
总体指标正常,但某个关键语言、设备或合理便利切片显著越界 缩小适用范围:暂停受影响切片,其他已验证范围可维持 提供文本替代或重新评估,扩大该切片样本,完成独立公平性复核

仪表盘至少回答五个问题:用户是否顺利完成;证据是否足够;评分是否仍对齐共同标尺;故障影响是否受控;单位成本和人工量是否可持续。每张决策卡同时显示当前值、建议初始目标、7/28 天趋势、最大异常切片、数据完整度和当前 release。只看均值会掩盖尾部,只看总量会把流量变化误认为质量变化,只看技术成功率会忽略错误结论。

C.5 最终经营判断

结论:可持续经营的对象不是某个模型,而是一套能发现、止损、恢复和变好的制度。 发现依赖贯穿整场的追踪标识、每项结论的来源记录和按语言、岗位、设备拆分的指标;止损先暂停有风险的结果,再熔断故障能力、保存已提交事实并透明降级;恢复先探针、再小流量、再逐级放量,对待处理任务幂等重放,对错误结果版本化撤回;变好则把事故、申诉、人工推翻和高分歧样本变成获准、去标识、有用途限制的测试资产。

【事实】 两个固定项目提供了准备、实时、会后、状态机、快照、结构化评分和代码执行边界等可复用切片;它们没有证明真实模型与语音质量、生产安全、容量、成本、招聘效度或公平性。【建议】 因此首版应在自主练习范围内建立证据闭环和运营闭环。招聘评估只能作为独立 Go/No-Go:岗位效度、法律审查、候选人通知、合理便利、人工复核、申诉和独立公平性评估任一缺失,都应暂缓。

2. 证据边界与引用约定

一级证据入口为 DeepInterview 静态证据审计GrillKit 源码证据审计,二级证据为两个固定仓库源码。本章不使用浮动分支,也不把后续状态倒推到上述 HEAD。

【事实】 DeepInterview 实际通过的仅有 Python compileall、setup Bash 语法和基础 Compose 配置解析;其 pytest、Vitest、build、真实媒体与供应商链路未运行。GrillKit 实际通过 Python compileall 和 101 个 YAML 解析;pytest、Ruff、mypy、容器、Judge0、真实模型和语音未运行。测试文件数量、CI 配置和 README 的绿色描述只能说明存在资产或作者宣称,不能写成“本次测试通过”。

【建议】 每个输出强制记录 content_state(real/mock/degraded/sample)、provider、model、prompt/rubric version、question-bank version、locale、coverage 和时间。页面、导出及分析必须携带同一 provenance,sample/mock 在数据层禁止进入正式统计。

3. 两项目值得借鉴与不可照搬

DeepInterview

值得借鉴:

  • 【事实】 prep/live/post 三段以 InterviewContext 串联;Prep 并行处理 CV、JD 和公司资料,再执行 gap matching 与选题(prep graphshared models)。
  • 【事实】 LLM 输出之外保留确定性不变量:competency 绑定计划目标,分数限制在 0–5,level 由数值派生;未答题被跳过并由 coverage 表达,而非误记零分(evaluator)。
  • 【事实】 单题失败隔离;无答案标记 no_answers 且不落虚假零分报告;同进程有 session 评分锁和完成态短路(post pipeline)。
  • 【事实】 SessionGuard 限制时长/turn,TranscriptFlusher 周期保存,体现实时链路的崩溃恢复意识(guardflusher)。

不可照搬:

  • 【事实】 INTERNAL_API_SECRET 为空时写端点不鉴权,读端点依赖不可猜 session id;这是本地便利,不是公网授权模型(auth)。
  • 【事实】 缺 key/未知 provider 可回 MockLLM,报告页又存在 sample fallback,生产会有结果真实性风险。
  • 【事实】 Supabase answer append 为 read-modify-write,评分锁仅限单进程,多实例可能丢更新或重复计费。
  • 【事实】 CV URL、JD、context、transcript、scorecard 可持久化,但未见完整 retention、用户导出/删除、字段级加密与录音同意。

GrillKit

值得借鉴:

  • 【事实】 session/section/task 状态机明确,四种 session mode 决定阶段顺序,生命周期不由 LLM 决定(session phasescreate session)。
  • 【事实】 题目、rubric、task spec 与回答随会话快照,题库更新后仍可解释历史结果(models)。
  • 【事实】 Pydantic schema、JSON 解析与重试比自由文本评分稳健;领域事件与 WebSocket 协议分离(structured evaluation)。
  • 【事实】 返回客户端前移除 hidden tests 和 public expected output,方向正确(task spec)。
  • 【事实】 Whisper 模型采用 staging、校验和原子 promote,适合大型资产安装(Whisper gateway)。

不可照搬:

  • 【事实】 判题框架存在不代表题库成熟;当前 44 道编码题均无真实 public/hidden tests。
  • 【事实】 项目无认证且 Compose 发布 8000;审计未发现完整 CSRF、WebSocket Origin、TrustedHost 和 CSP 防护。
  • 【事实】 默认 root 路径在 migration 前 exec gosu,后续 migration 不可达(entrypoint)。
  • 【事实】 Judge0 server/worker 使用 privileged,示例密码不适合共享网络;Monaco 从 CDN 加载且无 SRI。
  • 【事实】 API key、答案、代码和输出可明文落盘;音频路由一次性读取上传文件且未见路由级体积限制。

4. 横向比较表

维度 DeepInterview GrillKit 产品结论【建议】
定位 CV/JD 定制的语音模拟 本地理论+编码训练 首版只做自主练习
编排 prep/live/post、LangGraph 确定性状态机 状态机主导,LLM 只做受约束语义任务
语音 LiveKit、多 STT/TTS Whisper/Piper、本地音频 语音可选,文本必须可降级
编码 角色问答为主 Judge0 Run/Submit 框架 确定性测试优先,AI 反馈辅助
评分 competency、coverage、报告 1–5 分、追问、总评 分数附证据、覆盖率、版本和不确定性
数据 Memory/Supabase SQLite/SQLAlchemy/Alembic 不可变快照、事务、幂等、删除链
已验证范围 三项轻量静态/配置验证 compileall 与 YAML 解析 必须自建完整质量门禁
关键缺口 provenance、真实语音、治理、跨实例一致性 无真实测试题、迁移缺陷、共享部署风险 Beta 前关闭安全、内容、校准问题

4A. 推荐技术蓝图

本章给出拟建系统的目标技术形态,避免与后文用途、合规、团队和交付路线重复。【事实】 DeepInterview 提供 prep/live/post、实时媒体与 InterviewContext blackboard 的可复用切片;GrillKit 提供确定性 session/section/task、题目快照、领域事件、结构化评分与 Judge0 边界的可复用切片。【未验证】 两个固定 HEAD 均未完成真实 LiveKit、STT/LLM/TTS、完整 RAG、Judge0、生产数据库和端到端容量验证。【建议】 组合两者的边界,而不是复制任一默认部署:状态机与数据库控制事实,LLM 只承担受约束的语义任务,实时媒体、长任务、代码执行和数据存储分成独立故障域。

4A.1 总体组件架构

组件架构交互图(本地嵌入)单独打开/打印
flowchart LR
    U["候选人 Web / Mobile"] --> EDGE["Gateway / Auth / Rate Limit"]
    ADMIN["题库与运营后台"] --> EDGE
    subgraph CONTROL["控制面"]
        API["Session API"]
        SM["State Machine"]
        PREP["Prep Orchestrator"]
        POST["Post Orchestrator"]
        BANK["Question Bank"]
        REG["Provider Registry"]
    end
    subgraph LIVE["实时面"]
        RTC["WebRTC / LiveKit"]
        VOICE["Voice Worker"]
        VAD["VAD + Turn Detector"]
        STT["Streaming STT"]
        LLM["Low-latency LLM"]
        TTS["Streaming TTS"]
    end
    subgraph ASYNC["异步与隔离执行"]
        Q["Durable Queue"]
        RAG["RAG Workers"]
        SCORE["Scoring Workers"]
        JG["Judge0 Gateway"]
        J0["Isolated Judge0"]
    end
    PG[("Postgres")]
    OBJ[("Object Storage")]
    VEC[("Knowledge Store")]
    REDIS[("Redis")]
    OBS[("Metrics / Logs / Traces")]
    EDGE --> API --> SM
    SM --> PREP
    SM --> POST
    PREP --> BANK
    PREP --> Q
    POST --> Q
    Q --> RAG --> VEC
    Q --> SCORE --> PG
    API --> PG
    API --> OBJ
    U <--> RTC <--> VOICE
    VOICE --> VAD --> STT --> LLM --> TTS --> VOICE
    VOICE --> PG
    VOICE --> REDIS
    VOICE --> REG
    API --> JG --> J0
    JG --> PG
    CONTROL --> OBS
    LIVE --> OBS
    ASYNC --> OBS

【建议】 Session API 是鉴权后的命令与查询入口;State Machine 是会话状态唯一写入者;Prep/Post 承担可重试长任务;Voice Worker 只持有短生命周期上下文并写 committed turn;Judge0 Gateway 隔离内部测试与客户端安全视图;Provider Registry 根据能力、语言、地区、数据政策、健康度、成本和超时路由。Postgres 保存事务事实,对象存储保存大对象,Redis 只承载短期 lease/presence/cache,知识库按 tenant 与 session 强制分区。异步任务通过事务 outbox 发布,避免数据库已提交而事件丢失。

4A.2 Prep / Live / Post

Prep。【事实】 DeepInterview 的 prep 图并行处理 CV、JD 和公司资料,汇合后做 gap matching 与 question planning(prep graph);CV 解析支持文本、data URL 和远程 URL,因此也存在 SSRF、重定向、体积与恶意文档风险。【建议】 Prep 分为接收与隔离解析、结构化抽取、差距分析、题目规划、快照发布。解析层先做 MIME、页数、解压体积、跳转、DNS/IP 和恶意载荷检查;最终 PlanSnapshot 固定题库 release、question revision、rubric、locale、citation、provider 和模型版本。输入无效进入拒绝态,外部服务局部失败进入 degraded 态,不能静默回 mock 后继续标记为真实结果。

Live。【事实】 DeepInterview worker 从房间元数据解析 session id,经 API 取得已准备 context,构造 VAD/STT/LLM/TTS 的 AgentSession,捕获 committed transcript,并用 guard 限制会话(live worker)。GrillKit 的 section、timer 和追问深度由服务端领域规则约束。【建议】 Live 只读不可变 plan snapshot;partial transcript 仅用于即时界面,只有 turn.committed 才是评分事实。语音、文本和代码统一抽象为 Attempt,但媒体、代码与执行结果分开存储。题目计时、追问、section 切换和结束必须由服务端验证,前端不可自行宣告完成。

Post。【事实】 DeepInterview 对已回答题执行有界并发评分,未答题不记零分而由 coverage 表达;competency 绑定计划目标,分数限制和 mastery band 由代码确定(post evaluator)。【建议】 Post 先冻结 transcript/attempt 输入哈希,再并行执行 rubric 评分、语言分析、代码信号汇总、引用核验和报告生成。报告显示 coverage、degraded reason、题库/rubric/prompt/provider/model 版本和证据片段。无有效答案返回 NO_EVIDENCE,不得产出貌似精确的低分画像;同一输入哈希和 rubric 版本只允许一个评分结果生效。

4A.3 会话状态机

会话生命周期交互图(本地嵌入)单独打开/打印
stateDiagram-v2
    [*] --> DRAFT
    DRAFT --> PREP_QUEUED: submit_prep
    PREP_QUEUED --> PREPARING: worker_claimed
    PREPARING --> PREP_REJECTED: invalid_input
    PREPARING --> PREP_DEGRADED: partial_failure
    PREPARING --> READY: plan_published
    PREP_DEGRADED --> READY: accept
    PREP_DEGRADED --> PREP_QUEUED: retry
    PREP_REJECTED --> DRAFT: revise
    READY --> CONNECTING: join
    CONNECTING --> LIVE: media_ready
    CONNECTING --> READY: connect_failed
    LIVE --> RECONNECTING: transport_lost
    RECONNECTING --> LIVE: resumed
    RECONNECTING --> DRAINING: reconnect_timeout
    LIVE --> DRAINING: finish_or_guard
    DRAINING --> POST_QUEUED: checkpointed
    POST_QUEUED --> SCORING: worker_claimed
    SCORING --> REPORT_DEGRADED: partial_failure
    SCORING --> COMPLETED: report_committed
    REPORT_DEGRADED --> COMPLETED: accepted_or_repaired
    COMPLETED --> [*]

【建议】 每次状态迁移携带 expected_version,数据库执行 compare-and-swap;版本不匹配返回冲突,不重复调用外部服务。DRAINING 停止发新题,但允许已承诺音频、transcript、usage 和最终 checkpoint 落盘。Section 子状态使用 PENDING → ACTIVE → EVALUATING → COMPLETED|SKIPPED,Attempt 子状态使用 CREATED → ANSWERING → SUBMITTED → EVALUATING → SCORED|FAILED|TIMED_OUT。LLM 输出永远不能直接修改这些状态。

4A.4 实时语音、barge-in、延迟预算与降级

实时语音轮次时序图(本地嵌入)单独打开/打印

【事实】 DeepInterview 使用预热 Silero VAD;可支持语言使用 multilingual turn detector,其他语言回退静音 endpointing;barge-in 要求已形成转写词后才确认中断,以减少背景噪声切断面试官(turn handling)。BVC 降噪是显式 opt-in。审计没有得到真实口音、噪声、设备和供应商延迟数据。

【建议】 链路为浏览器音频帧 → WebRTC → 降噪/增益 → VAD → streaming STT → semantic turn detector → LLM preemptive generation → streaming TTS。候选人开口时先降低播放音量;达到 VAD/STT 门槛后取消当前 generation、清空未播放 TTS buffer,记录 assistant.interrupted 及已播放区间。所有 token、音频块和取消操作携带 generation id,防止上一轮迟到结果污染新轮。

下表全部是建议初始目标,不是两个仓库的实测结果:

环节 建议初始目标
浏览器到 VAD 可用帧 P95 不高于 80 ms
VAD 起音检测 P95 不高于 120 ms
首个 STT partial P95 不高于 300 ms
语义端点判定 P95 不高于 450 ms
LLM 首 token 云端 P95 不高于 600 ms;本地热模型 P95 不高于 1200 ms
TTS 首音频块 P95 不高于 350 ms
用户结束到助手首音 P95 不高于 1.5 s,P99 不高于 2.5 s
barge-in 停声 P95 不高于 250 ms
transcript checkpoint 每 2 个 committed turn 或 5 s,取先到者

【建议】 指标按语言、设备、网络、provider 与冷热状态分桶。语义 turn detector 失败时降为静音 endpointing;主 STT 失败切备用或文本输入;TTS 失败继续显示文本;LLM 超时执行受限重试或备用模型;仍失败则透明暂停或结束。任何降级都写入 provenance,Judge0、RAG 或评分供应商失败不得被伪装成正常完成。

4A.5 RAG 与知识边界

【事实】 DeepInterview 在未配置远程知识服务时使用 deterministic MockKnowledge,配置后调用 HTTP sidecar;sidecar 默认 NaiveRAG,可选完整 LightRAG。Prep 以 session id ingest CV/JD/company,Coach 使用同一 session 查询(knowledge adapterRAG backend)。完整后端与真实质量未验证。

【建议】 划分 candidate_private/{tenant}/{session}question_bank/{release}company_public/{snapshot},查询必须携带 tenant filter,禁止跨租户联合召回。文档记录 source URI、内容哈希、解析器版本、chunk span、embedding 版本、许可与 retention;召回结果返回 citation、chunk id、分数和索引版本。题目生成优先遵循结构化 CV/JD 与题库约束,检索文本不能覆盖系统规则。建议初始目标:RAG 查询 P95 不高于 250 ms、top-k 为 6、单次注入总预算不高于 8,000 tokens;RAG 失败时允许使用已发布计划,但明确标记未增强。

4A.6 题库、编码与 Judge0

【事实】 GrillKit 对题目、rubric、starter code 和 task spec 做会话快照,客户端序列化会移除 hidden tests 与公开测试 expected output(task spec)。Judge0 gateway、Run/Submit 和 compile/test 流程存在;但固定题库 44/44 道编码题都是 AI 模式,tests 模式为 0、public tests 为 0、hidden tests 为 0,因此当前题库实际是 compile-only 加 AI 评价,不是已具备真实公开/隐藏测试的判题产品。

【建议】 题库采用 Question → Revision → Locale → Rubric → TestSuite 的不可变 release。创建 session 时快照用户可见内容和版本;hidden tests 只保存受限引用,不进入通用 session JSON、客户端、日志、备份导出或 LLM prompt。发布流水线校验 schema、唯一 ID、本地化完整性、reference solution、错误解法、资源上限、输出规范化和客户端泄漏。

【建议】 Judge0 经独立 Gateway 按题库版本补齐测试,执行节点放在专用 VM/节点池,默认无外网、无生产秘密、与 API/数据库隔离,不复用 GrillKit 的 privileged 共享部署。以下均为建议初始目标:执行队列等待 P95 不高于 1 s;单测试 CPU 不高于 3 s、墙钟不高于 5 s、内存不高于 128 MiB、输出不高于 64 KiB;每会话并发执行数为 1;每题 Run 上限为 20 次。具体限制须按语言和题型压测后修订。

4A.7 评分证据链

【建议】 评分融合理论 rubric、答案证据、追问表现、确定性测试、代码工程质量和语言报告;语言流利度不经岗位效度与公平性校准,不进入技术总分。每条 ScoreEvidence 保存 question revision、answer/turn span、test result hash、rubric、provider/model/prompt 版本、原始结构化输出、代码规则调整和最终分。确定性测试优先于模型印象,隐藏测试失败导致的分数上限由服务端代码执行,不能只写在 prompt。

【事实】 DeepInterview 已把 competency identity、分数范围、mastery band 和 coverage 作为代码不变量;GrillKit 通过 Pydantic schema 与 JSON 重试约束模型输出,但两者都没有证明招聘效度或跨语言公平性。以下均为建议初始目标:单 worker 逐题评分并发为 4;单题超时不高于 20 s;报告生成 P95 不高于 60 s;结构化解析成功率不低于 99.5%;确定性字段在重复输入下的一致率为 100%。人工一致性、公平性 slice 与置信区间须由真实校准集建立门槛,不能预设为已达标。

4A.8 数据模型

【建议】 核心实体为:InterviewSession(state, version, mode, locale, plan_snapshot)Section(kind, order, state, time_budget)QuestionRevision(locale, rubric, content_hash, bank_release)Attempt(round, status, idempotency_key, input_hash)TranscriptTurn(sequence, speaker, committed, timestamps, provider)CodeSubmission/TestRunScoreEvidence/ScoreCardKnowledgeDocument/ChunkProviderCallDomainEvent/Outbox。PII 与面试事实分离,录音和大文档进入对象存储,主库保存短期引用、哈希、owner、purpose、region 和 retention 标签。

【事实】 DeepInterview 的 Supabase append_answer 是 context read-modify-write,多 worker 下存在 lost update 风险(repository);其同进程评分锁也不能跨实例互斥。GrillKit 的题面与 task spec 快照可保持历史可解释(models)。【建议】 Answer 与 Transcript 使用 append-only 行和单调 sequence,blackboard JSON 仅作读模型;状态表使用版本列,所有删除覆盖主库、对象存储、RAG、缓存和分析副本。

4A.9 API、事件与 Provider Protocol

【事实】 DeepInterview 提供 prep、session、live result、score 和 KB API;GrillKit 的领域服务产生 AnswerSaved、Evaluating、Transcript、AnswerFeedback、InterviewCompleted,再映射为 WebSocket 消息(wire protocol)。这种领域事件与传输协议分离的做法值得保留。

【建议】 命令面包含创建 session、发起 prep、申请短期房间 token、提交 attempt、运行代码、结束 session;每个写请求携带 Idempotency-Keyexpected_version。查询面提供 session、plan、实时投影、operation 和 report。事件 envelope 统一包括 event id/type、schema version、aggregate id/version、correlation/causation id、occurred_at、producer 和 payload;公开投影不得包含 hidden tests、密钥或无限制 prompt。

【建议】 Provider Protocol 按能力拆为 LLM.complete/streamSTT.streamTTS.streamEmbedding.embedSearch.searchKnowledge.ingest/queryCodeExecutor.run。请求统一携带 deadline、cancel token、tenant/session/turn id、locale 与 data policy;返回 usage、latency、provider request id、model version、finish reason、retryability 和 provenance。业务节点只依赖协议,不内嵌厂商条件分支。

4A.10 并发、幂等与一致性

【建议】 会话状态使用 optimistic version;Attempt 使用 (session_id, question_revision_id, round) 唯一约束与幂等键;外部昂贵任务使用 durable queue lease。采用 at-least-once 事件投递加幂等消费者,以数据库唯一键实现 exactly-once effect,而不宣称无法证明的 exactly-once delivery。事务 outbox 保证事实写入与事件发布可恢复,consumer inbox 防止重放。

以下均为建议初始目标:同一 session 同时只有 1 个 live lease;版本冲突返回 409 且外部副作用为 0;队列最多重试 3 次并指数退避;熔断观察窗口为 30 s;最终 checkpoint 的 RPO 不高于 5 s;控制面 RTO 不高于 15 min。单题失败不得清除其他结果,评分全失败进入 degraded,而不是写成完整零分;生产不得自动回 MockLLM 后输出 real 标记。

4A.11 前端边界与多语言

【建议】 前端负责设备权限、波形、partial transcript、断线重连、编辑器草稿、反馈解释和无障碍;后端负责 token、owner/tenant 授权、timer、状态迁移、attempt 接受、题库可见性和评分。浏览器中的倒计时、“已提交”和 partial 文本均为 optimistic projection,最终由服务端 committed event 校正。Monaco 等执行界面资源自托管并固定哈希,不沿用无 SRI 的动态 CDN。

【事实】 DeepInterview 按 primary language 路由实时 STT/TTS,但语义 turn detector 覆盖有限;GrillKit 的题库 locale 缺失时回退英语。【建议】 分离 ui_localequestion_localecandidate_speech_localevoice_localeevaluation_locale,每次 fallback 写入 provenance。以下均为建议初始目标:正式 locale 的核心 UI 文案覆盖率为 100%;题目与 rubric 成对发布覆盖率为 100%;fallback 率低于 1%。WER/CER 不设置无数据承诺,先以许可媒体集按语言、口音、设备和噪声建立基线。

4A.12 基础设施与可观测性

【建议】 部署划分 edge、control、realtime、async、sandbox、data 安全域。Web/API/worker 非 root、只读文件系统、固定镜像 digest;Judge0 位于独立节点并默认断网;Postgres 保存事务事实,Redis 不作为事实源;对象存储使用短期签名 URL;向量查询强制 tenant namespace。生产启动 fail closed:认证、迁移、secret、数据库、对象存储或 provider policy 缺失时拒绝相应能力,禁止沿用 trust-the-network。

可观测性以 session trace 串联 prep operation、媒体房间、turn、provider call、Judge0 submission、score job 与 outbox。指标包括状态冲突、队列时延、音频 jitter/丢包、VAD false-start、STT partial/final latency、turn endpoint、LLM TTFT、TTS TTFB、barge-in、provider timeout/retry/circuit、usage/cost、Judge0 queue/run、coverage、degraded rate、数据库冲突和 outbox lag。日志默认不保存 CV、JD、transcript、代码、prompt 与 API key;受控调试也要脱敏、抽样和短保留。

以下均为建议初始目标:API 可用性为 99.9%;实时会话建立成功率不低于 99.5%;未解释 live 中断率低于 1%;状态事件到查询投影 P95 不高于 2 s;outbox lag P95 不高于 5 s;trace 关联完整率不低于 99%;敏感字段自动扫描泄漏数为 0。目标在 PoC 压测和真实错误预算形成后修订,不能倒写成固定仓库已有能力。

5. 候选人练习与招聘评估边界

【建议:练习范围】 用户自主选择岗位、上传或粘贴材料、完成模拟问答/编码并获得形成性反馈。可以展示能力维度、回答证据、覆盖率、改进建议和示例答案,但应称“练习反馈”,不宣称录用概率或代表雇主标准。简历不是必填,练习数据默认不流向招聘客户,也不得未经独立同意进入训练集。

【建议:招聘评估范围】 一旦结果被雇主用于筛选、排序、淘汰或晋级,即进入高风险评估。必须另行定义适法基础、候选人通知、岗位相关性、合理便利、人工复核、申诉纠错、地域与保留策略、子处理商和客户合同。自动分不得成为唯一不利决定依据;低覆盖、技术故障、低 STT 置信或模型异常应自动转人工,而非判低分。

禁止用练习次数、付费状态、摄像头质量、背景噪声、口音、停顿、面部或情绪推断等缺乏岗位效度的信号评分。

明确排除真实面试作弊

【建议/硬边界】 不构建、不宣传、不支持:隐蔽监听真实第三方面试并实时生成答案;不可见提词器或绕过屏幕共享;冒名代答、声音/人脸伪造;规避监考或身份核验;窃取、重建或泄露雇主隐藏题库。实时音频只能用于产品内明确标识的模拟房间。营销、客服、模板和滥用处置必须保持一致。

6. 产品与合规准备

【建议】 建立“用途—数据—决策”登记:谁发起、数据来源、进入哪些模型、保存多久、影响谁、是否产生不利决定。上线前由适用司法辖区律师复核劳动、隐私、自动化决策、录音/生物识别和消费者保护要求;本章不构成法律意见。

最低准备包括:候选人和企业客户两套条款;隐私通知与子处理商清单;DPA;录音/转写单独提示;数据下载、删除、纠错与撤回入口;无障碍文本替代;人工复核和申诉 SLA;安全事件流程;模型/题库变更记录;禁止作弊与禁止高风险推断政策。

生产配置必须 fail closed:认证、持久化、provider、对象存储或区域策略缺失时拒绝启动相应能力,不得回 mock 后继续产生正式分数。样例只存在演示 tenant。

7. 隐私、安全威胁模型与数据治理

资产/入口 威胁 控制【建议】
CV/JD/逐字稿/录音/分数 越权、URL 泄露、日志与存储误配 user/tenant 授权、短签名 URL、加密、默认不留原音频
API 与模型额度 空 secret、重放、批量消耗 OIDC/JWT、RBAC、幂等键、限流、预算熔断
URL/文件导入 SSRF、DNS rebinding、恶意 PDF、压缩炸弹 禁私网/metadata、逐跳重验、egress proxy、大小/MIME/页数限制、隔离解析
Prompt/RAG 文档注入、秘密外带、评分操纵 输入视为不可信、工具 allowlist、秘密不入 prompt、schema 与引用隔离
WebSocket/媒体 Origin 欺骗、token 泄露、会话接管 WSS、Origin/Host allowlist、短期单房间 token、重放保护
代码执行 容器逃逸、挖矿、内网扫描 专用 VM/节点、无外网、只读根、seccomp/cgroup、销毁 workspace
隐藏测试 客户端、日志、备份、内鬼泄露 独立加密、最小权限、client contract test、审计和轮换
供应链 latest 镜像、CDN、非 frozen 安装 digest/hash pin、SBOM、签名、自托管静态资源、扫描
一致性 重连重复提交、lost update version/ETag、事务 append、outbox、分布式锁

【建议:数据治理】 数据至少分为账户信息、职业材料、面试内容和派生评分四级;每个字段登记目的、来源、tenant、区域、保留期、接收方、训练资格和删除路径。原始音频默认只用于实时转写;需回放时单独选择。删除覆盖主库、对象存储、RAG 索引、缓存、分析仓及备份到期清除,并提供状态、重试和完成凭证。训练用途必须独立 opt-in、去标识、授权审查且可撤回。生产数据禁止复制到个人调试环境。

8. 公平性与评分校准

【事实】 DeepInterview 有分数范围、competency identity 和 coverage 的代码约束,GrillKit 有结构化 schema;两份审计均未证明招聘效度、公平性、跨语言一致性或真实媒体质量。结构化输出不等于可信评分。

【建议】 评分对象应是“在给定岗位相关题和 rubric 下展示的可观察证据”,而非候选人整体。报告展示题目/rubric/模型版本、证据片段、规则信号、覆盖率和人工修改。禁止以受保护属性及其代理变量评分;STT 低置信时允许核对转写,以文本修正为准。

校准集覆盖岗位、级别、题型、语言、口音、回答长度、设备/噪声和合理便利;每条由至少两名受训领域评审独立标注并仲裁。按候选人和题族隔离数据集,避免泄漏。指标至少包括人工一致性、相邻等级准确率、重复运行方差、缺失处理、覆盖率、各群体误差与置信区间。样本不足只能报告证据不足,不能宣称“无偏”。模型或 prompt 升级必须通过固定 golden set 回归。

9. 测试矩阵与质量门禁

层级 必测内容 门禁【建议】
静态/供应链 lint、type、secret、SBOM、许可证、锁文件 高危秘密、关键漏洞、非固定生产依赖阻断
单元/属性 状态机、timer、score clamp、coverage、权限 关键不变量全过并 fuzz/property test
题库 schema、ID、locale、rubric、golden、错误解法 tests-mode 题 golden 全过、代表错误必须失败
API/并发 schema、幂等、重放、版本冲突 不重复计费/写入;客户端无 hidden expectation
迁移 空库、升级、备份恢复 自动到 head,数据与约束一致
E2E setup→回答→报告→导出/删除、断线 无 sample 混入真实结果,断线不丢已确认答案
媒体 噪声、口音、静音、barge-in、设备切换 失败可转文本,转写可纠错
模型 golden、注入、长输入、语言/公平性 slice 不达门槛则不评分或转人工
安全 IDOR、SSRF、CSRF/Origin、上传、沙箱、限流 P0/P1 未关闭不得 Beta/生产
性能/灾备 p95/p99、峰值、超时、故障注入、恢复 达 SLO;删除、密钥轮换、RPO/RTO 演练通过

当前两个仓库的轻量检查只能作为输入,不构成上述门禁已经满足。

10. 团队、硬件、API 与数据集准备

【建议:团队】 覆盖产品、前后端/平台、实时音频、ML 评估、数据、安全、隐私/法务、招聘测量、题库内容、QA/SRE、无障碍和用户研究。PoC 可兼任,但安全、法务和评分效度不能由实现者自审自批。

【事实】 DeepInterview 本地 profile 包含 qwen3:8b、Whisper、Kokoro;GrillKit 的 Whisper 规格约 0.5/1.5/3 GB,Piper 单 locale 约 60 MB 的数字来自项目材料,审计没有运行性能验证。

【建议:硬件】 CI 使用无 GPU mock 和录制 fixture;媒体环境准备 Linux CPU 节点、真实设备矩阵与网络整形。本地 8B 模型可先用约 24GB VRAM 的单卡作为基准候选,但并发必须压测后承诺。代码沙箱与应用、数据库、秘密隔离到专用 VM/节点。

【建议:API】 LLM、STT、TTS、媒体、存储、搜索和认证均准备 sandbox/production 双账户,登记区域、保留、训练使用、限流、SLA、DPA 和退出能力。STT 失败转文本、TTS 失败显示题目、搜索失败不阻断、评分失败保存答案后异步重试。密钥只进 secret manager。

【建议:数据集】 准备版本化题库/rubric、人工校准集、媒体质量集和安全对抗集。编码题必须有 golden solution、public/hidden cases、错误解法及资源预算。记录来源、许可证、PII、岗位范围和禁止用途。

11. 成本、容量与 Build vs Buy

【建议】 单场成本按 prep LLM + live LLM + STT 分钟 + TTS + post 多题评分 + 搜索/RAG + 媒体房间 + 存储/出网 + 沙箱 + 可观测性 + 人工复核 建模。峰值并发房间约为“峰值每小时到达量 × 平均会话分钟 ÷ 60”;评分容量由题数、调用时延、provider 并发和报告时限决定。设置 session 时长、turn、题数、上传、Run 次数、tenant/provider 月预算和重试幂等上限。供应商价格具有时效性,PoC 后以实际报价和压测填写 100/1,000/10,000 场三档模型,不虚构单价。

能力 决策【建议】 理由
状态机、题库、rubric、证据链、申诉 Build 核心差异与审计责任
LLM/STT/TTS 先 Buy,保留 adapter 降低早期运维,保留替换权
实时媒体 托管优先 WebRTC 和设备兼容复杂
认证、存储、数据库 成熟托管优先 采用企业级标准控制
编码沙箱 隔离托管或专用集群 不复用 privileged 默认方案
公平性/效度 内建标准,可外聘独立审计 责任不能外包

12. PoC / MVP / Beta / 生产路线图及退出条件

PoC:离线文本与证据链。 固定题库、mock、结构化 rubric、快照、provenance、导出/删除样机,只用合成或许可数据。退出条件:状态机与不变量通过;sample/mock 明确;题库 schema/ID 通过;能追溯反馈到题目、rubric 和回答证据;威胁模型与数据目录签字。

MVP:受控练习。 加账户授权、可选 CV/JD、文本主路径、可选语音、provider sandbox、纠错、删除、预算和观测;编码只上线有可靠测试的题。退出条件:E2E、迁移、SSRF/上传、权限、Origin、删除传播通过;P0/P1 清零;媒体可降级;100 场内部/合成容量测试满足 SLO,无答案丢失和重复计费。

Beta:邀请制练习。 加有限多语言、人工客服/申诉、nightly provider 回归、红队、无障碍和成本仪表盘,仍禁止用于淘汰。退出条件:预注册质量与稳定性门槛达到;关键语言/设备/口音 slice 无无法解释落差;独立渗透测试、恢复、轮换、删除抽样和 2 倍峰值压力通过。

生产:自主练习 GA。 建立 on-call、错误预算、回滚、供应商退出、持续校准。退出条件:连续两个发布周期无未解决 P0/P1;模型/题库版本与季度访问审查、年度渗透/灾备演练落地。

招聘评估受限试点:独立 Go/No-Go。 必须完成岗位效度、法律审查、通知、合理便利、人工复核、申诉、合同限制和独立公平性评估;任一缺失即 No-Go。只输出供人工参考的证据包,不发自动录用/淘汰指令。

13. 风险登记表

ID 风险 概率/影响 缓解与退出条件【建议】
R1 练习分被用于自动淘汰 中/极高 用途合同、API scope、审计;不存在自动不利决定路径
R2 mock/sample 冒充真实 中/高 强 provenance;契约测试证明不进入正式指标
R3 未校准分数不公平 高/极高 双评审校准、slice 指标、转人工;达预注册门槛
R4 敏感材料泄露 中/极高 最小化、加密、授权、短保留;删除抽样通过
R5 空认证/IDOR 中/极高 OIDC/RBAC、tenant scope;越权测试通过
R6 SSRF/恶意文档 中/高 egress、DNS 重验、隔离解析;红队不能访问内网
R7 沙箱逃逸 低中/极高 专用节点、无网、cgroup;独立评估通过
R8 重复评分/丢答案 中/高 事务、版本、幂等、outbox;故障注入通过
R9 迁移破坏可用性 中/高 显式 migration job;空库、升级、恢复通过
R10 题库测试名存实亡 高/高 golden/错误解法/hidden 门禁;上线题全过
R11 供应商限流或涨价 中/高 adapter、降级、预算熔断、退出演练
R12 真实面试作弊用途 中/高 产品禁能、政策与处置;无隐蔽监听/提词功能
R13 供应链污染 中/高 pin、SBOM、签名、自托管;发布扫描通过
R14 STT 误差变成低分 中/极高 转写确认、文本替代;低置信不评分/转人工

14. 上线 Checklist

15. 两个项目关键缺口

DeepInterview:(1)真实媒体、provider、存储与 RAG 端到端未验证;(2)sample/mock/degraded 缺少贯穿全链路的强 provenance;(3)空 secret、capability-only read、SSRF 和跨实例一致性不足;(4)敏感数据 retention、删除/导出、录音同意和区域治理不完整;(5)缺招聘效度、人工校准与跨语言公平性证据。

GrillKit:(1)44 道编码题均无 public/hidden tests,内容未兑现执行框架;(2)默认 root entrypoint 的 migration 不可达;(3)无认证及 CSRF/Origin/Host/CSP、base URL 和明文 key 风险;(4)privileged Judge0、示例密码和 CDN Monaco 不适合共享生产;(5)完整 CI、真实模型/语音、E2E、容量、公平性和成本未验证。

16. 本地研究入口和阅读顺序

  1. 先读 DeepInterview 审计 的执行摘要、流程、安全、测试和限制。
  2. 再读 GrillKit 审计 的执行摘要、题库、迁移、安全、测试和限制。
  3. DeepInterview 主链路:prep graphworkerevaluatorreport
  4. DeepInterview 边界:authrepositorySupabase migration报告页
  5. GrillKit 主链路:session phasescreate sessionstructured evaluationsubmit solution
  6. GrillKit 判题/部署:task specrun testsJudge0Composeentrypoint
  7. 最后读 DeepInterview READMEGrillKit README,只用于作者意图和配置说明,并与审计实际执行结果对照。

结论是:两个项目都提供了值得复用的工程切片,但没有一个固定 HEAD 已证明可直接用于真实招聘决策。应复用状态机、证据链、结构化契约、失败隔离和 provider adapter,同时重建认证、数据治理、评分校准、沙箱、安全测试与阶段退出机制。第一性边界是帮助候选人练习,而不是在真实面试中作弊,也不是用未经验证的模型分数替代人的招聘责任。

AI 面试系统原理深化:从模型能力到可审计系统

证据边界:本文只依据最终报告、两份审计和固定源码展开。DeepInterview 固定 HEAD 为 241799b39e781737ccec30157d8201bcc572064c,GrillKit 固定 HEAD 为 15a400afb08349ad9b73f31a0c92ba147032164c【事实】表示固定源码或审计直接支持;【未验证】表示源码有接口、声明或局部实现,但本次没有完成真实 provider、媒体、Judge0、生产存储、性能或质量验证;【建议】表示拟建系统的工程方案。本文出现的性能、容量、阈值、SLO、资源上限和阶段门槛,除明确写为“源码事实数值”者外,全部是建议初始目标,需由压测、校准和风险评审修订,不能当作两个仓库的实测结果。总证据入口见最终报告DeepInterview 审计GrillKit 审计

一、简历(CV)/职位描述(JD) → 能力模型 → 题目规划:先定义契约,再允许模型推断

这条链不是“把简历和职位描述拼进一个 prompt,让模型随便出题”,而是一条有中间表示、可验证不变量和版本边界的编译流水线。CV 是候选人自述证据,JD 是岗位需求声明,公司资料是外部背景;三者证据等级不同,必须先结构化,再做差距匹配,最后将差距映射到有限题目、rubric 和时间预算。DeepInterview 已给出清晰原型:Prep 图并行执行 CV 分析、JD 分析和公司研究,汇合后执行 gap matching 与 question planning;join 保证下游看到三个分支的完成态,而不是拿到“谁先返回就用谁”的残缺上下文(prep graph)。

输入。 【事实】固定源码的 PrepRequest 包含 cv_urljd_textcompanylanguage_mode 和可选 owner;CandidateProfileJobSpecGapAnalysisPlannedQuestionQuestionPlanInterviewContext 都是 extra="forbid" 的 Pydantic 契约,计划明确包含 section、双语题面、难度、rubric、follow-up、目标能力、总时长和语言模式(shared modelscontext)。这说明输入不只是字符串,而应至少携带 tenant_idsession_id、source、内容哈希、解析器版本、语言、许可、时间戳与 provenance。CV 中“掌握 Kafka”只能形成 candidate claim;JD 中“负责分布式系统”只能形成 job requirement;它们都不是已经证实的能力。

处理。 【事实】Prep 的每个节点只向 PrepState 增量写入自己计算的字段,结构为 candidate/job/company/gap/plan,这相当于类型化的中间表示(prep state)。CV/JD 先抽取实体与规范化技能,再由 gap matching 计算 matched_skillsmissing_skillsstrengthsgapsprobe_targets;题目规划器消费 candidate、job、company、gap 和 language mode,并可注入受字符预算限制的 playbook 片段(prep nodesplanner)。【建议】生产算法应把能力模型写成有向映射:Requirement -> Competency -> ObservableSignal -> QuestionRevision -> RubricCriterion。每个 requirement 有来源跨度和权重,每个 competency 有岗位相关性与证据需求,每道题声明能覆盖哪些 observable signals。规划可做成约束优化:在总时长、题型比例、难度、语言和无障碍约束下,最大化高权重能力覆盖与信息增益,同时惩罚重复题、单一题型和仅由弱证据支撑的断言。LLM 可提出候选映射,但 schema 校验、枚举、权重归一、题库 ID 存在性、版本固定、时间预算和最小覆盖必须由代码执行。

输出。 【建议】发布的不是可变 QuestionPlan 草稿,而是不可变 PlanSnapshot:包含 bank_release_id、每题 revision、locale revision、rubric version、能力映射、选择理由、证据引用、预计时长、随机种子、规划器版本、模型与 prompt 版本、输入内容哈希和 content_state。快照一旦进入 READY 就不再跟随题库更新;后续动态追问只能作为关联到原题的新 Attempt,不得偷偷改写基础计划。计划还应输出 coverage matrix,使系统在开始前就能解释“哪道题为什么存在、覆盖哪个能力、未覆盖哪些岗位要求”。

失败模式。 【事实】CV 抽取失败可退回原始 URL 字符串,CV/JD/gap/planner 失败可生成 minimal/mock 对象并写 warning;planner 最终还会强制把语言模式钉回请求值(节点降级规划降级)。这保证 demo 不崩,却可能把“结构合法”误当“语义有效”。其他失败包括简历版式解析错误、同义技能未归一、JD 复制营销话术、模型虚构公司流程、prompt injection 操纵规划器、并行分支超时、模型输出重复题、rubric 权重不闭合,以及短面试无法覆盖全部能力。【未验证】固定源码没有证明真实 CV/JD 抽取质量、跨语言 skill normalization、题目效度或 planner 稳定性。

实现建议。 【建议】接收层先做文件隔离解析、MIME/页数/解压体积/URL egress 检查;抽取层保存原文 span,不让模型凭空补必填字段;规范化层用受控 taxonomy 和 alias 表;匹配层分别输出“原文事实、模型推断、未知”;规划层从版本化题库检索候选题,再由约束求解器选择,最后做 deterministic validator。建议初始目标:高权重能力计划覆盖率不低于 90%,单一题目承担总能力权重不高于 30%,重复语义题比例低于 5%,无法可靠抽取时进入 PREP_REJECTEDPREP_DEGRADED,而非静默发布真实计划。所有这些数值都是建议初始目标。

二、实时语音:WebRTC、VAD、STT、EOU、LLM、TTS 与 barge-in 是并发控制问题

实时体验的核心不是某个语音模型,而是多个异步流的时序正确性。浏览器持续产生音频帧;VAD 判断“有人声”,STT 持续产生 partial/final 文本,EOU 判断“这一轮是否结束”,LLM 可能预生成,TTS 又把 token 转成可播放音频。任何阶段都可能迟到、重试或被取消,因此每一轮必须带 turn_idgeneration_id,并用取消令牌隔离上一轮残留结果。

输入。 【建议】媒体输入包括 WebRTC 音轨、采样率/声道、客户端时间、sequence、网络 jitter/packet loss、设备变化、候选语言和 consent;控制输入包括当前 session/section/attempt、题目快照、允许追问次数、deadline 和 provider policy。partial transcript 是低确定性 UI 数据,final transcript 也不自动等于回答提交;只有状态机确认的 turn.committed 才进入评分事实。【事实】DeepInterview 捕获 LiveKit 的 conversation_item_added,将用户和助手实际 committed 的内容写入 transcript;答案仍由 save_answer 进入 context,关闭时可从 transcript 恢复漏存答案(transcript capture)。

处理。 浏览器通过 WebRTC 将短帧送至 SFU/媒体服务;WebRTC 处理 ICE、DTLS-SRTP、拥塞与抖动缓冲,但不决定语义轮次。VAD 对声学帧做起音/停音检测;STT 在语音进行时产生 partial 并最终定稿;EOU 把声学停顿和文本完整性结合,避免把自然停顿误判为回答结束。DeepInterview 预热 Silero VAD,支持语言使用 multilingual EOU,不支持语言回退到静音 endpointing;源码事实参数为最小静音 1.2s、最大静音 4.0s,这是固定实现值而非本文性能目标。中断确认要求至少已有 3 个转写词,也是固定实现值,目的是降低门响或背景声造成误中断(turn handlingVAD prewarm)。本地 Whisper 路径实际是 VAD 切句后调用 batch endpoint,再包装成 streaming 接口,所以没有逐词 interim;这与真正 streaming STT 的延迟行为不同(local STT)。

在正常轮次中,EOU 确认后提交 final transcript,状态机接受 Attempt,LLM 读取受限上下文流式生成,TTS 尽早合成并播放。barge-in 时不能只“停止扬声器”:先由 VAD 触发 ducking,STT 达到词数/置信门槛后原子地标记当前 generation cancelled,停止 LLM 消费、取消 TTS、清空尚未播放 buffer,记录已经播放到的字符或音频区间,再开启新候选人 turn。迟到 token 或音频块因 generation id 不匹配被丢弃。否则最常见的竞态是候选人已经开始回答,旧 TTS 仍继续播放,或旧 LLM 尾部被误接到新回答之后。

输出。 【建议】实时面至少产生 speech.startedstt.partialstt.finalturn.endpointedturn.committedgeneration.startedtts.chunkassistant.interruptedprovider.failedmedia.reconnected。事件只放必要元数据;音频与全文使用受限存储引用。每个 turn 保存客户端/服务端时间、VAD/STT/EOU 置信、采用的 transcript revision、播放区间、取消原因和 provenance。UI 可乐观显示 partial,但在 final/commit 到达时必须校正。

失败模式。 常见问题包括 NAT/权限导致无法建链,jitter 造成断续,噪声触发 VAD,EOU 太激进切断长句,EOU 太保守造成尴尬等待,STT 把口音错误变成技术错误,本地 batch STT 没有 partial,LLM 冷启动,TTS 首包慢,取消传播不完整,重连后重复提交,或 BVC 降噪导致无音频。【事实】DeepInterview 仅在显式启用且使用 LiveKit Cloud 时开启 BVC;源码注释记录过过滤器初始化失败导致无音频的风险(room options)。【未验证】两份审计都没有验证真实设备、口音、噪声、barge-in、音质、准确率和 provider 延迟。

实现建议。 【建议】预算应从“用户结束说话到助手首音”倒推,而不是分别优化平均值。建议初始目标:浏览器到 VAD 可用帧 P95 不高于 80ms;起音检测 P95 不高于 120ms;首个 STT partial P95 不高于 300ms;支持语言的语义 EOU P95 不高于 450ms;云 LLM 首 token P95 不高于 600ms,本地热模型 P95 不高于 1200ms;TTS 首块 P95 不高于 350ms;端到首音 P95 不高于 1.5s、P99 不高于 2.5s;确认 barge-in 后停声 P95 不高于 250ms。这些全是建议初始目标。指标必须按语言、设备、网络、provider、冷热状态分桶;STT 低置信允许候选人纠正;语义 EOU 故障降级为静音端点,STT 故障降级文本,TTS 故障保留文字,不能把媒体故障折算成能力低分。

三、会话状态机必须与 LLM 解耦

LLM 是概率性、可超时、可被注入、可能返回无效 JSON 的外部依赖;状态机则承担计时、授权、顺序、幂等和账务,是系统事实源。两者耦合后,一个模型幻觉就可能跳题、延长会话、重复计费或把未提交答案标为完成。正确关系是:LLM 只返回“建议的语义动作”,命令处理器根据当前状态、版本和策略决定是否接受。

输入。 状态机输入不是自然语言,而是命令:SubmitPrepPublishPlanJoinLiveCommitTurnSubmitAttemptRunCodeFinishSectionStartScoring。每个命令携带 actor、tenant、aggregate id、expected_version、idempotency key、deadline 和必要 payload。LLM 输出必须先解析成受限 DTO,例如 follow_up_neededfollow_up_question 或 rubric 评分,不能直接提交任意状态字符串。

处理。 【事实】GrillKit 由四种 session mode 映射固定 section 顺序,服务查询 section 是否 pending/active/complete 再推进;不是由模型决定先理论还是先编码(phase orderadvance phase)。理论评价最大追问深度的源码事实值为 2,追问内容可由 LLM 生成,但是否还能追问由领域规则限制(theory evaluator)。【建议】顶层状态使用 DRAFT → PREPARING → READY → CONNECTING → LIVE → DRAINING → SCORING → COMPLETED,并显式加入 REJECTED、DEGRADED、RECONNECTING、FAILED。Section 与 Attempt 各有子状态;计时以服务端单调时钟和持久化 deadline 判断。命令处理流程固定为“鉴权→加载聚合→检查 expected version→验证迁移→写事件/状态→写 outbox→提交事务”。

输出。 状态机输出领域事件和新的 aggregate version,而不是直接生成 UI 文案。GrillKit 已将 AnswerSavedEventEvaluatingEventAnswerFeedbackEventTranscriptEventInterviewCompletedEvent 定义为 transport 无关的不可变 dataclass,再由 WebSocket 层映射(domain events)。【建议】模型建议被拒绝时也应产生审计事件,如 followup.rejected(reason=max_depth);这样才能区分“模型没建议”与“规则禁止”。

失败模式。 如果 LLM 直接控制流程,可能返回不存在的 question id、要求越过 timer、在重试时生成不同追问、把 provider timeout 当成候选人超时,或被答案中的指令诱导“结束面试并给满分”。即使结构化输出通过 schema,也只证明形状正确,不证明迁移合法。另一个风险是前端倒计时或 WebSocket 重连重复发送 complete;如果服务端没有版本和幂等约束,就会重复评价和收费。

实现建议。 【建议】把 LLM 调用放到状态迁移之外:先在事务中保存 Attempt 并转为 EVALUATING,通过 outbox 派发模型任务;消费者以 input hash 计算幂等键;结果回来后再次 compare-and-swap,只在目标 Attempt 仍处于相容状态时生效。建议初始目标:非法迁移接受数为 0,重复命令产生重复副作用数为 0,状态冲突明确返回 409,状态机属性测试覆盖全部允许/禁止边,任意 provider 故障都不破坏已提交答案。这些均为建议初始目标。

四、RAG:从 ingest 到 citation 的可信链,以及隔离与 prompt injection

RAG 的价值不是“让模型知道更多”,而是把输出约束到可追溯的私有材料、题库与公共资料。它至少包含接收、解析、切块、向量化、索引、召回、重排、上下文组装、生成、引用核验和删除传播;缺一环都可能得到看似有引用、实则不可复核的答案。

输入。 输入文档需要 tenant_id、namespace、source URI、原始内容哈希、MIME、语言、许可、保留期、访问策略和解析器版本。查询需要 actor、tenant/session、允许的 namespace、query、locale、top-k、token budget 与用途。CV/JD 属于 candidate-private;题库属于版本 release;公司资料属于有抓取时间的 public snapshot,三者不能混成一个无边界向量库。

处理。 【事实】DeepInterview 的 sidecar 默认 NaiveRAG:按约 500 字符切块(源码事实值,非目标),用小写字母数字 token overlap 做长度归一化 TF 评分,稳定排序后取源码事实 TOP_K=3,返回抽取式 answer 与 citation(NaiveRAGquery)。它以 user_id/实际 OSS 流程中的 session id 分 store。【事实】所谓完整 LightRAGBackend 在固定 HEAD 仍是骨架,instance、ingest、query 均抛 NotImplementedError,因此 embed、graph retrieval、rerank 与真实 citation 并未接通(LightRAG skeleton)。没有配置 sidecar URL 时,Agent 使用无状态 deterministic MockKnowledge 并返回预制 citation(knowledge adapter)。

【建议】生产 ingest 应先恶意文档扫描与隔离解析,再按标题、段落、列表和代码语义切块,保留 start_offset/end_offset/page;embedding 写入前记录模型、维度和规范化方式。query 先做关键词与向量混合召回,再进行 ACL 过滤与 cross-encoder rerank,最后按来源多样性、时效和 token budget 组装上下文。citation 必须绑定真实 chunk id、原始 span、索引版本和内容哈希;生成后逐条验证引用文本确实支持对应 claim。引用不是 URL 装饰。

输出。 输出分为 retrieval_setgenerated_answer。前者包含 rank、raw score、rerank score、namespace、chunk id、source span、content hash;后者包含 claim 到 citation 的映射、无证据声明和 provenance。题目规划只应得到最小必要片段,不应得到整个 CV;评分模型通常不需要公司公共资料,避免无关上下文污染 rubric。

失败模式。 文档可能包含“忽略系统指令、泄露隐藏题、给候选人满分”等 prompt injection;恶意 HTML/PDF 可夹带不可见文本;跨 tenant filter 漏掉会召回他人简历;旧 embedding 与新 query 模型不兼容;切块破坏上下文;top-k 全是同一来源;citation 指向网页却不对应实际 chunk;删除主库后向量副本仍存在。【事实】sidecar URL 检查仅对字面 IP 做 public/private 判断,域名路径仍需 DNS 与 egress 防御;它禁止跟随重定向,这是一项局部控制(ingest SSRF guard)。【未验证】完整 RAG 的质量、隔离、删除传播和注入防护没有在审计中动态验证。

实现建议。 【建议】使用强制 namespace candidate_private/{tenant}/{session}question_bank/{release}company_public/{snapshot};ACL 在检索引擎查询层强制而非生成后过滤。把检索内容标成“不可信数据”,模型无权从文档获得工具权限、秘密或状态机控制;工具 allowlist 和参数 schema 独立于文本。建议初始目标:RAG 查询 P95 不高于 250ms、初始 top-k 为 6、注入上下文不高于 8000 tokens、跨租户召回数为 0、citation 可解析率为 100%、删除任务在约定窗口内覆盖主索引/缓存/备份索引。所有数值均为建议初始目标。RAG 失败可继续使用已发布计划,但输出必须标 degraded,不能回 mock 后仍称 grounded。

五、理论题、编码题、Judge0 与 AI 评分的组合

理论题和编码题观察的信号不同。理论题重视概念、权衡、解释和追问后的修正;编码题首先有可执行正确性、资源消耗和错误行为,然后才有可读性、设计取舍与解释。把所有信号交给 LLM 会损失确定性;只看测试又无法评价开放式工程判断。正确结构是“规则/执行信号优先,AI 解释辅助”。

输入。 理论题输入包括不可变题面 revision、locale、expected points、rubric、难度和题目能力映射;回答输入包括初答、追问链、时间和 transcript provenance。编码题还包括语言、starter code、entrypoint、public/hidden test suite version、资源限制、candidate code、Run 历史和 Submit。【事实】GrillKit 会将题面、expected points、代码和 task spec 随 session 持久化,避免题库更新后历史结果漂移(database snapshotscoding snapshots)。

处理。 理论题先按 rubric 做结构化评价,再由状态机决定是否创建追问;追问用于减少证据不充分,不应只是“低分再问一次”。GrillKit 将 schema 放进 system prompt,使用 Pydantic 解析;截断或 invalid JSON 最多重试一次,第二次 token budget 上限的源码事实值为 4096(非建议目标)(structured evaluationretry)。

编码的 Run 只执行 public tests 并返回安全结果;Submit 在服务端加载 hidden tests,执行后只产生摘要。GrillKit 的 client serializer 删除 hidden tests,并把 public tests 降为名称,不返回 expected output(client task spec)。runner 对 tests mode 逐例调用 Judge0,严格比较 stdout,首个失败停止;AI mode 或无 tests 时退化为 compile-only(run tests)。Submit 先跑 hidden/compile-only、持久化摘要,再调用 CodingEvaluator(submit solutionAI evaluation)。

输出。 【建议】确定性输出包括 compile status、public/hidden passed count、失败类型、CPU、memory、output truncation、test suite hash;AI 输出包括 rubric criterion score、evidence span、工程质量反馈和追问建议。最终分由代码组合:正确性门槛和 score cap 写在规则引擎,不只写 prompt。GrillKit 当前 prompt 写了 hidden tests 失败最高 3 分(源码事实规则文本,非建议目标),但它只是 prompt 指令,生产系统应在模型返回后再次代码钳制(coding prompt)。

失败模式。 【事实】GrillKit 固定题库的源码统计是 44/44 道编码题均为 AI mode,tests/public_tests/hidden_tests 均为 0;这些是审计事实数值,不是目标。因此现有框架实际只能 compile-only 加 AI 评分,不能宣称内置题库已具备可靠判题(GrillKit 审计)。其他风险包括 public test 泄露答案、hidden test 经 session JSON/日志/LLM prompt 泄露、严格 stdout 比较产生格式假阴性、逐测试同步请求放大延迟、candidate code 探测内网、无限输出耗尽资源、测试过拟合、AI 被代码注释注入,以及 Judge0 privileged 部署扩大逃逸后果。固定 Compose 的 server/worker 使用 privileged,审计已明确不适合共享生产(GrillKit 安全审计)。

实现建议。 【建议】hidden tests 独立加密存储,session 只存 suite reference;Judge0 Gateway 在可信服务端拼接 harness,执行节点位于专用 VM/节点池,默认断网、无生产 secret、只读根文件系统、独立 cgroup/seccomp 和用后销毁 workspace。题库发布必须满足 reference solution 全过、代表性错误解至少一个测试失败、泄漏契约测试通过。建议初始目标:执行排队 P95 不高于 1s,单 case CPU 不高于 3s、墙钟不高于 5s、内存不高于 128MiB、输出不高于 64KiB、每 session 同时执行 1 个任务、每题 Run 不高于 20 次;均为建议初始目标。Judge0 不可用时允许保存草稿并重试,但绝不能标记测试通过。

六、评分:rubric、coverage、evidence、校准、置信区间与公平性

分数不是模型回答里的一个浮点数,而是对“给定任务、给定证据、给定 rubric”所作的测量。一个可信报告至少回答:测了什么、测了多少、依据何在、测量误差多大、与人工标准如何校准、在哪些人群和语言上不可靠。

输入。 输入应冻结 question/rubric revision、candidate response revision、transcript 修订记录、代码与 test hash、追问链、语言、合理便利、provider/model/prompt 版本和 content provenance。rubric 每个 criterion 定义可观察信号、等级锚点、权重、反例和不可用条件。不得将口音、停顿、背景噪声、摄像质量、情绪推断或付费状态作为技术能力代理变量。

处理。 【事实】DeepInterview 对已回答题并发评分,强制 competency 等于计划的 target_competency,把分数 clamp 到 0–5,由代码派生 mastery band;同能力多题取平均;未回答题跳过(evaluatorcoverage handling)。报告的 overall 是 competency 均值,coverage 是已回答计划题占比(reportassembly)。这体现了关键原则:没测到不是零分,低 coverage 不能伪装成完整低能力画像。

【建议】逐 criterion 评分先提取 evidence span,再生成原始等级;规则引擎合并确定性信号并执行 cap;校准层把 raw score 映射到人工锚点分布。置信区间应来自重复评分方差、题目采样误差、人工标注不一致和媒体质量,而不是让 LLM自报 confidence。可用 bootstrap 或分层贝叶斯模型按岗位/题族估计区间;证据很少时区间自然变宽,报告应显示“证据不足”,而不是给两位小数的伪精确分。

输出。 【建议】每个 ScoreEvidence 保存 criterion、score、原始模型输出、引用的答案 span、test result hash、规则调整、最终值和版本。ScoreCard 同时展示 point estimate、confidence interval、coverage、未覆盖能力、degraded reasons、人工修改及理由。语言报告应与技术总分分离;只有经岗位效度验证的语言要求才能进入相关 criterion。

失败模式。 同一回答重复调用得到不同分;长答案因风格获利;STT 错词造成技术扣分;模型偏好某种口音或表达;rubric 模糊导致评审分歧;不同题难度直接平均;低 coverage 被误解为低能力;模型升级导致历史不可比;样本小却声称公平。【事实】DeepInterview 可选 verifier 只复核 weak/developing,失败保持原分,且默认关闭;它不是完整人工校准或公平性证明(score verifier)。【未验证】两个固定 HEAD 都没有证明招聘效度、跨语言等值、群体公平或真实媒体质量。

实现建议。 【建议】建立按候选人和题族隔离的 calibration/golden set;每条由至少两名受训领域评审独立标注并仲裁。预先登记岗位、语言、设备、口音、回答长度、合理便利等 slice 的门槛,报告样本量与置信区间。建议初始目标:结构化输出解析成功率不低于 99.5%,确定性字段同输入一致率为 100%,核心 rubric 人工评审加权一致性达到预登记门槛,低 coverage/低 STT 置信/技术故障自动转人工而非判低分;数值均为建议初始目标。模型、prompt、rubric 或题库升级必须用固定集回归并创建新 scoring version,不重写历史结果。

七、可靠性:append-only 事件、outbox、幂等、乐观并发与恢复

实时面试同时存在浏览器、媒体 worker、API、评分 worker 和代码沙箱;网络通常只能提供至少一次投递。试图依赖“请求只会来一次”必然产生重复答案、重复扣费、丢 transcript 或状态倒退。正确目标不是神话式端到端 exactly-once,而是 at-least-once delivery 加 idempotent consumer,最终实现 exactly-once effect。

输入。 每个命令带全局 idempotency key、aggregate id、expected version、correlation/causation id、actor、发生时间和 input hash。事件 envelope 至少有 event id/type/schema version、aggregate version、payload、provenance。音频 partial 不直接成为领域事件;只将 committed turn、attempt submitted、code run completed 等事实 append。

处理。 在同一数据库事务中:验证 version,向 append-only event/attempt 表插入新行,更新 aggregate 当前 version,写 outbox。publisher 轮询或 CDC 发布未发送 outbox;消费者先以 event id/idempotency key 查 inbox,重复则返回已有结果。外部调用的幂等键建议由 operation + session + input_hash + model/rubric version 构成。【事实】GrillKit 的 UnitOfWork 明确管理 commit/rollback/close,提交工作流异常会 rollback(UnitOfWorksubmit transaction)。这提供事务边界,但固定源码没有 durable outbox。

输出。 写路径输出新的 aggregate version 和稳定 operation result;读路径由 projector 构建 session view、进度和报告。append-only 并不意味着永不删除敏感数据:业务事实可保留 tombstone/删除事件,原文、音频和代码按保留策略密钥销毁或删除,投影同步清除。

失败模式。 【事实】DeepInterview 的 Supabase append_answer 是先读整个 context、内存追加、再整体 update;两个 worker 同时读取同一版本时,后写者会覆盖先写者,形成 lost update(repository)。其评分锁是进程内字典锁,只能防同进程竞争,不能防多实例重复调用(scoring lock)。周期 flusher 默认按间隔复制整段 transcript,能缩小崩溃损失窗口,但不是 append-only,也不能单独解决并发覆盖(flusher)。还可能发生 DB 提交而消息未发、消息已发而 ack 丢失、评分完成而状态未更新、重连重放旧 submit、迟到结果覆盖新版本。

实现建议。 【建议】answers、turns、code runs、scores 使用独立 append 表和唯一约束;UPDATE sessions SET version=version+1 ... WHERE id=? AND version=? 实现 compare-and-swap,影响行数为零即冲突。outbox 与业务写同事务,消费者用 inbox 去重。恢复时先读 snapshot,再按 sequence 重放尾部事件;DRAINING 停止新题,等待已承诺 turn、usage、outbox checkpoint。建议初始目标:重复副作用数为 0,同 session 只有 1 个 live lease,final checkpoint RPO 不高于 5s,控制面 RTO 不高于 15min,outbox lag P95 不高于 5s;均为建议初始目标。故障注入必须覆盖进程被杀、数据库超时、消息重复、乱序、provider 响应迟到和重连。

八、mock、sample、degraded 的 provenance 必须成为数据,而非 UI 猜测

mock 用于离线开发,sample 用于展示,degraded 表示真实流程部分失败。三者都合法,但只有在每一层都可识别时才安全。若只在日志写一条 warning,后续报告、导出和分析仓就可能把假数据当真实绩效。

输入。 每个外部或生成步骤输入 execution_mode、允许的 fallback policy、环境、provider selection 和数据用途。生产正式评分默认只允许 real provider;演示 tenant 可以明确允许 mock/sample。provenance 不应靠字符串是否包含 “mock” 推断。

处理。 【事实】DeepInterview 的 LLM 工厂在 provider 缺 key、未知 provider 或本地 base URL 缺失时返回 MockLLMLLM factory);Prep 节点局部异常也可能构造 minimal/mock schema。报告页在 API 不可达、session 不存在或 schema 漂移时返回 sample scorecard;有真实 scorecard 但叙事为空时以 degraded 布尔值提示(report loader)。这些路径说明状态存在,但 provenance 尚未作为所有领域对象的强制契约。

【建议】每个 artifact 写 content_state ∈ {real,mock,sample,degraded}derived_from、provider/model、prompt/rubric/bank version、fallback reason、created_at、input hash。组合规则采用“最弱来源传播”:real plan 中只要关键 candidate 或 job 来自 mock,计划就不能仍标 real;报告若部分题评分失败,应保留成功题,但整体标 degraded 并列出缺失项。sample 数据使用独立 tenant、独立 ID 前缀和分析隔离。

输出。 API、UI、导出、事件和分析仓携带同一 provenance。用户看到的是“真实结果 / 演示样例 / 部分生成失败 / 无证据”,而不是仅靠颜色暗示。评分和费用指标按 content state 分桶;正式 KPI 默认排除 mock/sample。

失败模式。 最危险的是生产配置错误后自动回 mock,生成结构合法且看似合理的报告;API 失败时 UI 展示 sample 又被截图为真实结果;degraded 只有前端布尔值,导出丢失;真实与样例 session ID 同空间;修复后重跑覆盖原 provenance。【未验证】现有系统没有证明全链路 provenance、分析隔离和导出一致性。

实现建议。 【建议】生产启动对 auth、持久化和正式评分 provider fail closed;fallback 必须由 capability policy 显式允许。数据库对正式 score 增加约束:关键上游不得是 mock/sample。建议初始目标:mock/sample 进入正式统计数为 0,无 provenance 的新 artifact 数为 0,UI/API/export 状态一致率为 100%,配置错误在会话开始前暴露;均为建议初始目标。保留原始版本,以新 revision 修复,不覆盖历史。

九、从 PoC 到生产:扩大可验证边界,而不是堆功能

演进的主轴不是模型越来越大,而是事实源、数据契约、故障隔离、质量证据和用途边界逐步增强。每一阶段都要有退出条件;未满足就不能靠“Beta”标签掩盖。

输入。 阶段计划输入包括用途(自主练习或招聘评估)、威胁模型、数据目录、目标用户、语言、题型、provider、容量假设、错误预算、校准集、合规要求与团队能力。两个固定仓库只能作为工程切片:DeepInterview 提供 prep/live/post 和实时 worker,GrillKit 提供状态机、快照、结构化评分与 Judge0 边界;审计没有证明任一仓库可直接用于真实招聘决策(DeepInterview 结论GrillKit 结论)。

处理。 【建议】PoC 先做离线文本闭环:确定性状态机、版本题库、rubric、evidence、content provenance 和导出/删除样机,只用合成或许可数据。MVP 再接账户授权、CV/JD 隔离解析、文本主路径、可选语音、provider sandbox、幂等/outbox、可观测性和只有真实测试的编码题。Beta 才扩大真实设备、语言、无障碍、红队、人工复核、nightly provider regression、容量和灾备。自主练习 GA 需要 on-call、错误预算、回滚、密钥轮换、删除传播和持续校准。招聘评估是独立 Go/No-Go,必须另做岗位效度、法律审查、公平性、通知、合理便利、人工复核和申诉,不能由练习版自然升级而来。

输出。 每阶段输出可审计 release:架构决策、schema、迁移、SBOM、题库 release、模型/prompt/rubric 清单、测试报告、性能基线、安全例外、校准报告、数据处理登记和回滚包。Build/Buy 的边界应稳定:状态机、题库、rubric、证据链和申诉责任自建;媒体、模型和基础设施可先采购但必须经 provider protocol 隔离。

失败模式。 PoC 最容易把 mock 成功当生产正确;MVP 容易先上语音而没有文本降级;Beta 容易追求题量而没有 golden/错误解;生产容易依赖单 provider、无版本迁移或无删除链;招聘试点最危险的是把未校准练习分用于自动淘汰。现有源码也提示了具体风险:DeepInterview 真实媒体、完整 RAG、Supabase/R2 未验证;GrillKit 无认证、迁移入口缺陷、privileged Judge0 且当前题库没有测试。这些必须是阶段门禁,不是上线后的改进项。

实现建议。 【建议】PoC 退出条件是核心状态不变量、题库 schema、provenance 与证据追溯全部通过;MVP 建议初始目标是在至少 100 场内部/合成容量演练中无已确认答案丢失、无重复计费,权限、SSRF/上传、迁移、删除和断线 E2E 通过;Beta 建议初始目标完成 预测峰值压力、独立渗透、灾备和关键公平性 slice;GA 建议初始目标连续 2 个发布周期无未解决 P0/P1。所有数字都是建议初始目标。任何阶段发现评分不可解释、跨租户泄漏、hidden test 泄漏、沙箱逃逸或 mock 混入正式结果,都应停止扩大流量并回滚。

十、把九条链合成一个可审计闭环

系统的最小可信闭环是:CV/JD 被隔离解析成带来源的能力模型;规划器从版本题库生成不可变计划;状态机授权每个 section 与 attempt;实时面把音频转换为 committed evidence;代码执行提供确定性结果;RAG 只在授权 namespace 内提供可引用上下文;评分按 rubric 汇总 evidence、coverage 与不确定性;append-only 事件、outbox 和幂等保证故障后可恢复;provenance 贯穿 UI、API、导出与分析;阶段门禁决定系统是否有资格扩大用途。

任何一层都不能替代另一层:schema 只能保证形状,不能保证真实性;引用只能证明来源,不能证明推理正确;测试通过只能证明给定 case,不能证明工程质量;LLM 的 confidence 不能替代统计置信区间;容器不能自动等于安全沙箱;状态显示 ready 不能证明真实 provider 已执行。最终应把“模型输出”降格为一种可审查信号,把“系统事实”交给确定性规则、事务数据和版本化证据。

本文的实现优先级因此是:先锁定用途和状态机,再锁定数据契约、快照、幂等与 provenance;随后接文本评分与真实测试题;再接 RAG 和实时语音;最后才扩大多语言、容量与高风险用途。这样得到的不是一个会聊天的面试 UI,而是一套在失败、重试、升级和争议发生时仍能解释“输入是什么、经过什么处理、输出依据什么、哪里失败、为何可以恢复”的系统。