用 Trace、事件和测试定位故障

本章目标
让每次运行都能回答:走了哪条路径、状态如何变化、外部调用为何失败、成本是否超限。
启用 LangSmith
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY='在本机设置,不要写入代码'
export LANGSMITH_PROJECT=langgraph-support-tutorial
不要使用旧教程中的 LANGCHAIN_TRACING_V2 和 LANGCHAIN_API_KEY 作为新项目主配置。
运行配置中加入可过滤元数据:
config = {
"configurable": {"thread_id": "tenant-a:T-100"},
"tags": ["support", "refund"],
"metadata": {"tenant_id": "tenant-a", "ticket_id": "T-100"},
}
Trace 和日志不得记录密钥、完整个人信息、支付凭证或不必要的原始对话。
排查顺序

- 检查节点路径与条件边选择。
- 检查每个节点返回的局部更新。
- 检查模型、工具和数据库耗时及重试次数。
- 检查 token、步骤数和费用预算。
- 检查中断前是否发生非幂等副作用。
本地读取状态:
snapshot = await graph.aget_state(config)
print(snapshot.values)
print(snapshot.next)
history = [item async for item in graph.aget_state_history(config)]
不伪造观测数据
教程不提供虚构的“耗时 0.823 秒、Token 158”作为运行证据。实际数据依赖模型、网络、节点实现和追踪环境,应从自己的 Trace 中读取,并注明测试环境。
测试、日志和 Trace 各自解决不同问题:

- 测试防止行为回归。
- 日志记录业务事件和异常。
- Trace 解释一次运行内部的调用树和状态流。
统一关联标识
一次请求可能经过网关、API、图节点、模型和多个工具。至少贯穿以下标识:
request_id, run_id, thread_id, tenant_id, ticket_id,
checkpoint_id, node_name, idempotency_key
日志使用结构化字段,不要把它们拼进一段难以检索的消息:
logger.info(
"order_lookup_finished",
extra={
"thread_id": thread_id,
"ticket_id": ticket_id,
"node_name": "query_order",
"duration_ms": duration_ms,
"outcome": "success",
},
)
tenant_id 可以用于授权和过滤,但日志平台仍需租户级访问控制。问题全文、模型提示词和工具返回默认不进入日志;确需保留时进行字段级脱敏、加密和保留期审批。
用一次故障走完整排查链
以“订单查询先超时一次后成功”为例:
- API 日志确认
request_id、thread_id和调用入口。 - Trace 显示
query_kb一次成功,query_order因TimeoutError重试两次。 - 节点更新证明技术重试没有增加业务字段
attempts。 - 工具指标显示订单 API 首次超时、第二次成功及总延迟。
- 最终状态停在审批点,证明没有因为技术故障提前执行退款。
仓库测试 test_order_lookup_technical_retry_recovers 提供确定性故障源;接入 LangSmith 后应在自己的环境中保存对应 Trace 链接或截图,而不是在教程里伪造数值。
指标、SLO 与告警
至少采集:
| 类型 | 指标示例 |
|---|---|
| 流量 | 每租户运行数、节点调用数、SSE 连接数 |
| 延迟 | 运行端到端、节点、模型和工具 P50/P95/P99 |
| 错误 | 永久失败率、重试率、人工接管率、恢复失败率 |
| 资源 | PostgreSQL 连接池、队列深度、Worker 并发 |
| 成本 | 输入/输出 token、模型调用数、单工单费用 |
| 业务安全 | 重复副作用拦截数、未知执行结果数、超时审批数 |
告警必须对应可执行 Runbook。例如“Checkpoint 写入失败率持续五分钟超过阈值”应指导值班人员检查数据库连接池、磁盘、锁等待和最近发布,并明确是否暂停新运行。
故障注入清单
- 让一个工具返回 429、503、永久 400 和畸形 JSON。
- 在
interrupt()后、退款前重启进程。 - 在退款成功后、状态写回前终止 Worker。
- 断开 PostgreSQL,验证 readiness 和恢复行为。
- 让客户端缓慢读取或中断 SSE。
- 提交相同审批和相同运行请求。
每次实验都应给出预期路径、告警、最终状态和禁止发生的副作用。
本章验收
- 能通过一个关联标识从 API 日志追到 Trace、工具调用和业务记录。
- 能从真实 Trace 解释一次重试和一次中断恢复。
- 已定义延迟、错误、成本和业务安全指标及告警阈值。
- 日志与 Trace 有字段白名单、脱敏规则和保留期。