Skip to content

AI 面试教练项目

目录

1. 项目摘要

  • 项目类型:学习型生产项目设计;
  • 一句话目标:根据岗位和候选人的实时回答,一次提出一道问题,动态追问并给出有证据的多维评分与复习计划;
  • 主要用户:准备 AI 应用、AI 后端、算法或系统设计面试的学习者;
  • 核心技术:LLM、RAG、Agent、结构化评分、状态机、评测集和可观测性;
  • 最关键难点:追问质量、评分稳定性、事实证据、长对话状态、安全边界和效果验证;
  • 核心设计:外层使用确定性面试状态机,内层只在“分析回答和选择追问”环节使用 Agent;
  • 当前边界:本文是可实施设计,不代表系统已上线,也不声明任何未经实测的准确率或业务效果。

1.1 30 秒项目结论

我设计的不是一个“让模型随便提问”的聊天机器人,而是一套由能力图谱、题库、RAG、评分 Rubric 和受控 Agent 组成的面试训练系统。外层状态机保证一次一题、轮次、预算和结束条件,Agent 根据用户回答中的正确点、遗漏和错误选择下一道追问,评分器必须输出证据片段和分维度理由,最终把失败样本沉淀为复习任务和回归评测集。

1.2 为什么适合作为面试项目

该项目能同时展示:

  • 如何把 LLM 的自然语言能力变成结构化产品流程;
  • 为什么 RAG、Agent 和 Workflow 各自承担不同职责;
  • 如何处理评分漂移、幻觉、提示注入和长对话;
  • 如何设计离线评测、线上指标、成本与降级;
  • 如何用状态、证据和日志排查“主流程成功但质量失败”。

2. 背景、目标与约束

2.1 业务背景

传统题库只能展示固定答案,普通聊天模型又容易一次问多题、提前泄露答案、重复追问或给出没有证据的分数。学习者真正需要的是:回答后立即暴露知识缺口,并通过连续追问检验是否理解原理和工程边界。

2.2 功能目标

  1. 根据目标岗位、级别、主题和时间创建面试;
  2. 一次只展示一个主要问题;
  3. 从回答中抽取事实点、推理链、项目证据、错误和遗漏;
  4. 根据缺口选择追问、提示、讲解、切换主题或结束;
  5. 从准确性、原理深度、工程意识、项目表达和沟通结构五个维度评分;
  6. 每个分数提供引用用户回答的证据和改进建议;
  7. 生成主题掌握图、错题清单和间隔复习计划;
  8. 支持暂停、恢复、退出、删除记忆和导出复盘。

2.3 成功标准

不能用“模型回答看起来不错”作为验收。至少定义:

  • 题目是否与岗位、主题和难度匹配;
  • 是否保持一次一题且追问来自上一轮缺口;
  • 评分是否能引用真实回答证据;
  • 同一答案多次评分是否在可接受范围内;
  • 知识引用是否来自允许且有效的文档版本;
  • 是否能在服务重启后恢复会话;
  • 是否能识别退出、拒答和需要人工澄清的场景;
  • 延迟、成本和敏感数据是否符合产品约束。

具体阈值必须通过标注集、基线和实测确定,本文不虚构数值。

2.4 输入、输出与主要数据

输入:

  • 目标岗位、级别、知识主题和面试时长;
  • 用户回答、代码片段和项目描述;
  • 题库、知识文档、评分 Rubric 和历史薄弱点;
  • 用户对数据保存、难度和反馈方式的偏好。

输出:

  • 当前问题、必要提示和动态追问;
  • 分维度评分、证据、错误和遗漏;
  • 更好的 30 秒与 3 分钟回答;
  • 主题覆盖、薄弱点、复习任务和面试复盘;
  • 完整但受控的执行轨迹。

2.5 非功能约束

  • 交互延迟:问题生成和反馈适合流式返回;
  • 一致性:题目、评分和知识引用需要版本化;
  • 隐私:用户项目经历和答案按租户隔离并可删除;
  • 安全:用户输入与检索文本不能修改系统评分规则;
  • 成本:限制每轮上下文、工具和反思次数;
  • 可恢复:状态不能只保存在模型上下文或浏览器;
  • 可解释:最终分数必须有可定位证据。

3. 系统架构与调用链

3.1 组件职责

组件职责不能承担的职责
面试会话 API鉴权、创建、暂停、恢复、事件输出不直接决定面试内容
面试状态机控制轮次、阶段、预算和终止不自由生成追问
能力图谱与题库定义主题、难度、前置和覆盖不保存用户私密答案
回答分析器抽取事实点、错误、遗漏和项目证据不直接写最终分数
RAG 服务检索可靠知识和参考答案不决定用户是否通过
追问 Agent根据缺口选择下一动作不绕过状态机和预算
Rubric 评分器分维度评分并引用证据不执行真实副作用
状态与报告服务保存轮次、分数、薄弱点和报告不把调试日志当用户记忆
评测与观测回归、Trace、指标和告警不替代业务验收

