新闻详情

新闻详情

首页 / 资讯中心 / 详情

[MAF预定义Agent中间件-04]OpenTelemetryAgent:基于Agent的调用链跟踪和性能监控

发布时间:2026/9/25 17:44:46来源:尧图网络
[MAF预定义Agent中间件-04]OpenTelemetryAgent:基于Agent的调用链跟踪和性能监控
1. 当 Agent 调用链断在工具调用那一层如果你正在用 MAFMicrosoft Agent Framework搭多 Agent 系统大概率遇到过这种场景Agent 跑起来了日志也打了但一旦线上响应变慢你根本说不清时间花在哪——是模型推理慢还是工具函数卡住还是网络往返抖动。更麻烦的是当你兴冲冲接上 OpenTelemetry 想看调用链却发现 Jaeger 里只有孤零零一个invoke_agentSpan工具调用那一层凭空消失了。这就是OpenTelemetryAgent这个预定义中间件要解决的问题。它本质上是 MAF 里专门给 Agent 管道注入 Trace 和 Metrics 的中间件能自动为每次 Agent 调用生成 Span、记录耗时、统计 Token 消耗并把数据推到 Jaeger、Prometheus 这类后端。适合谁适合已经把 Agent 跑通、现在要上可观测性的团队尤其是做多轮对话、工具调用、流式输出的场景。我试过在本地把 Jaeger Prometheus Grafana 全拉起来配合 TaoToken 的统一 Key 通道跑了一遍完整链路中间踩了一个关于autoWireChatClient的坑这篇就把配置骨架、验证动作和排障过程完整拆开讲。2. TaoToken 前置统一 Key 与 API 通道在接 OpenTelemetry 之前得先让 Agent 能稳定调模型。MAF 的 Agent 底层走的是IChatClient而OpenAIClient需要一个 endpoint 和 apiKey。这里用 TaoToken 的好处是一个 Key 就能覆盖多种模型不用为每个模型单独配一套凭证Agent 中间件切换模型时也不用改代码结构。你需要准备三样东西API Key在控制台生成格式类似sk-开头Endpointhttps://taotoken.net/api模型名比如gpt-4o、claude-3-5-sonnet等按你实际订阅的填把这三个值写进.env文件代码里用DotEnv.Load()读进来避免硬编码MODELgpt-4o API_KEYsk-你的TaoToken密钥 OPENAI_URLhttps://taotoken.net/api注意OPENAI_URL不要带末尾斜杠OpenAIClientOptions.Endpoint对 URI 格式比较敏感多一个斜杠在某些版本会报Invalid endpoint。如果你还没生成 Key去控制台的 API Keys 页面创建接入细节可以对照接入文档里面有各语言的完整示例。这一步做完Agent 本身就能跑了接下来才是 OpenTelemetry 的事。3. 可复制配置TracerProvider MeterProvider Agent 中间件OpenTelemetry 在 .NET 里的核心是两个 ProviderTracerProvider管链路MeterProvider管指标。两者要用同一个serviceName否则 Jaeger 和 Prometheus 里的数据对不上号。先装 NuGet 包dotnet add package OpenTelemetry dotnet add package OpenTelemetry.Exporter.Console dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol dotnet add package OpenTelemetry.Exporter.Prometheus.HttpListener dotnet add package OpenTelemetry.Extensions.Hosting然后是完整的配置骨架。注意AddSource和AddMeter里的名字必须和后面UseOpenTelemetry的sourceName一致using OpenTelemetry; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; var serviceName AIApp; var serviceVersion 1.0.0; using (Sdk.CreateTracerProviderBuilder() .SetResourceBuilder(ResourceBuilder.CreateDefault() .AddService(serviceName, serviceVersion: serviceVersion)) .AddSource(serviceName) .AddConsoleExporter() .AddOtlpExporter(o { o.Endpoint new Uri(http://localhost:4317); o.Protocol OpenTelemetry.Exporter.OtlpExportProtocol.Grpc; }) .Build()) using (Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(ResourceBuilder.CreateDefault() .AddService(serviceName, serviceVersion: serviceVersion)) .AddMeter(serviceName) .AddConsoleExporter() .AddPrometheusHttpListener(o o.UriPrefixes [http://192.168.1.166:9464/]) .Build()) { // Agent 构建代码放这里 }Agent 侧的中间件注册是关键。UseOpenTelemetry是AIAgentBuilder的扩展方法它内部会 new 一个OpenTelemetryAgent包住内层 Agentvar agent new OpenAIClient( credential: new AzureKeyCredential(apiKey), options: new OpenAIClientOptions { Endpoint new Uri(endpoint) }) .GetChatClient(model: model) .AsIChatClient() .AsAIAgent(name: MyAgent) .AsBuilder() .UseOpenTelemetry(sourceName: serviceName) .Build();如果你要监控工具调用配置得改一下。默认autoWireChatClient: true会把OpenTelemetryChatClient插到FunctionInvokingChatClient前面导致工具调用的 Span 被吞掉。正确做法是显式注册 ChatClient 中间件再让 Agent 中间件用autoWireChatClient: truevar agent new OpenAIClient( credential: new AzureKeyCredential(apiKey), options: new OpenAIClientOptions { Endpoint new Uri(endpoint) }) .GetChatClient(model: model) .AsIChatClient() .AsBuilder() .UseOpenTelemetry(sourceName: serviceName) // ChatClient 层 .Build() .AsAIAgent(name: MyAgent, tools: [AIFunctionFactory.Create(GetWeather, nameof(GetWeather))]) .AsBuilder() .Use(inner new OpenTelemetryAgent(inner, serviceName, true)) // Agent 层 .Build();这样 Jaeger 里就能同时看到invoke_agent、chat、execute_tool三层 Span调用链才完整。4. 验证请求发起一次 Agent 调用并检查上报配置写完跑一次真实调用验证。下面这段代码手动造了三层 Activity 模拟外层业务逻辑再触发 Agentvar source new ActivitySource(serviceName); using (source.StartActivity(Agent-Server, kind: ActivityKind.Server, parentContext: default)) { await Task.Delay(200); using (source.StartActivity(Foo)) { await Task.Delay(300); using (source.StartActivity(Bar)) { await Task.Delay(400); await agent.RunAsync(苏州今天天气怎么样适合穿什么); } } }跑起来后控制台会先打印 Span 和 Metric 的原始输出。然后打开 Jaeger UIhttp://localhost:16686/选服务AIApp点 Find Traces你应该能看到一条完整的调用链Agent-Server→Foo→Bar→invoke_agent MyAgent→chat gpt-4o→execute_tool GetWeather。每个 Span 上会带这些标签用来区分 Agent 身份标签含义gen_ai.operation.name固定为invoke_agentgen_ai.provider.name模型提供商gen_ai.agent.idAgent 唯一标识gen_ai.agent.nameAgent 名称gen_ai.agent.descriptionAgent 描述指标侧打开 Prometheushttp://localhost:9090查gen_ai_client_operation_duration_seconds能看到每次调用的耗时分布。Grafana 里导入 Dashboard 后重点看四个指标gen_ai.client.operation.duration端到端延迟看 P95/P99 长尾gen_ai.client.token.usage按 input/output 拆分算成本gen_ai.client.operation.time_to_first_chunkTTFT流式场景体验核心gen_ai.client.operation.time_per_output_chunk流式输出流畅度验证成功的标志Jaeger 里 Span 层级完整Prometheus 里能查到gen_ai_client_operation_duration_seconds_count在增长Grafana 面板有曲线。5. 本篇常见错排查Span 里看不到工具调用。这是最常见的坑。原因是autoWireChatClient默认为true时OpenTelemetryChatClient被插到了FunctionInvokingChatClient前面当前 Activity 变成了chat而不是invoke_agent工具跟踪逻辑检查到不是 Agent 调用就直接跳过了。解法就是第 3 节里那个显式注册 ChatClient 中间件的写法。Prometheus 抓不到指标。检查PrometheusHttpListener的UriPrefixes是不是用了localhost。Prometheus 跑在 Docker 容器里容器内的localhost指向容器自己必须用宿主机 IP比如192.168.1.166。prometheus.yml里的 target 也要写宿主机 IPglobal: scrape_interval: 5s scrape_configs: - job_name: csharp_console_app static_configs: - targets: [192.168.1.166:9464]Jaeger 里没有数据。先确认 OTLP exporter 的 endpoint 是http://localhost:4317协议是 gRPC。如果 Jaeger 容器没映射 4317 端口加上-p 4317:4317。另外AddSource(serviceName)里的名字必须和UseOpenTelemetry(sourceName:)完全一致大小写敏感。Token 用量指标为空。gen_ai.client.token.usage依赖模型返回的 usage 字段。如果 TaoToken 通道返回的响应里没有 usage指标就不会记录。可以在控制台 exporter 的输出里确认一下ChatResponse是否带了 token 统计。流式指标缺失。time_to_first_chunk和time_per_output_chunk只在流式调用RunStreamingAsync时才有数据普通RunAsync不会产生。要验证这两个指标得改成流式调用。6. 把可观测性接进你的 Agent 工作流链路跟踪和性能监控不是跑一次就完事它得跟着你的开发流程走。我的做法是本地开发用 Console exporter 快速看输出联调环境推 Jaeger 看调用链生产环境用 Prometheus Grafana 做告警。TaoToken 的统一 Key 在这里的价值是——你换模型时不用动 OpenTelemetry 配置sourceName和中间件结构都不变只是 endpoint 后面的模型名换一下指标和链路自动跟着新模型走。如果你还在选型阶段想先验证模型对话效果可以直接在模型对话页面试要长期跑编码类 Agent、需要稳定的 Key 配额看 Coding Plan接入过程中遇到 Key 或 endpoint 问题去 API Keys 页面重新生成对照接入文档排查。把 OpenTelemetry 这套骨架搭好之后后面加 Agent、加工具、加模型监控都是自动覆盖的不用每次重新配。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

