Skip to main content

Agent Evals

Evaluations ("evals") measure how well your agent performs by assessing its execution trajectory, the sequence of messages and tool calls it produces. Unlike integration tests that verify basic correctness, evals score agent behavior against a reference or rubric, making them useful for catching regressions when you change prompts, tools, or models.

An evaluator is a function that takes agent outputs (and optionally reference outputs) and returns a score:

function evaluator({ outputs, referenceOutputs }: {
  outputs: Record<string, any>;
  referenceOutputs: Record<string, any>;
}) {
  const outputMessages = outputs.messages;
  const referenceMessages = referenceOutputs.messages;
  const score = compareMessages(outputMessages, referenceMessages);
  return { key: "evaluator_score", score: score };
}

The agentevals package provides prebuilt evaluators for agent trajectories. You can evaluate by performing a trajectory match (deterministic comparison) or by using an LLM judge (qualitative assessment):

ApproachWhen to use
Trajectory matchYou know the expected tool calls and want fast, deterministic, cost-free checks
LLM-as-judgeYou want to assess overall quality and reasoning without strict expectations

Install AgentEvals

npm install agentevals @langchain/core

Or, clone the AgentEvals repository directly.

Trajectory match evaluator

AgentEvals offers the createTrajectoryMatchEvaluator function to match your agent's trajectory against a reference. There are four modes:

ModeDescriptionUse case
strictExact match of message structure and tool calls in the same order (message content can differ)Testing specific sequences (e.g., policy lookup before authorization)
unorderedSame message structure and tool calls as reference, but tool calls can happen in any orderVerifying information retrieval when order doesn't matter
subsetAgent calls only tools from reference (no extras)Ensuring agent doesn't exceed expected scope
supersetAgent calls at least the reference tools (extras allowed)Verifying minimum required actions are taken

The examples below share a common setup, an agent with a get_weather tool:

import { createAgent } from "langchain";
import { tool } from "@langchain/core/tools";
import { HumanMessage, AIMessage, ToolMessage } from "@langchain/core/messages";
import { createTrajectoryMatchEvaluator } from "agentevals";
import * as z from "zod";

const getWeather = tool(
  async ({ city }) => {
    return `It's 75 degrees and sunny in ${city}.`;
  },
  {
    name: "get_weather",
    description: "Get weather information for a city.",
    schema: z.object({ city: z.string() }),
  }
);

const agent = createAgent({
  model: "claude-sonnet-4-6",
  tools: [getWeather],
});

Info

You can also set the toolArgsMatchMode property and/or toolArgsMatchOverrides to customize how the evaluator considers equality between tool calls in the actual trajectory vs. the reference. By default, only tool calls with the same arguments to the same tool are considered equal. Visit the repository for more details.

LLM-as-judge evaluator

You can use an LLM to evaluate the agent's execution path with the createTrajectoryLLMAsJudge function. Unlike trajectory match evaluators, it doesn't require a reference trajectory, but one can be provided if available.

Info

For more configurability over how the LLM evaluates the trajectory, visit the repository.

Run evals in LangSmith

For tracking experiments over time, log evaluator results to LangSmith. First, set the required environment variables:

export LANGSMITH_API_KEY="your_langsmith_api_key"
export LANGSMITH_TRACING="true"

LangSmith offers two main approaches for running evaluations: Vitest/Jest integration and the evaluate function.

Tip

To learn more about evaluating your agent, see the LangSmith docs.