LangGraph 分布式追踪:为什么你的 Agent 执行链总是“黑盒”?
这篇文章帮你搞定 LangGraph 分布式追踪的底层原理,从 Trace/Span 到全链路可观测
这篇文章帮你搞定 LangGraph 分布式追踪的底层原理,从 Trace/Span 到全链路可观测
阅读提示
- 适合谁看:有 LangGraph 或 LLM 应用开发经验,正在做生产级可观测性的工程师
- 看完能做什么:能设计可追踪、可调试、可监控的分布式追踪系统
- 不适合谁:还没理解 LangGraph State/Graph 基础概念的纯新手
先给结论
- 追踪不是“打印日志”,而是结构化的 Trace/Span 数据
- 每个节点执行都是一个 Span,Span 之间通过 TraceID 关联
- 生产级追踪必须考虑:采样策略、上下文传播、 exporter 选型
很多人做 LangGraph 时,demo 阶段跑得很顺,一上生产就发现 Agent 执行链是“黑盒”:
- 不知道哪个节点耗时最长
- 出错时不知道哪个节点出问题
- 性能瓶颈无法定位
看起来是日志问题,本质上是分布式追踪没设计好。
01 分布式追踪的本质:Trace 与 Span

分布式追踪的核心思想是Trace 与 Span:
- Trace:一次完整的执行链,包含所有 Span
- Span:执行链中的一个步骤,包含开始时间、结束时间、状态
- TraceID:Trace 的唯一标识,所有 Span 共享
- SpanID:Span 的唯一标识,用于关联父子关系
这意味着:
- 每个节点执行都是一个 Span
- Span 之间通过 TraceID 关联
- 父子 Span 通过 ParentSpanID 关联
为什么不能用日志代替?
# 误区:用日志记录执行链def execute_node(state): print(f"Node started: {node_name}") result = process(state) print(f"Node finished: {node_name}") return result
这种写法的问题在于:
- 日志是文本,无法结构化查询
- 无法关联父子关系
- 无法计算耗时
- 无法做采样和聚合
LangGraph 的解法是把追踪变成Trace + Span + Exporter:
- Trace:一次完整的执行链
- Span:执行链中的一个步骤
- Exporter:把 Span 数据导出到 Jaeger/Zipkin
场景代码示例:分布式追踪配置
from opentelemetry import tracefrom opentelemetry.sdk.trace import TracerProviderfrom opentelemetry.sdk.trace.export import BatchSpanProcessorfrom opentelemetry.exporter.jaeger.thrift import JaegerExporter# 1) 初始化 Tracerprovider = TracerProvider()jaeger_exporter = JaegerExporter( agent_host_name="localhost", agent_port=6831,)provider.add_span_processor(BatchSpanProcessor(jaeger_exporter))trace.set_tracer_provider(provider)tracer = trace.get_tracer("langgraph-agent")# 2) 运行入口:验证配置是否成功if __name__ == "__main__": print("Tracer configured:", tracer)
02 Span 的底层原理:执行步骤的结构化记录