3.2 技术栈、框架、库与组件清单

技术点 ID技术点/环节类型采用方案链路职责版本/证据边界
TP-01会话编排与恢复状态机/工作流模式持久化面试状态机 + 幂等事件 + 检查点控制轮次、预算、暂停、恢复、终止和唯一状态迁移当前是示例项目设计;框架选型需由恢复演练、并发与运维约束验证
TP-02知识证据检索RAG 服务 + 索引组件权限与版本过滤的混合召回、融合和 Rerank为回答分析和评分提供带来源、版本的知识证据是否需要向量库和 Rerank 由真实题库、查询集及 Recall/引用指标决定
TP-03回答评分与追问Schema、Rubric + 受控 Agent独立 Rubric 评分器;Agent 只选择下一动作抽取缺口、生成可解释分数,并在预算内追问/讲解/结束模型输出不是事实;须用重复评分、专家标注、越权和恢复测试验证

3.3 横向选型对比

技术点 ID候选方案优点缺点/代价适用场景不适用场景选择结论与依据
TP-01模型上下文或进程内会话状态实现快、链路短、原型成本低重启丢失、并发覆盖、恢复和审计困难单用户演示、短会话、允许重新开始多租户、长会话、暂停恢复与计费只用于原型;需要恢复、幂等或审计时切换持久化状态机
TP-01持久化状态机/工作流生命周期、版本冲突和恢复边界明确状态设计、迁移和运维复杂度更高正式面试、跨设备恢复、异步报告一次性无状态问答通过断连、重复提交和 Worker 重启演练后采用
TP-02固定题库/关键词检索可解释、成本低、专有术语稳定同义问法和开放知识覆盖弱题目范围小、知识变化低项目追问、自然语言变体和大量资料早期基线保留;检索失败切片证明语义缺口后升级
TP-02混合检索 + Rerank兼顾精确词和语义召回,排序可优化索引、延迟、版本和评测治理更复杂知识量大、问法多样、要求引用资料很少或没有可靠评测集以离线 Recall、排序和端到端引用正确率共同决定
TP-03单次 LLM 自由评分并直接追问原型快、表达灵活分数漂移、证据弱、状态和权限边界不清低风险练习、只给建议不做结论招聘决策、稳定评分、审计场景不能作为高风险最终评分;只保留为探索性建议
TP-03结构化 Rubric + 受控 Agent分数与动作职责分离,证据和停止条件清晰Schema、标注、评测和编排成本更高可解释训练、连续追问、质量回归无 Rubric、无专家样本的开放闲聊重复评分一致性和专家相关性达到门禁后使用

3.4 系统架构图

图:架构|AI 面试教练组件职责与治理边界

替代文本: 会话 API 把请求交给 TP-01 状态机,状态机编排能力图谱、回答分析、TP-02 RAG、TP-03 Rubric 与受控 Agent,最终把轮次状态和证据写入存储;评测、权限和观测作为横向治理能力覆盖链路。

图表加载中…

读图结论: LLM 和 Agent 是可替换能力组件,确定性状态机、Rubric、证据存储、权限和评测共同守住业务结果。

图中每个生成组件只能在状态机分配的输入、动作和预算边界内工作;最终状态和分数必须由可审计服务提交。

3.5 端到端调用链

图:技术调用流程|一次回答从提交到下一轮追问

图表加载中…

替代文本: 用户回答先经过轮次与版本校验,再进入分析、知识检索、Rubric 评分和受控追问;成功时状态机事务保存并返回下一轮,旧轮次、依赖超时或结果不可验证时记录冲突/检查点,并返回同一 Run 的降级或恢复入口,避免重复创建轮次。

读图结论: 追问由 Agent 动态决定,但评分、预算、状态和终止由确定性服务掌握。

图中回答分析器负责抽取缺口,RAG 提供可追溯证据,追问 Agent 只给出候选动作;真正提交状态变更的是状态机,并在事务保存成功后才向用户返回下一题或复盘结果。

3.6 状态机

图 2:面试会话从创建、追问到中断恢复和终止的生命周期

替代文本: 会话从创建、配置、提问、等待回答、分析、评分进入下一步决策;决策可继续提问、解释缺口或正常结束。任一非终态都可暂停、等待外部输入、进入可重试失败、不可恢复失败或取消,其中恢复和重试分别回到持久化的原状态或检查点。

图表加载中…

读图结论: 正常面试路径可以动态循环,但暂停、外部输入、失败、重试和取消都必须通过显式状态迁移;只有 FINISHEDFAILED_FINALCANCELLED 能结束生命周期。

图中的 任一非终态(图示汇总) 不是数据库中的真实枚举,而是把所有可中断工作状态的公共迁移集中展示。PAUSEDWAITING_FOR_INPUT 依赖 resume_state 回到被打断的位置,FAILED_RETRYABLE 依赖 checkpoint_state 从安全检查点重跑;不可恢复失败与主动取消则直接进入终态,不能原地恢复。

