Aller au contenu principal

Scorers de précision des appels d’outils

Mastra fournit deux scorers de précision des appels d’outils pour déterminer si un LLM sélectionne les bons outils parmi les options disponibles :

  1. Scorer basé sur le code — Évaluation déterministe fondée sur la correspondance exacte des outils
  2. Scorer basé sur un LLM — Évaluation sémantique qui utilise l’IA pour juger de la pertinence

Choisir entre les scorers
Lien direct vers Choisir entre les scorers

Quand utiliser le scorer basé sur le code
Lien direct vers Quand utiliser le scorer basé sur le code

  • Vous avez besoin de résultats déterministes et reproductibles
  • Vous souhaitez tester la correspondance exacte des outils
  • Vous devez valider des séquences d’outils précises
  • La vitesse et le coût sont prioritaires (aucun appel à un LLM)
  • Vous exécutez des tests automatisés

Quand utiliser le scorer basé sur un LLM
Lien direct vers Quand utiliser le scorer basé sur un LLM

  • Vous avez besoin d’une compréhension sémantique de la pertinence
  • La sélection des outils dépend du contexte et de l’intention
  • Vous souhaitez gérer des cas limites, comme les demandes de clarification
  • Vous avez besoin d’explications sur les décisions de notation
  • Vous évaluez le comportement d’un Agent en production

Scorer de précision des appels d’outils basé sur le code
Lien direct vers Scorer de précision des appels d’outils basé sur le code

La fonction createToolCallAccuracyScorerCode() du package @mastra/evals/scorers/prebuilt fournit une notation binaire déterministe fondée sur la correspondance exacte des outils. Elle prend en charge les modes d’évaluation strict et permissif, ainsi que la validation de l’ordre des appels d’outils.

Paramètres
Lien direct vers Paramètres

expectedTool:

string
Nom de l’outil qui doit être appelé pour la tâche donnée. Ignoré lorsque expectedToolOrder est fourni.

strictMode:

boolean
Contrôle le niveau de rigueur de l’évaluation. En mode outil unique, seuls les appels correspondant exactement à un seul outil sont acceptés. En mode de vérification de l’ordre, les outils doivent correspondre exactement et aucun outil supplémentaire n’est autorisé.

expectedToolOrder:

string[]
Tableau de noms d’outils dans l’ordre d’appel attendu. Lorsqu’il est fourni, active le mode de vérification de l’ordre et ignore le paramètre expectedTool.

Cette fonction renvoie une instance de la classe MastraScorer. Consultez la référence de MastraScorer pour en savoir plus sur la méthode .run() et ses entrées et sorties.

Modes d’évaluation
Lien direct vers Modes d’évaluation

Le scorer basé sur le code fonctionne selon deux modes distincts :

Mode outil unique
Lien direct vers Mode outil unique

Lorsque expectedToolOrder n’est pas fourni, le scorer évalue la sélection d’un seul outil :

  • Mode standard (strictMode: false) : renvoie 1 si l’outil attendu est appelé, quels que soient les autres outils
  • Mode strict (strictMode: true) : renvoie 1 uniquement si un seul outil est appelé et qu’il correspond à l’outil attendu

Mode de vérification de l’ordre
Lien direct vers Mode de vérification de l’ordre

Lorsque expectedToolOrder est fourni, le scorer valide la séquence d’appel des outils :

  • Ordre strict (strictMode: true) : les outils doivent être appelés exactement dans l’ordre indiqué, sans outil supplémentaire
  • Ordre flexible (strictMode: false) : les outils attendus doivent apparaître dans le bon ordre relatif (les outils supplémentaires sont autorisés)

Détails de la notation basée sur le code
Lien direct vers Détails de la notation basée sur le code

  • Scores binaires : renvoie toujours 0 ou 1
  • Déterministe : une même entrée produit toujours la même sortie
  • Rapide : aucun appel à une API externe

Options du scorer basé sur le code
Lien direct vers Options du scorer basé sur le code

// Standard mode - passes if expected tool is called
const lenientScorer = createCodeScorer({
expectedTool: 'search-tool',
strictMode: false,
})

// Strict mode - only passes if exactly one tool is called
const strictScorer = createCodeScorer({
expectedTool: 'search-tool',
strictMode: true,
})

// Order checking with strict mode
const strictOrderScorer = createCodeScorer({
expectedTool: 'step1-tool',
expectedToolOrder: ['step1-tool', 'step2-tool', 'step3-tool'],
strictMode: true, // no extra tools allowed
})

Résultats du scorer basé sur le code
Lien direct vers Résultats du scorer basé sur le code