维特智能WTVB05助力工业设备客户实现电机轴承健康度在线检测 2026/9/25 18:16:10

维特智能WTVB05助力工业设备客户实现电机轴承健康度在线检测

在工业现场,电机、风机、水泵等旋转设备的轴承故障是导致非计划停机的主要原因之一。传统人工巡检方式周期长、响应慢,难以在故障早期发现问题。本文分享一套基于维特智能 WTVB05-485/CAN 温振一体传感器的电机轴承在线健康监测方案,涵盖选型…

阅读更多 →
5G信令流程本质:状态机、跨域协同与参数驱动的实时协商机制 2026/9/25 18:16:10

5G信令流程本质:状态机、跨域协同与参数驱动的实时协商机制

1. 为什么5G信令流程不能只看“流程图”——从基站告警反推注册失败的真实逻辑我第一次在现网处理5G注册失败问题时,盯着网管系统里那张标着“NAS Registration Request → Authentication Request → Security Mode Command → Registration Accept”的标准信令流程…

阅读更多 →
YOLOv8工程落地实战:从环境配置到嵌入式部署全链路指南 2026/9/25 18:16:03

YOLOv8工程落地实战:从环境配置到嵌入式部署全链路指南

1. 为什么YOLOv8不是“又一个YOLO”,而是目标检测工程落地的分水岭YOLOv8刚发布时,我正带着团队在产线部署一套缺陷识别系统。当时用的是YOLOv5s,模型轻、推理快,但遇到两个死结:一是小目标漏检率高得离谱——比如PCB板…

