纲要
- 为什么 AI 应用需要可观测性
LangSmith核心功能一览- 全链路追踪
- 性能指标(P50/P99、Token 消耗)
- 错误监控与调试
- 零侵入集成:环境变量配置
- 核心指标解读
- 首 Token 时间、端到端延迟
- 成本统计与 Token 用量
- 错误率与运行详情
- 私有化部署简介
- 完整可运行示例
- 项目结构
- 依赖安装与
.env配置 main.py:一个带追踪的简单 Agent- 运行与查看追踪面板
- 总结与相关度说明
可观测性:从"感觉"到"数据"的开发转型
上线一个 AI 应用只是第一步,持续优化才是长期任务。传统应用可以通过埋点收集性能数据,而基于 LLM 的智能体面临更复杂的挑战:模型调用延迟、Token 消耗、工具链的每一步耗时......这些如果只靠本地测试,很难反映真实用户场景。
LangSmith 是 LangChain 官方推出的全栈可观测性平台,专为 LLM 应用设计,具备三大能力:
| 功能 | 描述 |
|---|---|
| 追踪 | 自动记录每一次 LLM 调用、工具执行、链的完整链路 |
| 评估 | 创建测试数据集,量化回答质量 |
| 提示词管理 | 版本化提示词模板,在线调试 |
我们最常用的是追踪功能:无需修改核心业务代码,只需配置几个环境变量,即可将生产环境的每一次交互完整地记录下来。
零侵入集成:只需这几行配置
LangChain 已经将 LangSmith 的追踪 SDK 内置在核心包中,开发者不需要额外安装或显式调用。唯一要做的是告诉它"往哪发送追踪数据"。
在项目根目录的 .env 文件中添加:
env
LANGCHAIN_TRACING_V2=true
LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
LANGCHAIN_API_KEY=ls__xxxx # 从 LangSmith 控制台生成
LANGCHAIN_PROJECT=xiaolang-dingtalk # 自定义项目名
然后在代码的入口处加载这些变量:
python
from dotenv import load_dotenv
load_dotenv()
此后,所有使用 LangChain 组件(Chain、Agent、Tool、LLM 调用)的代码都会被自动追踪,无需任何手动 @trace 装饰或回调注册。
核心指标:看什么、怎么看
在 LangSmith 的项目面板中,以下指标对日常优化至关重要:
- P50 延迟:第 50 百分位的请求耗时,代表"典型用户体验"。
- P99 延迟:第 99 百分位的耗时,反映"最差情况",帮助定位性能瓶颈。
- Token 消耗:每次调用的输入/输出 Token 数量及累计成本。
- 首 Token 时间:流式输出时,用户看到第一个字符的时间,直接影响体感速度。
- 错误率:七天内的运行失败比例。
点击任意一次运行记录,还能看到完整的调用树:从用户输入→ Agent 决策→工具调用→最终回答,每一步的耗时、输入输出、模型名称都一目了然。下图展示了一条典型的 Agent 追踪链路:
工具 LLM (gpt-4o) AgentExecutor 用户 工具 LLM (gpt-4o) AgentExecutor 用户 #mermaid-svg-ZpOWTsiktIPWufvM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZpOWTsiktIPWufvM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZpOWTsiktIPWufvM .error-icon{fill:#552222;}#mermaid-svg-ZpOWTsiktIPWufvM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZpOWTsiktIPWufvM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZpOWTsiktIPWufvM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZpOWTsiktIPWufvM .marker.cross{stroke:#333333;}#mermaid-svg-ZpOWTsiktIPWufvM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZpOWTsiktIPWufvM p{margin:0;}#mermaid-svg-ZpOWTsiktIPWufvM .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ZpOWTsiktIPWufvM text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-ZpOWTsiktIPWufvM .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ZpOWTsiktIPWufvM .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-ZpOWTsiktIPWufvM .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-ZpOWTsiktIPWufvM .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-ZpOWTsiktIPWufvM #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-ZpOWTsiktIPWufvM .sequenceNumber{fill:white;}#mermaid-svg-ZpOWTsiktIPWufvM #sequencenumber{fill:#333;}#mermaid-svg-ZpOWTsiktIPWufvM #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-ZpOWTsiktIPWufvM .messageText{fill:#333;stroke:none;}#mermaid-svg-ZpOWTsiktIPWufvM .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ZpOWTsiktIPWufvM .labelText,#mermaid-svg-ZpOWTsiktIPWufvM .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-ZpOWTsiktIPWufvM .loopText,#mermaid-svg-ZpOWTsiktIPWufvM .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-ZpOWTsiktIPWufvM .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ZpOWTsiktIPWufvM .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-ZpOWTsiktIPWufvM .noteText,#mermaid-svg-ZpOWTsiktIPWufvM .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-ZpOWTsiktIPWufvM .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ZpOWTsiktIPWufvM .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ZpOWTsiktIPWufvM .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ZpOWTsiktIPWufvM .actorPopupMenu{position:absolute;}#mermaid-svg-ZpOWTsiktIPWufvM .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-ZpOWTsiktIPWufvM .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ZpOWTsiktIPWufvM .actor-man circle,#mermaid-svg-ZpOWTsiktIPWufvM line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-ZpOWTsiktIPWufvM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 整个过程耗时 2.95s,消耗 1200 Token 提问 推理 (prompt + 历史) 决定调用 create_todo create_todo 执行 结果 再次推理 (含工具结果) 最终回答 回复
私有化部署:数据不出机房
对于数据敏感性高的场景,LangSmith 提供了完整的自托管方案。官方仓库中包含了 Docker Compose 配置,集成了前端、后端、ClickHouse、PostgreSQL、Redis 等服务,只需执行:
bash
git clone https://github.com/langchain-ai/langsmith
cd langsmith
docker compose up -d
部署完成后,将环境变量中的 LANGCHAIN_ENDPOINT 改为自己的服务器地址即可。
完整可运行示例
下面搭建一个最小化的可运行示例,展示如何启用追踪并观察结果。
项目结构
dir
observability_demo/
├── main.py
├── .env
└── requirements.txt
依赖安装
bash
pip install langchain langchain-openai python-dotenv
环境配置 .env
env
OPENAI_API_KEY=sk-xxxx
LANGCHAIN_TRACING_V2=true
LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
LANGCHAIN_API_KEY=ls__xxxx
LANGCHAIN_PROJECT=observability-demo
LANGCHAIN_API_KEY 需在 smith.langchain.com 注册并创建。
主程序 main.py
python
# main.py
import os
from dotenv import load_dotenv
load_dotenv()
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.tools import tool
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
# 定义一个简单工具
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气"""
# 模拟 API 调用
return f"{city} 今天晴朗,25°C"
tools = [get_weather]
def main():
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "你是小助手,可以使用工具回答用户问题。"),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=False)
# 模拟两次对话,产生追踪数据
print("第一次询问:")
res = executor.invoke({"input": "北京今天天气怎么样?"})
print("助手回答:", res["output"])
print("\n第二次询问:")
res = executor.invoke({"input": "我想记录一个待办:买水果"})
print("助手回答:", res["output"])
if __name__ == "__main__":
main()
运行后,登录 LangSmith 控制台,即可在 observability-demo 项目中看到两次完整的执行记录,包括工具调用详情、Token 消耗和端到端延迟。
总结
可观测性并非可选项,而是 AI 应用走向生产环境的必经之路。LangSmith 以极低的接入成本提供了强大的全链路追踪能力,配合 P50/P99 延迟、成本统计等关键指标,使开发者能够数据驱动地优化智能体的性能与成本。本文提供的示例代码可直接运行,帮助你快速上手。
本文覆盖了 LangSmith 的追踪配置、核心指标解读、私有化部署思路以及零侵入集成方法,并提供了示例代码