{
runId: string,
preprocessStepResult: {
expectedTool: string,
actualTools: string[],
strictMode: boolean,
expectedToolOrder?: string[],
hasToolCalls: boolean,
correctToolCalled: boolean,
correctOrderCalled: boolean | null,
toolCallInfos: ToolCallInfo[]
},
score: number // Always 0 or 1
}

Exemples du scorer basé sur le code
Lien direct vers Exemples du scorer basé sur le code

Le scorer basé sur le code fournit une notation binaire déterministe (0 ou 1) fondée sur la correspondance exacte des outils.

Sélection du bon outil
Lien direct vers Sélection du bon outil

src/example-correct-tool.ts
const scorer = createToolCallAccuracyScorerCode({
expectedTool: 'weather-tool',
})

// Simulate LLM input and output with tool call
const inputMessages = [
createTestMessage({
content: 'What is the weather like in New York today?',
role: 'user',
id: 'input-1',
}),
]

const output = [
createTestMessage({
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

Évaluation en mode strict
Lien direct vers Évaluation en mode strict

Le test réussit uniquement si un seul outil est appelé :

src/example-strict-mode.ts
const strictScorer = createToolCallAccuracyScorerCode({
expectedTool: 'weather-tool',
strictMode: true,
})

// Multiple tools called - fails in strict mode
const output = [
createTestMessage({
content: 'Let me help you with that.',
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 - fails because multiple tools were called

Validation de l’ordre des outils
Lien direct vers Validation de l’ordre des outils

Vérifie que les outils sont appelés dans un ordre précis :

src/example-order-validation.ts
const orderScorer = createToolCallAccuracyScorerCode({
expectedTool: 'auth-tool', // ignored when order is specified
expectedToolOrder: ['auth-tool', 'fetch-tool'],
strictMode: true, // no extra tools allowed
})

const output = [
createTestMessage({
content: 'I will authenticate and fetch the data.',
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 - correct order

Mode d’ordre flexible
Lien direct vers Mode d’ordre flexible

Autorise des outils supplémentaires tant que les outils attendus conservent leur ordre relatif :

src/example-flexible-order.ts
const flexibleOrderScorer = createToolCallAccuracyScorerCode({
expectedTool: 'auth-tool',
expectedToolOrder: ['auth-tool', 'fetch-tool'],
strictMode: false, // allows extra tools
})

const output = [
createTestMessage({
content: 'Performing comprehensive operation.',
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', // Extra tool - OK in flexible mode
args: { message: 'Starting fetch' },
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 comes before fetch-tool

Scorer de précision des appels d’outils basé sur un LLM
Lien direct vers Scorer de précision des appels d’outils basé sur un LLM

La fonction createToolCallAccuracyScorerLLM() du package @mastra/evals/scorers/prebuilt utilise un LLM pour déterminer si les outils appelés par un Agent conviennent à la requête de l’utilisateur. Elle fournit ainsi une évaluation sémantique plutôt qu’une correspondance exacte.

Paramètres
Lien direct vers Paramètres

model:

MastraModelConfig
Modèle LLM à utiliser pour évaluer la pertinence des outils

availableTools:

Array<{name: string, description: string}>
Liste des outils disponibles et de leurs descriptions, utilisée comme contexte

Fonctionnalités
Lien direct vers Fonctionnalités

Le scorer basé sur un LLM fournit les fonctionnalités suivantes :

  • Évaluation sémantique : comprend le contexte et l’intention de l’utilisateur
  • Évaluation de la pertinence : distingue les outils « utiles » des outils « appropriés »
  • Gestion des clarifications : reconnaît les situations où les Agents demandent à juste titre des précisions
  • Détection des outils manquants : identifie les outils qui auraient dû être appelés
  • Génération d’un raisonnement : explique les décisions de notation

Processus d’évaluation
Lien direct vers Processus d’évaluation

  1. Extraction des appels d’outils : identifie les outils mentionnés dans la sortie de l’Agent
  2. Analyse de la pertinence : évalue chaque outil au regard de la requête de l’utilisateur
  3. Génération du score : calcule un score selon le rapport entre les appels d’outils pertinents et le nombre total d’appels
  4. Génération du raisonnement : fournit une explication lisible

Détails de la notation basée sur un LLM
Lien direct vers Détails de la notation basée sur un LLM

  • Scores fractionnaires : renvoie des valeurs comprises entre 0,0 et 1,0
  • Prise en compte du contexte : tient compte de l’intention de l’utilisateur et de la pertinence
  • Explicatif : fournit le raisonnement associé aux scores

Options du scorer basé sur un LLM
Lien direct vers Options du scorer basé sur un LLM

// Basic configuration
const basicLLMScorer = createLLMScorer({
model: 'openai/gpt-5.6-sol',
availableTools: [
{ name: 'tool1', description: 'Description 1' },
{ name: 'tool2', description: 'Description 2' }
]
});

// With different model
const customModelScorer = createLLMScorer({
model: 'openai/gpt-5', // More powerful model for complex evaluations
availableTools: [...]
});

Résultats du scorer basé sur un LLM
Lien direct vers Résultats du scorer basé sur un LLM

{
runId: string,
score: number, // 0.0 to 1.0
reason: string, // Human-readable explanation
analyzeStepResult: {
evaluations: Array<{
toolCalled: string,
wasAppropriate: boolean,
reasoning: string
}>,
missingTools?: string[]
}
}

Exemples du scorer basé sur un LLM
Lien direct vers Exemples du scorer basé sur un LLM

Le scorer basé sur un LLM utilise l’IA pour déterminer si les outils sélectionnés conviennent à la requête de l’utilisateur.

Évaluation LLM de base
Lien direct vers Évaluation LLM de base

src/example-llm-basic.ts
const llmScorer = createToolCallAccuracyScorerLLM({
model: 'openai/gpt-5.6-sol',
availableTools: [
{
name: 'weather-tool',
description: 'Get current weather information for any location',
},
{
name: 'calendar-tool',
description: 'Check calendar events and scheduling',
},
{
name: 'search-tool',
description: 'Search the web for general information',
},
],
})

const inputMessages = [
createTestMessage({
content: 'What is the weather like in San Francisco today?',
role: 'user',
id: 'input-1',
}),
]

const output = [
createTestMessage({
content: 'Let me check the current weather for you.',
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 - appropriate tool usage
console.log(result.reason) // "The agent correctly used the weather-tool to address the user's request for weather information."

Gestion de l’utilisation d’un outil inadapté
Lien direct vers Gestion de l’utilisation d’un outil inadapté

src/example-llm-inappropriate.ts
const inputMessages = [
createTestMessage({
content: 'What is the weather in Tokyo?',
role: 'user',
id: 'input-1',
}),
]

const inappropriateOutput = [
createTestMessage({
content: 'Let me search for that information.',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-456',
toolName: 'search-tool', // Less appropriate than 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 - partially appropriate
console.log(result.reason) // "The agent used search-tool when weather-tool would have been more appropriate for a direct weather query."

Évaluation des demandes de clarification
Lien direct vers Évaluation des demandes de clarification

Le scorer LLM reconnaît les situations où les Agents demandent à juste titre des précisions :

src/example-llm-clarification.ts
const vagueInput = [
createTestMessage({
content: 'I need help with something',
role: 'user',
id: 'input-1'
})
];

const clarificationOutput = [
createTestMessage({
content: 'I'd be happy to help! Could you please provide more details about what you need assistance with?',
role: 'assistant',
id: 'output-1',
// No tools called - asking for clarification instead
})
];

const run = createAgentTestRun({
inputMessages: vagueInput,
output: clarificationOutput
});
const result = await llmScorer.run(run);

console.log(result.score); // 1.0 - appropriate to ask for clarification
console.log(result.reason); // "The agent appropriately asked for clarification rather than calling tools with insufficient information."

Comparaison des deux scorers
Lien direct vers Comparaison des deux scorers

Voici un exemple qui applique les deux scorers aux mêmes données :

src/example-comparison.ts
import {
createToolCallAccuracyScorerCode as createCodeScorer,
createToolCallAccuracyScorerLLM as createLLMScorer,
} from '@mastra/evals/scorers/prebuilt'

// Setup both scorers
const codeScorer = createCodeScorer({
expectedTool: 'weather-tool',
strictMode: false,
})

const llmScorer = createLLMScorer({
model: 'openai/gpt-5.6-sol',
availableTools: [
{ name: 'weather-tool', description: 'Get weather information' },
{ name: 'search-tool', description: 'Search the web' },
],
})

// Test data
const run = createAgentTestRun({
inputMessages: [
createTestMessage({
content: 'What is the weather?',
role: 'user',
id: 'input-1',
}),
],
output: [
createTestMessage({
content: 'Let me find that information.',
role: 'assistant',
id: 'output-1',
toolInvocations: [
createToolInvocation({
toolCallId: 'call-1',
toolName: 'search-tool',
args: { query: 'weather' },
result: { results: ['weather data'] },
state: 'result',
}),
],
}),
],
})

// Run both scorers
const codeResult = await codeScorer.run(run)
const llmResult = await llmScorer.run(run)

console.log('Code Scorer:', codeResult.score) // 0 - wrong tool
console.log('LLM Scorer:', llmResult.score) // 0.3 - partially appropriate
console.log('LLM Reason:', llmResult.reason) // Explains why search-tool is less appropriate