Skip to the content.
LANGCHAIN_TUTORIAL 回 Jason 主站

01 · Tracing — 看见 Agent 内部发生了什么

本步带回家的概念:LLM 应用是黑盒——你给一个问题,里面跑了 5 次 LLM 调用、3 次工具、2 次重试。LangSmith Trace = 把这盒子打开摊在桌上,每一步耗时、token、输入输出全可见。 配套代码final/03_langsmith/01_tracing.py 预计耗时:30-45 分钟(密度比 week-3 略低)


准备 (5 分钟)


任务卡

任务 1 · 跑起来 + 真去 LangSmith UI 转一圈(10 分钟)

做什么

python final/03_langsmith/01_tracing.py

跑完立刻去 smith.langchain.com,左侧 Projects → study,找到刚才那批 Trace。点开任意一条,重点看 4 件事

  1. 执行树:左侧的层级(chain → llm 调用 → tool 调用)
  2. Inputs / Outputs:每个节点的输入输出(点开能看到原始 JSON)
  3. Latency / Tokens:每步耗时和 token 用量
  4. Tags / Metadata:你在代码里设的 run_name="explain_concept"tags=["demo"]metadata={"version": "1.0"} 在 UI 哪里显示

为什么先看 UI

很多教程只讲”怎么开 trace”,但不告诉你 trace 长什么样、怎么读。这一步是让你先建立 UI 心智模型,再回头看代码就能问对问题。

给 AI 的 prompt(先去 UI 转一圈再问):

我刚跑了 final/03_langsmith/01_tracing.py 并在 LangSmith UI 看了这次的 trace 树。
我注意到 LangChain 链路(PromptTemplate | llm | StrOutputParser)的每个组件
都自动出现在执行树里。

请用日常类比帮我搞清 3 件事:

1. LangSmith 的 Trace 跟程序员熟悉的 stack trace 有什么共同点 / 不同点?
   是不是更像"飞机黑匣子"——除了报错,平时也在录?
2. 自动追踪是怎么实现的?为什么我不用在 LangChain 代码里加任何东西
   就能上报?(提示:跟环境变量 + LangChain 内部 callback 有关)
3. tags 和 metadata 的差别——我应该把"环境=dev"放 tags 还是 metadata?

回答 250 字内,每问独立段落,从日常类比开始。

自检:能讲清「为什么 LangChain 自动追踪开关只是一个 env var」(提示:所有 Runnable 内部都有 callback hook,env var 一开就把上报 callback 挂上)。


任务 2 · 给普通函数加 @traceable(10 分钟)

做什么:在 _scratch/my_ls01_tracing.py 里,写两个纯 Python 函数(不直接调 LangChain),用 @traceable 装饰:

再写一个父函数 process_text(text) 调用这两个,也加 @traceable。跑一次后去 UI 看嵌套 trace。

给 AI 的 prompt

我要在 _scratch/my_ls01_tracing.py 里给普通 Python 函数加 @traceable,
然后看嵌套 Trace。

请引导我(不直接给代码):
1. @traceable 装饰器干了什么?它跟 LangChain 自动追踪是同一套机制吗?
2. 嵌套追踪是怎么"自动嵌套"的——
   父函数加了 @traceable,子函数也加了 @traceable,
   LangSmith 怎么知道子函数是父函数的孩子?
   (提示:跟 contextvar / 当前 run 的栈有关)
3. @traceable 的 name=, tags=, metadata= 参数怎么用最划算?
   什么场景必须自定义 name?

每次只问我一个问题。

写完跑:

python _scratch/my_ls01_tracing.py

去 UI 看嵌套是不是真的层级显示。

自检:能讲清「为什么 @traceable 要装饰子函数才能进 trace 树」(提示:不装饰就是个普通 Python 函数,框架看不到它的边界,自然不会上报)。


任务 3 · 用 RunTree 手动控制 + 加 Feedback(10 分钟)

做什么:参考 finaldemo_run_tree,在 my_ls01_tracing.py 里写一段:

跑完去 UI 看你手动建的那条 trace。

给 AI 的 prompt

我要在 _scratch/my_ls01_tracing.py 里用 RunTree 手动建 trace。

请引导我(不直接给代码):
1. RunTree 跟 @traceable 比,多了什么自由度?什么场景必须用 RunTree?
   (提示:你想 trace 一段非 LangChain、非 Python 的代码——比如调外部 HTTP API)
2. .post() 和 .patch() 分别什么时候调?少调一个会怎样?
   (提示:post 是创建,patch 是更新——end 后必须 patch 才能把 outputs 上报)
3. 如果一个子 run 报错,应该怎么 end?
   (提示:end(error="xxx") 会把这个 run 标红)

每次只问我一个问题。

进阶:跑完拿到一个 run_id,用 ls_client.create_feedback(run_id=..., key="rating", score=0.8) 给它打分,去 UI 看分数显示。

自检:能讲清「RunTree 是给什么场景用的」(提示:非 LangChain 代码、混编系统、自定义 SDK 内部)。


任务 4 · 自检:跟 final 对比 + 看 trace 数据结构(5 分钟)

给 AI 的 prompt

我自己写的 _scratch/my_ls01_tracing.py:
[贴代码]

参考答案 final/03_langsmith/01_tracing.py:
[让 AI 自己读]

请帮我对比 3 处:
1. @traceable 的参数(name / tags / metadata)我有没有用得太杂或太少?
2. RunTree 的 post / patch 时机我对吗?
3. final 用 get_current_run_tree() 拿当前 run id 给 feedback —— 这个 idiom 我会用吗?

哪些是风格差异,哪些是真问题?

去 UI 把你的 trace 和 final 的 trace 摆一起对比”看上去能不能一目了然出执行流”。

自检:能讲清「trace 不只是 debug 工具,也是产品监控工具」(提示:上线后接入 dashboard、按 tag 过滤错误率、看延迟分布)。


通关条件


卡点日志(必填)

打开 _scratch/journal/,新建 2026-XX-XX-week4-01.md

# Week 4 · 01_tracing — 卡点日志

## 卡点

## "原来如此"时刻

## 想留作复用的 prompt

## 还没搞懂的(留尾巴)

通往下一站