LangSmith可观测性:AI应用出bug根本不知道哪里出了问题,我踩了4个坑

RAG上线一周,用户反馈"答得不准"。我看了一眼代码:

ini 复制代码
response = chain.invoke({"question": query})

一个黑盒。 question进去了,answer出来了,中间发生了什么?检索到哪些chunk?LLM收到了什么prompt?Token用了多少?------全不知道。

这感觉就像Java应用没有日志,线上出bug只能猜。以前写Spring Boot,起码有log4j、有skywalking、有APM,哪行报错一清二楚。AI应用呢?裸奔。

直到我用了LangSmith,才终于给AI应用装上了"监控面板"。


先说结论

功能 没有LangSmith 有LangSmith
追踪每次调用 只能看到最终输出 完整链路:检索→Prompt→生成
定位问题环节 猜,逐个打log 点开trace一看就知
Token成本统计 手动算API账单 自动统计,按链路分解
Prompt版本管理 Git提交代码 每次变更可对比效果
测试回归 手动问几遍 自动跑评估集

Java人的理解:LangSmith ≈ Skywalking/Zipkin。 分布式追踪给微服务装了眼睛,LangSmith给AI应用装了眼睛。


坑1:以为LangSmith只是个日志面板

翻车现场

一开始我把LangSmith当成普通的日志工具,只在最外层加了追踪:

ini 复制代码
import langsmith
​
# 只在最外层包了一下
with langsmith.trace("rag_query", run_type="chain") as run:
    response = chain.invoke({"question": query})
    run.end(outputs={"answer": response})

结果: LangSmith里只看到一条trace,知道"调了一次RAG",但中间发生了什么------检索了多少chunk?LLM输入是什么?------全不知道。

正确做法:自动追踪------LangChain原生集成,零代码改造

LangChain从0.1版本开始原生支持LangSmith,只需要设环境变量,不需要改任何代码:

lua 复制代码
import os
​
# 只需要这3行环境变量
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "lsv2_sk_xxx"
os.environ["LANGCHAIN_PROJECT"] = "my-rag-app"
​
# 原有代码完全不用改
response = chain.invoke({"question": "退货政策是什么?"})

LangSmith自动记录整个调用链:

scss 复制代码
rag_query (Chain)
  ├── retriever (Retriever) → 检索到3个chunk
  ├── prompt (ChatPromptTemplate) → 组装后的完整prompt
  └── llm (ChatModel) → 生成回答,耗时2.3s,token=428

每个环节的输入、输出、耗时、token数,全部自动记录。 不用你手动打log。


坑2:检索效果差,不知道是chunk的问题还是LLM的问题

翻车现场

用户问"退货要多久",AI回答"建议您联系客服"。

是检索没找到退货相关chunk?还是LLM收到正确的chunk但回答跑偏了?不知道。

以前的做法:在每个环节手动print,然后翻终端日志。效率极低,而且线上环境根本没有终端可看。

正确做法:用LangSmith的Trace视图逐环节排查

打开LangSmith的trace详情页,看到这样的链路:

ini 复制代码
retriever → 输出3个chunk:
  [1] "退货政策:未拆封7天内..." (similarity=0.82)
  [2] "退款流程:提交申请后..."  (similarity=0.71)
  [3] "常见问题:Q1 如何退货..." (similarity=0.68)
​
prompt → 组装后的完整prompt:
  "根据以下文档回答问题:\n[1] 退货政策:未拆封7天内...\n问题:退货要多久"
​
llm → 输出: "建议您联系客服确认退货时间"

一眼看出: 检索没问题(3个chunk都和退货相关),是LLM回答跑偏了。问题出在prompt------没有明确要求"必须根据文档回答,不要让用户联系客服"。

修复prompt后:

swift 复制代码
prompt = ChatPromptTemplate.from_messages([
    ("system", "根据提供的文档内容直接回答问题。如果文档中有明确答案,直接给出,不要说'请联系客服'。"),
    ("human", "文档内容:\n{context}\n\n问题:{question}")
])

再跑一遍,AI回答:"未拆封商品7天内可退货,3个工作日处理。"

如果没有LangSmith,这种排查可能要半小时。有了它,30秒定位问题。


坑3:上线后成本失控,不知道哪条链路最费token

翻车现场

月API账单从50涨到200,不知道是哪个功能吃掉的。

RAG问答?文档摘要?Agent工具调用?每种功能都调LLM,但不知道哪个是成本大头。

正确做法:LangSmith的成本分析------按链路、按模型拆分

LangSmith自动统计每次调用的token消耗和成本:

ini 复制代码
项目:my-rag-app(最近7天)
​
按链路类型:
  RAG问答:     1,234次  token=528,000  估算$12.5
  文档摘要:     456次  token=312,000  估算$8.2
  Agent工具调用: 89次  token=187,000  估算$4.1
