ツール呼び出し精度スコアの例
Mastra はツール呼び出し精度を評価するために、次の 2 種類のスコアを提供します:
- 決定論的評価向けのコードベースのスコア
- 意味的評価向けのLLM ベースのスコア
インストール
npm install @mastra/evals
APIの詳細なドキュメントと設定オプションについては、
Tool Call Accuracy Scorers
をご覧ください。
コードベースのスコアラーの例
コードベースのスコアラーは、ツールの完全一致に基づいて、決定的な二値スコア(0または1)を返します。
インポート
import { createToolCallAccuracyScorerCode } from "@mastra/evals/scorers/code";
import { createAgentTestRun, createUIMessage, createToolInvocation } from "@mastra/evals/scorers/utils";
適切なツールの選択
src/example-correct-tool.ts
const scorer = createToolCallAccuracyScorerCode({
expectedTool: 'weather-tool'
});
// ツール呼び出しを伴う LLM の入出力をシミュレート
const inputMessages = [
createUIMessage({
content: 'What is the weather like in New York today?',
role: 'user',
id: 'input-1'
})
];
const output = [
createUIMessage({
content: 'Let me check the weather for you.',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-123',
toolName: 'weather-tool',
args: { location: 'New York' },
result: { temperature: '72°F', condition: 'sunny' },
state: 'result'
})
]
})
];
const run = createAgentTestRun({ inputMessages, output });
const result = await scorer.run(run);
console.log(result.score); // 1
console.log(result.preprocessStepResult?.correctToolCalled); // true
厳格モードでの評価
ツールがちょうど1つだけ呼び出された場合にのみ合格します:
src/example-strict-mode.ts
const strictScorer = createToolCallAccuracyScorerCode({
expectedTool: 'weather-tool',
strictMode: true
});
// 複数のツールが呼び出されているため、厳格モードでは不合格
const output = [
createUIMessage({
content: 'お任せください。',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-1',
toolName: 'search-tool',
args: {},
result: {},
state: 'result',
}),
createToolInvocation({
toolCallId: 'call-2',
toolName: 'weather-tool',
args: { location: 'New York' },
result: { temperature: '20°C' },
state: 'result',
})
]
})
];
const result = await strictScorer.run(run);
console.log(result.score); // 0 - 複数のツールが呼び出されたため不合格
ツール呼び出し順序の検証
ツールが特定の順序で呼び出されているかを検証します。
src/example-order-validation.ts
const orderScorer = createToolCallAccuracyScorerCode({
expectedTool: 'auth-tool', // 順序が指定されている場合は無視される
expectedToolOrder: ['auth-tool', 'fetch-tool'],
strictMode: true // 追加のツールは許可しない
});
const output = [
createUIMessage({
content: '認証してデータを取得します。',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-1',
toolName: 'auth-tool',
args: { token: 'abc123' },
result: { authenticated: true },
state: 'result'
}),
createToolInvocation({
toolCallId: 'call-2',
toolName: 'fetch-tool',
args: { endpoint: '/data' },
result: { data: ['item1'] },
state: 'result'
})
]
})
];
const result = await orderScorer.run(run);
console.log(result.score); // 1 - 正しい順序
柔軟な順序モード
期待されるツールが相対的な順序を保っている限り、追加のツールを許可します:
src/example-flexible-order.ts
const flexibleOrderScorer = createToolCallAccuracyScorerCode({
expectedTool: 'auth-tool',
expectedToolOrder: ['auth-tool', 'fetch-tool'],
strictMode: false // 追加のツールを許可
});
const output = [
createUIMessage({
content: '包括的な処理を実行します。',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-1',
toolName: 'auth-tool',
args: { token: 'abc123' },
result: { authenticated: true },
state: 'result'
}),
createToolInvocation({
toolCallId: 'call-2',
toolName: 'log-tool', // 追加ツール — 柔軟モードではOK
args: { message: 'フェッチを開始' },
result: { logged: true },
state: 'result'
}),
createToolInvocation({
toolCallId: 'call-3',
toolName: 'fetch-tool',
args: { endpoint: '/data' },
result: { data: ['item1'] },
state: 'result'
})
]
})
];
const result = await flexibleOrderScorer.run(run);
console.log(result.score); // 1 - auth-tool が fetch-tool より前にある
LLM ベースのスコアリング例
LLM ベースのスコアラーは、ユーザーのリクエストに対してツール選択が適切かどうかを AI で評価します。
インポート
import { createToolCallAccuracyScorerLLM } from "@mastra/evals/scorers/llm";
import { openai } from "@ai-sdk/openai";
基本的な LLM 評価
src/example-llm-basic.ts
const llmScorer = createToolCallAccuracyScorerLLM({
model: openai('gpt-4o-mini'),
availableTools: [
{
name: 'weather-tool',
description: '任意の場所の現在の天気情報を取得'
},
{
name: 'calendar-tool',
description: 'カレンダーの予定や日程を確認'
},
{
name: 'search-tool',
description: '一般的な情報をウェブで検索'
}
]
});
const inputMessages = [
createUIMessage({
content: '今日のサンフランシスコの天気は?',
role: 'user',
id: 'input-1'
})
];
const output = [
createUIMessage({
content: '現在の天気を確認します。',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-123',
toolName: 'weather-tool',
args: { location: 'San Francisco', date: 'today' },
result: { temperature: '68°F', condition: 'foggy' },
state: 'result'
})
]
})
];
const run = createAgentTestRun({ inputMessages, output });
const result = await llmScorer.run(run);
console.log(result.score); // 1.0 - ツールの適切な使用
console.log(result.reason); // "エージェントはユーザーの天気に関する依頼に対応するため、weather-tool を正しく使用しました。"
不適切なツール使用の扱い
src/example-llm-inappropriate.ts
const inputMessages = [
createUIMessage({
content: 'What is the weather in Tokyo?',
role: 'user',
id: 'input-1'
})
];
const inappropriateOutput = [
createUIMessage({
content: 'Let me search for that information.',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-456',
toolName: 'search-tool', // 直接の天気照会には weather-tool の方が適切
args: { query: 'Tokyo weather' },
result: { results: ['Tokyo weather data...'] },
state: 'result'
})
]
})
];
const run = createAgentTestRun({ inputMessages, output: inappropriateOutput });
const result = await llmScorer.run(run);
console.log(result.score); // 0.5 - 部分的に適切
console.log(result.reason); // "エージェントは直接の天気問い合わせには weather-tool がより適切なところを、search-tool を使用しました。"
確認質問の評価
LLM スコアラーは、エージェントが適切に確認の質問を行った場合にそれを認識します:
src/example-llm-clarification.ts
const vagueInput = [
createUIMessage({
content: 'I need help with something',
role: 'user',
id: 'input-1'
})
];
const clarificationOutput = [
createUIMessage({
content: 'お手伝いできます。どのような点でお困りなのか、もう少し詳しく教えていただけますか?',
role: 'assistant',
id: 'output-1',
// ツールは呼び出さず、代わりに確認質問を行う
})
];
const run = createAgentTestRun({
inputMessages: vagueInput,
output: clarificationOutput
});
const result = await llmScorer.run(run);
console.log(result.score); // 1.0 - 確認質問を行うのが適切
console.log(result.reason); // "エージェントは情報が不十分なままツールを呼び出すのではなく、適切に確認質問を行いました。"
両スコアラーの比較
同じデータで両方のスコアラーを使う例です:
src/example-comparison.ts
import { createToolCallAccuracyScorerCode as createCodeScorer } from '@mastra/evals/scorers/code';
import { createToolCallAccuracyScorerLLM as createLLMScorer } from '@mastra/evals/scorers/llm';
import { openai } from '@ai-sdk/openai';
// 両方のスコアラーをセットアップ
const codeScorer = createCodeScorer({
expectedTool: 'weather-tool',
strictMode: false
});
const llmScorer = createLLMScorer({
model: openai('gpt-4o-mini'),
availableTools: [
{ name: 'weather-tool', description: 'Get weather information' },
{ name: 'search-tool', description: 'Search the web' }
]
});
// テストデータ
const run = createAgentTestRun({
inputMessages: [
createUIMessage({
content: 'What is the weather?',
role: 'user',
id: 'input-1'
})
],
output: [
createUIMessage({
content: 'その情報を探します。',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-1',
toolName: 'search-tool',
args: { query: 'weather' },
result: { results: ['weather data'] },
state: 'result'
})
]
})
]
});
// 両方のスコアラーを実行
const codeResult = await codeScorer.run(run);
const llmResult = await llmScorer.run(run);
console.log('Code Scorer:', codeResult.score); // 0 - ツールが不適切
console.log('LLM Scorer:', llmResult.score); // 0.3 - 一部適切
console.log('LLM Reason:', llmResult.reason); // search-tool が望ましくない理由の説明
設定項目
コードベースのスコアリングオプション
// 標準モード - 想定されたツールが呼び出されれば合格
const lenientScorer = createCodeScorer({
expectedTool: 'search-tool',
strictMode: false
});
// 厳格モード - ツールがちょうど1つだけ呼び出された場合に合格
const strictScorer = createCodeScorer({
expectedTool: 'search-tool',
strictMode: true
});
// 厳格モードでの順序チェック
const strictOrderScorer = createCodeScorer({
expectedTool: 'step1-tool',
expectedToolOrder: ['step1-tool', 'step2-tool', 'step3-tool'],
strictMode: true // 余分なツールは許可しない
});
LLM ベースのスコアラーのオプション
// 基本設定
const basicLLMScorer = createLLMScorer({
model: openai('gpt-4o-mini'),
availableTools: [
{ name: 'tool1', description: '説明 1' },
{ name: 'tool2', description: '説明 2' }
]
});
// 別のモデルを使用
const customModelScorer = createLLMScorer({
model: openai('gpt-4'), // より高度な評価向けの高性能モデル
availableTools: [...]
});
結果の理解について
コードベースのスコアラーの結果
{
runId: string,
preprocessStepResult: {
expectedTool: string,
actualTools: string[],
strictMode: boolean,
expectedToolOrder?: string[],
hasToolCalls: boolean,
correctToolCalled: boolean,
correctOrderCalled: boolean | null,
toolCallInfos: ToolCallInfo[]
},
score: number // 常に0または1
}
LLMベースのスコアラー結果
{
runId: string,
score: number, // 0.0 〜 1.0
reason: string, // 人間が読める説明
analyzeStepResult: {
evaluations: Array<{
toolCalled: string,
wasAppropriate: boolean,
reasoning: string
}>,
missingTools?: string[]
}
}
スコアラーの使い分けの目安
次の用途でコードベースのスコアラーを使用:
- ユニットテスト
- CI/CD パイプライン
- 回帰テスト
- ツールの厳密な適合要件
- ツールのシーケンス検証
LLMベースのスコアラーの主な用途
- 本番環境での評価
- 品質保証
- ユーザー意図との整合
- コンテキストを踏まえた評価
- 例外的ケースへの対応