AI 面试产品交付:从练习工具到可审计系统
证据基线:2026-09-07。DeepInterview 固定 HEAD 为
241799b39e781737ccec30157d8201bcc572064c,GrillKit 固定 HEAD 为15a400afb08349ad9b73f31a0c92ba147032164c。文中 【事实】 仅指两份审计或固定源码直接支持的结论;【建议】 是面向拟建产品的交付主张;【未验证】 表示虽有源码或项目自述,但审计未完成真实集成、性能或质量验证。README 只用于理解作者意图,不作为测试通过证据。
1. 执行摘要
【建议】AI 面试首先是一条业务闭环,不是一个“会问答的模型”。 它从候选人材料和岗位要求出发,把岗位拆成可观察的能力,把能力映射为有依据的题目,再通过语音、文本或代码收集证据。系统随后按预先发布的评分标尺解释证据,生成带出处、覆盖范围和不确定性的反馈。用户纠错、人工复核、申诉和线上质量数据又回到题库、评分标尺和发布流程,推动下一版改进。只有材料、能力、题目、对话、证据、评分、反馈和复盘首尾相接,产品才是可管理系统;只让模型自然地问几句话,只能证明一次演示能进行。
这条闭环直接决定产品能否经营。材料必须说明来源,题目必须说明为什么被选中,追问必须受轮次和范围约束,分数必须指向回答或测试结果,技术故障必须与能力不足分开,旧报告必须能还原当时使用的题库、模型和规则。这样,团队才能回答三个基本问题:这次结果依据什么;如果错了,影响到谁;修复后怎样恢复而不改写历史。第一版因此应先交付“可重复、可解释、出错后可恢复的练习与反馈链路”,再逐步增加语音、检索、代码执行和更高风险用途。
【事实】 DeepInterview 是以实时语音为主要交互方式的模拟面试系统。固定源码覆盖网页体验、简历与职位描述解析、公司信息检索、问题规划、实时对话、逐字稿、结构化评分、报告和数据保存,并非单纯的界面样机;但真实媒体、语音识别与合成、模型、完整知识检索、云端数据库和对象存储并未在本次审计中完成端到端运行。报告页在若干尚未就绪的状态使用样例评分卡,所以页面可显示不能证明真实面试评分成功(DeepInterview 审计,报告页源码)。
【事实】 GrillKit 是单用户、本地优先的技术面试训练器。固定源码覆盖理论题、编码题、组合会话、计时、最多两轮追问、结构化 AI 评价、本地数据库、离线语音和可选的隔离代码执行。它定义了候选人可见的公开测试、仅服务端可见的隐藏测试及相应执行流程;但固定题库中 44/44 道编码题均为 AI 模式,测试执行模式、公开测试和隐藏测试的数量都为 0。因此项目说明中的“运行公开测试、提交后运行隐藏测试”是能力描述,不是当前题库已验证的体验(GrillKit 审计,task spec,run tests)。
【建议】 第一版应定位为候选人自主练习与形成性反馈工具,而非自动录用、淘汰、排名或远程监考系统。应组合 DeepInterview 的上下文准备和语音闭环,与 GrillKit 的确定性状态机、题目快照和代码执行边界;不应照搬两者的默认信任网络、未校准模型分数或不完整数据治理。招聘评估必须作为独立高风险产品线重新完成岗位效度、法律审查、公平性校准、人工复核和申诉机制。产品明确排除真实面试中的隐蔽监听、实时提词、代答、伪造身份和规避监考。
A. 一场 AI 面试如何真正完成
结论:一场面试真正完成,不是页面出现“已结束”,而是每个结论都能沿着材料、计划、回答和评分一路查回去。 以下用一个贯穿案例解释建议流程。人物、岗位、回答和数值均为示例,不代表两个参考项目已经实现或达到相同质量;引用的工程切片则来自固定源码与两份审计。
候选人林晨申请“中级后端工程师”。他的简历(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_ERROR、TEST_FAILED、NOT_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_CONFIDENCE、MODEL_TIMEOUT、SESSION_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 graph,shared models)。 - 【事实】 LLM 输出之外保留确定性不变量:competency 绑定计划目标,分数限制在 0–5,level 由数值派生;未答题被跳过并由 coverage 表达,而非误记零分(evaluator)。
- 【事实】 单题失败隔离;无答案标记
no_answers且不落虚假零分报告;同进程有 session 评分锁和完成态短路(post pipeline)。 - 【事实】 SessionGuard 限制时长/turn,TranscriptFlusher 周期保存,体现实时链路的崩溃恢复意识(guard,flusher)。
不可照搬:
- 【事实】
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 phases,create 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 adapter、RAG 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/TestRun;ScoreEvidence/ScoreCard;KnowledgeDocument/Chunk;ProviderCall;DomainEvent/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-Key 和
expected_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/stream、STT.stream、TTS.stream、Embedding.embed、Search.search、Knowledge.ingest/query、CodeExecutor.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_locale、question_locale、candidate_speech_locale、voice_locale、evaluation_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. 本地研究入口和阅读顺序
- 先读 DeepInterview 审计 的执行摘要、流程、安全、测试和限制。
- 再读 GrillKit 审计 的执行摘要、题库、迁移、安全、测试和限制。
- DeepInterview 主链路:prep graph → worker → evaluator → report。
- DeepInterview 边界:auth → repository → Supabase migration → 报告页。
- GrillKit 主链路:session phases → create session → structured evaluation → submit solution。
- GrillKit 判题/部署:task spec → run tests → Judge0 → Compose → entrypoint。
- 最后读 DeepInterview README 和 GrillKit 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_url、jd_text、company、language_mode
和可选
owner;CandidateProfile、JobSpec、GapAnalysis、PlannedQuestion、QuestionPlan
与 InterviewContext 都是 extra="forbid" 的
Pydantic 契约,计划明确包含
section、双语题面、难度、rubric、follow-up、目标能力、总时长和语言模式(shared
models、context)。这说明输入不只是字符串,而应至少携带
tenant_id、session_id、source、内容哈希、解析器版本、语言、许可、时间戳与
provenance。CV 中“掌握 Kafka”只能形成 candidate claim;JD
中“负责分布式系统”只能形成 job
requirement;它们都不是已经证实的能力。
处理。 【事实】Prep 的每个节点只向
PrepState 增量写入自己计算的字段,结构为
candidate/job/company/gap/plan,这相当于类型化的中间表示(prep
state)。CV/JD 先抽取实体与规范化技能,再由 gap matching 计算
matched_skills、missing_skills、strengths、gaps
和 probe_targets;题目规划器消费
candidate、job、company、gap 和 language mode,并可注入受字符预算限制的
playbook 片段(prep
nodes、planner)。【建议】生产算法应把能力模型写成有向映射: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_REJECTED 或
PREP_DEGRADED,而非静默发布真实计划。所有这些数值都是建议初始目标。
二、实时语音:WebRTC、VAD、STT、EOU、LLM、TTS 与 barge-in 是并发控制问题
实时体验的核心不是某个语音模型,而是多个异步流的时序正确性。浏览器持续产生音频帧;VAD
判断“有人声”,STT 持续产生 partial/final 文本,EOU
判断“这一轮是否结束”,LLM 可能预生成,TTS 又把 token
转成可播放音频。任何阶段都可能迟到、重试或被取消,因此每一轮必须带
turn_id 与
generation_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
handling、VAD
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.started、stt.partial、stt.final、turn.endpointed、turn.committed、generation.started、tts.chunk、assistant.interrupted、provider.failed
和
media.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 只返回“建议的语义动作”,命令处理器根据当前状态、版本和策略决定是否接受。
输入。
状态机输入不是自然语言,而是命令:SubmitPrep、PublishPlan、JoinLive、CommitTurn、SubmitAttempt、RunCode、FinishSection、StartScoring。每个命令携带
actor、tenant、aggregate id、expected_version、idempotency
key、deadline 和必要 payload。LLM 输出必须先解析成受限 DTO,例如
follow_up_needed、follow_up_question 或 rubric
评分,不能直接提交任意状态字符串。
处理。 【事实】GrillKit 由四种 session
mode 映射固定 section 顺序,服务查询 section 是否
pending/active/complete 再推进;不是由模型决定先理论还是先编码(phase
order、advance
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 已将
AnswerSavedEvent、EvaluatingEvent、AnswerFeedbackEvent、TranscriptEvent、InterviewCompletedEvent
定义为 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(NaiveRAG、query)。它以
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_set 和
generated_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
snapshots、coding
snapshots)。
处理。 理论题先按 rubric
做结构化评价,再由状态机决定是否创建追问;追问用于减少证据不充分,不应只是“低分再问一次”。GrillKit
将 schema 放进 system prompt,使用 Pydantic 解析;截断或 invalid JSON
最多重试一次,第二次 token budget 上限的源码事实值为
4096(非建议目标)(structured
evaluation、retry)。
编码的 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 solution、AI 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;同能力多题取平均;未回答题跳过(evaluator、coverage
handling)。报告的 overall 是 competency 均值,coverage
是已回答计划题占比(report、assembly)。这体现了关键原则:没测到不是零分,低
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(UnitOfWork、submit
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 缺失时返回
MockLLM(LLM
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 建议初始目标完成 2×
预测峰值压力、独立渗透、灾备和关键公平性 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,而是一套在失败、重试、升级和争议发生时仍能解释“输入是什么、经过什么处理、输出依据什么、哪里失败、为何可以恢复”的系统。