resume_statecheckpoint_state 必须随事件持久化,不能由模型自由填写。FINISHEDFAILED_FINALCANCELLED 是终态;恢复失败时要重新打开会话或创建新会话。

当前状态允许的外部命令关键校验下一状态
CONFIGURINGSAVE_CONFIG岗位、主题、预算合法ASKING
WAITING_FOR_ANSWERSUBMIT_ANSWER当前 round、session version、轮次唯一ANALYZING
PAUSEDRESUME操作者与会话一致,resume_state 可恢复resume_state
WAITING_FOR_INPUTPROVIDE_INPUT输入类型和请求 ID 匹配resume_state
FAILED_RETRYABLERETRY错误可重试、预算未耗尽、检查点存在checkpoint_state
任一非终态PAUSE / CANCEL权限与当前版本PAUSED / CANCELLED

其他状态收到旧答案或不允许命令时返回冲突,不靠 Prompt 猜测是否接受。每次迁移携带 version 和事件唯一键,拒绝旧请求覆盖新轮次。

3.7 上下游依赖

  • 上游:身份、岗位配置、用户授权和知识库;
  • 下游:模型供应商、向量/关键词索引、报告服务和通知;
  • 横向:模型网关、预算、缓存、Trace、审计和评测集;
  • 降级:固定题库、规则评分、延迟生成完整复盘。

4. 核心技术方案

4.1 能力图谱与题目模型

每道题不是孤立字符串,至少包含:

  • topic_id、难度和岗位适用范围;
  • 前置知识和可追问能力点;
  • 合格答案要点、加分项和常见错误;
  • 可引用的一手知识来源;
  • 最大追问深度和结束条件;
  • 题目、Rubric 和 Prompt 版本。

能力图谱用于保证覆盖和难度递进,避免模型只围绕熟悉词语随机出题。

4.2 回答分析 Schema

json
{
  "claims": [{"text": "...", "status": "correct|wrong|uncertain"}],
  "covered_points": ["..."],
  "missing_points": ["..."],
  "project_evidence": [{"quote": "...", "strength": "weak|medium|strong"}],
  "ambiguities": ["..."],
  "suggested_followup_capability": "...",
  "citations": [{"document_id": "...", "version": "..."}]
}

所有字段需要 Schema 校验。uncertain 不能被悄悄转成错误或正确,必要时通过追问确认。

4.3 RAG 方案

检索 Query 由当前题目、目标能力和回答中的关键 Claim 共同构成,而不是直接使用整段回答。过滤条件包括主题、文档状态、岗位、语言和权限。返回结果经过重排,并保留原文片段、来源和版本。

检索失败时:

  • 不以模型记忆替代事实来源;
  • 将事实评分标记为证据不足;
  • 可以继续考察表达结构或请求澄清;
  • 把空召回记录到评测样本。

4.4 评分模型

五个维度各 0-5 分,但分数不是单一模型直觉。完整 0~5 锚点以 AI 面试冲刺题库与复盘的五维评分 为单一事实源,QuestionVersion 保存所用 rubric_version。每个维度包含:

text
score = rubric_level(answer_evidence, expected_points, error_severity)

若第 i 个维度分数为 si,岗位权重为 wi,则:

S5=iwisi,iwi=1,S25=5S5

默认等权只是初始配置;权重、阈值和 Rubric 必须共同版本化。严重错误使用硬门禁,不能被其他维度平均掩盖:核心事实反向时 accuracy 不高于 1;虚构项目贡献时 project 为 0 且禁止标记 mastered;建议直接执行越权或重复副作用时 engineering 不高于 1。门禁命中、证据不足和 Judge 不一致都要进入人工复核。

评分输出必须包含:

  • 引用用户回答的原句;
  • 对应 Rubric 等级;
  • 评分理由和命中的严重错误门禁;
  • 未覆盖的关键点;
  • 严重错误和不确定项;
  • 如何提升到下一级,以及下一次复测动作。

最终分数必须连同 rubric_versionweight_version、证据和门禁结果保存,才能重放和解释。

4.5 Agent 决策空间

追问 Agent 只能从有限动作中选择:

  • ASK_FOLLOWUP(capability_id)
  • ASK_CLARIFICATION(reason)
  • GIVE_HINT(level)
  • EXPLAIN_GAP(point_ids)
  • MOVE_TO_NEXT_TOPIC(topic_id)
  • FINISH(reason)

状态机检查问题是否重复、主题是否允许、预算是否足够以及是否触发结束条件。模型不能自行修改分数、用户权限或最大轮次。

4.6 状态与数据模型

