首页 / 文章 / 代理忽略了失败的工具调用:在 CI 中捕获的方法
← 返回
AI技术

代理忽略了失败的工具调用:在 CI 中捕获的方法

✍️ zhirenhun 📅 2026/8/18 👁 120 阅读 ⏱ 13 分钟
代理忽略了失败的工具调用:在 CI 中捕获的方法

您部署了一个 AI 代理。它调用工具,读取结果,再调用更多工具,给出答案。大多数时候它能正常工作。然后用户报告出了问题,您打开追踪,发现了它:charge_card 工具返回了 402,而代理只是……继续前进,并告诉客户他们的订单已发货。

这不是指“编造事实”意义上的幻觉。这是运行中的一个 结构性 缺陷——被忽略的工具错误。而关于结构性缺陷的关键在于:您不需要另一个 LLM 来发现它们。 通过查看追踪可以判定它们。

这就是 tracelint 的全部前提:它是代理运行的 linter。它读取执行追踪——代理 实际做了什么——并以确定性的方式标记结构性错误,以确切的追踪行作为证据并返回 CI 退出码。它在运行之后、在追踪上运行,而不是在您的代码上运行。永不需要第二个模型来判断它。

为什么不直接使用 LLM 评判器?

因为对于这类错误,评判器是错误的工具。已发表的追踪错误基准显示,LLM 评判器的定位准确率较低——它们只会告诉您“似乎有问题”,而不会可靠地指出是 哪一步 出错。它们还具有非确定性、每条追踪会产生费用,并且无法用于 CI 阻塞(您会因为一次掷硬币而让构建失败吗?)。

与此同时,一类代理错误是 可结构性判定的

这些都不需要模型。它们需要追踪和验证器。这就是 tracelint 所做的。

60秒版

pip install tracelint
tracelint demo --html demo.html

demo 运行无密钥验证套件 — — 每种缺陷植入一个实例,加上干净的对照 — — 并生成 HTML 报告。无需 API 密钥,无需下载模型。

要在真实追踪上对 CI 进行门禁:

tracelint check ./trace.json --tools ./tools.json    # exit 2 on a structural defect

退出码:0 干净,2 结构上可证明的缺陷,3 输入错误。启发式发现不会自行导致 CI 失败。

重要部分:它运行在您已经收集的追踪上

这是分布洞察。您可能已经在为您的代理添加仪器 — 与 OpenInference (OpenTelemetry 语义约定,用于 AI),向 Arize Phoenix、Langfuse 或 OTel 收集器提供数据。tracelint 直接读取该遥测数据。您不需要学习新的追踪格式;您只需将其指向您已有的跨度。

tracelint check spans.json --format openinference    # Phoenix, OTLP, TRAIL
tracelint check trace.json --format langfuse
tracelint check messages.json --format openai

或者直接从正在运行的 Phoenix 实例中,在 Python 中:

import phoenix as px
from tracelint import lint_otel_trace

spans = px.Client().get_spans_dataframe().to_dict("records")
report = lint_otel_trace(spans)
print(report.exit_code)          # 0 or 2
for f in report.active_findings:
    print(f.rule, f.tier.value, f.summary)

我根据真实的 OpenInference 导出进行了验证,而不仅仅是手工构建的 fixtures — 一个真实的 Phoenix trace,一个 OTel-SDK span 导出,以及 Phoenix dataframe 的形状。在一个真实的 Phoenix trace 上,tracelint 的确定性地定位到了一个真实的工具故障:

[hard_event] R2a tool_error_event  (step 9)
  'add_spans_to_dataset' returned an error (GraphQL query 'exampleMutation' ... 'an unexpected error occurred')

循环中没有模型。只是:此 TOOL span 具有 ERROR 状态,恰好在此步骤,这里是消息。

它捕获什么

规则 发现
R1 模式违规 — 参数未通过工具的 JSON Schema
R2 工具返回了错误 / 后来的副作用调用重用了一个出错的值
R3 幻觉参数 — 值无法从任何观察到的东西推导出来
R4 循环 — N 次完全相同且无进展的调用
R5 冗余调用 — 完全相同的调用 + 完全相同的结果,中间没有变化
R6 参数格式错误 — 工具调用的参数不是有效的 JSON
R7 未知工具 — 对未在声明的工具集中出现的工具的调用

这是通过 OpenInference 适配器运行的卡住循环示例:

[candidate] R4 loop  (step 2,4,6)
  'search' called 3 times in a row with identical arguments and no change in result state (ok)
[candidate] R5 redundant_call  (step 2,6)
  'search' repeats an earlier identical call with no mutating call in between

我愿意捍卫的两个设计决策

1. 候选,而非裁决。 只有结构上可证明的事项(模式违规,格式错误的 JSON)是导致 CI 失败的硬性缺陷。启发式信号 — 循环,冗余调用,可疑参数 — 会被显示为 带有证据的候选项,供人工审查,从不被断定为真理,并且它们自身不会导致你的构建失败。重试循环和卡住的循环在结构上看起来相似;tracelint 会向你展示证据并让你决定,而不是假装它知道。

2. 它告诉你它不能检查什么。 这是我最关心的一点。如果追踪中缺少规则所需的字段 — — 没有工具模式,也没有结果负载 — — 该规则不会静默通过。它给出理由并抑制,在报告中打印出来:

suppressed (2) — not checked, not a clean pass:
  R1 schema_violation: no tool schema available for any called tool
  R7 unknown_tool: no tool registry supplied — cannot know which tools were declared

一个看似干净却隐藏漏洞的报告比没有报告更糟——这是虚假的自信。tracelint 拒绝给你这种感觉。

诚实的局限

试用

pip install tracelint
tracelint demo --html demo.html

它是开源的(MIT),依赖轻量(jsonschema + 标准库),支持 Python 3.10–3.12,整个测试套件是离线且确定性的。

如果您正在收集代理追踪并希望对其进行确定性检查,我真的很想知道您的实际导出中会出现什么问题——这就是最近三个真实世界形状修复发生的方式。欢迎提交问题和追踪。

——

🧑‍💻

zhirenhun

一个热爱技术的程序员,喜欢分享前沿AI知识和开发经验。

ai python opensource agents
← 上一篇
不要给模型SQL
下一篇 →
将 CLAUDE.md 从 548KB 压至 34KB:测量加载时机及保持小巧的提交门禁

📌 相关推荐

停止相信仅文本代理排行榜:来自 Cua-Bench 和 Factorio 的教训
2026/8/26
Agent Memory 有两种不同含义,回答引擎给出的却是错误的那一种
2026/8/26
LLM的止境:AI辅助VAPT流水线的确定性评分
2026/8/22
← 返回文章列表