mcpField
L
langsmith-evaluator

langsmith-evaluator

github.com/langchain-ai测试与质量1645.0k 次安装1 天前更新
代码仓库

关于 langsmith-evaluator

用于创建和运行 LangSmith 评估器的技能,可用 LLM 裁判或自定义代码评估 Agent 输出。内容涵盖本地评估,以及附加到数据集或项目的评估器,并提供 Python 与 TypeScript 指引。

主要功能

  1. 01LLM 裁判与代码评估器
  2. 02捕获 Agent 输出的运行函数
  3. 03使用 evaluate() 进行本地评估
  4. 04数据集与项目评估器流程
  5. 05Python 和 TypeScript 指引

适用场景

  1. 01依据数据集示例评估 Agent 输出
  2. 02在无参考示例时检查生产运行
  3. 03上传前在本地测试评估逻辑
  4. 04编写提取逻辑前检查运行输出与 trace

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/langchain-ai/langsmith-skills --skill langsmith-evaluator

安装后在 Claude Code 中输入/langsmith-evaluator确认已加载。

详细介绍

三个核心组件:**(1)创建评估器**——LLM-as-Judge、自定义代码;**(2)定义运行函数**——捕获 Agent 输出/轨迹以供评估;**(3)运行评估**——使用 `evaluate()` 在本地运行,或通过上传的评估器自动运行。包含 Python 和 TypeScript 示例。 环境变量
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>

黄金法则:先检查,再实现

关键: 在编写任何评估器或提取逻辑之前,你必须:

  1. 运行你的 Agent,使用示例输入并捕获实际输出
  2. 检查输出——打印输出、查询 LangSmith 追踪,并了解其确切结构
  3. 然后再编写处理该输出的代码

不同框架、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=[...])。

```python from typing import TypedDict, Annotated from langchain_openai import ChatOpenAI

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>

自定义代码评估器

编写评估器前:

  1. 检查数据集,了解预期的字段名称(参见上文的黄金法则)
  2. 测试运行函数,并验证其输出结构与数据集架构相符
  3. 查询 LangSmith 跟踪记录,调试任何不匹配之处
```python def trajectory_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 {} # IMPORTANT: Replace these placeholders with your actual field names # 1. Query your LangSmith trace to see what fields exist in run outputs # 2. Check your dataset schema for expected field names # Note: Trajectory data may not appear in default output - verify against trace! actual = run_outputs.get("YOUR_TRAJECTORY_FIELD", []) expected = example_outputs.get("YOUR_EXPECTED_FIELD", []) return {"score": 1 if actual == expected else 0, "comment": f"Expected {expected}, got {actual}"} ``` ```javascript function trajectoryEvaluator(run, example) { const runOutputs = run.outputs ?? {}; const exampleOutputs = example.outputs ?? {}; // IMPORTANT: Replace these placeholders with your actual field names // 1. Query your LangSmith trace to see what fields exist in run outputs // 2. Check your dataset schema for expected field names const actual = runOutputs.YOUR_TRAJECTORY_FIELD ?? []; const expected = exampleOutputs.YOUR_EXPECTED_FIELD ?? []; const match = JSON.stringify(actual) === JSON.stringify(expected); return { score: match ? 1 : 0, comment: `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}` }; } ```

<run_functions>

定义运行函数

运行函数会执行你的 Agent,并返回用于评估的输出。

重要:请先测试运行函数: 编写评估器前,你必须先测试运行函数并检查实际输出结构。输出形状会因框架、Agent 类型和配置而异。

调试工作流:

  1. 在示例输入上运行一次 Agent
  2. 查询跟踪记录,查看执行结构
  3. 打印原始输出,并对照跟踪记录进行验证,确保输出包含正确的数据
  4. 根据需要调整运行函数
  5. 验证输出与数据集架构相符

**尽最大努力让运行函数的输出与数据集架构相符。**这样可以让评估器更简单,也更易复用。如果无法匹配,评估器必须知道如何从两侧提取并比较正确的字段。

```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:

  1. 先检查输出 — 运行 Agent 并检查结果结构。输出中可能已经包含执行轨迹数据(例如 result.tool_calls、result.steps 等)
  2. 回调 / 钩子 — 如果框架支持执行回调,请注册一个钩子,在每次调用时记录工具名称
  3. 解析执行日志 — 作为最后的手段,从结构化日志或跟踪数据中提取工具名称

关键是在执行时捕获工具名称,而不是在定义时捕获。 </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>

  1. 对 LLM 评判器使用结构化输出 — 比解析自由文本更可靠
  2. 让评估器匹配数据集类型
    • 最终响应 → 使用 LLM 作为评判器评估质量
    • 执行轨迹 → 使用自定义代码评估序列
  3. 对 LLM 评判器使用异步 — 支持并行评估
  4. 单独测试评估器 — 先用已知的好 / 坏示例进行验证
  5. 选择合适的语言
    • Python:用于 Python Agent、langchain 集成
    • JavaScript:用于 TypeScript / Node.js Agent </best_practices>

<running_evaluations>

运行评估

已上传的评估器会在运行实验时自动运行 — 无需编写代码。开发 / 测试时,直接传入本地评估器。

```python from langsmith import evaluate

Uploaded 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

- [LangSmith 评估概念](https://docs.langchain.com/langsmith/evaluation-concepts) - [自定义代码评估器](https://changelog.langchain.com/announcements/custom-code-evaluators-in-langsmith) - [OpenEvals - 即用型评估器](https://github.com/langchain-ai/openevals)

评论

支持 Markdown