mcpField
L
langsmith-evaluator

langsmith-evaluator

github.com/langchain-aiテスト・品質11955 回インストール10 週間前に更新
リポジトリ

langsmith-evaluator について

langsmith-evaluator は、LangSmith で評価器を定義、実行、アップロードする方法を紹介するスキルです。エージェントの出力や実行軌跡を検査する開発者向けに、LLM による判定とコード評価、およびローカル評価とオンライン評価を扱います。

主な機能

  1. 01LLM 判定評価器の定義
  2. 02決定的なコード評価器の作成
  3. 03実行出力と軌跡の取得
  4. 04ローカル評価とオンライン評価
  5. 05コード評価器の LangSmith へのアップロード

活用シーン

  1. 01参照回答とエージェント出力の評価
  2. 02ツール呼び出し軌跡の順序検証
  3. 03本番実行のリアルタイム品質チェック
  4. 04LangSmith データセットでの実験実行

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/langsmith-evaluatorを入力して読み込まれたか確認します。

詳細

3 つの主要コンポーネント:**(1)評価器の作成** - LLM-as-Judge、カスタムコード;**(2)実行関数の定義** - 評価用にエージェントの出力/軌跡を取得;**(3)評価の実行** - `evaluate()` を使ってローカルで実行するか、アップロードした評価器で自動実行します。Python と TypeScript の例を含みます。 環境変数
LANGSMITH_API_KEY=lsv2_pt_your_api_key_here          # REQUIRED
LANGSMITH_PROJECT=your-project-name                   # Check this to know which project has traces
LANGSMITH_WORKSPACE_ID=your-workspace-id              # Optional: for org-scoped keys
OPENAI_API_KEY=your_openai_key                        # For LLM as Judge

認証は必須です。LANGSMITH_API_KEY 環境変数を設定するか、CLI コマンドに --api-key フラグを渡してください(推奨):

langsmith evaluator list --api-key $LANGSMITH_API_KEY

重要: LangSmith にクエリを実行したり、操作したりする前に、必ず環境変数または .env ファイルで LANGSMITH_PROJECT を確認してください。これにより、関連するトレースとデータを含むプロジェクトがわかります。LangSmith プロジェクトが見つからない場合は、最善の判断で適切なプロジェクトを特定してください。

Python の依存関係

pip install langsmith langchain-openai python-dotenv

CLI ツール(評価器のアップロード用)

curl -sSL https://raw.githubusercontent.com/langchain-ai/langsmith-cli/main/scripts/install.sh | sh

JavaScript の依存関係

npm install langsmith openai

<crucial_requirement>

原則:実装前に調査する

重要: 評価器や抽出ロジックを記述する前に、必ず次の手順を実行してください。

  1. サンプル入力でエージェントを実行し、実際の出力を取得します
  2. 出力を調査します。出力を表示し、LangSmith のトレースをクエリして、正確な構造を把握します
  3. その後で初めて、その出力を処理するコードを記述します

出力構造は、フレームワーク、エージェントの種類、設定によって大きく異なります。形状を決めつけず、必ず最初に確認してください。出力に必要なデータが含まれていない場合は、LangSmith のトレースをクエリし、実行結果からの抽出方法を把握してください。 </crucial_requirement>

<evaluator_format>

オフライン評価器とオンライン評価器

オフライン評価器(データセットに紐付け):

  • 関数シグネチャ:(run, example) - 実行出力とデータセットの例の両方を受け取ります
  • 用途:エージェントの出力をデータセット内の期待値と比較します
  • アップロード方法:--dataset "Dataset Name"

オンライン評価器(プロジェクトに紐付け):

  • 関数シグネチャ:(run) - 実行出力のみを受け取り、example パラメーターは受け取りません
  • 用途:本番実行の品質をリアルタイムで確認します(参照データはありません)
  • アップロード方法:--project "Project Name"

