先确认错在题意还是实现
在编程学习工作台里,同一句“为什么错”,可能指向两种不同问题:学生误解了题目条件,或者题意理解正确,但当前草稿的边界处理有问题。
如果直接让一个模型同时读题、看草稿、查历史并组织教学回答,容易把旧提交和新草稿混在一起,也不容易检查哪一步缺了证据。当前实现因此把一次询问拆给协调、题目、代码和复核四种角色。
这些角色是后端自己的工作流组织,使用现有模型 provider,不需要因为出现多个角色就宣称引入了某个 Agent 框架。
每个角色要有具体输入和产物
| 角色 | 重点 | 主要产物 |
|---|---|---|
| 协调者 | 选择专家、技能和执行顺序 | 结构化计划、最终答复 |
| 题目专家 | 条件、样例、约束与思路 | 题意和算法层面的报告 |
| 代码专家 | 当前草稿、选区及按需取得的历史提交 | 与代码证据相连的诊断 |
| 复核者 | 对照原始证据检查实际答复 | 通过或明确的修正意见 |
角色分开以后,最重要的约束是“谁能看到哪份代码”。当前草稿并不等于最近提交,用户选区也不能脱离它所属的草稿版本解释。不能用旧提交的 WA,直接证明新稿仍有同一个错误。
能否并行,要看信息依赖
如果题意分析与代码检查可以分别推进,就让两个专家并行。若代码诊断需要先知道题目允许什么条件,就使用 problem_first:先得到题目报告,再交给代码专家。
例如某道题允许空集合,代码却默认至少有一个元素。题目专家确认这一条件后,代码专家才能把初始化问题与题意联系起来。这里的例子是为了说明依赖关系,不涉及任何真实学生记录。
因此,“两个角色就一起跑”不是默认最优策略。并行节省的等待时间,需要与信息缺失、汇总开销和额外调用次数一起衡量。
复核应该检查将要发送的内容
协调者完成答复后,独立复核者会对照原始证据审查这份实际输出。双专家任务或存在不确定项时会触发复核;没通过就允许一次修正,再复核一次,仍不通过则明确失败。
这个上限避免了“再检查一次”无限循环。当前简单流程约三次模型调用,双专家带复核约五次,走到修正与再次复核最多七次;这些是工作流路径中的调用计数,不是效果评测成绩。
整个过程还受总时限控制。某一阶段不能因为自己的默认超时更长,就突破整次请求剩余的预算。并行中的必需阶段失败时,也需要取消不再有用的同伴任务。
Skill 是可版本化的输入
项目把题意澄清、样例推演、代码诊断、边界分析等方法写成十个技能文件。协调阶段先看到名称与说明,实际执行的角色才收到被选择的技能正文。
每次新问题固定一份技能快照与内容指纹。即使管理员在请求中途修改了文件,本轮也不应该混用前后两个版本。角色白名单、最多选择多少技能、可以调用什么工具,都由程序约束。
技能内容可以解释方法,却不能自行提升权限。这里也没有编译运行学生代码的工具,所以对程序行为的结论应明确属于静态分析或人工推演,不能写成“已经运行验证”。
相同请求号,还要确认内容相同
成功结果支持重放,但仅有 request_id 不足以保证上下文一致。项目的输入指纹还包含题号、问题、草稿、版本、选区和历史。一个旧请求号配上一份新草稿,不应该悄悄拿到旧回答。
这与业务接口的幂等思路相通:标识用于找到一次意图,内容校验用于确认确实还是那一次意图。
源码可从 teaching_agent.py、agent_evidence.py、agent_contracts.py 和 skill_loader.py 进入。离线测试能检查调度、取消、重放和契约,但真实模型的教学质量仍要用独立任务和人工检查评估。把角色拆开只是让过程更可检查,不能单靠角色数量证明答案更好。