为什么“模型能回答”还不够

让模型根据几张证据卡回答问题并不难。难的是把这次判断接到一个可运行的系统中:如果模型引用了不存在的主张怎么办?如果搜索返回空结果怎么办?如果模型调用成功、应用却在写数据库前崩溃怎么办?重试是否会多花一次费用?

这些问题分布在模型之外,却直接影响研究结果能不能被信任和复用。Agent Loop 决定观察、决策、行动、验证和停止怎样衔接;Harness 则提供协议、权限、预算、恢复和记录,让这条循环受到约束。

这一章先讲当前真实路径,再讲为什么需要这些约束。它不把“支持循环协议”写成模型已经能自主浏览、执行任意工具。

当前哪一步由代码决定,哪一步由模型判断

在默认 SpringAiDecisionEngine 路径中,没有观察时,代码构造首次 SEARCH_EVIDENCE,用当前问题搜索,并限制候选数量。检索后的观察全部表示没有证据时,代码直接返回 INCONCLUSIVE,不为补齐答案再调用供应商。

有候选证据时,Resolver 读回限定材料。模型收到问题、候选与预算等数据,返回受约束的 STOP 决策:对问题的立场、中文回答,以及候选中的支持或反驳 ID。代码随后解码与检查。

Agent Evidence Lab代码推进循环,模型在限定位置做语义判断

这是当前默认 Spring AI 路径,不将 Loop 协议能表达的所有动作都算作模型自主动作。

  1. 01代码检查剩余额度

    确认步数、deadline、用量与租约等执行条件。

  2. 02代码决定首次检索

    尚无观察时搜索证据;没有证据时确定性返回证据不足。

  3. 03模型判断候选

    有证据时读取限定候选,返回立场、回答和候选引用 ID。

  4. 04代码验证与记账

    解析协议、拒绝未知引用,保存实际用量、结果与运行阶段。

  5. 05推进、恢复或终止

    按已分类失败与剩余预算继续,或明确完成、失败、耗尽。

恢复回到已保存阶段,不是无限重新调用。模型给出 STOP 也必须通过程序校验;缺失供应商用量不能记成零。

图 03 · 默认执行路径的责任示意。Checkpoint、Trace 和受限恢复共同约束这条路径。

所以,当前默认实现的模型自主空间主要在语义解释、立场和引用选择。首次检索、空证据处理、工具执行、保存和停止约束由代码控制。这个划分应从实际实现中读出,而不是只看“Agent”这个名字。

Loop 协议能够表达搜索与停止,也保留其他执行面适配。协议的表达能力、默认引擎实际使用的动作,以及未来希望引入的自主补证据能力,是三个层次。不能因为协议支持一种决策,就宣称模型已能自由选择这类动作。

用一段伪代码看清责任边界

下面按现有职责压缩,省略并发、事务和异常分支;它不是可以替换生产 Runner 的实现。持久化执行应阅读 CheckpointedEvidenceAgentRunner,早期 BoundedEvidenceAgentLoop 只适合帮助理解基本循环。

// 阅读示意:描述边界,不对应一个可直接调用的方法集合。
while (withinStepAndTimeLimits()) {
    Checkpoint saved = loadCheckpoint();
    ensureLeaseAndRemainingBudget(saved);      // 代码

    Decision decision = decide(saved);         // 可能是确定性分支,也可能调用模型
    validateProtocolAndAllowedReferences(decision);

    if (decision.requestsSearch()) {
        executeAndRecordAllowedSearch(decision); // 工具执行与保存由代码负责
    } else {
        verifyCompletion(decision);             // 模型说完成,仍需检查
        saveTerminalResult(decision);
        break;
    }
}

这段示意中的 decide 不等于“每轮都调用模型”。同样,verifyCompletion 不是另一位全知裁判:当前检查的重点是引用是否属于已观察集合,以及支持或反驳立场是否带有相应引用。它不能独立证明引用的语义真的支持结论。

代码与模型的职责对照

环节 当前代码负责 当前模型负责
首次动作 构造受限搜索 不调用供应商
没有证据 确定性证据不足终止 不补写外部事实
有候选材料 按观察与画像版本解析候选 判断材料相对问题命题的关系
决策输出 严格解析结构,检查候选 ID 和合法立场 生成回答、支持/反驳引用与理由
工具与权限 执行白名单能力,验证参数与运行条件 不从文本获得额外执行权限
用量与停止 记录实际用量,检查步数、时间与预算 看到剩余额度不等于拥有预算控制权
保存与恢复 保留阶段、调用身份、版本和租约 不决定数据库事务是否成功

