外观
Q09–Q12:生成、评审、修订与人工处理
这组是项目深挖的主线。准备一份真实运行记录,能按教材版本、评审报告和任务事件把每一步串起来。
Q09 怎样让评审真正独立,而且有用?
**考察目的:**角色隔离、评审契约、质量闭环。**难度:**核心。
**主问题:**生成 Agent 自己再检查一遍不就够了吗?为什么要独立评审?
直接答案与 STAR
让生成者自查可以有帮助,但它可能受自身上下文与已有判断影响。独立评审通过重新构建上下文,让评审从候选教材、检索证据、规则和明确标准出发。生成角色负责写作与局部修改,评审角色只能报告问题和提出修订要求,不直接覆盖教材。
评审报告必须能驱动下一步:标识被审版本,列出稳定内容 ID 或路径、问题类别、严重程度、依据及修订要求。确定性检查与模型评审互补。报告不是一段“整体不错”的评语,自动通过也不应替代最终教研复核。
**STAR|简历事实 + 学习复现:**S:教材生成后需要质量审核。T:降低生成与自评混在一起带来的偏差,并让问题可处理。A:简历采用双 Agent、上下文隔离与结构化评审;复现中保留候选与报告的版本关联。R:历史结果只表述为系统生成、评审后由教研复核;本次效果要看固定问题样本与运行报告。
第一层追问:评审给出“表达不自然”,怎么自动修?
**直接答案:**这种报告不够具体,不能可靠驱动局部修订。需要位置、具体问题、适用标准和可操作要求,例如指定某个句子降低词汇难度,而不是让生成者重新猜。报告自身也要做 Schema 和业务校验;不合法位置或缺依据的报告应报错或进入人工处理。
**STAR|学习复现:**S:一条评审只有泛化建议。T:检验报告契约。A:提交缺少位置和要求的评审样本,对照完整报告验证后续行为。R:不完整报告不能被当作有效自动修订任务,避免整章漂移。
第二层追问:评审也可能挑错,如何衡量?
**直接答案:**同时看漏报和误报。固定样本应包含已知问题和合格内容,标注问题位置与类别,统计命中、遗漏与错误警报;人工核对语义判断。单看“发现问题数量”会鼓励过度挑错。还应记录评审调用次数与延迟,比较质量和成本。
**STAR|学习复现:**S:更严格的评审提示词报告了更多问题。T:确认是否真正改善质量。A:在相同标注集比较漏检和误报,并查看报告依据。R:若新增问题多为误报,就不能宣称审核质量提升;结果只代表这个小样本。
分支追问:能不能让评审 Agent 直接修改,减少一次调用?
**直接答案:**可以作为另一种设计,但会弱化职责隔离和可审计性。若让评审直接修改,也需保留原版本、修改范围和依据,不能只留下最终文本。本项目选择评审报告驱动局部修订,方便测试未受影响内容与连续追问。
**STAR|假设方案:**S:调用成本成为瓶颈。T:评估合并评审与修改是否值得。A:比较两种方案的错误残留、意外改动、调用量和可追溯性。R:依据实验决定取舍,不以少一次请求就认定整体成本更低。
**优秀回答:**能展示具体问题条目,并解释评审自身如何被评估。**常见误区:**独立评审等于绝对客观;评审越严格越好;自然语言意见天然可执行。
实际源码:system/app/graph.py 的 context()、review();system/app/content.py::business_review();system/app/schemas.py::Review。
验证与实验:system/tests/test_system.py::test_complete_revision_approval_delivery、test_context_and_tool_permissions;L01。演示评审为模板加确定性规则,不用于声称真实模型审校质量。
Q10 局部修订如何保证没改坏其他部分?
**考察目的:**稳定标识、版本控制、并发写入。**难度:**核心。
**主问题:**模型说“只修这一处”,你如何验证它真的只改了这一处?
直接答案与 STAR
先定义可修改范围,把评审问题定位到稳定内容 ID 或明确路径。修订请求基于一个确定的教材版本,模型返回有限范围的替换数据;程序校验目标存在、类型合法、路径被允许,然后在原版本上应用修改,生成新版本。保留原始对象与差异,检查未授权位置不变,再进行业务校验和复审。
不能仅依赖 prompt 中“只改这里”。也不能用数组下标作为长期稳定身份而忽略插入排序。若允许修改产生新增/删除,需要单独定义操作协议与约束,不能把任意 JSON Patch 全量开放给模型。
**STAR|学习复现:**S:一份教材只有一个练习答案出错。T:修复答案而不重写课文和词汇。A:按练习 ID 定位允许变更字段,应用前后对比其他内容。R:验收证据是新旧版本差异只覆盖允许范围、错误被修正、复审通过;不能把整章重新生成称为局部修订。
第一层追问:教研同时手动修改了同一版本怎么办?
**直接答案:**使用期望版本或乐观并发控制。写入时确认当前版本仍是修订基线,若已变化则拒绝旧基线提交,并提示重新加载或有意识合并。不能简单“最后写入覆盖”。冲突解决产生新版本并重新审核,不继承旧版本通过状态。
**STAR|假设方案:**S:模型修订尚未完成,人工已修改同一题。T:避免模型覆盖人工内容。A:提交时携带基线版本并比较数据库当前值。R:旧基线返回冲突,人工版本保持不变;后续是否采纳模型结果由明确操作决定。
第二层追问:只改了文本,也要重新生成所有素材吗?
**直接答案:**不用机械地全部重做,但必须按依赖判断。配音依赖朗读文本与语音配置,图片依赖画面描述,视频依赖图片、音频、字幕和合成参数。修改题目答案可能不影响课文配音,修改课文朗读内容则至少影响音频和依赖它的视频。复用必须以输入指纹匹配为依据。
**STAR|学习复现:**S:修改课文中的一句话。T:更新关联音视频,同时避免无关图片重复生成。A:比较各素材任务的规范化输入指纹,重建发生变化的依赖节点。R:应能展示哪些资源被复用、哪些失效以及原因,而不是凭文件名猜测。
分支追问:稳定 ID 是谁生成的,模型可以改吗?
**直接答案:**应由应用管理或在生成后受控分配,并作为内容身份保持稳定。模型可以引用 ID,但修订不能随意重新编号、重复使用或指向其他章节。新内容需要新增 ID,删除也应保留版本历史中的可追溯关系。
**STAR|假设方案:**S:模型把 exercise-2 改成 exercise-3。T:避免评审定位和素材关联失效。A:比较修订前后的身份集合,拒绝未授权的 ID 变化。R:问题报告仍能追到同一内容对象,新增内容走明确的创建流程。
**优秀回答:**能解释允许修改集合、基线版本、差异与验证四者关系。**常见误区:**只要模型说局部修改就可信;以最后一次更新时间解决所有冲突;通过状态可随文本一起复制。
实际源码:system/app/content.py 的 apply_patch()、version_diff();system/app/api.py::edit();system/app/db.py::save_version()。
验证与实验:system/tests/test_system.py::test_patch_cannot_change_unreviewed_or_unknown_blocks、test_incremental_edit_and_old_result_protection;L14 内容更新。检查 c1 变化与 c2 复用的实际输入指纹。
Q11 有 Checkpoint,进程重启就万事大吉了吗?
**考察目的:**恢复语义与副作用边界。**难度:**高。
**主问题:**在生成、人工等待和素材执行三个时刻杀掉进程,分别会发生什么?
直接答案与 STAR
恢复依赖具体持久化时点,而不是“用了 LangGraph”四个字。Checkpoint 保存已写入的图状态;节点未完成时可能从节点边界重新执行。人工等待需要持久化的中断状态及同一个线程标识;内存 checkpointer 无法跨进程恢复。素材执行还依赖任务表、租约、外部请求记录和已保存文件。
最危险的窗口是“外部调用已经产生结果,但本地尚未记录”。恢复时重跑可能导致重复收费或副作用。要在应用层使用幂等键、唯一约束、结果查询或人工核对。Checkpoint、业务事务与外部 API 不是天然的单一原子事务。
**STAR|学习复现:**S:用户可能在等待审校或制作素材时重启服务。T:区分哪些状态能恢复、哪些操作可能重复。A:在确定边界中断 worker,检查持久化记录后重启,并核对任务/版本数和结果。R:只对实际执行的崩溃窗口报告恢复结果,不能从一次正常重启推导“任意时刻不会丢失”。
第一层追问:interrupt() 前面能随便发送消息或创建外部任务吗?
**直接答案:**不能假设这段代码只执行一次。恢复时中断所在节点可能从头开始,位于中断之前的副作用应移到受控节点,或设计为幂等。中断返回值与后续业务状态也要校验,不能接受任意客户端提交。
**STAR|假设方案:**S:人工恢复一次流程却重复创建了素材任务。T:定位恢复路径中的重复副作用。A:检查中断前的代码,把创建任务改为受唯一键约束的受控提交。R:重复恢复请求不会增加相同业务任务,审计仍记录重复请求。
第二层追问:Checkpoint 已写入,业务版本没写入,如何避免对不上?
**直接答案:**优先用清晰的写入顺序和可重入节点,把业务操作做成幂等,并在恢复时验证关联记录存在。需要承认独立持久化之间可能有崩溃窗口;复杂系统可用事务性 outbox 或协调协议降低风险。不能把框架状态当成业务记录已成功的唯一证据。
**STAR|假设方案:**S:流程状态包含版本 ID,但业务写入未成功。T:避免恢复后继续处理不存在的教材。A:读取版本记录并核对,不存在则执行受控重试或报不一致错误;记录修复动作。R:恢复要么重新建立完整关联,要么明确停住,不继续生成伪交付物。
分支追问:能不能承诺 exactly-once?
**直接答案:**必须限定范围。在同一数据库事务内,唯一约束可保证一条业务记录不重复;跨进程和外部服务通常是至少一次执行加幂等效果。供应商是否支持幂等、查询和保留时长决定边界。不能用一个任务 UUID 推导端到端恰好一次。
**STAR|假设方案:**S:外部图片 API 不提供幂等或查询。T:说明超时后的可靠性边界。A:把结果不明单列状态,暂停自动重试并要求核对。R:避免冒险重复扣费;能力限制被清楚记录,而不是被“自动恢复”掩盖。
**优秀回答:**能画出提交前后崩溃窗口,并承认跨系统原子性限制。**常见误区:**Checkpoint 等于数据库备份;恢复从 Python 中断行继续;有 UUID 就一定恰好一次。
关联学习:LangGraph 持久化、任务恢复。
实际源码:system/app/graph.py 的 cache_node()、human()、run_workflow();system/app/worker.py::recover_expired()。
验证与实验:system/tests/test_system.py::test_new_process_resumes_checkpoint、test_killed_worker_resumes_after_generation、test_unknown_external_result_not_silently_retried;L09、L12。kill 用例选定生成后的窗口,不代表穷举所有崩溃位置。
Q12 修订不收敛时怎么办?人工“退回”和“恢复”有什么区别?
**考察目的:**循环终止、状态转移和人工权限。**难度:**中高。
**主问题:**模型修改了三轮仍不通过,你会让它继续到通过为止吗?
直接答案与 STAR
不会。设定修订次数、调用预算和时间上限。达到上限进入人工处理,保留当前版本、各轮评审与失败原因。区分模型可修的内容错误、资料/规则冲突和系统错误:证据不足不能靠更多生成修复,接口鉴权失败也不属于教材质量问题。
人工通过表示对一个确定版本给出批准;退回表示提出新的修订要求,创建后续工作;终止表示停止流程并阻止后续交付;恢复表示根据允许的状态继续此前中断或失败的处理。四者的前置条件、版本校验和审计记录应不同。人工操作不是一个随意把状态改为“成功”的万能接口。
**STAR|学习复现:**S:固定样本始终违反一条无法自动满足的规则。T:验证自动流程能够安全停止。A:设置修订上限,观察达到上限后的人工入口,再分别测试退回与终止。R:验收是没有无限循环、已有证据不丢失、终止后不会继续交付;并不代表问题被自动解决。
第一层追问:人已经通过,随后发现错误,能直接编辑吗?
**直接答案:**可以提供编辑能力,但编辑应产生新版本,原审核决定仅适用于原版本。新版本需要重新审校和批准,相关素材重新判断失效。已经交付的旧包可保留但要标识版本与状态,不能偷偷替换其内容。
**STAR|假设方案:**S:通过后发现参考答案有误。T:修正教材且保留审计。A:从已通过版本创建修订,记录原因,重新审核并更新交付版本。R:使用者能区分旧包和纠正版,批准记录没有被移花接木。
第二层追问:用户连续点两次“通过”,会不会重复生成素材?
**直接答案:**客户端禁用按钮只能改善体验,服务端仍需幂等和状态校验。对同一版本的相同决定应返回已记录结果;冲突决定应报错或走明确的撤回流程。素材创建还要有唯一业务键,不能依赖按钮只发一次请求。
**STAR|学习复现:**S:网络慢导致同一批准请求被重复提交。T:验证端到端幂等。A:发送相同版本与操作标识的请求两次,检查决定和任务记录。R:业务效果只有一次,重复请求可被审计;不能只看 HTTP 都返回 200。
分支追问:人工强行通过有严重问题的教材,系统应允许吗?
**直接答案:**需要明确政策。结构不完整、资源缺失、版本不一致等不可交付条件应由程序阻断;可接受的质量例外可以由有权限的人说明理由后处理,并保留风险与决定。学习系统的具体行为以实现和验收为准,不应口头许诺有复杂审批制度。
**STAR|假设方案:**S:教研认为某个文化表达是可接受例外。T:允许专业判断但不绕过技术完整性。A:记录规则、例外理由与审核人,保持版本/资源校验。R:交付依据可追溯;缺文件或旧版本问题不会被人工按钮掩盖。
**优秀回答:**能列举状态转移前置条件,并区分质量例外与技术不完整。**常见误区:**循环次数越多质量越高;人工通过可以跳过所有检查;恢复等于从头再跑。
实际源码:system/app/graph.py 的 human()、build_graph();system/app/api.py 的 decide()、recover()。
验证与实验:system/tests/test_system.py::test_revision_limit_and_manual_edit、test_stale_decision_and_termination_recovery;L06。当前实现在严重问题尚存时拒绝批准,不存在无条件强行通过入口。
官方核对资料
核对日期:2026-11-03;恢复语义需结合本包锁定版本及实际持久化配置阅读。