实体关键字段一致性要求
InterviewSessionuser、role、level、state、resume/checkpoint_state、version乐观锁更新
Roundquestion、answer_hash、analysis、score、revision、analysis_status、worker/lease/attempt(session_id, round_id) 唯一;分析任务原子认领;修改走显式 revision
QuestionVersiontopic、rubric_version、prompt、sources不可变版本
RubricVersion0~5 锚点、权重版本、严重错误门禁可重放、不可原地覆盖
Evidenceanswer span、document span、source可追溯
Weaknesscapability、confidence、first/last seen用户隔离与 TTL
AgentRunmodel、tools、steps、termination可审计、可恢复
EvalCaseinput、expected、labels、versions固定回归
OutboxEventevent_id、round_id、type、published_at与业务事务原子写入、至少一次投递

4.7 最小伪代码

python
def accept_answer(session_id, round_id, answer, expected_version):
    answer_hash = stable_hash(answer)
    with transaction() as tx:
        session = tx.lock_session(session_id)
        existing = tx.find_round(session_id, round_id)
        if existing:
            if existing.answer_hash != answer_hash:
                raise Conflict("round already has a different answer; create revision")
            return existing  # 完全相同的重放
        require(
            session.state == "WAITING_FOR_ANSWER"
            and session.current_round_id == round_id
            and session.version == expected_version
        )
        round_record = tx.insert_round_unique(
            session_id=session_id,
            round_id=round_id,
            answer=answer,
            answer_hash=answer_hash,
            status="ANALYSIS_PENDING",
        )
        tx.transition_session(session, "ANALYZING", expected_version)
        tx.insert_outbox_unique("ROUND_ANALYSIS_REQUESTED", round_record.id)
    return round_record


def analyze_round(round_id, worker_id):
    # ANALYSIS_PENDING/RETRYABLE -> RUNNING 使用条件更新原子认领。
    claim = claim_round_for_analysis(
        round_id=round_id,
        worker_id=worker_id,
        lease_seconds=300,
    )
    if claim is None:
        return  # 已被其他有效租约认领或已经完成

    # 慢调用在事务和数据库锁之外执行;长调用期间续租。
    snapshot = claim.immutable_snapshot
    question = load_immutable_question(snapshot.question_version_id)
    try:
        analysis = analyze_answer(question, snapshot.answer)
        evidence = retrieve_evidence(question, analysis.claims)
        score = grade_with_rubric(
            question.rubric_version, snapshot.answer, analysis, evidence
        )
        action = enforce_policy(
            snapshot.session_state,
            decide_next_action(snapshot, analysis, score),
        )
    except Exception as error:
        mark_retryable_if_lease_owner(round_id, claim.lease_token, error)
        raise

    with transaction() as tx:
        # 只有仍持有有效租约的 Worker 能提交同一个分析版本。
        completed = tx.complete_round_once_if_lease_owner(
            round_id,
            claim.lease_token,
            analysis,
            evidence,
            score,
            action,
        )
        if not completed:
            raise LeaseLost("analysis lease expired or ownership changed")
        advanced = tx.advance_session_if_current(
            snapshot.session_id,
            snapshot.session_version_after_accept,
            action,
        )
        if not advanced:
            raise Conflict("session version changed; rollback round completion")

接收答案的短事务只做状态校验、(session_id, round_id) 唯一占位、版本迁移和 Outbox 写入;相同轮次只有一个主答案,重复 Payload 返回已有结果,不同 Payload 返回冲突,修改必须走显式 revision

Outbox 是至少一次投递,所以 Worker 在任何模型调用前必须把 ANALYSIS_PENDING/RETRYABLE -> RUNNINGworker_id、lease_until、attempt 条件更新为原子认领。有效租约避免两个 Worker 并发产生模型费用;长任务定期续租,过期后由看门狗在核对现有调用状态后回收,并受最大 attempt/预算限制。提交阶段必须在同一数据库事务中完成“验证租约 → 完成 Round → 推进 Session”;丢失租约时抛错并回滚整笔事务,绝不能继续推进旧 Action。对支持幂等请求键或结果查询的模型供应商复用稳定调用 ID;供应商不支持时,进程在响应落库前崩溃仍可能产生重复费用,必须记录为残余的至少一次边界,不能宣称 exactly-once。

5. 关键权衡

决策选择备选方案原因代价与风险
外层控制状态机完全自由 Agent保证一次一题、预算和恢复需维护状态与动作协议
评分Rubric + 证据模型直接给总分可解释、可评测Rubric 建设成本
题目来源题库 + 动态变体完全临时生成覆盖稳定且可追溯题库维护与版本
知识来源RAG + 一手资料仅模型参数知识降低事实漂移检索失败和索引治理
对话历史结构化状态 + 摘要全量消息回放控制 Token 与噪声摘要可能丢信息
多 Agent初期单 Agent + 工具多专家 Handoff降低协调复杂度单 Agent 提示更复杂

5.1 性能与成本

  • 轻量模型完成结构抽取,复杂评分或追问按需升级;
  • RAG 只在事实判断需要证据时执行;
  • 题目和 Rubric 缓存按版本复用;
  • 完整报告异步生成,不阻塞下一题;
  • 每会话设置 Token、轮次、工具和费用预算;
  • 记录每阶段成本,不能只看模型总账单。

