如果你问一个做过生产级 Agent 的人"最重要的一课是什么",大概率回答是:永远不要相信模型的输出。
这不是说模型不可靠。而是说模型在统计意义上"大部分时候正确"跟"每一次都正确"之间有巨大的鸿沟。在传统软件里,一个函数要么返回正确结果,要么抛异常。但在 Agent 系统里,模型可能返回结构正确的 JSON 但语义完全错误,或者格式正确但参数值不合理。
验证闭环(Validation Loop)就是 Harness 的第二根缰绳——在模型的每一次关键输出后面加一道检查,检查不通过就走修正路径,而不是直接向下游传递错误。
Agent 的输出有很多层,每一层都需要不同类型的验证:
模型输出的 JSON 是否符合 Schema 要求?字段类型是否正确?必填字段是否缺失?这是最基础的验证,但也是最容易被忽略的。
// 工具调用参数的格式验证
function validateToolCall(toolCall):
schema = getToolSchema(toolCall.name)
// 1. 参数是否完整
for field in schema.required:
if field not in toolCall.arguments:
return reject("缺少必填参数: " + field)
// 2. 参数类型是否正确
for key, value in toolCall.arguments:
expectedType = schema.properties[key].type
if typeof(value) != expectedType:
return reject("参数类型不匹配: " + key)
// 3. 参数值是否在合理范围内
if schema.properties[key].minimum && value < schema.properties[key].minimum:
return reject("参数超出范围: " + key)
return accept() 格式正确不代表语义正确。比如模型调用了"查询用户"工具,传入了 user_id=12345——格式正确,但这个用户是否存在?模型是否应该先确认用户权限?
语义验证需要额外的上下文来判断。常见做法:
模型是否试图执行危险操作?参数中是否包含注入攻击?输出中是否含有敏感信息?
验证的目的是"发现错误",但真正改变系统行为的是"发现错误后做什么"。
三种修正路径:
路径 A:自动修正(格式问题)
发现问题 → 自动修正 → 记录日志 → 继续执行
适用:格式错误、类型不匹配、参数名拼写错误
路径 B:重试(模型输出质量问题)
发现问题 → 重新调用 LLM(带上错误信息) → 重试
适用:语义错误、推理不完整、选择了错误的工具
注意:需要设定最大重试次数,防止无限循环
路径 C:人工介入(安全/高风险问题)
发现问题 → 暂停执行 → 通知人工 → 等待审批
适用:删除操作、大额交易、权限变更、敏感数据访问 把验证和修正组合起来,就形成了完整的验证闭环:
每一轮工具调用的验证闭环:
LLM 输出工具调用请求
↓
Step 1: 格式验证
├─ 通过 → 继续
└─ 失败 → 自动修正 → 修正成功?→ 继续 / 重试
↓
Step 2: 语义验证
├─ 通过 → 继续
└─ 失败 → 重试(带上错误信息)
↓
Step 3: 安全验证
├─ 通过 → 继续
└─ 失败(高风险)→ 暂停 + 人工审批
↓
Step 4: 执行工具
├─ 成功 → 结果注入上下文,进入下一轮
└─ 失败 → 错误注入上下文,LLM 决定下一步
↓
Step 5: 结果验证
├─ 通过 → 最终输出
└─ 失败 → 重试或回退 这个闭环不是理论设计,是生产系统的必需品。以实际数据为例:一个未加验证闭环的 Agent 系统,工具调用出错率约 5-8%。加上格式验证 + 语义验证 + 安全验证后,可以将出错率降至 1% 以下。
验证不是免费的——每一次验证都有计算成本和时间成本。关键是在覆盖率和成本之间找到平衡。
| 验证类型 | 成本 | 延迟影响 | 建议策略 |
|---|---|---|---|
| 格式验证(代码) | 极低 | <1ms | 全部开启 |
| 规则验证(代码) | 低 | 1-5ms | 核心路径全开,非核心选开 |
| 语义验证(LLM) | 高 | 500ms-3s | 仅用于高风险操作 |
| 交叉验证(双 LLM) | 极高 | +1次 LLM 调用 | 仅用于关键决策点 |
| 人工审批 | 最高 | 分钟级 | 仅用于不可逆操作 |
一个实用的分层策略:低成本验证放行 99% 的调用,高成本验证只拦截最后的 1%。不要试图用 LLM 去验证每一个 JSON 字段——用代码做格式验证,把 LLM 验证留给真正需要理解语义的场景。
验证是一次性的检查。闭环是持续的改进。两者结合才能形成真正的 Harness:
验证闭环的飞轮效应:
发现错误 → 记录日志 → 分析模式 → 更新验证规则
↑ │
└──────────────────────────────────┘
每次迭代让系统越来越健壮 验证闭环的三层结构:
第一层:格式验证(代码实现,零成本)
检查 JSON Schema、参数类型、必填字段
→ 拦截 60% 的格式问题
第二层:语义验证(规则+轻量 LLM)
检查前置条件、参数合理性、权限边界
→ 拦截 30% 的语义错误
第三层:安全验证(规则+人工)
检查敏感操作、权限越界、数据泄露
→ 拦截最后 10% 的高风险问题
修正路径:自动修正 → 重试 → 人工审批
记住:验证的目的是防护,不是惩罚。
每一次验证失败都是系统改进的机会。 加验证闭环不会让你的 Agent 更聪明,但会让你的 Agent 更可靠。在生产环境中,可靠性比聪明重要得多——一个偶尔出错的"聪明"Agent 比一个稳定但略笨的 Agent 更难维护,因为你不知道它下一次会在哪里出错。验证闭环就是告诉你"它会在这里出错,而且我们已经挡住了"。
💬 评论