重要 - 戻り値の形式:

  • 各評価器が返すメトリクスは 1 つだけ です。複数のメトリクスが必要な場合は、評価器関数を複数作成してください。
  • {"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 as Judge - LLM を使って出力を評価します。主観的な品質(正確性、有用性、関連性)の評価に最適です。
  • カスタムコード - 決定論的なロジックです。客観的な確認(完全一致、軌跡の検証、形式の準拠)に最適です。 </evaluator_types>

<llm_judge>

LLM as Judge 評価器

注: LLM-as-Judge のアップロードは現在 CLI ではサポートされておらず、コード評価器のみがサポートされています。データセットに対する評価では、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. データセットを調べ、想定されるフィールド名を把握します(上記の「Golden Rule」を参照)
  2. run 関数をテストし、その出力構造がデータセットのスキーマと一致することを確認します
  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>

Run 関数の定義

Run 関数はエージェントを実行し、評価用の出力を返します。

重要 — Run 関数を先にテストしてください: 評価器を作成する前に、必ず run 関数をテストし、実際の出力構造を確認してください。出力の形式は、フレームワーク、エージェントの種類、設定によって異なります。

デバッグのワークフロー:

  1. サンプル入力でエージェントを一度実行します
  2. トレースを照会し、実行構造を確認します
  3. 生の出力を表示し、トレースと照合して、出力に正しいデータが含まれていることを確認します
  4. 必要に応じて run 関数を調整します
  5. 出力がデータセットのスキーマと一致することを確認します

run 関数の出力を、できる限りデータセットのスキーマに合わせてください。 これにより、評価器をシンプルかつ再利用可能にできます。一致させられない場合は、各側から適切なフィールドを抽出して比較する方法を評価器で把握する必要があります。

```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 } ```
軌跡の取得

軌跡を評価するには、run 関数で実行中のツール呼び出しを取得する必要があります。

重要: run の出力形式は、フレームワークやエージェントの種類によって大きく異なります。実装する前に、必ず確認してください。

LangGraph エージェント(LangChain OSS): stream_mode="debug" と subgraphs=True を使用して、ネストされたサブエージェントのツール呼び出しを取得します。

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 以外のエージェント:

  1. まず出力を確認する — エージェントを実行し、結果の構造を確認します。軌跡データが出力にすでに含まれている場合があります(例:result.tool_calls、result.steps など)。
  2. コールバック/フック — フレームワークが実行コールバックに対応している場合は、各呼び出し時にツール名を記録するフックを登録します。
  3. 実行ログを解析する — 最終手段として、構造化ログまたはトレースからツール名を抽出します。

重要なのは、定義時ではなく実行時にツール名を取得することです。 </run_functions>

## LangSmith への評価器のアップロード

重要 — 自動実行の動作: データセットにアップロードされた評価器は、そのデータセットで実験を実行すると自動的に実行されます。evaluate() に渡す必要はありません。エージェントをデータセットに対して実行するだけで、アップロード済みの評価器が自動的に実行されます。

重要 — ローカルとアップロード済みの評価器: アップロード済みの評価器は、パッケージへのアクセスが非常に制限されたサンドボックス環境で実行されます。組み込みライブラリまたは標準ライブラリのインポートのみを使用し、すべてのインポートを評価器関数の本体内に記述してください。データセット(オフライン)評価器の場合は、まず evaluate(evaluators=[...]) を使ってローカルで実行することをおすすめします。これにより、すべてのパッケージを利用できます。

重要 — コード評価器と構造化評価器:

  • コード評価器(CLI がアップロードするもの):外部パッケージを利用できない制限環境で実行されます。決定的なロジック(完全一致、軌跡の検証)に使用してください。
  • 構造化評価器(LLM による判定):LangSmith UI で設定し、モデル/プロンプト/スキーマを含む特定のペイロード形式を使用します。CLI はまだこの形式に対応していません。

重要 — 適切な対象を選択してください:

  • --dataset:(run, example) シグネチャのオフライン評価器。期待値との比較に使用します。
  • --project:(run) シグネチャのオンライン評価器。リアルタイムの品質チェックに使用します。

どちらか一方を指定する必要があります。グローバル評価器には対応していません。

# List all evaluators
langsmith evaluator list --api-key $LANGSMITH_API_KEY

# Upload offline evaluator (attached to dataset)
langsmith evaluator upload my_evaluators.py \
  --name "Trajectory Match" --function trajectory_evaluator \
  --dataset "My Dataset" --replace --api-key $LANGSMITH_API_KEY

# Upload online evaluator (attached to project)
langsmith evaluator upload my_evaluators.py \
  --name "Quality Check" --function quality_check \
  --project "Production Agent" --replace --api-key $LANGSMITH_API_KEY

# Delete
langsmith evaluator delete "Trajectory Match" --api-key $LANGSMITH_API_KEY

重要 — 安全性に関するプロンプト:

  • CLI は破壊的な操作の前に確認を求めます。
  • ユーザーが明示的に要求しない限り、--yes フラグは絶対に使用しないでください。

<best_practices>

  1. LLM による判定には構造化出力を使用する — 自由形式のテキストを解析するよりも信頼性が高くなります。
  2. 評価器をデータセットの種類に合わせる
    • 最終応答 → 品質評価には LLM による判定
    • 軌跡 → シーケンス評価にはカスタムコード
  3. LLM による判定には非同期処理を使用する — 並列評価が可能になります。
  4. 評価器を個別にテストする — まず、正解と不正解が既知の例で検証してください。
  5. 適切な言語を選択する
    • Python:Python エージェントや langchain との統合に使用します。
    • JavaScript:TypeScript/Node.js エージェントに使用します。 </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",
});
詳細な実験メタデータ

metadata={...} を evaluate() に渡すと、構造化情報を使って実験にタグを付けられます。予約済みのキー models、prompts、tools は LangSmith の実験 UI の専用列に自動入力されます。これにより、モデル、プロバイダー、プロンプトのバージョン、ツールの種類ごとに実行を簡単に絞り込み、比較できます。それ以外のキーは自由形式のメタデータとして保存されます。

```python EXPERIMENT_METADATA = { "models": ["openai:gpt-4o-mini"], "prompts": ["my-org/my-eval-prompt:abc12345"], "tools": [ { "name": "web_search", "description": "Search the web for information", "parameters": { "type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], }, }, ], }

results = evaluate( run_agent, data="My Dataset", evaluators=[my_evaluator], experiment_prefix="eval-v1", metadata=EXPERIMENT_METADATA, )

</python>

<typescript>
```javascript
const EXPERIMENT_METADATA = {
  models: ["openai:gpt-4o-mini"],
  prompts: ["my-org/my-eval-prompt:abc12345"],
  tools: [
    {
      name: "web_search",
      description: "Search the web for information",
      parameters: {
        type: "object",
        properties: { query: { type: "string" } },
        required: ["query"],
      },
    },
  ],
};

const results = await evaluate(runAgent, {
  data: "My Dataset",
  evaluators: [myEvaluator],
  experimentPrefix: "eval-v1",
  metadata: EXPERIMENT_METADATA,
});

メタデータにシークレットを含めないでください。メタデータは保存され、LangSmith UI に表示されます。 </running_evaluations>

## よくある問題

出力が期待と一致しない: LangSmith のトレースを確認してください。各ステップの正確な入力と出力が表示されます。表示内容と抽出しようとしている内容を比較してください。

評価器ごとに指標は1つ: {"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)

コメント