5.2 安全、权限与隐私

  • 用户答案和项目经历按租户与用户隔离;
  • 检索文档是外部数据,不能覆盖系统规则;
  • Trace 默认不保存不必要的敏感原文;
  • 长期薄弱点记忆需用户可见、可删除;
  • 导出和分享报告使用短期签名与明确授权;
  • 管理员查看训练数据需要独立审计。

5.3 可维护性

  • 模型、Prompt、题目、Rubric、文档和索引分别版本化;
  • 业务状态使用内部枚举,不复制供应商状态;
  • 模型响应通过适配层归一化;
  • 新岗位通过能力图谱和 Rubric 扩展,不复制整套流程;
  • 失败样本进入回归集,防止修复只停留在 Prompt 热补丁。

5.4 技术难点清单

技术难点为什么难核心矛盾可落地抓手
评分正确、稳定与可解释同时成立自然语言答案允许多种正确表达,模型评分又会随上下文、随机性和版本变化语义判断需要模型弹性,用户申诉与产品验收需要确定性证据版本化 Rubric、答案原文 Span、知识证据、严重错误门禁、重复评分与人工一致性评测
动态追问与面试流程控制高质量追问必须承接上一轮缺口,但自由 Agent 容易重复、越级、泄露答案或无法结束个性化探索与一次一题、预算、覆盖和终止约束相互牵制能力图谱、有限动作枚举、状态机校验、问题指纹、最大追问深度
RAG 证据冲突与不可信输入检索结果可能为空、过期、互相矛盾或包含间接 Prompt Injection需要外部知识核验事实,又不能让外部文本改变系统评分规则来源白名单、权限与版本过滤、指令/数据隔离、引用 Schema、证据不足状态与人工复核
异步分析的一致性与重复费用模型响应慢且不可放在长事务中;Worker 在响应落库前崩溃会留下结果不确定区间数据库状态希望原子推进,外部模型调用无法参与本地事务短事务占位、Outbox、租约认领与续租、稳定调用 ID、提交阶段所有权校验
长对话状态与可删除记忆全量回放会增加噪声、延迟和成本,摘要又可能丢掉关键证据;长期记忆还涉及租户隔离和删除个性化需要历史,评分重放与隐私要求又限制历史使用原始 Round、结构化状态、阶段摘要分层保存;证据回指原文;记忆 TTL、作用域和删除审计
质量改进的因果归因模型、Prompt、题库、Rubric、语料和索引可能同时变化指标变化容易被误归因,回滚时也无法定位责任版本固定 EvalCase、全链路版本快照、单变量灰度、影子评测和失败样本回归

5.5 方案亮点的证据化表达

以下亮点仍是待实现、待验证的设计主张。面试表达应同时给出验证材料;没有代码、测试、Trace 或评测结果时,只能说“设计了验证方案”,不能说“已经解决”。

问题关键决策证据或验证方式适用边界
自由 Agent 容易破坏一次一题和结束条件外层由状态机掌握状态、预算和终止,Agent 只从有限动作空间建议下一步重放重复题、越权改分、多问一题和超预算动作,核对策略层拒绝记录与状态不变开放式陪练可放宽动作,但计分面试、考试或高影响反馈仍需确定性控制
总分看似合理却无法解释分数必须绑定回答 Span、Rubric 等级、知识来源、版本和门禁命中对每个分数执行证据完整性检查;用同一答案重复评分并与人工区间比较主观表达维度无法完全变成客观事实,仍需置信度、申诉和人工复核
Worker 重试可能重复调用模型并推进两轮接收答案、异步分析和状态提交分段;使用 Outbox、租约所有权与乐观锁控制提交注入重复消息、租约过期、响应后崩溃和并发提交,核对调用 ID、Round 唯一约束与 Session 版本供应商不支持幂等或查询时,仍可能产生重复费用,不能承诺端到端 exactly-once
RAG 不可用时系统容易编造事实判断将“证据不足”作为显式结果,只继续结构评分或请求澄清,不用模型记忆冒充来源注入空召回、过期索引和冲突文档,核对事实分数降级、引用为空和用户提示结构、沟通等不依赖外部事实的维度可继续评估,但不能借此判定技术 Claim 正误
Prompt 热修复容易反复引入旧问题将失败 Round 连同输入、期望、证据和版本固化为 EvalCase,发布前影子回放对模型、Prompt、Rubric 或索引变更运行固定回归并比较分项差异EvalCase 只能覆盖已知分布,仍需持续采样新岗位、口语和恶意输入

6. 实现难点与故障处理

6.1 问题矩阵

