1. 为什么需要 LangSmith
在简单案例中,我们通常只看终端输出:
回答:退款通常在 1 至 3 个工作日到账。
但真实项目出问题时,只看最终输出远远不够。
例如:
RAG 回答错了
你需要知道:
- 用户原始问题是什么
- Retriever 检索到了哪些文档
- Prompt 最终长什么样
- 模型输入了多少 Token
- 模型输出了什么
- 哪一步耗时最长
- Agent 有没有调用工具
- 工具参数是否正确
- 工具返回了什么
LangSmith 就是用来观察、调试和评估大模型应用的平台。
它可以把一次 LangChain 调用记录成完整链路。
2. LangSmith 能看到什么
开启追踪后,LangSmith 中可以看到:
|-----------|---------------|
| 内容 | 作用 |
| Trace | 一次完整调用链路 |
| Run | 链路中的一个步骤 |
| Input | 当前步骤输入 |
| Output | 当前步骤输出 |
| Prompt | 发送给模型的提示词 |
| Tool Call | Agent 调用工具的记录 |
| Token | 模型输入和输出消耗 |
| Latency | 每一步耗时 |
| Error | 报错信息 |
| Metadata | 自定义业务信息 |
对于 RAG 项目,重点看:
- 检索问题是否正确
- 检索结果是否相关
- 上下文是否传给模型
- 模型是否根据资料回答
对于 Agent 项目,重点看:
- 是否调用了工具
- 调用了哪个工具
- 工具参数是否正确
- 工具结果是否被模型正确使用
3. 开通和配置 LangSmith
访问:
https://smith.langchain.com
登录后创建 API Key。
在项目根目录创建 .env:
DEEPSEEK_API_KEY=你的DeepSeek API Key
DEEPSEEK_BASE_URL=https://api.deepseek.com
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=你的LangSmith API Key
LANGSMITH_PROJECT=langchain-course-demo


环境变量说明:
|---------------------|------------------------|
| 变量 | 作用 |
| LANGSMITH_TRACING | 是否开启追踪 |
| LANGSMITH_API_KEY | LangSmith API Key |
| LANGSMITH_PROJECT | 追踪记录所属项目 |
| DEEPSEEK_API_KEY | DeepSeek API Key |
| DEEPSEEK_BASE_URL | DeepSeek OpenAI 兼容接口地址 |
如果暂时不想开启 LangSmith,可以改成:
LANGSMITH_TRACING=false
4. 安装依赖
安装本章依赖:
pip install langsmith
国内镜像:
pip install langchain langchain-openai langsmith python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple
如果要运行综合 RAG 和 Agent 项目,还需要:
pip install langchain-community langchain-text-splitters sentence-transformers pypdf pydantic
5. 案例一:追踪一次普通模型调用
创建 01_trace_chat.py:
from utils.model_factory import get_deepSeek_model
model=get_deepSeek_model()
respone=model.invoke("帅哥为什么这么帅?")
print(respone.content)
运行:
python 01_trace_chat.py
如果 .env 中配置了:
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=...
LANGSMITH_PROJECT=langchain-course-demo
运行后就可以在 LangSmith 项目中看到这次调用。
你可以重点查看:
- 输入内容
- 模型输出
- 调用耗时
- Token 消耗
- 模型名称

6. 案例二:追踪 LCEL Chain
创建 02_trace_chain.py:
from langchain_core.output_parsers import StrOutputParser
from utils.model_factory import get_deepSeek_model
from utils.prompt_template import getPromptTemplate
model=get_deepSeek_model()
prompt_template=getPromptTemplate(
"你是一个python讲师,善于使用最简洁易懂的语言讲解问题",
"{question}"
)
parser=StrOutputParser()
chain=prompt_template | model | parser
result=chain.invoke(
{"question":"python中的魔法方法有哪些?"},
config={
"run_name": "concept_explain_chain",
"tags": ["chapter10", "lcel"],
"metadata": {
"course": "LangChain",
"chapter": 10,
},
},
)
print(result)
print(type(result).__name__)
运行:
python 02_trace_chain.py
这里的 config 可以给本次运行增加信息:
config={
"run_name": "concept_explain_chain",
"tags": ["chapter10", "lcel"],
"metadata": {
"course": "LangChain",
"chapter": 10,
},
}
在 LangSmith 中,run_name、tags 和 metadata 可以帮助你筛选和定位调用记录。

过滤:

7. 案例三:追踪 Agent 工具调用
创建 03_trace_agent.py:
from langchain.agents import create_agent
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
from utils.model_factory import get_deepSeek_model
@tool
def search_order_wuliu(order_id:str)->str:
"""根据订单号查询订单状态,包括是否付款、是否发货、快递单号和签收状态。"""
fake_orders = {
"A1001": "已付款,等待发货",
"A1002": "已发货,快递单号 SF123456",
"A1003": "已签收",
}
return fake_orders.get(order_id, "没有查询到该订单")
# agent
agent=create_agent(
model=get_deepSeek_model(),
tools=[search_order_wuliu],
system_prompt="你是一个电商客户,善于使用工具查询物流信息"
)
result=agent.invoke(
{
"messages":[HumanMessage(content="帮我查询一下订单编号为A1001的物流信息")]
},
config={
"run_name":"agent电商客服助手"
}
)
print(result['messages'][-1].content)
运行:
python 03_trace_agent.py
在 LangSmith 中可以看到:
用户问题
-> 模型请求调用 get_order_status
-> 工具返回订单状态
-> 模型生成最终回答
用户提问 → 大模型识别需要调用工具 → 调用查询订单接口 → 获取接口数据 → 大模型把原始数据整理成自然语言回答用户
这对调试 Agent 非常有用。
如果 Agent 没有调用工具,可以在 Trace 中检查:
- 工具描述是否传给模型
- 用户问题是否包含订单号
- 模型是否直接生成了答案
- 工具调用参数是否错误
8. 什么是评估
调试解决的是单次调用问题。
评估关注的是一批问题的整体效果。
例如 RAG 知识库问答,我们希望知道:
10 个测试问题中,有几个回答正确?
最简单的评估方式是准备测试集:
test_cases = [
{
"question": "退款多久到账?",
"expected_keyword": "1 至 3 个工作日",
},
{
"question": "每个月可以补卡几次?",
"expected_keyword": "两次",
},
]
然后批量调用应用,检查答案中是否包含预期关键词。
这种程序可以称为一个简单的评估 harness。
9. 案例四:评估普通 Chain
创建 04_eval_chain.py:
from langchain.agents import create_agent
from langchain_core.output_parsers import StrOutputParser
from utils.model_factory import get_deepSeek_model
from utils.prompt_template import getPromptTemplate
model=get_deepSeek_model()
prompt_template=getPromptTemplate(
"你是一个langchain老师,善于回答各种关于langchain的问题,答案要简洁,不要超过30个字",
"{question}"
)
test_cases = [
{
"question": "LangChain 中 PromptTemplate 的作用是什么?",
"expected_keyword": "模版",
},
{
"question": "RAG 的核心流程是什么?",
"expected_keyword": "检索",
},
{
"question": "Agent 为什么需要 Tool?",
"expected_keyword": "外部",
},
]
chain = prompt_template | model | StrOutputParser()
pass_num=0
for index,case in enumerate(test_cases,start=1):
question=case['question']
expected_keyword=case['expected_keyword']
print(f"开始第{index}个问题")
result=chain.invoke({
"question":question
})
passed=False
if expected_keyword in result:
passed=True
pass_num+=1
print("-" * 60)
print(f"用例 {index}")
print(f"问题:{question}")
print(f"答案:{result}")
print(f"预期关键词:{expected_keyword}")
print(f"是否通过:{passed}")
# 计算通过率
print(f"总共有{len(test_cases)}个问题")
print(f"通过了{pass_num}个")
print(f"通过率是:{pass_num/len(test_cases):.2f}")
运行:
python 04_eval_chain.py
关键词评估很简单,但适合入门。
真实项目中还可以继续增加:
- 人工评分
- 大模型评分
- 标准答案对比
- 检索结果相关性评估
- 工具调用正确性评估
10、案例七:通过 langsmith 进行评估
以上三个案例都是本地进行评估测试,和 langsmith 无关
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langsmith import Client, evaluate
load_dotenv()
client = Client()
model = init_chat_model(
model="deepseek-v4-flash",
model_provider="openai",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_BASE_URL"),
temperature=0,
)
prompt_template = ChatPromptTemplate.from_messages(
[
("system", "你是一名课程助教,请用简洁中文回答。回答中尽量使用行业标准术语。"),
("human", "{question}"),
])
chain = prompt_template | model | StrOutputParser()
# ---------------------- 关键词评估器 ----------------------
def keyword_check_evaluator(run, example):
try:
output_text = run.outputs["output"]
expected_keyword = example.outputs["expected_keyword"]
hit = expected_keyword in output_text
return {
"key": "keyword_match",
"score": 1 if hit else 0,
"comment": f"预期关键词:{expected_keyword},是否命中:{hit}"
}
except Exception as e:
return {
"key": "keyword_match",
"score": None,
"comment": f"评估执行异常: {str(e)}"
}
# ---------------------- 数据集 ----------------------
dataset_name = "llm_course_qa_testset2"
try:
dataset = client.read_dataset(dataset_name=dataset_name)
except Exception as e:
print(e)
dataset = client.create_dataset(dataset_name=dataset_name)
client.create_examples(
inputs=[
{"question": "LangChain 中 PromptTemplate 的作用是什么?"},
{"question": "RAG 的核心流程是什么?"},
{"question": "Agent 为什么需要 Tool?"},
],
outputs=[
{"expected_keyword": "提示词"},
{"expected_keyword": "检索"},
{"expected_keyword": "外部"},
],
dataset_id=dataset.id
)
# ==========【重点改动】替换lambda,定义包装函数 ==========
def target_function(inputs):
result_str = chain.invoke(inputs)
# 强制返回字典,保证run.outputs["output"]稳定存在
return {"output": result_str}
# 启动评估
experiment = evaluate(
target_function,
data=dataset_name,
evaluators=[keyword_check_evaluator],
experiment_prefix="keyword_eval_course_qa_fixed",
)
print("评估任务已提交,请前往LangSmith网页查看实验结果!")
运行,查看结果:

数据集:

评估效果:
