Skip to content
LangSmith 文档版本 跟随上游 源快照 e90a2620 更新于 2026-10-18

使用 SDK 管理评估器

使用 SDK 以编程方式创建、检索、更新、列出和删除 LangSmith 评估器。

使用 LangSmith SDK 以编程方式创建和管理评估器。通过 SDK 创建的评估器是工作区级资源,会显示在 LangSmith UI 的 Evaluators 表中,与在 UI 中创建的评估器相同。你可以将它们附加到数据集以运行离线评估,也可以附加到追踪项目以运行在线评估。使用 SDK 自动化评估器管理,并将评估集成到现有工作流中。

前置条件

通过 SDK 管理评估器需要:

  • Python:langsmith>=0.9.8(PyPI)
  • TypeScript:langsmith>=0.7.16(npm)

NOTE

有关安装和设置,请参阅 Python SDK 文档和 TypeScript SDK 文档。

本页示例在初始化客户端时不传参数,因此它会读取 LANGSMITH_API_KEY 和 LANGSMITH_ENDPOINT 环境变量。请通过环境变量配置你的 API 密钥,而不要硬编码。

在以下示例中,请将 <evaluator-uuid> 等占位符替换为 LangSmith 中的对应信息。本页所有 Python 异步示例都假设它们在 async def main(): ... asyncio.run(main()) 中运行,如创建代码评估器示例所示。

创建评估器

代码评估器

代码评估器使用你定义的函数为每个运行或示例评分。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()

    created = await client.evaluators.create(
        name="Correctness evaluator",
        type="code",
        code_evaluator={
            "code": "def perform_eval(run, example):\n    return {'score': 1}",
            "language": "python",
        },
    )
    evaluator_id = created.evaluator.id
    print("Created evaluator:", evaluator_id)

asyncio.run(main())
typescript
import { Client } from "langsmith";

const client = new Client();

const created = await client.evaluators.create({
  name: "Correctness evaluator",
  type: "code",
  code_evaluator: {
    code: "def perform_eval(run, example):\n    return {'score': 1}",
    language: "python",
  },
});
const evaluatorId = created.evaluator?.id;
console.log("Created evaluator:", evaluatorId);

LLM 作为评判者的评估器

LLM 作为评判者的评估器引用提示中心中的提示,并将你的运行或示例字段映射到提示变量。

NOTE

提示必须是结构化提示(类型 StructuredPrompt)。StructuredPrompt 将提示模板与输出模式结合,确保模型以定义的结构返回数据。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()

    created = await client.evaluators.create(
        name="LLM judge",
        type="llm",
        llm_evaluator={
            "prompt_repo_handle": "<prompt-repo-handle>",
            "commit_hash_or_tag": "<commit-hash-or-tag>",
            "variable_mapping": {
                "input": "inputs.question",
                "output": "outputs.answer",
                "reference": "reference.answer",
            },
        },
    )
    evaluator_id = created.evaluator.id

asyncio.run(main())
typescript
const created = await client.evaluators.create({
  name: "LLM judge",
  type: "llm",
  llm_evaluator: {
    prompt_repo_handle: "<prompt-repo-handle>",
    commit_hash_or_tag: "<commit-hash-or-tag>",
    variable_mapping: {
      input: "inputs.question",
      output: "outputs.answer",
      reference: "reference.answer",
    },
  },
});
const evaluatorId = created.evaluator?.id;

prompt_repo_handle 是提示的内部仓库名称,而不是其显示标题或 URL。要查找它,请列出工作区提示并读取 repo_handle 字段,或在 LangSmith 中通过提示标识符检索特定提示。提示的标识符格式可以是:

  • promptName(用于私有提示),例如 my-prompt。
  • owner/promptName(用于公开提示),例如 langchain-ai/correctness。
python
# List workspace prompts and read each repo handle
for prompt in client.list_prompts(limit=10).repos:
    print("prompt-repo-handle:", prompt.repo_handle)   # value to use for prompt_repo_handle
    print("prompt-full-name:", prompt.full_name)     # display name
    print("description:", prompt.description)

# Or retrieve a specific prompt by identifier
prompt = client.get_prompt("<prompt-identifier>")
print("prompt-repo-handle:", prompt.repo_handle)
typescript
// List workspace prompts and read each repo handle.
// listPrompts() has no `limit` option in this SDK version — it's an async
// generator over all prompts, so cap the count client-side and break.
const prompts = client.listPrompts();
let count = 0;
for await (const prompt of prompts) {
  console.log("prompt-repo-handle:", prompt.repo_handle);
  console.log("prompt-full-name:", prompt.full_name);
  console.log("description:", prompt.description);
  console.log("---");
  if (++count >= 10) break; // first 10 only; stops further pagination
}

// Or retrieve a specific prompt by identifier
const prompt = await client.getPrompt("<prompt-identifier>");
console.log("prompt-repo-handle:", prompt.repo_handle);

检索评估器