现象根因解决验证
追问与上一回答无关Agent 只看到摘要、缺口 Schema 为空保存证据片段;动作绑定 capability人工标注追问相关集
重复问相似问题无问题指纹和覆盖状态语义去重、能力覆盖图、最大深度长会话回归
同一答案分数变化大Rubric 模糊、随机性、证据不同固定 Rubric、低随机性、版本和示例锚点重复评分方差
错误答案获高分只评价表达,不核对事实RAG 证据、严重错误门槛、反例集错误样本召回测试
检索内容操纵评分间接 Prompt Injection指令/数据隔离、来源白名单、结构化引用恶意文档红队集
上下文越来越慢全量对话和工具结果回放结构化状态、阶段摘要、按需原文长度与延迟曲线
提交后一直处理中状态只在 Worker 内存事件、检查点、看门狗、可重试状态Worker 重启测试
同一回答生成两轮客户端重试无幂等轮次版本 + answer hash 唯一约束重放请求测试
用户间记忆串线查询缺少 tenant/user 过滤强制作用域、行级权限、审计跨用户渗透测试
模型不可用导致面试中断无降级路径固定题库、规则反馈、异步复盘故障注入和切换测试

6.2 排查顺序

  1. 查询 session_id 当前状态、版本和最近事件;
  2. 确认问题版本、回答哈希和本轮是否已提交;
  3. 查看回答分析、检索证据、Rubric 和 Agent 动作;
  4. 区分模型失败、检索失败、状态冲突和客户端重复;
  5. 检查 Prompt/模型/索引/Rubric 版本是否发生变化;
  6. 将可复现失败加入固定评测集,再修复和回归。

6.3 超时、重试与降级

  • 回答分析超时:使用规则抽取或请求稍后重试;
  • RAG 超时:标记证据不足,继续结构评分;
  • 评分失败:不伪造分数,保存本轮并异步补评;
  • Agent 决策失败:按能力图谱选择固定下一题;
  • 报告生成失败:面试状态不回滚,只重试报告任务;
  • 状态提交冲突:重新加载最新版本,禁止覆盖新轮次。

6.4 生产易发问题闭环

当前项目没有线上事故和实测报告,所以下表用于实现评审、故障演练和未来复盘。表中的“证据”是必须采集的定位材料,“根因”是常见候选而非已经发生的事实。

现象影响证据根因止损修复验证预防
同一答案在发布后分数整体漂移用户前后结果不可比,掌握度和复习计划被污染Answer hash、评分明细、证据 Span、模型/Prompt/Rubric/索引版本及发布批次多个评分依赖同时升级,Rubric 锚点变化或检索证据集合变化暂停新评分展示;切回上一版本;保留原结果并标记待复评,不直接覆盖历史分数评分快照版本化,依赖单变量灰度;对必要样本创建显式 revision用冻结答案集做新旧版本盲评,比较分维度变化、严重错误门禁和人工区间发布前影子评测;为漂移、门禁反转和证据变化设告警;禁止无版本热改
接口成功但追问无关、重复或突然跳级会话仍可用但训练质量失败,用户无法暴露真实缺口Round Trace、回答分析 Schema、缺口列表、候选动作、问题指纹、能力覆盖状态分析器漏抽取,摘要丢失证据,Agent 未绑定 capability 或去重只按字面暂停动态追问,回退到固定题库或请求澄清;不让错误动作继续污染覆盖图强制动作绑定缺口能力;语义去重;保存证据 Span;调整追问深度和终止规则用标注的相关/重复/难度样本跑长会话回归,并人工检查动作链单独监控追问相关率、重复率和回退率;失败 Round 自动进入评测候选池
一次提交产生两次分析费用或会话跳过一轮增加成本,分数与下一题竞争写入,状态不可解释Outbox 消费记录、Worker/lease/attempt、供应商调用 ID、Round 唯一键、Session version至少一次消息重复投递、租约过短或丢失所有权后旧 Worker 仍提交冻结该 Session 推进;撤销过期 Worker 提交权;保留唯一主 Round 并对账外部调用原子认领与续租;提交时校验 lease token;Round 唯一约束和 Session 乐观锁放入同一事务注入重复消息、长模型调用、租约过期和并发提交,确认只有所有者能完成与推进监控单 Round 多调用和 lease lost;租约按长尾设置且受最大 attempt/预算约束
RAG 返回内容却把错误答案判为正确错误知识被强化,评分公信力和复习内容受损Query、召回与重排结果、document/version、引用 Span、门禁命中和评分 Prompt召回文档过期或冲突,评分器只看语义相似,检索文本注入系统指令将该事实维度标记证据不可信并暂停发布分数;切换允许来源或交人工复核来源与状态白名单、冲突检测、引用蕴含校验、指令/数据隔离和严重错误反例集用过期、冲突、恶意和“表述相似但结论相反”的文档做红队回归文档、索引和引用版本可追溯;监控来源分布、空召回、冲突与引用失配
暂停恢复后重复上一题或丢失当前答案用户进度受损,旧请求可能覆盖新状态Session 事件序列、resume/checkpoint_state、current_round_id、客户端 expected_version、流式连接记录只保存页面或模型上下文,状态与响应流不同步,恢复时未校验版本停止接受该会话新答案;按持久化事件重建状态并向用户确认当前题状态迁移事务化;响应携带 session/round/version;恢复只使用服务器检查点在 ASKING、ANALYZING、SCORING 和流式中断点分别重启,验证恢复位置与幂等提交定期执行会话恢复演练;对状态年龄、版本冲突和重复题告警
用户看到其他人的薄弱点、项目经历或报告片段严重隐私与租户隔离事故tenant/user 查询条件、授权决策、缓存键、向量过滤、Trace 和导出审计查询漏作用域、共享缓存键、索引元数据缺失或后台任务丢失身份上下文立即关闭受影响查询/分享入口,撤销链接与缓存,保全审计并启动通知流程在 Repo、缓存、RAG、对象存储和导出层统一强制租户作用域;后台任务携带不可伪造身份跨租户渗透测试、缓存碰撞、异步任务和删除后检索回归行级权限与策略测试进入 CI;敏感 Trace 最小化;对跨租户命中零容忍告警