语义任务交给模型不意味着放弃评测。比如“这条证据支持哪个命题”就曾出现过反对被判成支持的失败,需要用明确任务和反例持续检查。

什么时候应该停止

一个有用的循环需要多种停止方式,而不只是一条成功路径。

停止条件 为什么需要 结果应表达什么
合法完成决策通过检查 得到了可接受的有限回答 结果、立场、引用与运行记录
无证据或证据不足 避免用语言流畅度填补材料缺口 INCONCLUSIVE 与范围
步数、时间、Token 或费用预算耗尽 防止继续无界调用 对应预算耗尽原因
非法引用或输出 模型不能绕过契约 分类失败,或在限定条件下恢复
重复动作 相同动作可能无法增加信息 有限恢复或明确失败
无法可靠取得必要用量 不能把未知成本当成免费 用量不完整或相应终止原因

预算有不同的时间边界。服务可以在下一次调用前检查余额,并在返回后根据供应商实际用量记账;已经发出的外部调用有自己的超时和输出限制。这不等于服务端能回收已产生费用,也不等于记录金额就是供应商账单。

另一个容易混淆的边界是补充原文解读:它有单独的调用与持久化记录,不能把它的用量算成原 M3 Run 内部某一步,更不能因为 M3 有预算就假设所有研究环节共享同一个全局费用上限。

恢复为什么离不开 Checkpoint

想象搜索工具已经返回,结果也已经写入数据库,应用随后中断。新进程接管时,理想行为是从已保存阶段继续,而不是忘记已完成操作再搜索一遍。

Checkpoint 保存运行阶段、观察和继续执行所需状态。版本 CAS 检查“我读到的版本是否仍然有效”,租约限定“当前谁拥有推进权”。这和后端系统防止并发写入的思想相通,只是这里还跨过可能付费、可能不确定的外部调用。

有一类中断更难:调用已经发出,但没有可靠记录证明供应商是否处理过。当前 Trace 使用 UNCERTAIN 保留这种不确定性,接管后可以按既有规则用同一逻辑调用身份重放并增加尝试次数。稳定 ID 能帮助追踪,不会让外部供应商自动支持 exactly-once。 因此不能宣称任何故障下都不会重复执行或计费。

当前恢复验收包含固定故障和重启场景。CheckpointRecoveryIT 验证工具结果落盘后重启接管,已保存搜索未重复执行;这是一项具体保证,不是任意工具和任意故障的普遍恢复证明。

Trace 要保留什么,又为什么不保留全部文本

Trace 用来回答发生了哪一步、哪个逻辑调用、尝试几次、用时多久、引用了哪些 Claim、用量是否已知、在哪个边界失败。它帮助人和后续工具重建运行过程。

但原问题、完整 Prompt、证据正文和供应商原始异常可能含有不适合进入日志或公共运行响应的信息。因此当前 Trace 使用安全字段、参数摘要与允许的引用 ID;完整个人报告由受保护的研究读取路径提供。

记录 主要用途 不应混同的内容
Checkpoint 支持正确继续执行 面向人阅读的研究解释
Step / Call Trace 解释运行行为与尝试 全量 Prompt 和原始供应商 payload
Research Report 保存研究结果和来源关系 外部事实已经独立验证
Briefing 对完整已保存来源做补充解读 原 Agent Run 的同一次模型调用

可观测性与完整内容保存之间需要有意设计。什么都不留难以排错,什么都写进日志又会扩大暴露范围。这个项目选择把可审计的运行记录和个人研究材料分开管理。

沿实现继续核查

项目内逻辑路径 建议检查的问题
agent/runtime/SpringAiDecisionEngine.java 哪些分支不会调用供应商?模型允许返回什么决策?
agent/loop/protocol/DecisionProtocolCodec.java 未知字段、非法状态和引用形状怎样拒绝?
agent/loop/CompletionVerifier.java 完成检查究竟验证了什么,哪些语义判断仍未覆盖?
agent/checkpoint/CheckpointedEvidenceAgentRunner.java 预算、外部调用、恢复与终态如何衔接?
agent/checkpoint/JdbcAgentExecutionStore.java Trace 与 Checkpoint 的事务、版本和租约守卫
agent/trace/ModelUsage.java、UsageStatus.java 已知、缺失与不确定用量怎样表达?
SpringAiDecisionEngineTest、CheckpointRecoveryIT、CheckpointedEvidenceAgentRunnerTest 无证据、非法引用、限额、故障和恢复的固定验证

本章的重要收获应是一条责任链:模型的建议只有经过协议、权限、预算、执行与保存等边界,才成为系统动作。这些边界需要分别验证,不能只靠一个写得很长的 Prompt。