三个 Agent 互相甩锅,token 烧光却什么都没干成

0 阅读6分钟

多智能体系统的"病理学诊断"器:Agent Trace 的算法选型与准确率门控

把多个 LLM Agent 串起来协作的时候,LangGraph、CrewAI 或自研框架的开发者几乎都会撞上同一类问题,而单 Agent 系统根本不会出这些毛病。问题集中表现为三种:

第一是死锁。Agent A 等 B 释放资源,B 也在等 A,系统无声挂起,日志干净得像在睡午觉,没有任何报错。第二是循环依赖。A 把任务交给 B,B 又转给 C,C 转了一圈交回 A,三个 Agent 互相踢皮球,token 烧光但产出一片空白。第三是上下文膨胀。对话越拖越长,token 累积到模型窗口边缘,上下文被截断,推理质量断崖式下降,前文聊过什么,模型已经完全忘掉。

现有的可观测性工具,例如 Langfuse、Phoenix、Helicone,主要回答的是"发生了什么",它们给出漂亮的调用链和指标仪表盘。但用户真正想问的是"哪里出了病",这就需要一个病理学诊断器而不是观测台。Agent Trace 的定位正是如此:用结构化算法直接指证病灶,每个算法在发布前都必须通过 100% 准确率门控。

下面聊聊三个核心检测器的算法选型思路,以及为什么我最终选定了这套组合。

死锁检测:为什么用 WFG + DFS,而不是简单的超时检测

最简单的"死锁检测"思路是给每个 Agent 调用设个超时,超时未返回就告警。这个方法听起来直接,但实际工程里有两个致命问题:一是慢,死锁的告警要等到超时阈值才会触发,而线上服务往往需要秒级响应;二是漏报,两个 Agent 之间互相等待的资源,各自占用时间不到超时阈值,系统卡死但告警器安安静静。

Agent Trace 用的是经典的等待图(Wait-For Graph)+ 增量 DFS。每次 Agent 请求资源时,就在 WFG 上加一条有向边,边表示"谁在等谁释放"。完成 DFS 环检测的时间复杂度是 O(V+E),几十个 Agent 规模下亚毫秒级,根本等不到超时就能发现问题。

具体的代码用法只有 4 行:

from agent_trace.detectors import DeadlockDetector
​
deadlock = DeadlockDetector()
deadlock.acquire("agent_a", "db_connection")
deadlock.acquire("agent_b", "file_lock")
deadlock.request("agent_a", "file_lock")
deadlock.request("agent_b", "db_connection")  # → DeadlockDetected!

在 20 个场景的基准测试(10 个死锁 + 10 个安全路径)上,精确率 P 和召回率 R 都达到 1.0,也就是说零误报、零漏报

循环检测:为什么是 Tarjan SCC,而不是普通 DFS

Agent 之间的委派关系天然构成有向图,检环是最经典的需求。很多人第一反应是写个普通 DFS 加 visited 集合就能搞定,在大多数情况下确实能跑。问题在于,普通 DFS 找到的"环"其实是回溯边对应的子结构,容易受递归顺序影响,而且对于一个图中存在多个环的复杂场景,普通 DFS 会重复报告,定位不准确。

Agent Trace 用的是 Tarjan 强连通分量算法,时间复杂度 O(V+E),一次性输出图中所有的强连通分量,凡是大小大于 1 的 SCC 就是真实存在的环,定位精确,不会重复,也不会漏报。

from agent_trace.detectors import CycleDetector
​
detector = CycleDetector()
detector.add_handoff("planner", "researcher")
detector.add_handoff("researcher", "writer")
detector.add_handoff("writer", "planner")  # → CycleDetected!

50 张图的基准测试(25 张含环 + 25 张 DAG)上,F1 分数达到 1.0000,零误报零漏报。

上下文膨胀预测:为什么是 EMA 三层,而不是固定阈值

最容易想到的膨胀检测是"token 数量超过 100000 就告警"。这种基于固定阈值的方法,在不同模型、不同任务、不同 prompt 模板下,误报率极高。GPT-4o 跑长文档总结,100k token 是常态,告警会刷屏;Claude 跑短指令任务,30k 就告警,但其实还在合理范围。

Agent Trace 用的是 tiktoken + 三层 EMA(指数移动平均) :第一层跟踪每步 token 增量,第二层跟踪整体趋势,第三层做长周期预测。系统不仅能在"已经膨胀"时告警,还能预测未来 5 步之后的 token 用量(detector.predict("agent_1", steps_ahead=5)),让上层应用提前触发压缩或摘要。

在 100 步的对照实验上,MAE(平均绝对误差)为 1.0%,告警召回率达到 100%。

异常检测:5 特征加权投票

除了三类主病灶,Agent Trace 还内置了异常检测器,它不像传统机器学习模型那样需要训练集,而是采用5 特征加权投票:token 历史曲线、span 总数、span 错误数、handoff 深度、循环告警数、上下文 token 数。这些特征各有权重,任何一个超阈值都会贡献一个分数,总分超过阈值就标为异常。

100 个场景基准测试(50 异常 + 50 正常)上 F1 = 1.0000。

Web UI:火焰图与调用图

光有数字告警还不够,定位问题需要可视化。Agent Trace 自带 Web UI,默认端口 7600,两个核心视图:

火焰图:

火焰图

横轴是累计 token 消耗,颜色深度代表本步骤自身 token 消耗。容器型步骤(比如 planner)通常又宽又浅(它们只委派不计算),烧 token 的叶子步骤(比如 writer)既宽又深红,那才是真正的热点。

调用图:

调用图

圆形布局,Agent 是节点,委派关系是边。Tarjan SCC 检出的环用红色箭头标出,页面顶部还会显示告警横幅。

整体面板:

整体面板

与同类工具的对比

维度Agent TraceLangfusePhoenix (Arize)Helicone
死锁检测WFG + DFS
循环依赖Tarjan SCC
上下文膨胀预测EMA 三层
异常检测5 特征加权投票基础
OTel GenAI 语义v1.41 全量部分部分
零基础设施SQLite 默认需 Postgres需 ClickHouse需 Postgres
准确率门控每模块 100%N/AN/AN/A

横向看,Langfuse 偏观测平台,Phoenix 偏评估,Helicone 偏代理监控,三家都强,也都重。Agent Trace 的差异点是病理检测:不抢你的观测仪表盘市场,专门补"哪里出了病"这一段空白。基础设施侧,只用一个 SQLite 文件,不用 Postgres、不用 ClickHouse、不用 Docker,pip install agent-trace[web] 就完事。

仓库与声明

GitHub 仓库:github.com/Apageoflove…

148 个测试,100% 准确率门控,Apache 2.0 许可证。

声明:这是个人项目,开发和测试资源有限,功能与结论仅供参考,不构成生产级保证。如有问题欢迎评论指正,Issue 和 PR 也都欢迎。