389个测试通过了,但结果依然是错的
很多开发者习惯把“确定性计算”等同于“绝对正确”,觉得只要让 AI Agent 调用外部工具(比如计算器或 Python 解释器)就能解决 LLM 算数差的问题。但我最近在用 Rust 写一个给 Agent 用的计算工具时,被狠狠上了一课:确定性并不意味着可信,一个程序可以永远地、极其稳定地给你一个错误答案。
很多人追求的是“可靠性”,但实际上,计算工具提供的不是“可信”,而是“可重复”。只要执行路径是确定的,这个结果就是可审计、可回溯的。
下一篇
上下文质量比模型参数更重要:别再盲目喂Token了 →
我在代码里故意把一个乘号改成了加号,结果在 Rust 的测试套件中,390 个测试用例竟然通过了 389 个。唯一失败的那个,是因为我引入了 NIST(美国国家标准与技术研究院)的认证数据集作为比对。这让我意识到,如果测试集是自洽的(即预期结果也是由同一套逻辑生成的),那么 Bug 很容易被掩盖。
对于构建 AI Agent 工作流,这里有一个核心的认知误区需要纠正:
- 语义边缘(Semantic Edge): LLM 负责理解需求、拆解问题、选择工具并解释结果。这部分是概率性的。
- 计算边缘(Computational Edge): 窄工具负责验证输入、执行具体操作并返回结构化输出。这部分是执行性的。
很多人追求的是“可靠性”,但实际上,计算工具提供的不是“可信”,而是“可重复”。只要执行路径是确定的,这个结果就是可审计、可回溯的。
为了避免工具本身的“自嗨”,我建议在部署关键 Agent 工具时,必须引入独立的第三方参考数据(Reference Data)进行压力测试,而不是只依赖于自己写的单元测试。
如果你在搞 AI Agent 的工具调用(Tool Use),可以参考这个逻辑来划分职责:
// 伪代码:一个简单的工具执行逻辑
fn execute_tool(input: ToolInput) -> Result<ToolOutput, ToolError> {
// 1. 严格的输入校验(计算边缘的第一道防线)
let validated_data = input.validate()?;
// 2. 执行确定性操作
let result = perform_calculation(validated_data);
// 3. 独立验证(如果涉及高精度,应比对外部标准库而非内部逻辑)
if !verify_with_external_reference(&result) {
return Err(ToolError::AccuracyFailure);
}
Ok(ToolOutput::new(result))
}这种“生成”与“执行”的分离,才是让 AI Agent 走向实战的关键。不要迷信工具的确定性,要迷信可验证的证据。