LangSmith 可观测性实战:给 AI 装上”监控摄像头”
系列文章第二篇,深入理解 LangSmith 的可观测性原理,让你的 Agent 调试不再”盲人摸象”
1. 引言 - 为什么需要可观测性?
在上一篇文章《从零理解 LangChain》中,我们构建了一个天气查询 Agent。它能理解用户意图、调用工具、保持对话记忆——一切看起来都很完美。
但当你真正开始使用时,会遇到这些问题:
1 2 3 4 5 6
| 用户: "帮我查一下上海今天天气" Agent: (沉默...)... (30秒后...) Agent: "抱歉,我暂时无法回答"
你: 😱 - "到底哪里出错了??"
|
没有可观测性时,Agent 就像一个黑盒子:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ┌─────────────────────────────────────┐ │ Agent 黑盒子 │ ├─────────────────────────────────────┤ │ │ │ 输入 ──────────────────► 输出 │ │ │ │ ❓ 中间发生了什么? │ │ ❓ 哪个工具被调用了? │ │ ❓ 为什么花了这么长时间? │ │ ❓ LLM 收到了什么 Prompt? │ │ ❓ 工具返回了什么结果? │ │ │ └─────────────────────────────────────┘
|
这就是 LangSmith 要解决的问题。
你可以把 LangSmith 想象成:
给 AI Agent 装上的”监控摄像头”——记录每一个决策、每一次调用、每一秒耗时
2. LangSmith 是什么?
核心概念:AI 应用的”监控录像”
LangSmith 是 LangChain 官方推出的可观测性平台,它让你能够:
| 能力 |
说明 |
| 完整追踪 |
记录 Agent 执行的每一步 |
| 性能监控 |
统计 Token 使用、API 调用延迟 |
| 可视化调试 |
图形化展示执行流程 |
| 会话回放 |
重新运行历史对话,验证修改效果 |
| 异常诊断 |
捕获并分析错误发生的位置和原因 |
一个形象的类比:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 传统调试 vs LangSmith
┌─────────────────────┐ ┌─────────────────────────────┐ │ 传统调试方式 │ │ 使用 LangSmith │ ├─────────────────────┤ ├─────────────────────────────┤ │ │ │ │ │ print("调试信息") │ │ 📸 自动录制完整执行过程 │ │ print("工具调用") │ │ 📊 Token/延迟自动统计 │ │ print("结果...") │ │ 🔍 点击查看任意步骤详情 │ │ print("...") │ │ 🎬 一键回放历史会话 │ │ │ │ │ │ 😰 代码到处是日志 │ │ ✨ 零侵入,自动追踪 │ └─────────────────────┘ └─────────────────────────────┘
|
LangSmith 的工作原理
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 34 35
| ┌─────────────────────────────────────────────────────────────────┐ │ LangSmith 追踪原理 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 你的代码 │ │ ┌──────────────────────────────────────────────┐ │ │ │ agent.invoke({"messages": "北京天气怎么样?"}) │ │ │ └──────────────────────┬───────────────────────┘ │ │ │ │ │ ▼ │ │ LangChain 自动注入追踪层 │ │ ┌──────────────────────────────────────────────┐ │ │ │ 每个步骤开始 → 记录时间戳、输入参数 │ │ │ │ ↓ │ │ │ │ 执行 LLM 调用 → 记录 Prompt、响应、Token │ │ │ │ ↓ │ │ │ │ 执行工具调用 → 记录工具名、参数、返回值 │ │ │ │ ↓ │ │ │ │ 每个步骤结束 → 记录输出、耗时 │ │ │ └──────────────────────┬───────────────────────┘ │ │ │ │ │ ▼ │ │ 数据上传到 LangSmith 云端 │ │ ┌──────────────────────────────────────────────┐ │ │ │ https://smith.langchain.com/ │ │ │ │ │ │ │ │ 项目: langchain-langsmith-demo │ │ │ │ ├── 追行记录 2024-01-15 10:23 │ │ │ │ │ ├── LLM 调用 (1.2s, 156 tokens) │ │ │ │ │ ├── 工具调用 get_weather (0.1s) │ │ │ │ │ └── 最终响应生成 (0.8s) │ │ │ │ └── ... │ │ │ └──────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘
|
3. 快速开始:三步集成 LangSmith
步骤 1:获取 LangSmith API Key
- 访问 https://smith.langchain.com/
- 注册/登录账号
- 进入 Settings → API Keys
- 创建新的 API Key(格式:
lsv2_...)
步骤 2:配置环境变量
在你的 .env 文件中添加:
1 2 3 4
| LANGCHAIN_API_KEY=lsv2_xxx... LANGCHAIN_TRACING_V2=true LANGCHAIN_PROJECT=langchain-langsmith-demo
|
步骤 3:自动生效
关键点:不需要修改任何代码!
LangChain 会自动检测环境变量,启用追踪:
1 2 3 4 5 6
| from src.agent.factory import build_advanced_agent
agent = build_advanced_agent() response = agent.invoke({"messages": "北京天气怎么样?"})
|
原理揭秘:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| if os.getenv("LANGCHAIN_TRACING_V2") == "true": def traced_wrapper(original_func): def wrapper(*args, **kwargs): trace_id = start_trace() start_time = time.time()
result = original_func(*args, **kwargs)
duration = time.time() - start_time upload_trace(trace_id, { "input": args, "output": result, "duration": duration }) return result return wrapper
_original_invoke = traced_wrapper(_original_invoke)
|
4. LangGraph Studio:可视化调试界面
什么是 LangGraph Studio?
LangGraph Studio 是 LangSmith 的本地开发伴侣,它让你能够:
- 在本地运行和调试 Agent
- 实时查看执行流程
- 可视化展示状态变化
- 修改后立即看到效果
启动 Studio
1 2 3 4 5
| pip install --upgrade "langgraph-cli[inmem]"
langgraph dev
|
启动后你会看到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌────────────────────────────────────────────────────────────┐ │ LangGraph Studio 已启动 │ ├────────────────────────────────────────────────────────────┤ │ │ │ 🌐 API 端点: │ │ http://127.0.0.1:2024 │ │ │ │ 🎨 Studio 界面: │ │ https://smith.langchain.com/studio/?baseUrl=... │ │ │ │ 📊 可用的 Graph: │ │ • agent - 高级 Agent(带记忆) │ │ • basic_agent - 基础 Agent(单工具) │ │ │ └────────────────────────────────────────────────────────────┘
|
Studio 界面一览
打开 Studio 界面后,你会看到:
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
| ┌─────────────────────────────────────────────────────────────────┐ │ LangGraph Studio 界面 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ ┌─────────────────────────────────────┐ │ │ │ Graph 列表 │ │ 执行追踪详情 │ │ │ │ │ ├─────────────────────────────────────┤ │ │ │ ▶ agent │ │ Thread: user-001 │ │ │ │ basic_agent │ │ │ │ │ │ │ │ ┌─ Step 1: LLM 调用 ────────┐ │ │ │ │ │ │ │ 时间: 2024-01-15 10:23:01 │ │ │ │ │ │ │ │ 耗时: 1.2s │ │ │ │ │ │ │ │ Tokens: 156 input / 42 out │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 输入: │ │ │ │ │ │ │ │ "北京天气怎么样?" │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 输出: │ │ │ │ │ │ │ │ [工具调用] │ │ │ │ │ │ │ │ get_weather_for_location │ │ │ │ │ │ │ │ {"city": "北京"} │ │ │ │ │ │ │ └────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌─ Step 2: 工具调用 ───────┐ │ │ │ │ │ │ │ 耗时: 0.1s │ │ │ │ │ │ │ │ 结果: "晴朗,约 12C" │ │ │ │ │ │ │ └────────────────────────────┘ │ │ │ └─────────────────┘ └─────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘
|
5. 追踪数据的解读
完整的执行链路
当你在 LangSmith 中查看一次 Agent 执行,会看到类似这样的追踪:
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 34 35
| ┌─────────────────────────────────────────────────────────────────┐ │ Agent 执行追踪示例 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 📅 2024-01-15 10:23:45 │ │ 🧵 Thread: user-001 │ │ ⏱️ 总耗时: 2.1s │ │ 💰 总 Tokens: 234 │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Step 1: agent:LLM (理解意图并决策) │ │ │ │ ├─ 耗时: 1.2s │ │ │ │ ├─ Tokens: 156 in / 42 out │ │ │ │ ├─ 输入: "北京天气怎么样?" │ │ │ │ └─ 输出: [工具调用] get_weather_for_location("北京") │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Step 2: agent:tools:get_weather_for_location │ │ │ │ ├─ 耗时: 0.1s │ │ │ │ ├─ 参数: {"city": "北京"} │ │ │ │ └─ 结果: "晴朗,约 12C" │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Step 3: agent:LLM (生成最终回复) │ │ │ │ ├─ 耗时: 0.8s │ │ │ │ ├─ Tokens: 36 in / 89 out │ │ │ │ ├─ 输入: (工具结果 "晴朗,约 12C") │ │ │ │ └─ 输出: "北京今天天气晴朗,温度约12度..." │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘
|
关键指标解读
| 指标 |
说明 |
用途 |
| Latency |
单个步骤的耗时 |
定位性能瓶颈 |
| Tokens |
输入/输出 Token 数量 |
估算成本、优化 Prompt |
| Cost |
API 调用成本(估算) |
监控花费 |
| Error |
错误信息(如果有) |
快速定位问题 |
6. 实战:调试一个真实问题
让我们通过一个实际例子,展示 LangSmith 如何帮助调试。
问题场景
用户反馈:Agent 有时返回”抱歉,我暂时无法回答”
没有 LangSmith 时
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def run_agent(question): try: response = agent.invoke({"messages": [question]}) return response except Exception as e: print(f"出错了: {e}")
|
使用 LangSmith 后
- 在 LangSmith 中找到失败的那次执行
- 展开每个步骤查看详情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 问题定位过程:
┌─────────────────────────────────────────────────────┐ │ Step 1: LLM 调用 │ ├─────────────────────────────────────────────────────┤ │ 输入: "查一下三藩市天气" │ │ │ │ 输出: [工具调用] │ │ get_weather_for_location({"city": "三藩市"}) │ │ │ │ ✅ LLM 理解正确,知道要调用天气工具 │ └─────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ Step 2: 工具调用 get_weather_for_location │ ├─────────────────────────────────────────────────────┤ │ 参数: {"city": "三藩市"} │ │ │ │ 结果: "暂无 三藩市 的实时数据" │ │ │ │ ❌ 找到问题了! │ │ 城市别名解析不支持"三藩市"这个称呼 │ └─────────────────────────────────────────────────────┘
|
- 修复问题
1 2 3 4 5
| CITY_ALIASES = { "San Francisco": ["sf", "san francisco", "旧金山", "三藩市"], ... }
|
- 验证修复:在 Studio 中回放同一条对话,确认现在能正确处理
7. langgraph.json 配置详解
langgraph.json 是 LangGraph Studio 的配置文件:
1 2 3 4 5 6 7 8
| { "dependencies": ["."], "graphs": { "agent": "./graphs.py:agent", "basic_agent": "./graphs.py:basic_agent" }, "env": ".env" }
|
字段解释:
| 字段 |
说明 |
dependencies |
Python 包依赖(. 表示当前目录) |
graphs |
定义的 Graph 列表,格式为 文件路径:变量名 |
env |
环境变量文件路径 |
graphs.py 的作用:
1 2 3 4 5 6 7 8 9 10 11 12
| """ graphs.py 导出已编译的 agent,供 Studio 使用 """
from src.agent.factory import build_advanced_agent, build_basic_agent
basic_agent = build_basic_agent()
agent = build_advanced_agent(with_checkpointer=False)
|
8. 高级功能
8.1 会话回放(Replay)
LangSmith 允许你重新运行历史对话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 场景:你修改了 Prompt 或工具实现
┌─────────────────────────────────────────────────────────┐ │ LangSmith 回放功能 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 历史执行 #1234 │ │ ├── 步骤 1: LLM 调用 │ │ ├── 步骤 2: 工具调用 │ │ └── 步骤 3: 最终回复 │ │ │ │ [🔄 Replay 按钮] │ │ │ │ │ ▼ │ │ 用最新代码重新运行同一条输入 │ │ → 对比新旧结果,验证修改效果 │ │ │ └─────────────────────────────────────────────────────────┘
|
8.2 项目管理
你可以为不同环境创建不同项目:
1 2 3 4 5 6 7 8
| LANGCHAIN_PROJECT=langchain-dev
LANGCHAIN_PROJECT=langchain-test
LANGCHAIN_PROJECT=langchain-prod
|
8.3 性能优化建议
通过 LangSmith 追踪,你可以发现:
| 问题 |
追踪中的表现 |
优化方案 |
| Prompt 太长 |
输入 Token 过高 |
精简 Prompt,去除冗余内容 |
| 串行调用 |
总耗时 = 各步骤耗时之和 |
改为并行调用 |
| 重复调用同一工具 |
同一工具被多次调用 |
添加结果缓存 |
| LLM 响应慢 |
单次 LLM 调用耗时过长 |
换更快的模型或优化 Prompt |
9. 总结
核心概念回顾
| 概念 |
一句话理解 |
| LangSmith |
AI 应用的”监控摄像头” |
| Trace(追踪) |
一次完整的执行记录 |
| Span(跨度) |
执行中的一个步骤 |
| LangGraph Studio |
本地可视化调试工具 |
LangSmith 的核心价值
调试不再”盲人摸象”
性能优化有据可依
团队协作效率提升
持续改进的依据
与上一篇文章的关联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ┌─────────────────────────────────────────────────────────┐ │ 系列文章知识体系 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 第一篇:LangChain Agent 原理 │ │ ├── Agent = LLM + Tools + 规划 │ │ ├── 工具调用(Function Calling) │ │ ├── 对话记忆(Memory) │ │ └── 结构化输出(Structured Output) │ │ │ │ │ ▼ │ │ 第二篇:LangSmith 可观测性(本文) │ │ ├── 为什么需要可观测性 │ │ ├── LangSmith 工作原理 │ │ ├── LangGraph Studio 可视化调试 │ │ └── 追踪数据解读与实战调试 │ │ │ │ │ ▼ │ │ 下一阶段(待续) │ │ ├── 更复杂的 Agent 编排 │ │ ├── RAG(检索增强生成) │ │ └── 多 Agent 协作 │ │ │ └─────────────────────────────────────────────────────────┘
|
10. 快速上手
运行本项目的 LangSmith Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| git clone https://git.liupx.com/study/langchain_langsmith_demo cd langchain_langsmith_demo
python3 -m venv .venv source .venv/bin/activate
pip install langchain langgraph python-dotenv openai pip install --upgrade "langgraph-cli[inmem]"
cp .env.example .env
langgraph dev
|
查看追踪数据
启动 Studio 并执行一些查询后,访问 https://smith.langchain.com/ 查看完整的追踪记录。
11. 参考资料
相关文档
本项目文档
源码索引
系列文章导航:
关于作者:本文基于 langchain_langsmith_demo 项目编写,延续上一篇文章的风格,专注于 LangSmith 可观测性的原理与实践。欢迎 Star 和 Fork!