​
按模型:
  qwen-plus:  token=820,000  $15.2
  qwen-turbo: token=207,000  $1.6
​
异常调用(token>2000):
  6月12日 14:23 RAG问答 token=4,280 ⚠️

那个token=4,280的异常调用,点进去一看: 检索到12个chunk全塞进prompt了。正常应该只塞3-5个,是retriever的k值设错了。

ini 复制代码
# 修复前
retriever = vectorstore.as_retriever(search_kwargs={"k": 12})  # 传太多了
​
# 修复后
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})   # 合理数量

修复后,RAG问答的平均token从428降到210,成本直接砍半。


坑4:改了prompt不知道效果变好还是变差

翻车现场

优化prompt是AI应用的日常操作,但改完prompt全靠手动问几遍来判断效果。

问题:

  • 今天改了,下周又改,不知道哪个版本效果最好
  • 手动测试3-5个问题,不代表整体效果
  • 没法量化"变好了多少"

正确做法:LangSmith的评估+数据集功能

第1步:创建评估数据集

ini 复制代码
from langsmith import Client
​
client = Client()
​
# 创建一个评估数据集
dataset = client.create_dataset("rag-qa-eval")
​
# 添加测试用例
examples = [
    {"question": "退货要多久?", "expected": "未拆封7天内,3个工作日"},
    {"question": "支持什么支付方式?", "expected": "支付宝、微信支付、银行卡"},
    {"question": "配送范围有哪些?", "expected": "全国大部分地区,偏远地区需加运费"},
]
​
for ex in examples:
    client.create_example(
        inputs={"question": ex["question"]},
        outputs={"expected": ex["expected"]},
        dataset_id=dataset.id
    )

第2步:跑评估

ini 复制代码
from langsmith.evaluation import evaluate
​
def target_fn(inputs: dict) -> dict:
    response = chain.invoke({"question": inputs["question"]})
    return {"answer": response}
​
results = evaluate(
    target_fn,
    data="rag-qa-eval",
    evaluators=[
        # 评估答案和期望的相似度
        langsmith.evaluation.evaluators.EmbeddingDistance(),
    ],
)

第3步:对比不同版本

改了prompt后,再跑一次评估。LangSmith自动对比:

java 复制代码
版本对比:
  v1 (6月10日): 平均相似度 0.72, 平均耗时 2.1s
  v2 (6月12日): 平均相似度 0.81, 平均耗时 1.8s  ← 当前最优
  v3 (6月14日): 平均相似度 0.76, 平均耗时 2.3s

现在优化prompt有了量化依据,不再是"感觉好一点"。


LangSmith的免费额度够用吗?

免费版 限制
每月trace数 5,000条
团队成员 1人
数据保留 14天

个人项目和刚上线的小应用完全够用。 日请求量<200的RAG,一个月大概3000-4000条trace。

如果trace超过5000条,两个选择:

  1. 只追踪关键链路(设置采样率)
  2. 自部署LangSmith开源版(Docker一键启动)
bash 复制代码
# 设置采样率,只追踪10%的调用
os.environ["LANGCHAIN_SAMPLING_RATE"] = "0.1"

回头看

坑 一句话总结
只当日志面板用 LangChain原生集成,设环境变量就自动追踪全链路
不知道问题出在哪个环节 Trace视图逐环节排查,30秒定位
成本失控不知道谁吃的 按链路/模型拆分token统计,一眼看清
改prompt不知道变好变差 评估数据集+自动对比,量化优化效果

AI应用没有可观测性,就像生产环境没有监控------能跑,但出问题就是瞎子。 LangSmith是目前最方便的AI应用监控工具,和LangChain无缝集成,推荐第一时间配上。

相关推荐
在世修行1 小时前
智学文枢:AI 产出的持久化之道
python
CaptainT1 小时前
第 1 卷:执行模型与基础语法
python
总裁余(余登武)1 小时前
K-means算法改进(Python版)
python·算法·kmeans
CaptainT1 小时前
第 2 卷:函数、模块与推导式
python
Shockang1 小时前
项目驱动的 Python 入门
python
十年Java程序媛1 小时前
Java 多线程基础与锁机制详解|进程线程、锁升级、synchronized 与 Lock 对比
java·开发语言·spring boot
弯_弯1 小时前
FDE 的工程能力画像:数据接入、PoC 与可复用资产的落地口径
java·服务器·开发语言
余槐i2 小时前
transformers 升级后加载旧权重报错:三处不兼容如何逐一验证
python·大模型·transformers·模型量化·模型推理
CCblandy2 小时前
向量检索 ANN 参数实测:换一种数据分布,recall 掉了 51 个百分点
人工智能·python·算法·自然语言处理·性能优化