AI Agent白手起家58: 项目可观测性——用 LangSmith 实现全链路追踪

纲要

  • 为什么 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 的追踪配置、核心指标解读、私有化部署思路以及零侵入集成方法,并提供了示例代码

相关推荐
小白狮ww1 小时前
小模型「扛」住自由运镜:InSpatio-World 开源实时 4D 模拟器
人工智能·ai
Alkaid20771 小时前
【手搓 Agent 第2.1关】搭建 Agent 进阶能力:RAG(上)
人工智能·agent
躺不平的理查德1 小时前
OpenCV Mat 备忘录
人工智能·opencv·计算机视觉
Days20501 小时前
剪纸风城市文旅宣传海报提示词分享
人工智能·ai作画·gpt-image
只会迪霸戈1 小时前
系统验收测试从3天缩短到3小时:用 TRAE Work 跑完30+接口并自动生成验收报告
人工智能
love530love1 小时前
Photoshop 2026 AI 功能排障复盘:Camera Raw 卡死 / Neural Filters 灰 / 皮肤平滑下载失败 全定位
人工智能·ui·photoshop
喜欢睡觉1 小时前
给大模型套上"缰绳":Harness 框架如何让 AI 自己考试、自己改卷、选最优解
人工智能
Albart5751 小时前
【玩转 AtomCode】替代Claude Code!开源多模型免费AI编码Agent深度实测教程
人工智能·rust·开源·atomcode·多模型ai
宋哥转AI1 小时前
深入理解 AI Agent · MCP 子系列 #02:MCP Server 开发实战—从工具注册到无状态新规范
人工智能·agent·mcp