关于 langsmith-evaluator
用于创建和运行 LangSmith 评估器的技能,可用 LLM 裁判或自定义代码评估 Agent 输出。内容涵盖本地评估,以及附加到数据集或项目的评估器,并提供 Python 与 TypeScript 指引。
主要功能
- 01LLM 裁判与代码评估器
- 02捕获 Agent 输出的运行函数
- 03使用 evaluate() 进行本地评估
- 04数据集与项目评估器流程
- 05Python 和 TypeScript 指引
适用场景
- 01依据数据集示例评估 Agent 输出
- 02在无参考示例时检查生产运行
- 03上传前在本地测试评估逻辑
- 04编写提取逻辑前检查运行输出与 trace
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ langchain-ai/ langsmith-skills --skill langsmith-evaluator安装后在 Claude Code 中输入/langsmith-evaluator确认已加载。
详细介绍
LANGSMITH_API_KEY=your-api-key # Alternative to `langsmith auth login`
LANGSMITH_ENDPOINT=https://api.smith.langchain.com # SDK/CLI environment
LANGSMITH_PROJECT=your-project-name # Default for trace/run queries only
LANGSMITH_WORKSPACE_ID=your-workspace-id # Optional: for org-scoped keys
OPENAI_API_KEY=your-openai-key # For locally executed OpenAI judges
使用已保存的 CLI 配置文件进行身份验证(推荐):
langsmith auth login
langsmith auth info
或者,设置 LANGSMITH_API_KEY。隐藏的 --api-key 标志仍可用于兼容,但请勿将密钥直接放入命令或日志中。选择已保存的配置文件时,请使用 --profile 或 LANGSMITH_PROFILE。
重要: LANGSMITH_PROJECT 用于指定追踪和运行查询的默认项目;它不会选择评估器目标。创建和上传评估器时,必须明确指定 --dataset 或 --project。
CLI 和 SDK 的身份验证彼此独立: CLI OAuth 配置文件仅用于验证 langsmith ... 命令。Python 和 TypeScript SDK 不会自动使用该配置文件。在使用 SDK 执行评估器 CRUD 操作之前,请确认 LANGSMITH_ENDPOINT、LANGSMITH_API_KEY,以及(如有需要)LANGSMITH_WORKSPACE_ID 指向与 langsmith auth info 相同的环境和工作区。如果 CLI 和 SDK 指向不同环境,请停止操作。
在使用 SDK 辅助执行任何 CRUD 操作之前,先进行只读预检:
from langsmith import Client
client = Client()
client.read_dataset(dataset_name="My Dataset")
Python 依赖项
pip install langsmith langchain-openai python-dotenv
CLI 工具
curl -fsSL https://cli.langsmith.com/install.sh | sh
langsmith self-update
JavaScript 依赖项
npm install langsmith openai
<cli_feedback> 在 CLI 实际失败、需要使用未记录的变通方法、输出令人困惑或缺少功能后,请针对任务中的每个不同问题提交一条简短的产品反馈。不要报告常规成功,也不要报告与 CLI 无关的低评估分数或应用程序故障。
CLI 要求: langsmith feedback 需要 LangSmith CLI v0.2.58 或更高版本。使用 langsmith --version 检查已安装的版本。
检查 langsmith feedback --help 中是否有 feedback <note> 和 --category;如果没有,请勿使用原始 HTTP 请求或未发布的构建版本提交反馈。使用现有的已验证配置文件、端点和工作区。反馈会发送至 LangSmith Cloud,包括通过 BYOC 中继发送的情况;独立自托管部署请跳过。遵守用户/组织的限制;如果不确定是否有权限发送反馈,请先询问。
用自己的话概述 CLI 的预期行为与实际观察到的行为,以及任何变通方法。切勿发送机密、客户数据、评估器提示词、数据集内容、追踪载荷、完整堆栈跟踪、复制的命令输出、原始参数、环境变量值、本地路径或资源标识符。CLI 会附加版本/操作系统/架构信息,但不会对你的反馈内容进行脱敏;如果无法安全脱敏,请跳过。
请选择 bug、feature-request、usability、documentation 或 other。这是 CLI 产品反馈,不是评估分数或评论。以下仅为示例格式——除非确实遇到相应问题,否则请勿提交:
langsmith feedback --category feature-request --format json "Please support selecting a single evaluator by ID when display names collide."
不要重试提交失败或受到速率限制的反馈,不要通过切换凭据/端点来绕过失败,也不要因反馈而阻碍原始任务。 </cli_feedback>
<crucial_requirement>
黄金法则:先检查,再实现
关键: 在编写任何评估器或提取逻辑之前,你必须:
- 运行你的 Agent,使用示例输入并捕获实际输出
- 检查输出——打印输出、查询 LangSmith 追踪,并了解其确切结构
- 然后再编写处理该输出的代码
不同框架、Agent 类型和配置的输出结构可能有很大差异。切勿假设输出结构——务必先验证。如果输出不包含所需数据,请查询 LangSmith 追踪,了解如何从执行过程中提取数据。 </crucial_requirement>
<evaluator_format>
离线与在线评估器
离线评估器(附加到数据集):
- 函数签名:
(run, example)——同时接收运行输出和数据集示例 - 使用场景:将 Agent 输出与数据集中的预期值进行比较
- 上传时使用:
--dataset "Dataset Name"
在线评估器(附加到项目):
- 函数签名:
(run)——只接收运行输出,不接收example参数 - 使用场景:对生产运行进行实时质量检查(无参考数据)
- 上传时使用:
--project "Project Name"
重要——返回格式:
- 每个评估器只返回一个指标。若需返回多个指标,请创建多个评估器函数。
- 不要返回
{"metric_name": value}或指标列表,否则会报错。
重要——本地与上传后的差异:
本地 evaluate() | 上传到 LangSmith | |
|---|---|---|
| 列名 | Python:根据函数名自动生成。TypeScript:必须包含 key 字段,否则列名为空 | 取自上传时设置的评估器名称。不要包含 key——否则会创建重复列 |
Python run 类型 | RunTree 对象 → run.outputs(属性访问) | dict → run["outputs"](下标访问)。两种情况都要处理:run.outputs if hasattr(run, "outputs") else run.get("outputs", {}) |
TypeScript run 类型 | 始终使用属性访问:run.outputs?.field | 始终使用属性访问:run.outputs?.field |
| Python 返回值 | {"score": value, "comment": "..."} | {"score": value, "comment": "..."} |
| TypeScript 返回值 | { key: "name", score: value, comment: "..." } | { score: value, comment: "..." } |
| </evaluator_format> |
<evaluator_types>
- LLM 作为评判者——使用大模型为输出评分。最适合评估主观质量(准确性、实用性、相关性)。
- 自定义代码——确定性逻辑。最适合进行客观检查(完全匹配、轨迹验证、格式合规性)。 </evaluator_types>
<llm_judge>
LLM 作为评判者的评估器
使用 langsmith evaluator create-llm 创建由服务端管理的 LLM 评判型运行规则。该命令需要 --model-config 以及且仅需一个目标(--dataset 或 --project)。提供 --prompt 和 --schema JSON 文件,或使用带有 --hub-ref 的 Prompt Hub 引用。
LLM 评判型运行规则的原生 CLI 增删改查
以下原生生命周期用于管理附加到数据集或项目的 LLM 评判型评估器。
创建
langsmith evaluator create-llm \
--name "Accuracy Judge" \
--dataset "My Dataset" \
--prompt prompt.json \
--schema schema.json \
--model-config model.json
在线评估器请使用 --project 替代 --dataset。如果评判提示词存储在 Prompt Hub 中,请使用 --hub-ref owner/prompt:latest 替代 --prompt 和 --schema。
模型配置
--model-config 需要使用服务器支持的序列化模型配置。切勿根据本地 LangChain 模型构造函数自行编造 model.json。请从已知可用的 LangSmith 评估器、LangSmith 评估器 UI,或目标环境的其他文档化来源获取配置。创建或替换评估器前,请确认目标服务器允许使用该序列化模型类。
langsmith evaluator get 不会导出完整的序列化模型配置。如果创建失败并提示 Deserialization ... is not allowed,说明模型配置包含服务器允许列表禁止的类。请勿使用猜测的序列化对象重试;请获取受支持的配置,或联系环境管理员。
读取
# List all attached evaluator rules
langsmith evaluator list --format json
# Get every rule with this exact display name
langsmith evaluator get "Accuracy Judge"
# Narrow project rules with a project session ID
langsmith evaluator get "Accuracy Judge" --session-id <project-session-id>
get 基于显示名称,因此可能返回多条规则。它会报告规则元数据和选定的 LLM 字段,但不会导出完整的内联提示词、架构和模型配置。
更新 / 替换
没有单独的 update 子命令。使用相同的名称和目标重新运行 create-llm,并添加 --replace;CLI 会在对匹配的规则执行 PATCH 前提示确认。请再次提供完整的目标 LLM 配置。
langsmith evaluator create-llm \
--name "Accuracy Judge" \
--dataset "My Dataset" \
--prompt prompt-v2.json \
--schema schema-v2.json \
--model-config model-v2.json \
--replace
删除
# Inspect every match before deleting
langsmith evaluator get "Accuracy Judge"
langsmith evaluator delete "Accuracy Judge"
delete 基于名称进行删除,会删除所有显示名称相同的工作区运行规则,即使它们属于不同的数据集或项目。如果匹配到多条规则,但只应移除其中一条,请停止操作,不要使用原生删除命令;langsmith evaluator 目前尚不支持按确切 ID 删除。
对于快速本地开发,或必须使用本地包的评估器,请定义本地评估器,并将其传递给 evaluate(evaluators=[...])。
class Grade(TypedDict): reasoning: Annotated[str, ..., "Explain your reasoning"] is_accurate: Annotated[bool, ..., "True if response is accurate"]
judge = ChatOpenAI(model="gpt-4o-mini", temperature=0).with_structured_output(Grade, method="json_schema", strict=True)
async def accuracy_evaluator(run, example): run_outputs = run.outputs if hasattr(run, "outputs") else run.get("outputs", {}) or {} example_outputs = example.outputs if hasattr(example, "outputs") else example.get("outputs", {}) or {} grade = await judge.ainvoke([{"role": "user", "content": f"Expected: {example_outputs}\nActual: {run_outputs}\nIs this accurate?"}]) return {"score": 1 if grade["is_accurate"] else 0, "comment": grade["reasoning"]}
</python>
<typescript>
```javascript
import OpenAI from "openai";
const openai = new OpenAI();
async function accuracyEvaluator(run, example) {
const runOutputs = run.outputs ?? {};
const exampleOutputs = example.outputs ?? {};
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
temperature: 0,
response_format: { type: "json_object" },
messages: [
{ role: "system", content: 'Respond with JSON: {"is_accurate": boolean, "reasoning": string}' },
{ role: "user", content: `Expected: ${JSON.stringify(exampleOutputs)}\nActual: ${JSON.stringify(runOutputs)}\nIs this accurate?` }
]
});
const grade = JSON.parse(response.choices[0].message.content);
return { score: grade.is_accurate ? 1 : 0, comment: grade.reasoning };
}
<code_evaluators>
自定义代码评估器
编写评估器前:
- 检查数据集,了解预期的字段名称(参见上文的黄金法则)
- 测试运行函数,并验证其输出结构与数据集架构相符
- 查询 LangSmith 跟踪记录,调试任何不匹配之处
<run_functions>
定义运行函数
运行函数会执行你的 Agent,并返回用于评估的输出。
重要:请先测试运行函数: 编写评估器前,你必须先测试运行函数并检查实际输出结构。输出形状会因框架、Agent 类型和配置而异。
调试工作流:
- 在示例输入上运行一次 Agent
- 查询跟踪记录,查看执行结构
- 打印原始输出,并对照跟踪记录进行验证,确保输出包含正确的数据
- 根据需要调整运行函数
- 验证输出与数据集架构相符
**尽最大努力让运行函数的输出与数据集架构相符。**这样可以让评估器更简单,也更易复用。如果无法匹配,评估器必须知道如何从两侧提取并比较正确的字段。
```python def run_agent(inputs: dict) -> dict: result = your_agent.run(inputs) # ALWAYS inspect output shape first - run this, check the print, query traces print(f"DEBUG - type: {type(result)}, keys: {result.keys() if hasattr(result, 'keys') else 'N/A'}") print(f"DEBUG - value: {result}") return {"output": result} # Adjust to match your dataset schema ``` ```javascript async function runAgent(inputs) { const result = await yourAgent.invoke(inputs); // ALWAYS inspect output shape first console.log("DEBUG - type:", typeof result, "keys:", Object.keys(result)); console.log("DEBUG - value:", result); return { output: result }; // Adjust to match your dataset schema } ``` ### 捕获执行轨迹进行执行轨迹评估时,运行函数必须在执行期间捕获工具调用。
重要提示: 不同框架和 Agent 类型的运行输出格式差异很大。实现前必须先检查:
LangGraph Agent(LangChain OSS): 使用 stream_mode="debug" 和 subgraphs=True 捕获嵌套子 Agent 的工具调用。
import uuid
def run_agent_with_trajectory(agent, inputs: dict) -> dict:
config = {"configurable": {"thread_id": f"eval-{uuid.uuid4()}"}}
trajectory = []
final_result = None
for chunk in agent.stream(inputs, config=config, stream_mode="debug", subgraphs=True):
# STEP 1: Print chunks to understand the structure
print(f"DEBUG chunk: {chunk}")
# STEP 2: Write extraction based on YOUR observed structure
# ... your extraction logic here ...
# IMPORTANT: After running, query the LangSmith trace to verify
# your trajectory data is complete. Default output may be missing
# tool calls that appear in the trace.
return {"output": final_result, "trajectory": trajectory}
自定义 / 非 LangChain Agent:
- 先检查输出 — 运行 Agent 并检查结果结构。输出中可能已经包含执行轨迹数据(例如
result.tool_calls、result.steps等) - 回调 / 钩子 — 如果框架支持执行回调,请注册一个钩子,在每次调用时记录工具名称
- 解析执行日志 — 作为最后的手段,从结构化日志或跟踪数据中提取工具名称
关键是在执行时捕获工具名称,而不是在定义时捕获。 </run_functions>
## 将评估器上传到 LangSmith重要提示 — 自动运行行为:
上传到数据集的评估器会在你对该数据集运行实验时自动运行。无需将它们传递给 evaluate() — 只需针对数据集运行 Agent,上传的评估器就会自动执行。
重要提示 — 本地评估器与已上传评估器:
已上传的评估器在沙盒环境中运行,可使用的包非常有限。只能使用内置 / 标准库导入,并将所有导入语句放在评估器函数体内。对于数据集(离线)评估器,建议先在本地使用 evaluate(evaluators=[...]) 运行 — 这样可以使用完整的包。
重要提示 — 代码评估器与结构化评估器:
- 代码评估器: 使用
langsmith evaluator upload上传。它们在无法使用外部包的受限环境中运行,适用于确定性逻辑。 - 结构化评估器(LLM-as-Judge): 使用模型配置以及提示词 / 架构文件或
--hub-ref,通过langsmith evaluator create-llm创建。
重要提示 — 选择正确的目标:
--dataset:离线评估器,采用(run, example)签名 — 用于与预期值进行比较--project:在线评估器,采用(run)签名 — 用于实时质量检查
必须指定其中一个。不支持全局评估器。
# List all attached evaluator rules
langsmith evaluator list
# Inspect matching rules by display name
langsmith evaluator get "Trajectory Match"
# Inspect project rules by session ID (not project name)
langsmith evaluator get --session-id <project-session-id>
# Upload offline evaluator (attached to dataset)
langsmith evaluator upload \
--name "Trajectory Match" \
--function trajectory_evaluator \
--dataset "My Dataset" \
my_evaluators.py
# Upload online evaluator (attached to project)
langsmith evaluator upload \
--name "Quality Check" \
--function quality_check \
--project "Production Agent" \
my_evaluators.py
# Replace an existing rule with the same name and target (prompts first)
langsmith evaluator upload \
--name "Trajectory Match" \
--function trajectory_evaluator \
--dataset "My Dataset" \
--replace \
my_evaluators.py
# Delete by display name (prompts first)
langsmith evaluator delete "Trajectory Match"
重要提示 — 安全提示:
upload --replace和create-llm --replace会先修补匹配的规则和提示词delete NAME会删除工作区中所有显示名称为该名称的规则,可能涉及多个目标;请先运行get NAME并检查所有匹配项- 除非用户明确要求,否则绝不要使用
--yes标志
CRUD 验证
仅验证用户要求的生命周期操作:
- 确认 CLI 和任何 SDK 调用都指向相同的环境和工作区
- 使用
list和get验证创建 - 在用户要求时,使用
--replace验证替换 - 仅使用唯一的一次性名称并获得明确授权后,才测试删除
- 如果某个名称对应多条规则,且无法安全确认目标规则,则停止操作
<best_practices>
- 对 LLM 评判器使用结构化输出 — 比解析自由文本更可靠
- 让评估器匹配数据集类型
- 最终响应 → 使用 LLM 作为评判器评估质量
- 执行轨迹 → 使用自定义代码评估序列
- 对 LLM 评判器使用异步 — 支持并行评估
- 单独测试评估器 — 先用已知的好 / 坏示例进行验证
- 选择合适的语言
- Python:用于 Python Agent、langchain 集成
- JavaScript:用于 TypeScript / Node.js Agent </best_practices>
<running_evaluations>
运行评估
已上传的评估器会在运行实验时自动运行 — 无需编写代码。开发 / 测试时,直接传入本地评估器。
```python from langsmith import evaluateUploaded evaluators run automatically
results = evaluate(run_agent, data="My Dataset", experiment_prefix="eval-v1")
Or pass local evaluators for testing
results = evaluate(run_agent, data="My Dataset", evaluators=[my_evaluator], experiment_prefix="eval-v1")
</python>
<typescript>
```javascript
import { evaluate } from "langsmith/evaluation";
// Uploaded evaluators run automatically
const results = await evaluate(runAgent, {
data: "My Dataset",
experimentPrefix: "eval-v1",
});
// Or pass local evaluators for testing
const results = await evaluate(runAgent, {
data: "My Dataset",
evaluators: [myEvaluator],
experimentPrefix: "eval-v1",
});
## 常见问题
**输出与预期不符:**查询 LangSmith 跟踪记录。它会显示每一步的确切输入和输出;请将看到的内容与要提取的内容进行比较。
**每个评估器对应一个指标:**返回 {"score": value, "comment": "..."}。如需评估多个指标,请创建单独的函数。
**字段名称不匹配:**运行函数的输出必须与数据集架构完全一致。请先使用 client.read_example(example_id) 检查数据集。
**RunTree 与 dict(仅限 Python):**本地 evaluate() 会传入 RunTree,上传的评估器则会接收 dict。请同时处理这两种情况:
run_outputs = run.outputs if hasattr(run, "outputs") else run.get("outputs", {}) or {}
TypeScript 始终使用属性访问:run.outputs?.field