6.5 可复用经验积累

可复用经验适用信号推荐做法使用边界
“接口成功”与“质量成功”必须分开观测请求无报错但追问、评分或引用明显变差技术成功率之外,单独记录相关性、重复、证据完整性、门禁和人工纠错质量指标需要标注口径,不能只凭用户停留时长推断
模型输出是建议,不是业务事实或状态源LLM 能生成分数、动作、记忆和终止理由Schema 校验后交给策略层;权限、状态、预算和终止由代码决定低风险文案生成可以更自由,但涉及分数、权限和副作用必须受控
评分链要能从结果反向追到原文和规则用户申诉时只能看到一句“模型认为”保存 Answer Span、知识 Span、Rubric/权重/Prompt/模型版本和门禁结果可追溯不等于结论必然正确,仍需人工复核和纠错 revision
按至少一次语义设计外部调用队列、网络和 Worker 都可能重试业务唯一键、Outbox、原子认领、幂等提交、所有权校验与补偿外部供应商无幂等时只能控制内部状态,不能消除所有重复费用
降级时要同时降低结论强度RAG 或评分器失败后仍想保持会话可用可以继续固定题或结构反馈,但显式标记证据不足、延迟评分或转人工不得用模型参数知识伪装成已检索的一手证据
长期记忆必须有完整生命周期个性化数据不断累积且会进入后续 Prompt定义来源、用途、作用域、置信度、TTL、用户可见性、删除与审计调试日志不是用户记忆;删除业务数据也要处理索引、缓存和备份策略
每次质量修复都要转化为评测资产问题靠改 Prompt 暂时消失,升级后再次出现将失败输入、期望能力、证据、版本和判定规则固化为 EvalCase回归集会老化,需抽样线上新分布并防止针对测试集过拟合

7. 评测、监控与验证

7.1 离线评测集

评测样本至少包含:

  • 完全正确、部分正确、概念混淆和自信错误回答;
  • 只会背定义但不会项目落地的回答;
  • 项目完整但缺少原理的回答;
  • 中英文混合、口语、代码和长回答;
  • Prompt Injection、复制标准答案和无关内容;
  • 同义表达、矛盾表达和主动承认不知道。

每个样本由人工标注覆盖点、严重错误、合理分数区间、推荐追问能力和证据。

7.2 核心指标

质量指标:

  • 题目岗位匹配、追问相关、关键遗漏发现和严重错误识别;
  • 分维度评分与人工评分的一致性;
  • 同一答案重复评分稳定性;
  • 引用正确、问题不重复和结束条件正确。

工程指标:

  • TTFT、每轮端到端延迟和长尾;
  • 模型、检索、评分和 Agent 各阶段成功率;
  • 重试、状态冲突、恢复和降级次数;
  • 单轮 Token、成本和上下文长度;
  • 敏感数据和安全策略命中。

7.3 线上验证

  • 先影子评测,不向用户展示新评分;
  • 再小流量灰度,保留旧版本回滚;
  • 对低置信度和高影响结果人工抽检;
  • 将用户纠错与申诉关联到原始证据;
  • 质量、延迟、成本和安全同时达标才扩大流量。

7.4 监控与 Trace

图 3:Round Trace 从输入快照到状态提交的证据与版本链

替代文本: 每轮以不可变输入快照开始,依次形成回答分析、检索证据、Rubric 评分、候选动作和策略校验,再以事务提交 Round、Session 与 Outbox;各阶段同时把模型、Prompt、题目、Rubric、文档、索引、策略和会话版本汇入同一条 Trace。

图表加载中…

读图结论: Round Trace 不能只记录调用顺序;它要把“基于什么输入和证据得到什么分数、选择什么动作、最终提交到哪个状态版本”连成可重放、可归因的证据链。

