LangSmith追踪

本地 print state 难以复现线上 20 步 Agent 失败路径。LangSmith 相当于记录 Agent 沿着图实际走过的路径,以及路径上每个 span 的 资源消耗(耗时、token、费用)。图结构与 Chain 追踪共用同一套 UI。

段末注释Smith = 这条走过的路 + 路上花了多少资源;没走到的条件边不会出现在 trace 里。完整 State 链与时间旅行仍靠 checkpointer 的 get_state_history

图 1 Smith 记走过的路和油耗;整车货物在 history(对应 §4.2~§4.5)


1. 定位

维度 内容
角色 记录实际执行路径 + 各 span 资源账
输入 → 输出 一次 invoke → span 树(路径)+ latency/token/费用
核心 API 环境变量 + LangChain 自动 instrumentation
依赖 LangChain @traceable、RunTree(可选)

2. 图拓扑

节点表

节点名 职责
alpha 第一步 log
beta 第二步 log

边表

目标 类型
START alpha 固定
alpha beta 固定
beta END 固定

3. invoke 生命周期(观测视角)

1
2
3
4
1. invoke 开始 → 根 run(graph)
2. alpha 执行 → 子 span(node)
3. beta 执行 → 子 span
4. END → 根 run 结束上传(若 LANGCHAIN_TRACING_V2=true)

4. 原理

4.1 环境变量

1
2
3
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=lsv2_...
export LANGCHAIN_PROJECT=langgraph-demo

4.2 节点即 span:走过的路

LangGraph 与 LangChain 集成后,各 node 名称出现在 trace 树。树的主干就是这次 invoke 实际调度过的节点;节点内再套 LLM / tool 子 span。条件边没选中的分支 不会 出现。

这是调用轨迹,不是图的静态边清单,也不是每一拍合并后的完整 values

4.3 路径上的资源消耗

每个 span 带 latency;模型子 span 再带 token / 费用。用来对比「哪一站最贵、哪一站最慢」,不能用来 update_state 或 fork。

4.4 无 Smith 的本地替代

compile(debug=True) + stream(updates) 仅本地;不上云。

4.5 不是 get_state_history 的云镜像

LangSmith 追踪 get_state_history
一句话 这条走过的路 + 路上花了多少资源 每一站的整车货物,并能从某站再开出去
没走到的边 trace 里没有 无对应快照(那一拍没发生)
完整 State 一般没有 values 是全量
时间旅行 不能 checkpoint_id + invoke

没配 checkpointer 时 trace 仍在,但 不能 续跑。部署到 Agent Server 后,Studio 的 thread history 才是远程封装的同一套 checkpoint API。故障复现要 trace(看见当时调了什么、花了多少)+ history(回到那一拍的 state)


5. 最小可运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import operator
import os
from typing import Annotated, TypedDict

from langgraph.graph import StateGraph, START, END

# 本地演示:若未配置 API Key,图仍可运行,只是不上传
os.environ.setdefault("LANGCHAIN_TRACING_V2", "false")


class State(TypedDict):
log: Annotated[list[str], operator.add]


def alpha(_: State) -> dict:
return {"log": ["alpha"]}


def beta(_: State) -> dict:
return {"log": ["beta"]}


builder = StateGraph(State)
builder.add_node("alpha", alpha)
builder.add_node("beta", beta)
builder.add_edge(START, "alpha")
builder.add_edge("alpha", "beta")
builder.add_edge("beta", END)

graph = builder.compile()
out = graph.invoke({"log": []})
print(out["log"])
# 配置 Smith 后,同一次 invoke 可在 UI 看到 alpha → beta 两 span

5.1 可选显式 traceable

1
2
3
4
5
from langsmith import traceable

@traceable(name="beta-node")
def beta(_: State) -> dict:
return {"log": ["beta"]}

6. 执行追踪

Smith UI 层级 对应执行 路径上记什么
Graph run 整次 invoke 总 latency;走过 alpha→beta
alpha span superstep 1 该站 I/O + 耗时
beta span superstep 2 该站 I/O + 耗时
(若有 LLM 子 span) 节点内模型调用 token / 费用

重要配置参数

参数 类型 / 默认 作用与影响 参考起点 配置指导
LANGCHAIN_TRACING_V2 true/false 开关追踪 开发 true CI 可 false
LANGCHAIN_PROJECT str 项目分组 按服务名 多环境分离
LANGCHAIN_API_KEY secret 上传凭证 Smith 控制台 勿提交 git
compile(debug=True) bool 本地日志 无 Smith 临时
@traceable 装饰器 自定义 span 名 关键节点 可选
采样率 平台配置 降本 高 QPS Smith 项目设置

7. 易踩坑

  1. 未设 PROJECT 全进 default:难以筛选 LangGraph 实验。
  2. 把 trace 当审计唯一来源:合规仍需自有日志与 checkpoint。
  3. 敏感数据进 span:invoke 输入含 PII 需脱敏或关闭追踪。

小结

  • Smith = 这条走过的路 + 路上花了多少资源;没走到的条件边不在 trace 里。
  • 这不是 get_state_history:完整 State 与 fork 必须靠 checkpointer
  • 本地无 Key 时图照常跑;观测改用 stream/debug

参考链接

-------------本文结束感谢您的阅读-------------