langsmith-evaluator について
langsmith-evaluator は、LangSmith で評価器を定義、実行、アップロードする方法を紹介するスキルです。エージェントの出力や実行軌跡を検査する開発者向けに、LLM による判定とコード評価、およびローカル評価とオンライン評価を扱います。
主な機能
- 01LLM 判定評価器の定義
- 02決定的なコード評価器の作成
- 03実行出力と軌跡の取得
- 04ローカル評価とオンライン評価
- 05コード評価器の LangSmith へのアップロード
活用シーン
- 01参照回答とエージェント出力の評価
- 02ツール呼び出し軌跡の順序検証
- 03本番実行のリアルタイム品質チェック
- 04LangSmith データセットでの実験実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ langchain-ai/ skills-benchmarks --skill langsmith-evaluatorインストール後、Claude Code で/langsmith-evaluatorを入力して読み込まれたか確認します。
詳細
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>
原則:実装前に調査する
重要: 評価器や抽出ロジックを記述する前に、必ず次の手順を実行してください。
- サンプル入力でエージェントを実行し、実際の出力を取得します
- 出力を調査します。出力を表示し、LangSmith のトレースをクエリして、正確な構造を把握します
- その後で初めて、その出力を処理するコードを記述します
出力構造は、フレームワーク、エージェントの種類、設定によって大きく異なります。形状を決めつけず、必ず最初に確認してください。出力に必要なデータが含まれていない場合は、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=[...]) で使用するローカル評価器を定義することを強く推奨します。
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>
カスタムコード評価器
評価器を作成する前に:
- データセットを調べ、想定されるフィールド名を把握します(上記の「Golden Rule」を参照)
- run 関数をテストし、その出力構造がデータセットのスキーマと一致することを確認します
- LangSmith のトレースを照会し、不一致をデバッグします
<run_functions>
Run 関数の定義
Run 関数はエージェントを実行し、評価用の出力を返します。
重要 — Run 関数を先にテストしてください: 評価器を作成する前に、必ず run 関数をテストし、実際の出力構造を確認してください。出力の形式は、フレームワーク、エージェントの種類、設定によって異なります。
デバッグのワークフロー:
- サンプル入力でエージェントを一度実行します
- トレースを照会し、実行構造を確認します
- 生の出力を表示し、トレースと照合して、出力に正しいデータが含まれていることを確認します
- 必要に応じて run 関数を調整します
- 出力がデータセットのスキーマと一致することを確認します
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 以外のエージェント:
- まず出力を確認する — エージェントを実行し、結果の構造を確認します。軌跡データが出力にすでに含まれている場合があります(例:
result.tool_calls、result.stepsなど)。 - コールバック/フック — フレームワークが実行コールバックに対応している場合は、各呼び出し時にツール名を記録するフックを登録します。
- 実行ログを解析する — 最終手段として、構造化ログまたはトレースからツール名を抽出します。
重要なのは、定義時ではなく実行時にツール名を取得することです。 </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>
- LLM による判定には構造化出力を使用する — 自由形式のテキストを解析するよりも信頼性が高くなります。
- 評価器をデータセットの種類に合わせる
- 最終応答 → 品質評価には LLM による判定
- 軌跡 → シーケンス評価にはカスタムコード
- LLM による判定には非同期処理を使用する — 並列評価が可能になります。
- 評価器を個別にテストする — まず、正解と不正解が既知の例で検証してください。
- 適切な言語を選択する
- Python:Python エージェントや langchain との統合に使用します。
- JavaScript:TypeScript/Node.js エージェントに使用します。 </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",
});
詳細な実験メタデータ
metadata={...} を evaluate() に渡すと、構造化情報を使って実験にタグを付けられます。予約済みのキー models、prompts、tools は LangSmith の実験 UI の専用列に自動入力されます。これにより、モデル、プロバイダー、プロンプトのバージョン、ツールの種類ごとに実行を簡単に絞り込み、比較できます。それ以外のキーは自由形式のメタデータとして保存されます。
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