Multi-agent系统追踪实战
多Agent协作最让人头疼的不是逻辑跑不通,而是性能崩了之后根本没法排查。单次LLM调用好说,但一旦进入Swarm模式,几个Agent并行跑,其中一个超时了悄悄 fallback 到低端模型,另一个 Critic Agent 又把结果打回重做。最后整个链路跑了40秒且Token预算超支,看日志时全是交织在一起的乱码,根本分不清到底是哪个角色在“烧钱”。
下一篇
模型精度从94%提到96%,在公司业务线里可能根本没人在乎 →
为了解决这个问题,我尝试在团队项目中引入了 otel-swarm 这个库,它把 OpenTelemetry 的链路追踪给简化了,不用给每个 Provider 调用手动写埋点。
具体实操起来非常简单,核心就是 task、agent 和 llm 这三个方法:
import { createSwarm } from 'otel-swarm';
const swarm = createSwarm({ service: 'my-swarm', otlpEndpoint: 'http://localhost:4318' });
await swarm.task('generation', { 'my.prompt': prompt }, async (root) => {
// 这里的 agent 会创建一个子 span,明确标注角色
const plan = await swarm.agent('planner', () =>
swarm.llm('planner', {
model: 'primary-model-id',
fallbackModel: 'fallback-model-id',
call: async (model) => {
const res = await yourProviderCall(model);
return { content: res.text, inputTokens: res.usage.in, outputTokens: res.usage.out };
}
})
);
await swarm.agent('critic', async (span) => {
swarm.reviewEvents(span, issues);
});
});在实际落地效果上,通过配合 SigNoz 仪表盘,整个调用链路变成了清晰的树状结构。一个 root span 下面挂着 planner、frontend、backend 等各个 Agent 的子 span。最关键的是,如果发生了模型回退,它会记录一个 fallback_promotion 事件,直接告诉你从哪个模型跳到了哪个模型,以及具体的报错原因。
这里分享一个踩坑经验:千万不要把 fallback 的模型名称直接覆盖在原有的模型属性上。
我之前试过直接修改 gen_ai.request.model 属性,结果导致监控面板数据完全失真——主模型的所有超时和失败都被算到了 fallback 模型头上,导致数据上看主模型性能完美,而低端模型延迟高得离谱。正确的做法是把回退记录为 Span Event,这样才能在不干扰聚合统计的前提下,追踪到真实的调用路径。
目前这个方案在我们的代码生成流中跑了快 300 次模型调用,处理了数百万 Token,排查问题的速度比翻日志快了不止一个数量级。