输入快照冻结本轮题目和答案身份,证据节点保留来源 Span 与文档/索引版本,评分节点绑定回答 Span、Rubric、门禁和模型版本,动作节点同时记录 Agent 建议与策略层裁决。只有状态事务提交成功后才形成新的 session_version 并输出响应;所有节点共享 trace_idround_id 和版本快照,才能区分模型漂移、检索变化、规则变化与并发覆盖。

每个 Span 还应记录耗时、错误类型和非敏感摘要。原始回答是否进入 Trace 由数据策略控制;即使不保存原文,也应保留受控的哈希、Span 标识或脱敏摘要,避免可观测性破坏隐私边界。

8. 实施路线与复盘

8.1 第一阶段:固定题库与状态机

  • 建立能力图谱、题目和 Rubric;
  • 一次一题、暂停恢复和固定追问;
  • 保存 Round 事件和评分证据;
  • 不引入自由 Agent。

验收:状态稳定、题目可追溯、固定评分流程可回归。

8.2 第二阶段:RAG 与结构化评分

  • 引入知识索引和权限过滤;
  • 回答分析、事实核验和分维度评分;
  • 建设人工标注评测集;
  • 保存模型、Prompt、索引和 Rubric 版本。

验收:评分能引用证据,失败可归因到检索或评分。

8.3 第三阶段:动态追问 Agent

  • 将动作限制为有限枚举;
  • 增加重复检测、预算和终止;
  • 动态调整难度和追问方向;
  • 建立恶意输入和长对话回归。

验收:追问质量优于固定基线,且不破坏状态与安全边界。

8.4 第四阶段:报告与个性化

  • 生成薄弱能力图和间隔复习;
  • 用户可查看、修改和删除长期记忆;
  • 建设岗位级评测、灰度和反馈闭环;
  • 优化模型路由、缓存和异步报告成本。

8.5 当前未验证边界

  • 尚无真实标注集和人工一致性基线;
  • 尚无实际用户完成率、延迟和成本数据;
  • 不应将规划中的模型、框架或指标写成既成事实;
  • 实现后必须用测试、Trace、数据库状态和用户反馈更新本文。

9. 面试表达

9.1 30 秒项目介绍

我把 AI 面试教练设计成“确定性状态机 + RAG 证据 + 受控追问 Agent”。系统一次只问一道题,先结构化分析回答,再检索知识证据,用固定 Rubric 给出分维度评分,Agent 只能在有限动作中选择下一道追问。这样既保留动态追问能力,又能控制轮次、预算、重复、安全和恢复,并通过固定评测集验证评分与追问质量。

9.2 2~3 分钟完整表达

  1. 背景:固定题库没有动态追问,普通聊天模型评分又不稳定;
  2. 约束:一次一题、证据可追溯、长对话恢复、用户隔离和成本;
  3. 架构:会话 API、状态机、题库、分析器、RAG、评分器、Agent 和评测观测;
  4. 关键决策:外层固定 Workflow,Agent 只选择下一动作;
  5. 难点:评分漂移、重复追问、注入、上下文和幂等;
  6. 验证:人工标注集、重复评分、恶意样本、重启和重复请求;
  7. 演进:岗位图谱、个性化记忆、多模型路由和灰度评测。

9.3 个人贡献表达规则

实际实现后,只陈述自己真实完成的边界,例如状态机、RAG、评分评测或观测。使用代码、接口、测试、Trace 或数据作为证据,不把团队结果全部归为个人贡献。

10. 递进追问

  1. 为什么这个项目不能完全使用固定 Workflow?
  2. 为什么又不能让 Agent 自由控制整个流程?
  3. 如何证明分数稳定,而不是模型“看起来合理”?
  4. 检索正确但评分错误,调用链上如何定位?
  5. 服务在模型成功后、状态提交前崩溃,如何避免重复一轮?
  6. 如何防止知识库中的恶意文本改变评分规则?
  7. 如果并发扩大十倍,模型、检索、数据库和报告谁先成为瓶颈?
  8. 如果重新设计,哪些能力应先做确定性基线再引入 Agent?

11. 证据与关联文档

11.1 当前证据状态

  • 当前只有项目设计文档和关联知识文档;
  • 尚未创建代码、数据库迁移、测试、Trace 或实测报告;
  • 因此 doc_status 保持 draft,不能声明项目已经完成。

11.2 关联文档

11.3 一手参考资料

以下资料于 2026-07-10 核对:

12. 简明总结

一句话记忆: AI 面试教练用确定性状态机守住流程,用 RAG 提供证据,用受控 Agent 选择真正有价值的下一问。

  • 一次一题、轮次、预算、评分和终止由代码控制;
  • Agent 只在有限动作空间中根据回答缺口动态追问;
  • 每个分数必须绑定 Rubric、用户回答证据和知识来源;
  • 评分漂移、重复追问、注入和状态丢失都要进入固定回归集;
  • 没有代码和实测证据前,本项目只能标记为设计草案。