图 2|Span 执行流程
Span 的核心是执行步骤的结构化记录:
- 开始时间:Span 开始的时间戳
- 结束时间:Span 结束的时间戳
- 状态:Span 的执行状态(OK/ERROR)
- 属性:Span 的附加信息(key-value)
这意味着:
- Span 不是“日志行”,而是“结构化数据”
- Span 可以嵌套,形成父子关系
- Span 可以导出到外部系统,做可视化和分析
场景代码示例:Span 的使用方式
from opentelemetry import tracetracer = trace.get_tracer("langgraph-agent")def execute_node(state): # 创建 Span with tracer.start_as_current_span("execute_node") as span: # 设置属性 span.set_attribute("node_name", "my_node") span.set_attribute("input", str(state)) # 执行逻辑 result = process(state) # 设置状态 span.set_status(trace.StatusCode.OK) span.set_attribute("output", str(result)) return result# 最小验证if __name__ == "__main__": print("execute_node ready")
03 上下文传播:跨节点的 Trace 关联
图 3|上下文传播机制
上下文传播是分布式追踪的关键:
- TraceContext:携带 TraceID 和 SpanID
- 传播方式:通过 HTTP Header 或 gRPC Metadata
- 自动传播:OpenTelemetry 自动注入和提取
这意味着:
- 跨节点调用时,TraceContext 自动传播
- 子节点自动继承父节点的 TraceID
- 无需手动传递 TraceID
场景代码示例:上下文传播配置
from opentelemetry import tracefrom opentelemetry.propagate import set_global_textmapfrom opentelemetry.propagators.composite import CompositePropagatorfrom opentelemetry.propagators.tracecontext import TraceContextTextMapPropagator# 1) 配置传播器set_global_textmap( CompositePropagator([TraceContextTextMapPropagator()]))# 2) 运行入口:验证传播器配置if __name__ == "__main__": print("Propagator configured")
04 最小实验:观察追踪如何工作
实验条件
- 环境:LangGraph latest,Python 3.10+,Jaeger
- 输入:一个简单任务,包含两个节点
- 预期观察:Jaeger 中看到两个 Span,通过 TraceID 关联
- 先准备什么:启动 Jaeger,配置 OpenTelemetry
- 先跑什么:执行任务,观察 Jaeger 中的 Span
- 你应该看到什么:两个 Span,通过 TraceID 关联
代码 1
from opentelemetry import tracefrom opentelemetry.sdk.trace import TracerProviderfrom opentelemetry.sdk.trace.export import BatchSpanProcessorfrom opentelemetry.exporter.jaeger.thrift import JaegerExporter# 配置 Tracerprovider = TracerProvider()jaeger_exporter = JaegerExporter( agent_host_name="localhost", agent_port=6831,)provider.add_span_processor(BatchSpanProcessor(jaeger_exporter))trace.set_tracer_provider(provider)tracer = trace.get_tracer("langgraph-agent")def node_a(state): with tracer.start_as_current_span("node_a") as span: span.set_attribute("input", str(state)) return {"result": "a"}def node_b(state): with tracer.start_as_current_span("node_b") as span: span.set_attribute("input", str(state)) return {"result": "b"}# 测试# with tracer.start_as_current_span("root") as root_span:# result_a = node_a({"task": "test"})# result_b = node_b(result_a)# root_span.set_attribute("output", str(result_b))
如果结果不符合预期,先看哪里
- Jaeger 是否正常连接
- TraceID 是否正确传播
- Span 是否正确创建
- Exporter 是否正确导出
05 跑出来不对时,先看这几件事
- 现象 1:Jaeger 中看不到 Span → 可能 Exporter 配置错误,先检查连接
- 现象 2:Span 之间没有关联 → 可能上下文传播未生效,先检查 Propagator
- 现象 3:Span 耗时不准确 → 可能时间戳错误,先检查时区
- 现象 4:采样率太低 → 可能采样策略配置错误,先检查 Sampler
06 什么时候该用,什么时候别急着上
- 更适合:复杂 Agent 执行链、生产级可观测性、性能分析
- 不适合:简单任务、原型验证、低并发场景
- 成本会突然变高的点:Span 存储、采样策略、Exporter 选型
3 问判断法
- 你的 Agent 是否包含多个节点?
- 是否需要定位性能瓶颈?
- 是否需要生产级可观测性?
如果 3 个问题大多是否定,先不要上复杂方案。
07 小结:从“日志”到“结构化追踪”
分布式追踪的底层原理可以总结成三句话:
- Trace 是核心:一次完整的执行链,包含所有 Span
- Span 是关键:执行步骤的结构化记录,支持嵌套和关联
- 上下文是保障:TraceContext 自动传播,跨节点关联
当你把追踪从“日志”升级为“结构化追踪”,系统才真正具备可调试性、可监控性和可优化性。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

更多推荐


所有评论(0)