LLM 应用的瓶颈不是「能不能跑通」,而是「跑通之后能不能被度量、被对照、被回滚」。LangSmith 把这三件事变成系统能力。
它到底解决什么痛
传统软件出错有堆栈、有日志、有断言。LLM 应用不一样:一次回答可能穿过 检索 → 拼 prompt → 调模型 → 解析 → 工具调用 → 再调模型 一长串步骤,任何一环出问题,你在终端看到的只是「最后那段不对的文本」。更要命的是「对不对」本身没有硬标准。下面三张卡片是 LangSmith 真正瞄准的靶子。
调用链黑盒
- 典型表现
- Agent 答错,但不知道是检索没命中、prompt 拼错还是模型幻觉
- 判断标准
- 复现一次问题要靠 print 大法翻日志
- 解决方向
- Tracing 自动记录每一步的输入/输出/耗时/token/报错,整条 Trace 可视化回放
效果不可量化
- 典型表现
- 改了 prompt 感觉变好了,但说不出好多少、哪些 case 退化了
- 判断标准
- 上线决策靠「我试了几条感觉还行」
- 解决方向
- 把测试样本沉淀成 Dataset,用 evaluate 跑批量评估,输出可对比的分数
回归没护栏
- 典型表现
- 改 A 功能悄悄打挂了 B 功能,上线才发现
- 判断标准
- 没有一道自动门能在合并前拦住效果退化
- 解决方向
- 把评估接进 CI,分数低于阈值直接 fail,回归变成可审计的门禁
架构全景:SDK → 后端 → 五大模块
从数据流向看,LangSmith 分三层:客户端 SDK 在你的应用里采集数据并上报;LangSmith 后端(SaaS 或自托管)负责存储、聚合、计算评估;五大功能模块在后端之上提供能力。下表是这五大模块的职责边界和对应的本 wiki 章节。
| 模块 | 解决什么 | 核心对象 / API | 本 wiki 对应章节 |
|---|---|---|---|
| Tracing | 调用链黑盒 | Run / Trace、@traceable、wrap_openai | CHAPTER 03 核心概念 |
| Datasets | 测试样本散落 | Dataset / Example、create_dataset | CHAPTER 04 数据集 |
| Evaluation | 效果不可量化 | evaluate()、内置 / 自定义 evaluator | CHAPTER 05 评估 |
| Prompt Hub | prompt 无版本 | pull_prompt / push_prompt | CHAPTER 07 Prompt Hub |
| Monitoring | 线上无感知 | Dashboard / 告警 / 在线评估 | CHAPTER 08 监控与 CI |
三十秒看到一条 Trace
光说不练没意思。下面是最小可运行示例:装 SDK、配两个环境变量、用 @traceable 装饰一个普通函数,跑一次就能在 LangSmith 网页上看到完整 Trace。后续章节会把每个能力展开,这里先建立直觉。
# 安装 LangSmith SDK(独立包,不依赖 langchain)
pip install -U langsmith
# 两个核心环境变量:开关 + 鉴权
export LANGSMITH_TRACING=true # 总开关,true 才上报
export LANGSMITH_API_KEY="lsv2_pt_xxxxxxxx" # 在 smith.langchain.com Settings 里生成
export LANGSMITH_PROJECT="langsmith-quickstart" # 可选:不设则进 default 项目
# quickstart.py —— 用 @traceable 手动接入,任何 Python 函数都能追踪
import os
from langsmith import traceable
# 也可以在代码里设置,效果等同于 export 环境变量
os.environ["LANGSMITH_TRACING"] = "true"
# os.environ["LANGSMITH_API_KEY"] = "lsv2_pt_..." # 建议仍走环境变量,别硬编码
@traceable # 这一行就让函数的输入/输出/耗时/异常被记录成一个 Run
def retrieve(query: str) -> str:
# 真实场景这里是向量检索;示例用假数据
return f"context-for: {query}"
@traceable(run_type="chain") # run_type 标注节点类型:chain / llm / tool / retriever
def answer(query: str) -> str:
ctx = retrieve(query) # 嵌套调用会自动成为父 Trace 下的子 Run
return f"基于 [{ctx}] 给出的回答"
if __name__ == "__main__":
print(answer("什么是 LangSmith"))
# 跑完后去 https://smith.langchain.com 对应项目里,能看到一条
# answer -> retrieve 的嵌套 Trace,含输入输出和毫秒级耗时
# 如果你用的是裸 OpenAI SDK,一行包装即可零侵入追踪每次 LLM 调用
from langsmith.wrappers import wrap_openai
from openai import OpenAI
# wrap_openai 返回一个被代理的 client,所有 chat.completions 调用自动成为 llm 类型 Run
client = wrap_openai(OpenAI())
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "用一句话解释可观测性"}],
)
print(resp.choices[0].message.content)
# LangSmith 会自动记录 model、prompt tokens、completion tokens、延迟和成本估算
贯穿全 wiki 的可观测闭环
把五大模块串起来,就是这条 追踪 → 数据集 → 评估 → 监控 → CI 回归 的闭环。它不是线性流程,而是一个会自我增强的回路:线上 Trace 里发现的坏 case,回流成 Dataset 里的新样本;新样本让评估更严;更严的评估接进 CI 形成护栏;护栏又保护下一次迭代。这条闭环就是本 wiki 后面每一章的学习地图。
- 追踪:开发与线上都开 Tracing,每次调用沉淀成 Run / Trace(CHAPTER 03)
- 数据集:把好 case 和翻车 case 从 Trace 收集成 Dataset(CHAPTER 04)
- 评估:用
evaluate()在 Dataset 上跑内置 / 自定义 / LLM-as-judge 评估器打分(CHAPTER 05、06) - 版本:用 Prompt Hub 管理 prompt 版本,让每次评估对照的是明确版本(CHAPTER 07)
- 监控 + 回归:线上 Dashboard 看指标与告警,CI 里把评估当门禁拦住退化(CHAPTER 08)
✓推荐做法
- 从第一天就开 Tracing,数据沉淀越早闭环越值钱
- 把线上发现的坏 case 立刻回流进 Dataset
- 评估分数化、阈值化,再接进 CI 当门禁
✗不推荐
- 把 LangSmith 只当成「在线日志查看器」用
- 等到要上线了才想起来补评估集
- 依赖人工肉眼判断「这次改得好不好」
⚠常见误区
- 以为必须用 LangChain 才能接 LangSmith——纯 SDK 一样能跑
- API key 硬编码进代码提交进仓库——务必走环境变量
判断标准:当你能回答「这次改动让评估集分数从 X 涨到 Y、没有 case 退化、CI 已绿」时,你的闭环才真正闭上了。
瓶颈是验证,不是生成。能被度量的问题才能被完成。
— 本 wiki 的设计信条
下一章我们就动手:完成注册、拿到 API key、把 LANGSMITH_TRACING / LANGSMITH_API_KEY 配置到位,并验证第一条 Trace 真的出现在 Dashboard 上。