阅读更多 →
Agent技能库实战:从Function Calling到Skills封装与工作流编排 2026/9/25 18:15:56

Agent技能库实战:从Function Calling到Skills封装与工作流编排

开头先打个招呼,最近不少做AI应用的朋友都在问同一个项目:agent-skills。我的理解里,它不只是一个开源仓库的名字,更是一套让Agent“真正做事”的方法论——把一个个可执行的能力封装成标准化模块,让大模型在遇到具体任…

阅读更多 →
Atlas 300V推理加速卡与YOLO模型昇腾部署全流程解析 2026/9/25 18:15:31

Atlas 300V推理加速卡与YOLO模型昇腾部署全流程解析

作为算法工程师,最近这两年被问得最多的硬件问题,除了各类开发板,就是华为的Atlas系列。热搜里那个“atlas 300v 24g 是运算加速卡吗”就不用怀疑了,它确实是运算加速卡,而且是一块专门为AI推理场景设计的加速卡。至于…

阅读更多 →
Atlas 300V 24G推理加速卡与YOLO部署全攻略 2026/9/25 18:15:24

Atlas 300V 24G推理加速卡与YOLO部署全攻略

最近逛社区,发现很多人都在搜“atlas部署yolo”和“atlas 300v 24g 是运算加速卡吗”。这两个问题恰好是我过去一年在边缘侧做AI落地时被问得最多的。我自己手头有3张Atlas 300V 24G,用它们跑过YOLOv5和YOLOv8的工地安全帽检测、车间人员闯入检测、还有一…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