基于 OpenTelemetry 的 Agent 全链路追踪实战:解读 mcp-agent 的 Agent Tracing 示例
【免费下载链接】mcp-agentBuild effective agents using Model Context Protocol and simple workflow patterns项目地址: https://gitcode.com/GitHub_Trending/mc/mcp-agent
在构建多工具、多服务器的 MCP Agent 时,定位"某次工具调用为什么慢""哪个 MCP 服务器抛了错""LLM 到底调用了几轮"是日常排查的痛点。mcp-agent 框架内置了基于 OpenTelemetry(OTEL)的分布式追踪能力,而 examples/tracing/agent 正是展示这一能力的最小完整示例:它用一个同时挂载fetch与filesystem两个 MCP 服务器的 "finder" Agent,演示了如何把 Agent 的所有方法调用以 Span 形式输出到控制台,并可一键切换到 OTLP 导出,把追踪数据发送到 Jaeger 等 Collector 进行可视化分析。读完本文,你将掌握 mcp-agent 追踪体系的配置方法、运行方式、控制台输出解读,以及如何将追踪数据接入 Jaeger 进行链路分析。
示例概览:一个带完整追踪的最小 Agent
本示例的核心文件位于 examples/tracing/agent:
- main.py:示例主程序,定义一个名为
finder的 Agent; - mcp_agent.config.yaml:框架配置,包含 MCP 服务器、模型与 OTEL 追踪配置;
- mcp_agent.secrets.yaml.example:密钥占位模板(API Key 存放处,可被 gitignore);
- requirements.txt:依赖清单,其中以
mcp-agent @ file://../../../的形式直接链接本地仓库根目录,其余依赖为anthropic与openai。
该示例的运行方式极其简单,在examples目录下执行:
uv run tracing/agent说明:该命令假设你已安装 uv 目录运行;若希望独立安装,可参照 安装文档 先在本地完成框架安装,再运行 main.py。
finderAgent 的定位是:同时拥有 filesystem 与 fetch 能力,根据用户的请求在本地文件系统与远程 URL 之间找到最接近的匹配项,并返回其 URI 与内容。它注册的指令(instruction)在 main.py 中定义:
finder_agent = Agent( name="finder", instruction="""You are an agent with access to the filesystem, as well as the ability to fetch URLs. Your job is to identify the closest match to a user's request, make the appropriate tool calls, and return the URI and CONTENTS of the closest match.""", server_names=["fetch", "filesystem"], human_input_callback=human_input_handler, )server_names指明该 Agent 连接的两个 MCP 服务器,它们分别由uvx mcp-server-fetch(抓取 URL)与npx -y @modelcontextprotocol/server-filesystem(访问文件系统)提供。
配置解读:OTEL 追踪的三要素
示例的完整配置位于 mcp_agent.config.yaml,追踪相关部分如下:
logger: transports: [file] level: debug progress_display: true path_settings: path_pattern: "logs/mcp-agent-{unique_id}.jsonl" unique_id: "timestamp" # Options: "timestamp" or "session_id" timestamp_format: "%Y%m%d_%H%M%S" mcp: servers: fetch: command: "uvx" args: ["mcp-server-fetch"] filesystem: command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem"] openai: default_model: "gpt-4o-mini" otel: enabled: true exporters: - console - file # To export to a collector, also include: # - otlp: # endpoint: "http://localhost:4318/v1/traces" service_name: "BasicTracingAgentExample"otel配置块对应源码中 OpenTelemetrySettings 模型,核心字段含义如下:
| 配置项 | 默认值 | 说明 |
|---|---|---|
enabled | false | 总开关,置为true才启用追踪 |
exporters | [] | 导出器列表,可同时启用多个:console(输出到标准输出)、file(写入 JSONL 文件)、otlp(发送到 Collector),既支持字符串形式(如"console")也支持键值映射形式(如{file: {path: "trace.jsonl"}}),同时支持历史兼容的{type: "console"}形式 |
service_name | "mcp-agent" | 服务名,用于在追踪后端标识来源,本示例设置为"BasicTracingAgentExample" |
service_instance_id | 自动生成 | 服务实例 ID,缺省时自动取会话 ID |
service_version | 安装的mcp-agent版本 | 服务版本号 |
sample_rate | 1.0 | 采样率,1.0表示全量采样,可设0~1之间的小数做比例采样 |
值得注意的有两点:其一,exporters可多路并存,本示例同时启用了console与file——控制台用于实时观察,文件用于事后分析;其二,字符串形式的导出器会回退读取历史遗留字段(如otlp_settings、path、path_settings),这一兼容逻辑实现在 config.py 的模型校验器中。
此外,file导出器的文件路径由path_settings控制。对应源码中的 TracePathSettings 模型:path_pattern默认为traces/mcp-agent-trace-{unique_id}.jsonl,占位符{unique_id}可由unique_id字段决定替换为timestamp(时间戳)或session_id(会话 ID),timestamp_format则指定时间戳格式(默认%Y%m%d_%H%M%S)。
openai.default_model指定默认使用的模型(本示例为gpt-4o-mini),而 API Key 则放在 mcp_agent.secrets.yaml.example 所示的 secrets 文件中(运行前需复制为mcp_agent.secrets.yaml并填入真实密钥):
openai: api_key: openai_api_key anthropic: api_key: anthropic_api_key主程序流程:被追踪的 Agent 方法全演练
main.py 通过asyncio.run(agent_tracing())启动整个流程,其追踪对象覆盖了 Agent 几乎全部方法,正好构成一份"哪些操作会生成 Span"的清单:
- 初始化 App 与上下文:
MCPApp(name="agent_tracing_example", human_input_callback=human_input_handler)创建应用实例,其内部配置加载自mcp_agent.config.yaml/mcp_agent.secrets.yaml。这里传入的human_input_handler是一个模拟单步响应的回调,直接返回HumanInputResponse,使示例无需真实交互即可运行。 - 动态注入文件系统路径:
context.config.mcp.servers["filesystem"].args.extend([os.getcwd()])将当前工作目录追加到 filesystem 服务器参数中,使 Agent 能够读取当前目录。 - 服务器能力探测:
finder_agent.list_tools()列出所有工具;finder_agent.get_capabilities("fetch")与get_capabilities("filesystem")分别获取两个服务器的能力描述;list_prompts("fetch")/list_prompts("filesystem")列出服务器提供的 Prompt 模板;get_prompt("fetch_fetch", {"url": "https://modelcontextprotocol.io"})拉取具体 Prompt 实例。
- 挂载 LLM 并生成文本:
await finder_agent.attach_llm(OpenAIAugmentedLLM)将 OpenAI 增强 LLM 挂到 Agent 上,随后调用llm.generate_str(message="Print the contents of mcp_agent.config.yaml verbatim")让模型输出配置文件原文。 - 请求人工输入:
finder_agent.request_human_input(...)触发一次带timeout_seconds=5与元数据的人工输入请求,验证追踪对人工输入流程的覆盖。 - 直接调用 MCP 工具:
finder_agent.call_tool("fetch_fetch", {"url": "https://modelcontextprotocol.io"})绕过 LLM 直接调用 fetch 工具。 - 切换 LLM 供应商:再次
attach_llm(AnthropicAugmentedLLM)把同一 Agent 切换到 Anthropic 增强 LLM,并让其总结https://modelcontextprotocol.io/introduction的前两段——演示了同一个 Agent 可在运行时切换不同 LLM 后端的能力。
最后程序会打印总运行时长:
start = time.time() asyncio.run(agent_tracing()) end = time.time() print(f"Total run time: {t:.2f}s")控制台 Span 输出:为什么"所有 Agent 方法"都有追踪
示例 README 指出:"The tracing implementation will log spans to the console for all agent methods."(追踪实现会把所有 Agent 方法以 Span 形式记录到控制台)。这并非偶然——mcp-agent 在框架层面对 Agent 的核心方法做了统一埋点。其实现位于 src/mcp_agent/tracing/telemetry.py:
TelemetryManager.traced(...)是一个装饰器工厂,自动为函数创建并管理 Span,同时兼容同步与异步函数(见async_wrapper/sync_wrapper);- 发生异常时调用
span.record_exception(e)并设置StatusCode.ERROR,保证错误链路可被追溯; record_attributes/serialize_attribute会把方法的简单参数序列化进 Span 属性,长字符串会被截断到 255 个字符。
以console导出器运行时,终端会看到形如以下的结构化输出(真实输出为 OpenTelemetry 控制台导出器的完整 JSON/结构化格式),其中finder.list_tools、finder.call_tool等即为对应方法的 Span 名:
{ "name": "finder.list_tools", "context": {"trace_id": "...", "span_id": "..."}, "parent_id": "...", "attributes": {}, ... }若同时启用file导出器,相同的数据会以 JSONL 形式落盘,供后续离线分析。
进阶:把追踪导出到 Jaeger Collector
示例 README 给出了将追踪数据接入 Jaeger 的方法:先在本地安装 Jaeger(官方快速开始指南),再在mcp_agent.config.yaml的otel.exporters中追加一个带 Collector 端点的类型化 OTLP 导出器:
otel: enabled: true exporters: - console - file - otlp: endpoint: "http://localhost:4318/v1/traces"启用后,所有 Span 会经 OTLP/HTTP 协议批量发送到 Jaeger 的 Collector 端点,随后可在 Jaeger UI 中按service.name = "BasicTracingAgentExample"检索完整的调用链——包括finder.list_tools、finder.call_tool("fetch_fetch")、llm.generate_str等各个阶段的耗时与父子关系。
这一配置在源码中的落地路径为 src/mcp_agent/tracing/tracer.py 的TracingConfig.configure方法:
- 资源标识:为服务创建
Resource,写入service.name、service.instance.id、service.version、session.id等属性;其中session.id缺省时自动生成 UUID,保证每次运行链路可区分; - 采样控制:仅当显式设置了
sample_rate时,才用ParentBased(TraceIdRatioBased(sample_rate))采样器,否则全量采样; - 导出器装配:遍历
exporters,解析字符串形式与键值映射形式,分别挂载ConsoleSpanExporter、OTLPSpanExporter(从 payload 中读取endpoint与headers)和FileSpanExporter(从 payload 或历史遗留字段中读取path/path_settings); - 自动埋点:首次配置时对
AnthropicInstrumentor与OpenAIInstrumentor执行全局instrument(),从而让底层 LLM SDK 的调用自动产生 Span——这正是"所有 Agent 方法 + LLM 调用"都能被追踪的底层原因;若未安装对应 instrumentation 包,会记录错误日志提示安装opentelemetry-instrumentation-anthropic。
另外,TracingConfig还提供flush(timeout_ms)与shutdown()方法,用于强制刷出待导出的 Span 以及优雅关闭后台导出线程。
参数进阶与排查要点
1.exporters的三种写法
源码 config.py 明确兼容多种写法,可按需选择:
otel: enabled: true exporters: # 写法一:纯字符串,简单直观 - console - file - otlp # 写法二:键值映射,可为 file/otlp 指定详细参数 - file: path: "logs/trace.jsonl" - otlp: endpoint: "http://localhost:4318/v1/traces" headers: {"Authorization": "Bearer xxx"} # 写法三:历史兼容的 type 字段形式 - type: "file" path: "/tmp/out"其中otlp导出器支持endpoint与可选headers(对应源码中的 OTLPExporterSettings),file导出器支持path与path_settings(对应 FileExporterSettings)。
2. 采样率与生产环境建议
高吞吐场景下可降低sample_rate以控制数据量,例如:
otel: enabled: true sample_rate: 0.1 # 采样 10% 的链路 exporters: [console, file]3. 排查要点
- 未看到 Span:首先确认
otel.enabled: true;其次确认exporters至少包含console;最后确认 logger 的level足够低(示例中为debug),避免输出被过滤。 - OTLP 无数据:确认 Collector 端点可达(
http://localhost:4318/v1/traces是 Jaeger 默认的 OTLP/HTTP 接收路径),并留意源码 tracer.py 中的错误分支——未提供 endpoint 时仅记录错误日志。 - 密钥缺失:示例运行会连接 OpenAI/Anthropic,请务必先按 mcp_agent.secrets.yaml.example 创建 secrets 文件,否则相关 LLM 调用会失败。
延伸阅读
追踪体系在仓库中还有其他场景的示例,可对照学习:
- examples/tracing/llm:直接使用 LLM(OpenAI / Anthropic / Azure)时的追踪,演示
generate、generate_str、generate_structured三类生成方式; - examples/tracing/mcp:MCP 服务器层的追踪;
- examples/tracing/temporal:与 Temporal 工作流引擎结合时的追踪;
- examples/tracing/langfuse:对接 Langfuse 追踪后端的示例;
- 追踪配置的完整 schema 可参考 schema/mcp-agent.config.schema.json,日志与事件体系的更多细节见 docs/mcp-agent-sdk/advanced/observability.mdx 与 docs/advanced/monitoring.mdx。
从控制台到文件、再到 Jaeger 的全链路导出,examples/tracing/agent用不到百行代码覆盖了 mcp-agent 追踪体系的核心用法——先跑通示例观察控制台 Span,再按需叠加file落盘与otlp接入 Collector,即可完成从"本地调试"到"生产可观测"的平滑升级。
【免费下载链接】mcp-agentBuild effective agents using Model Context Protocol and simple workflow patterns项目地址: https://gitcode.com/GitHub_Trending/mc/mcp-agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考