通过 ID 获取单个评估器以读取其配置,包括名称、类型、反馈键和运行规则。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()
    evaluator_id = "<evaluator-uuid>"

    evaluator = await client.evaluators.retrieve(evaluator_id)
    print(evaluator.name)
    print(evaluator.type)
    print(evaluator.feedback_keys)
    print(evaluator.run_rules)

asyncio.run(main())
typescript
const evaluator = await client.evaluators.retrieve(evaluatorId);
console.log(evaluator.name);
console.log(evaluator.type);
console.log(evaluator.feedback_keys);
console.log(evaluator.run_rules);

更新评估器

传递与评估器类型匹配的字段:代码评估器使用 code_evaluator,LLM 作为评判者的评估器使用 llm_evaluator。update 只更改你传递的字段。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()

    # Update a code evaluator
    code_evaluator_id = "<code-evaluator-uuid>"

    updated = await client.evaluators.update(
        code_evaluator_id,
        name="Updated correctness evaluator",
        code_evaluator={
            "code": "def perform_eval(run, example):\n    return {'score': 0.8}",
            "language": "python",
        },
    )
    print(updated.evaluator.name if updated.evaluator else None)

    # Update the name and prompt of an LLM-as-a-judge evaluator
    llm_evaluator_id = "<llm-evaluator-uuid>"

    await client.evaluators.update(
        llm_evaluator_id,
        name="Updated LLM judge",
        llm_evaluator={
            "prompt_repo_handle": "<prompt-repo-handle>",
            "commit_hash_or_tag": "<commit-hash-or-tag>",
        },
    )

asyncio.run(main())
typescript
// Update a code evaluator
const codeEvaluatorId = "<code-evaluator-uuid>";

const updated = await client.evaluators.update(codeEvaluatorId, {
  name: "Updated correctness evaluator",
  code_evaluator: {
    code: "def perform_eval(run, example):\n    return {'score': 0.8}",
    language: "python",
  },
});
console.log(updated.evaluator?.name);

// Update the name and prompt of an LLM-as-a-judge evaluator
const llmEvaluatorId = "<llm-evaluator-uuid>";

await client.evaluators.update(llmEvaluatorId, {
  name: "Updated LLM judge",
  llm_evaluator: {
    prompt_repo_handle: "<prompt-repo-handle>",
    commit_hash_or_tag: "<commit-hash-or-tag>",
  },
});

配置运行时设置

LLM 作为评判者的评估器接受控制其追踪评分方式的附加设置:

  • variable_mapping:将运行或示例字段映射到评判提示变量。它在评估器运行时适用。
  • use_corrections_dataset 和 num_few_shot_examples:启用基于人工分数修正的 few-shot 学习。它们仅在评估器附加到项目或数据集且已提交修正时适用。

NOTE

这些设置会在下一次评估运行时生效,而不是在你调用 update 时生效。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()
    llm_evaluator_id = "<llm-evaluator-uuid>"

    await client.evaluators.update(
        llm_evaluator_id,
        llm_evaluator={
            "prompt_repo_handle": "<prompt-repo-handle>",
            "commit_hash_or_tag": "<commit-hash-or-tag>",
            "variable_mapping": {
                "input": "inputs.question",
                "output": "outputs.answer",
            },
            "use_corrections_dataset": True,
            "num_few_shot_examples": 3,
        },
    )

asyncio.run(main())
typescript
const llmEvaluatorId = "<llm-evaluator-uuid>";

await client.evaluators.update(llmEvaluatorId, {
  llm_evaluator: {
    prompt_repo_handle: "<prompt-repo-handle>",
    commit_hash_or_tag: "<commit-hash-or-tag>",
    variable_mapping: {
      input: "inputs.question",
      output: "outputs.answer",
    },
    use_corrections_dataset: true,
    num_few_shot_examples: 3,
  },
});

列出评估器

按名称、类型、反馈键、附加资源或标签值筛选,并对结果排序或分页。list() 在你直接迭代返回对象时会自动分页遍历所有匹配项。limit 设置每页请求大小(1 到 100),而不是结果总数。sort_by 是可选的,接受 created_at 或 updated_at,默认值为 created_at。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()

    # Read a single page of results
    page = await client.evaluators.list(
        name_contains="correctness",
        type="code",
        limit=10,
    )
    for evaluator in page.evaluators:
        print(evaluator.id, evaluator.name, evaluator.type)

    # Collect every match into a list
    evaluators = [
        evaluator
        async for evaluator in client.evaluators.list(feedback_key="correctness", limit=20)
    ]

    # Filter, sort, and paginate
    page = await client.evaluators.list(
        feedback_key="correctness",
        name_contains="judge",
        resource_id=["<project-or-dataset-uuid>"],
        tag_value_id=["<tag-value-uuid>"],
        type="llm",
        sort_by="updated_at",  # "created_at" (default) or "updated_at"
        sort_by_desc=False,
        limit=20,
        offset=0,
    )

asyncio.run(main())
typescript
// Read a single page of results
const page = await client.evaluators.list({
  name_contains: "correctness",
  type: "code",
  limit: 10,
});
for (const evaluator of page.evaluators) {
  console.log(evaluator.id, evaluator.name, evaluator.type);
}

