























LangSmith 批量评估是 LangChain 生态系统的核心功能,用于自动化、规模化地测试和评估 LLM 应用的性能。
将多个测试用例组织成数据集,自动化运行测试,并使用预定义的评估器对结果进行多维度打分。
测试数据集(Dataset)
↓
自动化运行(Test Function)
↓
多维度评估(Evaluators)
↓
结果可视化(Dashboard)
传统方式的问题:
LangSmith 的优势:
| 框架 | 批量评估 | 可视化 | 自定义评估器 | 数据集管理 | 价格 |
|---|---|---|---|---|---|
| LangSmith | ✅ | ✅ Web UI | ✅ | ✅ | 付费(有免费额度) |
| DeepEval | ✅ | ❌ | ✅ | ⚠️ | 开源免费 |
| Ragas | ✅ | ⚠️ | ✅ | ⚠️ | 开源免费 |
| LangFuse | ⚠️ | ✅ | ⚠️ | ⚠️ | 开源+付费 |
选择建议:
假设我们有一个电商客服助手,需要评估其回答质量。
pip install langsmith langchain-openai
配置环境变量:
# Windows PowerShell
$env:LANGSMITH_API_KEY="your-api-key"
$env:LANGCHAIN_TRACING_V2="true"
$env:OPENAI_API_KEY="your-openai-key"
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 定义客服助手
llm = ChatOpenAI(model="gpt-3.5-turbo")
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个电商客服助手,专业、友好地回答用户问题。"),
("user", "{question}")
])
chain = prompt | llm
def customer_service_agent(question: str) -> str:
"""客服助手函数"""
response = chain.invoke({"question": question})
return response.content
from langsmith import Client
client = Client()
# 创建数据集
dataset_name = "customer-service-test"
client.create_dataset(
dataset_name=dataset_name,
description="电商客服助手测试数据集"
)
# 定义测试用例
test_cases = [
{
"inputs": {"question": "我的订单什么时候能到?"},
"outputs": {
"expected_topics": ["物流", "订单"],
"tone": "professional"
}
},
{
"inputs": {"question": "这个商品支持退货吗?"},
"outputs": {
"expected_topics": ["退货", "售后"],
"tone": "professional"
}
},
{
"inputs": {"question": "你们有什么优惠活动?"},
"outputs": {
"expected_topics": ["优惠", "活动"],
"tone": "friendly"
}
},
{
"inputs": {"question": "商品质量有问题,我要投诉!"},
"outputs": {
"expected_topics": ["投诉", "质量"],
"tone": "empathetic"
}
}
]
# 添加测试用例
for case in test_cases:
client.create_example(
inputs=case["inputs"],
outputs=case["outputs"],
dataset_name=dataset_name
)
print(f"✓ 测试数据集创建完成: {dataset_name}")
from langsmith.schemas import Example
def test_function(example: Example) -> dict:
"""测试函数:运行客服助手并返回结果"""
question = example.inputs["question"]
# 调用客服助手
response = customer_service_agent(question)
return {
"response": response,
"question": question
}
from langsmith import RunEvaluator
from langsmith.schemas import Run, Example
from typing import Dict, Any
class TopicCoverageEvaluator(RunEvaluator):
"""评估回答是否覆盖期望话题"""
def evaluate_run(self, run: Run, example: Example, **kwargs) -> Dict[str, Any]:
response = run.outputs.get("response", "").lower()
expected_topics = example.outputs.get("expected_topics", [])
# 检查话题覆盖
found_topics = [
topic for topic in expected_topics
if topic in response
]
coverage = len(found_topics) / len(expected_topics) if expected_topics else 0
return {
"key": "topic_coverage",
"score": coverage,
"comment": f"覆盖 {len(found_topics)}/{len(expected_topics)} 个话题: {found_topics}"
}
class ToneEvaluator(RunEvaluator):
"""评估回答语气是否合适"""
def evaluate_run(self, run: Run, example: Example, **kwargs) -> Dict[str, Any]:
response = run.outputs.get("response", "")
expected_tone = example.outputs.get("tone", "")
# 简单语气检测(实际应使用更复杂的 NLP 方法)
tone_indicators = {
"professional": ["请", "您", "感谢", "抱歉"],
"friendly": ["亲", "您好", "😊", "欢迎"],
"empathetic": ["理解", "抱歉", "立即", "帮助"]
}
indicators = tone_indicators.get(expected_tone, [])
found = sum(1 for word in indicators if word in response)
score = min(1.0, found / 2) if indicators else 0
return {
"key": "tone_match",
"score": score,
"comment": f"期望语气: {expected_tone}, 找到 {found} 个指标词"
}
from langsmith.evaluation import evaluate
from datetime import datetime
# 配置评估器
evaluators = [
TopicCoverageEvaluator(),
ToneEvaluator()
]
# 运行评估
experiment_name = f"cs-eval-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
results = evaluate(
test_function,
data=dataset_name,
evaluators=evaluators,
experiment_prefix=experiment_name,
max_concurrency=2
)
print(f"✓ 评估完成: {experiment_name}")
print(f"查看结果: https://smith.langchain.com")
访问 https://smith.langchain.com:
from langsmith.evaluation.evaluators import (
answer_relevance_evaluator,
hallucination_evaluator
)
results = evaluate(
test_function,
data=dataset_name,
evaluators=[
answer_relevance_evaluator,
hallucination_evaluator
]
)
results = evaluate(
test_function,
data=dataset_name,
evaluators=evaluators,
max_concurrency=5 # 根据 API 限流调整
)
# 运行多个实验
results_v1 = evaluate(test_function_v1, data=dataset_name, evaluators=evaluators)
results_v2 = evaluate(test_function_v2, data=dataset_name, evaluators=evaluators)
# 在 Web 界面中对比两个实验
import json
# 从 JSON 文件加载
with open("test_cases.json", "r", encoding="utf-8") as f:
test_cases = json.load(f)
for case in test_cases:
client.create_example(
inputs=case["inputs"],
outputs=case["outputs"],
dataset_name=dataset_name
)
完整的生态系统
灵活的评估器
企业级功能
付费服务
学习曲线
并发限制
# ✅ 好的测试用例
{
"inputs": {"question": "订单延迟了怎么办?"},
"outputs": {
"expected_topics": ["订单", "延迟", "解决方案"],
"tone": "empathetic",
"should_contain": ["抱歉", "立即", "联系"]
}
}
# ❌ 差的测试用例
{
"inputs": {"question": "你好"},
"outputs": {"should_contain": ["你好"]}
}
# ✅ 好的评估器(可量化、可复现)
class CoverageEvaluator(RunEvaluator):
def evaluate_run(self, run, example):
found = len([kw for kw in expected if kw in response])
score = found / len(expected)
return {"key": "coverage", "score": score}
# ❌ 差的评估器(主观判断)
class GoodEvaluator(RunEvaluator):
def evaluate_run(self, run, example):
if "感觉不错":
return {"score": 1.0}
dataset-v1, dataset-v2开发阶段:
- 每次提交前:冒烟测试(5-10 用例)
- 每天:完整评估(50-100 用例)
生产阶段:
- 每周:完整评估
- 每月:大规模回归测试(200+ 用例)
| 维度 | 价值 |
|---|---|
| 效率 | 节省 80% 测试时间 |
| 质量 | 标准化评估,减少主观偏差 |
| 可追溯 | 完整历史记录,便于对比 |
| 可视化 | Web Dashboard,一目了然 |
开始你的 LangSmith 批量评估之旅!🚀
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。