// Collect every match into an array
const evaluators = [];
for await (const evaluator of client.evaluators.list({
  feedback_key: "correctness",
  limit: 20,
})) {
  evaluators.push(evaluator);
}

// Filter, sort, and paginate
await client.evaluators.list({
  feedback_key: "correctness",
  name_contains: "judge",
  resource_id: ["<project-or-dataset-uuid>"],
  tag_value_id: ["<tag-value-uuid>"],
  type: "llm",
  sort_by: "updated_at", // "created_at" (default) or "updated_at"
  sort_by_desc: false,
  limit: 20,
  offset: 0,
});

跟踪评估器支出

检索评估器的估计美元支出和追踪数量:

  • period_start:仅日期的 ISO 字符串,例如 2026-06-29。传递日期时间会返回 400 错误。
    • 窗口:period_start 会开始一个固定的 7 天窗口,包含 period_start 及其后六天。窗口是半开的 [period_start, period_start + 7 days),因此 period_end(period_start 加 7 天)不包括在内。例如,period_start 为 2026-06-29 时覆盖 2026-06-29 到 2026-07-05,不包括 2026-07-06。
  • type:将结果限定为单一评估器类型,llm 或 code。省略它以包含所有类型。
  • 空结果:如果该窗口没有记录支出,返回的 groups 列表为空。

NOTE

请仅传递 group_by、evaluator_id、session_id(LangSmith 追踪项目 UUID)或 dataset_id 中的一个。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()
    evaluator_uuid = "<evaluator-uuid>"
    start_date = "<period-start-date>" # for example, "2026-06-29"

    # Spend for a single evaluator
    spend = await client.evaluators.spend(
        period_start=start_date,
        evaluator_id=evaluator_uuid,
    )
    for group in spend.groups or []:
        print(group.evaluator_name, group.total_spend_usd, group.total_trace_count)

    # Group spend by evaluator
    spend_by_evaluator = await client.evaluators.spend(
        period_start=start_date,
        group_by="evaluator",
        type="llm",
    )
    print("Group by evaluator")
    for group in spend_by_evaluator.groups or []:
        print(group.evaluator_name, group.total_spend_usd, group.total_trace_count)

    # Group spend by resource
    spend_by_resource = await client.evaluators.spend(
        period_start=start_date,
        group_by="resource",
        type="llm",
    )
    print("Group by resource")
    for group in spend_by_resource.groups or []:
        print(group.session_name, group.dataset_name, group.total_spend_usd, group.total_trace_count)

    # Group spend by run_rule
    spend_by_run_rule = await client.evaluators.spend(
        period_start=start_date,
        group_by="run_rule",
        type="llm",
    )
    print("Group by run_rule")
    for group in spend_by_run_rule.groups or []:
        print(group.run_rule_name, group.total_spend_usd, group.total_trace_count)

asyncio.run(main())
typescript
const evaluatorUUID = "<evaluator-uuid>";
const startDate = "<period-start-date>"; // for example, "2026-06-29"

// Spend for a single evaluator
const spend = await client.evaluators.spend({
  period_start: startDate,
  evaluator_id: evaluatorUUID,
});
for (const group of spend.groups ?? []) {
  console.log(group.evaluator_name, group.total_spend_usd, group.total_trace_count);
}

// Group spend by evaluator
const spendByEvaluator = await client.evaluators.spend({
  period_start: startDate,
  group_by: "evaluator",
  type: "llm",
});
console.log("Group by evaluator");
for (const group of spendByEvaluator.groups ?? []) {
  console.log(group.evaluator_name, group.total_spend_usd, group.total_trace_count);
}

// Group spend by resource
const spendByResource = await client.evaluators.spend({
  period_start: startDate,
  group_by: "resource",
  type: "llm",
});
console.log("Group by resource");
for (const group of spendByResource.groups ?? []) {
  console.log(group.session_name, group.dataset_name, group.total_spend_usd, group.total_trace_count);
}

// Group spend by run_rule
const spendByRunRule = await client.evaluators.spend({
  period_start: startDate,
  group_by: "run_rule",
  type: "llm",
});
console.log("Group by run_rule");
for (const group of spendByRunRule.groups ?? []) {
  console.log(group.run_rule_name, group.total_spend_usd, group.total_trace_count);
}

删除评估器

当评估器附加到追踪项目或数据集时,你无法删除它。请将 delete_run_rules 设置为 true,以便在删除评估器之前删除引用它的运行规则。

python
import asyncio

from langsmith import Client

async def main():
    client = Client()
    evaluator_id = "<evaluator-uuid>"

    await client.evaluators.delete(
        evaluator_id,
        delete_run_rules=True, # run rules referencing the evaluator are deleted first
    )

asyncio.run(main())
typescript
const evaluatorId = "<evaluator-uuid>";

await client.evaluators.delete(evaluatorId, {
  delete_run_rules: true, // run rules referencing the evaluator are deleted first
});

相关


BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。