The tools landscape
There are dozens of eval tools, and their marketing pages all sound the same. Underneath, they fall into five families that answer different questions. Once you see the families, and see that every tool is the same four boxes with different names, picking one becomes a short decision rather than a week of reading.
By the end of this module you can
- Place red-teaming scanners (garak, PyRIT), transcript analysis (Docent), shared eval collections (Inspect Evals) and third-party measurement (Artificial Analysis, OpenRouter) next to the core eval tools, and say what each can and cannot tell you.
- Sort any eval tool into one of five families and place it on a two-axis map (offline vs online, library vs hosted platform).
- Explain what each major tool (Inspect, promptfoo, DeepEval, Braintrust, LangSmith, Langfuse, Phoenix, Weave, Opik, MLflow, Ragas, TruLens, lm-eval-harness, HELM and the cloud services) is best at, and where it is weak.
- Read and write the same small eval in five different tools, and translate vocabulary between them.
- Choose a tool (or a stack of tools) for a given team, and argue the trade-offs on licensing, lock-in and data privacy.
Everything factual on this page was checked against official docs and repositories on 2026-09-29. Four changes you may not know about: OpenAI is shutting down its hosted Evals platform and graders (read-only from 2026-10-31, shut down 2026-11-30) and recommends promptfoo, which OpenAI acquired (announced 2026-03-09). Langfuse became part of ClickHouse (January 2026). Inspect is now co-developed by the UK AI Security Institute and the non-profit Meridian Labs. And Google renamed Vertex AI to Gemini Enterprise Agent Platform (April 2026). Where a detail could not be verified from a primary source, this page leaves it out rather than guess.
A mental model: five families of tools
Every tool in this module implements the pipeline from Module 01: a dataset of inputs, a system under test that produces outputs, a grader that scores them, and a metric that aggregates scores so you can compare runs. What differs is who the tool was built for and therefore which question it answers best. That gives five families.
In one sentence each:
- Research harnesses run standardized tasks against models, often in sandboxes, with a strong focus on reproducibility. Their user is a researcher comparing models, not a product team comparing prompts.
- Developer test and CI tools feel like a test runner. You write cases in a config file or as test functions, run a command, and get pass or fail. They plug into GitHub Actions or pytest.
- Observability plus eval platforms start from tracing: recording every model call, tool call and step of your live application as a tree of spans (a span is one timed unit of work, such as "call the search tool"; a trace is the whole tree for one request). They add datasets, experiments and LLM judges on top, usually with a web UI for the team.
- Metric and judge libraries give you scoring functions (faithfulness, factuality, helpfulness) and nothing else. You call them from whichever harness or platform you use.
- Cloud vendor services are evaluation features inside a model provider's or cloud's console, convenient if you are already committed to that vendor.
A research harness is a food-science lab: precise, reproducible, slow to set up. A developer test tool is the chef tasting every dish before it leaves the pass. An observability platform is the CCTV and the customer comment cards in the dining room. A metric library is the thermometer and the scales: you use them in all the other places. Cloud services are the kitchen that came pre-fitted with the building you rented.
The landscape map
Families are useful, but tools blur the edges. A second way to see the market is a map with two axes:
- Horizontal: offline and research ↔ online and production. Offline means you run a fixed dataset before release. Online means you score real traffic after release (see Module 15).
- Vertical: code-first library ↔ hosted platform. A library is something you
pip installand run on your own machine or CI. A hosted platform has a server, a database and a team UI (run by a vendor, or by you if it is self-hostable).
Read the map diagonally. The bottom-left is where frontier labs, safety institutes and academics live: free, code-first, reproducible, no production concept at all. The top-right is where product teams live once they have real users: hosted UIs, traces from production, judges running on sampled traffic. The bottom-middle is the developer's inner loop: a CLI or pytest in CI. The top-left is vendor consoles: easy, point-and-click, tied to one provider.
The most common beginner mistake is to compare tools from different regions as if they were rivals. "Inspect or Langfuse?" is like "microscope or security camera?". The right question is usually "which harness for offline evals and which platform for production traces?".
Tool by tool
Each card gives the maker, license, language, core abstractions (the nouns you will type), what it is best at, and how it handles agents, multimodal inputs and LLM judges (Module 13). Snippets are copied from each tool's official docs or README (trimmed where marked). If a feature is not listed, it is because it could not be verified from a primary source, not necessarily because it is missing.
Research harnesses
Inspect (inspect_ai)
Maker: UK AI Security Institute and Meridian Labs (a 501(c)(3) non-profit). License: MIT. Language: Python (log viewer in TypeScript/React). Used by the UK AISI, US CAISI, EU AI Office, and the Japanese and Korean AISIs.
- Core abstractions: a
Taskcombines aDataset(samples withinputandtarget), aSolver(anything from a singlegenerate()call to a full agent) and aScorer(text match, model grading, or custom). - Best at: rigorous, reproducible research and safety evals of models and agents. Ships with 200+ pre-built evals in
inspect_evals. - Agents and tools: the strongest here. Built-in
react()agent; custom and MCP tools; built-in bash, python, text editor, web search, web browsing and computer tools; sandboxes in Docker, Kubernetes, Modal, Proxmox and Vagrant. "Agent Bridge" plugs in external agent frameworks, and Inspect SWE runs Claude Code or Codex CLI as the agent under test. - Multimodal: image, audio and video inputs. Judge:
model_graded_qa()and other model-graded scorers. Viewing: Inspect View (web log viewer) and Inspect Scout for scanning transcripts.
from inspect_ai import Task, task
from inspect_ai.dataset import FieldSpec, hf_dataset
from inspect_ai.scorer import model_graded_qa
from inspect_ai.solver import generate
@task
def simpleqa():
return Task(
dataset=hf_dataset(
"codelion/SimpleQA-Verified",
split="train",
sample_fields=FieldSpec(input="problem", target="answer"),
),
solver=generate(), # swap for an agent, e.g. react() with tools
scorer=model_graded_qa(), # an LLM judge compares output to target
)
Inspect Evals (the inspect_evals collection)
Maker: the UK AI Security Institute with community contributors (repository UKGovernmentBEIS/inspect_evals). What it is: not a new tool but a library of ready-made evals written for Inspect: 200+ public benchmarks, from knowledge and reasoning sets such as GPQA to agentic and coding benchmarks such as SWE-bench, each packaged as an Inspect task you can run with one command.
- Why it matters: re-implementing a benchmark yourself is where many silent differences creep in (prompt wording, answer parsing, scorer details). Using a shared implementation makes your number comparable with other people who used the same one.
- The catch: a shared implementation is still an implementation. It may differ from the original paper's prompt or scorer. Report "GPQA Diamond as implemented by
inspect_evals, version X, 3 epochs", not just "GPQA" (Module 18).
pip install inspect-evals
# run a ready-made benchmark against any model Inspect supports
inspect eval inspect_evals/gpqa_diamond --model <provider/model> --epochs 3 --limit 50
inspect view # browse the logs
EleutherAI lm-evaluation-harness
Maker: EleutherAI. License: MIT. Language: Python, with tasks defined in YAML plus Jinja2 prompt templates.
- Best at: few-shot academic benchmarks on open-weight models (60+ benchmarks, hundreds of subtasks). It is the backend of the Hugging Face Open LLM Leaderboard. Backends include Hugging Face transformers, vLLM and API models.
- Agents: not a focus. Multimodal: prototype only (
hf-multimodal,vllm-vlm), with a pointer to thelmms-evalfork. - Recent: CLI subcommands (
lm-eval run,lm-eval ls,lm-eval validate) and a plugin system.
lm_eval --model hf \
--model_args pretrained=EleutherAI/gpt-j-6B \
--tasks hellaswag \
--device cuda:0 \
--batch_size 8
HELM (Stanford CRFM)
Maker: Stanford Center for Research on Foundation Models. License: Apache-2.0. Language: Python.
- Best at: "holistic, reproducible and transparent evaluation of foundation models": standardized scenarios, metrics beyond accuracy, and public leaderboards (HELM Capabilities, HELM Safety, VHELM for vision-language, and domain boards).
- Multimodal: yes, via VHELM. Agents: not its focus.
helm-run --run-entries mmlu:subject=philosophy,model=openai/gpt2 --suite my-suite --max-eval-instances 10
helm-summarize --suite my-suite
helm-server --suite my-suite # browse results at http://localhost:8000/
Harbor (Terminal-Bench harness)
Maker: the creators of Terminal-Bench (Laude Institute). License: Apache-2.0.
- Best at: containerised end-to-end agent evals where the agent under test is a full CLI agent (Claude Code, OpenHands, Codex CLI and more) and grading is by outcome tests inside the container. Official harness for Terminal-Bench 2.0; runs in parallel on cloud sandboxes (Daytona, Modal and others) and can generate RL rollouts. Anthropic's agent-eval post cites it.
export ANTHROPIC_API_KEY=<YOUR-KEY>
harbor run --dataset terminal-bench@2.0 \
--agent claude-code \
--model anthropic/claude-opus-5-5 \
--n-concurrent 4
Smaller and legacy research tools
- Lighteval (Hugging Face, MIT): 1000+ tasks;
inspect-aiis its preferred backend. Example:lighteval eval "hf-inference-providers/openai/gpt-oss-20b" gpqa:diamond. - OpenBench (Groq, MIT): 95+ benchmarks built on
inspect-ai. Example:bench eval mmlu --model groq/openai/gpt-oss-120b --limit 10. - Petri and Bloom (both started at Anthropic, both MIT, now developed by Meridian Labs): Petri is an automated auditing agent (auditor, target, judge) for alignment behaviors; Bloom auto-generates behavioral evals for one target behavior in four stages (Understanding, Ideation, Rollout, Judgment). See Module 17.
- OpenAI simple-evals (MIT): reference implementations of MMLU, GPQA, MATH, HumanEval, SimpleQA, BrowseComp, HealthBench and others. "As of July 2025, simple-evals will no longer be updated for new models or benchmark results"; HealthBench, BrowseComp and SimpleQA are still maintained as reference code.
- OpenAI Evals repo (
openai/evals, MIT): a registry of evals defined in YAML plus JSONL data; not accepting evals with custom code. Treat it as a historical reference.
Developer test and CI tools
promptfoo
Maker: Promptfoo, now part of OpenAI (acquisition announced 2026-03-09): "Promptfoo remains open source and MIT licensed." License: MIT. Language: TypeScript/Node CLI; you write config in YAML.
- Core abstractions:
prompts×providers(models) ×tests(each withvarsandassert). Assertion types includeequals,contains,contains-json,javascript,similarandllm-rubric. - Best at: declarative regression matrices (every prompt against every model against every test) and red teaming (automated vulnerability scanning). OpenAI's recommended replacement for its Evals platform.
- Judge: the
llm-rubricassertion. CI: the GitHub Actionpromptfoo/promptfoo-action@v1posts eval diffs on pull requests. Agents: agent and RAG testing are listed features.
prompts:
- file://prompt1.txt
- file://prompt2.txt
providers:
- openai:gpt-6-luna
- id: vertex:gemini-3.5-flash
config:
region: global
tests:
- vars:
language: French
input: Hello world
assert:
- type: llm-rubric
value: does not describe self as an AI, model, or chatbot
DeepEval (Confident AI)
Maker: Confident AI. License: Apache-2.0. Language: Python. Optional hosted platform (Confident AI, commercial).
- Core abstractions:
LLMTestCase(input, actual output, expected output, context), metrics such asGEval, andassert_test(), run by pytest ordeepeval test run. - Best at: "unit tests for LLMs": pytest-style assertions with a large catalog of metrics.
- Agents: metrics TaskCompletion, ToolCorrectness, GoalAccuracy, StepEfficiency, PlanAdherence; trajectory evaluation via
@observe()tracing. Multimodal: multimodal metrics (for example image generation and editing quality). Judge: G-Eval, and most metrics are judge-based.
from deepeval import assert_test
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCase, SingleTurnParams # older docs: LLMTestCaseParams
def test_case():
correctness = GEval(
name="Correctness",
criteria="Determine if the 'actual output' is correct based on the 'expected output'.",
evaluation_params=[SingleTurnParams.ACTUAL_OUTPUT, SingleTurnParams.EXPECTED_OUTPUT],
threshold=0.5,
)
tc = LLMTestCase(input="What if these shoes don't fit?",
actual_output="You have 30 days to get a full refund at no extra cost.",
expected_output="We offer a 30-day full refund at no extra costs.")
assert_test(tc, [correctness])
Pydantic Evals and Google ADK eval
- Pydantic Evals (Pydantic): code-first
Case,Dataset,EvaluatorandLLMJudge, with span-based evaluation of agent internals over OpenTelemetry and a Logfire UI. - Google ADK eval: for agents built with Google's Agent Development Kit.
.test.jsonunit files and.evalset.jsonmulti-turn sets; criteria such astool_trajectory_avg_score(exact tool-call sequence match),response_match_score(ROUGE-1),final_response_match_v2(LLM-judged),hallucinations_v1andmulti_turn_task_success_v1; run withadk evalor pytest'sAgentEvaluator. More in Module 06.
from pydantic_evals import Case, Dataset
dataset = Dataset(name='capital_quiz', cases=[Case(name='simple_case',
inputs='What is the capital of France?', expected_output='Paris')])
async def guess_city(question: str) -> str:
return 'Paris'
dataset.evaluate_sync(guess_city).print()
Giskard and Strands Evals
- Giskard (Giskard AI, a French company): an open-source Python testing library (the repository is now
Giskard-AI/giskard-oss, described as an evaluation and testing library for LLM agents) plus a commercial hub. It is best known for two things. The scan automatically probes an LLM app for weaknesses such as prompt injection, harmful content, sensitive-information disclosure, hallucination and lack of robustness, then turns what it finds into a reusable test suite. RAGET generates a question-and-answer test set from your own knowledge base to evaluate a RAG pipeline (Module 06). The library has been reorganized more than once, so copy code from its current docs rather than from older blog posts. - Strands Evals: AWS's open-source Strands Agents SDK has a companion evaluation package for agents built with it, with checks on the final output and on the agent's trajectory (the sequence of tool calls), including LLM-judged ones. It is young, its API is still moving, and its details could not be re-checked against a primary source for this page; if you build on Strands, start from the evaluation section of the Strands documentation. If you do not, it is one more example of the pattern this module keeps showing: every agent framework now ships its own eval harness, and all of them share the dataset, task, scorer shape.
Observability plus eval platforms
Braintrust
Maker: Braintrust (commercial SaaS). Its scorer library autoevals is MIT-licensed, in Python and TypeScript. No open-source platform repository was found.
- Core abstractions:
Eval(name, data, task, scores); Experiments ("a permanent record of how your task performed on the dataset"), Datasets, Scorers;braintrust.auto_instrument()for tracing; online scoring of production logs; "Loop", an in-UI assistant. - Best at: a tight eval → experiment → compare loop plus production logging in one UI, with Python and TypeScript parity.
- Judge: autoevals LLM-as-judge scorers (Factuality, ClosedQA, Battle, Summarization, SQL, Translation and more) plus RAG, embedding and heuristic scorers. CI: run evals in GitHub Actions to catch regressions.
from braintrust import Eval
from autoevals import ExactMatch
Eval(
"Evaluation quickstart",
experiment_name="Movie matcher (Python)",
data=[{"input": "A detective investigates a series of murders based on the seven deadly sins.",
"expected": "Se7en"}],
task=task, # def task(input): -> str (calls the model)
scores=[ExactMatch],
)
LangSmith
Maker: LangChain. License: SDK MIT (Python and JS/TS); the hosted platform is commercial.
- Core abstractions: Dataset, Target function, Evaluators, Experiments. LLM judges via the
openevalspackage (create_llm_as_judge). Tracing is the core product (for examplewrappers.wrap_openai). - Best at: teams on LangChain or LangGraph who want tracing, datasets, experiments and annotation in one place; it also works without LangChain via wrappers.
- CI: pytest (Python) and jest/vitest (JS) integrations.
from langsmith import Client
from openevals.llm import create_llm_as_judge
from openevals.prompts import CORRECTNESS_PROMPT
def correctness_evaluator(inputs, outputs, reference_outputs):
judge = create_llm_as_judge(prompt=CORRECTNESS_PROMPT, model="openai:o3-mini",
feedback_key="correctness")
return judge(inputs=inputs, outputs=outputs, reference_outputs=reference_outputs)
Client().evaluate(target, data="Sample dataset", evaluators=[correctness_evaluator],
experiment_prefix="first-eval-in-langsmith", max_concurrency=2)
Langfuse
Maker: Langfuse, "now part of ClickHouse" (January 2026). License: "MIT licensed, except for the ee folders" (an open-core model: the core is open source, some enterprise features are not). Self-host via Docker Compose, Helm or Terraform, or use the cloud.
- Core abstractions: traces and observations, Datasets, Experiments (
run_experiment(data, task, evaluators)), Scores /Evaluation, prompt management. - Best at: open-source, self-hostable observability plus evals, for example when data must stay in your region. Anthropic's agent-eval post mentions it as a self-hosted alternative.
- Judge: LLM-as-judge, code evaluators, user feedback and manual labeling. Tracing: OpenTelemetry, LangChain, OpenAI SDK and LiteLLM integrations.
from langfuse import get_client, Evaluation
langfuse = get_client()
def accuracy_evaluator(*, input, output, expected_output, metadata, **kwargs):
ok = expected_output and expected_output.lower() in output.lower()
return Evaluation(name="accuracy", value=1.0 if ok else 0.0)
result = langfuse.run_experiment(name="Geography Quiz", data=local_data,
task=my_task, evaluators=[accuracy_evaluator])
print(result.format())
Arize Phoenix
Maker: Arize AI. License: Elastic License 2.0 (ELv2), which is source-available, not OSI open source: you can read, run and self-host the code, but the license restricts offering it as a managed service. arize-phoenix-evals is also ELv2. Language: Python and TypeScript.
- Core abstractions: OpenTelemetry / OpenInference traces, evaluators (LLM classifiers), datasets and experiments, prompt management, a playground.
- Agents: integrations include the Claude Agent SDK, OpenAI Agents, LangGraph and CrewAI; a remote MCP server lets coding agents query your traces.
- Judge:
create_classifierwith anLLM.
from phoenix.evals import create_classifier
from phoenix.evals.llm import LLM
llm = LLM(provider="openai", model="gpt-4o")
evaluator = create_classifier(
name="helpfulness",
prompt_template="Rate the response to the user query as helpful or not:\n\nQuery: {input}\nResponse: {output}",
llm=llm,
choices={"helpful": 1.0, "not_helpful": 0.0},
)
scores = evaluator.evaluate({"input": "How do I reset?", "output": "Go to settings > reset."})
W&B Weave
Maker: Weights & Biases. License: Apache-2.0. SDKs: Python and TypeScript.
- Core abstractions:
@weave.op(a traced function: inputs and outputs are captured automatically),Model,Evaluation(dataset, scorers),evaluation.evaluate(model), andEvaluationLoggerfor logging evals imperatively from your own loop. - Best at: teams already using W&B for ML experiments who want LLM traces and evals in the same place.
import weave, asyncio
from weave import Evaluation, Model
weave.init('intro-example')
@weave.op()
def match_score1(expected: str, output: dict) -> dict:
return {'match': expected == output['generated_text']}
class MyModel(Model):
prompt: str
@weave.op()
def predict(self, question: str):
return {'generated_text': 'Hello, ' + question + self.prompt}
evaluation = Evaluation(dataset=examples, scorers=[match_score1])
asyncio.run(evaluation.evaluate(MyModel(prompt='World')))
Opik (Comet)
Maker: Comet. License: Apache-2.0, full platform self-hostable. SDKs: Python, TypeScript (Ruby via OpenTelemetry).
- Features: tracing for multi-step agents, LLM-as-judge metrics (Hallucination, Moderation, AnswerRelevance, ContextPrecision), datasets and experiments, an Agent Optimizer SDK, guardrails, and "a PyTest integration to test LLM pipelines on every commit".
from opik import track
@track # traces this function
def my_function(input: str) -> str:
return input
# the evaluate() call as shown in Opik's docs:
evaluation = evaluate(dataset=dataset, task=evaluation_task, scoring_metrics=[Hallucination()])
MLflow GenAI evaluation (MLflow 3)
Maker: open-source project originally from Databricks. License: Apache-2.0. Python plus TS/JS and Java SDKs; self-host, or managed on Databricks, SageMaker or Azure ML.
- Core abstractions:
mlflow.genai.evaluate(data, predict_fn, scorers); data rows withinputsandexpectations; built-in LLM judges (Correctness,Guidelines) and custom@scorerfunctions. OpenTelemetry-based tracing, 50+ built-in metrics, prompt registry, AI gateway. - Agents: evaluation of "LLM applications and AI agents", plus production monitoring and human feedback.
import mlflow
from mlflow.genai import scorer
from mlflow.genai.scorers import Correctness, Guidelines
@scorer
def is_concise(outputs: str) -> bool:
return len(outputs.split()) <= 5
eval_dataset = [{"inputs": {"question": "What is the capital of France?"},
"expectations": {"expected_response": "Paris"}}]
results = mlflow.genai.evaluate(
data=eval_dataset,
predict_fn=qa_predict_fn, # def qa_predict_fn(question: str) -> str
scorers=[Correctness(), Guidelines(name="is_english", guidelines="The answer must be in English"), is_concise],
)
Galileo
Maker: Galileo (commercial SaaS, with enterprise deployment options). What it is: an evaluation and observability platform for LLM apps and agents: tracing, experiments, metrics dashboards and real-time checks on production traffic.
- Distinctive idea: Luna, which Galileo calls "evaluation foundation models": small models trained to act as evaluators, pitched as a cheaper and faster alternative to running a large LLM judge on every trace, and fast enough to use as an inline guardrail (Module 15 explains why that latency matters).
- Agents: Galileo has marketed an agent reliability offering (including a free tier announced in 2025) aimed at tracing and scoring multi-step agents.
- How to judge it: like any vendor judge, a Luna score is someone else's grader. Before you gate on it, measure its agreement with your own human labels on your own traces (Module 13). Its SDK syntax could not be verified from a primary source for this page, so no snippet is shown.
Metric and judge libraries
Ragas
Maker: VibrantLabs (formerly Exploding Gradients; the repo is still explodinggradients/ragas). License: Apache-2.0. Language: Python.
- Core abstractions: metrics (LLM-based and traditional, for example
DiscreteMetric),SingleTurnSample,EvaluationDataset, experiments, and test-set generation. - Best at: RAG metrics (faithfulness, context precision and recall; see Module 06) and generating synthetic test sets.
from openai import AsyncOpenAI
from ragas.metrics import DiscreteMetric
from ragas.llms import llm_factory
llm = llm_factory("gpt-4o", client=AsyncOpenAI())
metric = DiscreteMetric(
name="summary_accuracy",
allowed_values=["accurate", "inaccurate"],
prompt="Evaluate if the summary is accurate and captures key information.\nResponse: {response}\nAnswer with only 'accurate' or 'inaccurate'.",
)
score = await metric.ascore(llm=llm, response="The summary of the text is...")
print(score.value, score.reason)
TruLens
Maker: TruEra, now part of Snowflake. License: MIT. Language: Python.
- Core abstractions:
TruSession, feedback functions /Metric(judges backed by a model provider), aTruAppwrapper,@instrumentspan types, and a leaderboard. Known for the RAG Triad: groundedness, context relevance, answer relevance. - Agents: evaluators LogicalConsistency, ExecutionEfficiency, PlanAdherence, PlanQuality, ToolSelection, ToolCalling, ToolQuality; MCP tool calls are captured as spans. Tracing: OpenTelemetry-native, exportable to Jaeger, Grafana Tempo or Datadog.
from trulens.core import TruSession, Metric
from trulens.providers.openai import OpenAI
from trulens.apps.app import TruApp
session = TruSession()
provider = OpenAI(model_engine="gpt-4-turbo")
f_groundedness = Metric(
implementation=provider.groundedness_measure_with_cot_reasons_consider_answerability,
name="Groundedness")
tru_rag = TruApp(rag, app_name="RAG", feedbacks=[f_groundedness])
with tru_rag as recording:
rag.query("What is ...?")
session.get_leaderboard()
Other scorer packages and judge models
- autoevals (Braintrust, MIT), openevals (LangChain) and arize-phoenix-evals (ELv2) are standalone scorer libraries you can call from any harness, not only their parent platform.
- Patronus AI (commercial) sells judge models rather than a harness: Glider ("3B evaluator LLM that can score any text input on user-defined criteria"), Lynx (hallucination detection), and Percival ("evaluation copilot for agentic systems built to detect 20+ failure modes in agentic traces"), plus experiments, logging and multimodal (image-to-text) judging. Its SDK syntax could not be verified, so no snippet is shown.
Cloud vendor services
OpenAI Evals API and graders (being shut down)
Status: "OpenAI is deprecating the Evals platform... Evals will become read-only for existing users on October 31, 2026, and the platform is scheduled to shut down on November 30, 2026." Graders are being deprecated too. Announced 2026-06-03, with an official migration guide to promptfoo.
- Core abstractions (still worth learning, because they are clean): an Eval holds a
data_source_config(a JSON-schemaitem_schemadescribing each row) andtesting_criteria(a list of graders). A Run executes that eval against data plus a model and prompt. Templates reference{{ item.* }}(the dataset row) and{{ sample.output_text }}(the model's output). - Grader types:
string_check,text_similarity(fuzzy match, BLEU, ROUGE…),score_model,label_model,python,multi. The same graders were used for reinforcement fine-tuning.
eval_obj = client.evals.create(
name="IT Ticket Categorization",
data_source_config={"type": "custom", "item_schema": {...}, "include_sample_schema": True},
testing_criteria=[{
"type": "string_check", "name": "Match output to human label",
"input": "{{ sample.output_text }}", "operation": "eq",
"reference": "{{ item.correct_label }}",
}],
)
Agent evals and trace grading. OpenAI's docs also describe evaluating whole agent workflows, not just single responses. Trace grading attaches graders to the trace of an agent run (the record of model calls, tool calls, handoffs and guardrail checks that the Agents SDK captures), so you can score where in a workflow things went wrong, not only whether the final answer was right. The AgentKit launch (October 2025) bundled Agent Builder, a visual workflow editor, with eval features such as datasets, trace grading and automated prompt optimization. These sit on the same hosted evals and graders stack whose deprecation is described above, so check their status on OpenAI's deprecations page before building on them. The idea outlives the product: grade the trajectory, not just the answer (Module 05). Module 16 covers OpenAI's agent-eval approach in depth.
Google, Microsoft and Anthropic
- Google Gen AI evaluation service (in Gemini Enterprise Agent Platform, formerly Vertex AI): two paths, the GenAI Client in the Agent Platform SDK (
client.evals) and the olderEvalTaskmodule. Metric types: rubric-based (managed and adaptive rubrics), computation-based, and custom functions; judge model configuration; AutoSxS pairwise comparison; dedicated agent-evaluation docs. - Microsoft Foundry evaluation: the
azure-ai-evaluationSDK with quality, RAG, safety and agent evaluators (tool call accuracy, task completion) and OpenTelemetry tracing. - Anthropic Console Evaluate tool (announced 2024-07-09): generate prompts and test cases, run them, compare prompt versions side by side, and let subject-matter experts grade on a 5-point scale. Its current feature set could not be re-verified in 2026. Anthropic's bigger contribution to tooling is guidance (the "Demystifying evals for AI agents" post and the "develop tests" docs) and the open-source Petri and Bloom.
# Google GenAI Client (from the python-aiplatform README; model id may be dated)
inference_results = client.evals.run_inference(model="gemini-2.5-flash-preview-05-20", src=prompts_df)
eval_result = client.evals.evaluate(
dataset=inference_results,
metrics=[types.Metric(name='exact_match'), types.Metric(name='rouge_l_sum'), types.RubricMetric.TEXT_QUALITY],
)
Beyond the five families: red teaming, transcripts, public numbers
Three more kinds of tool sit next to the five families. They are not rivals to your harness or platform; each answers a question the others do not. Red-teaming scanners ask "how can this be broken?". Transcript analysis tools ask "what is actually happening across thousands of runs?". Third-party measurement asks "what do independent runs say about models I have not tested yet?". The map at the end of this section places them next to the tools you already know.
Red-teaming scanners
The tools above mostly run datasets you wrote. Red-teaming scanners bring the dataset with them: large, curated families of attacks (jailbreaks, prompt injection, encoding tricks, data-leak bait), a way to send them to your model or app, and a detector that decides whether each attack got through. Think of them as an eval tool with an adversarial test generator built in. The concepts behind them (attack success rate, injection, jailbreak robustness) are in Module 17 and Module 25; here is how the two best-known open-source scanners are built.
garak
Maker: NVIDIA (open source; repository NVIDIA/garak, tagline "the LLM vulnerability scanner"). Language: Python CLI.
- Core abstractions: probes (families of attack prompts: jailbreaks, prompt injection, encoding tricks, data leakage, toxicity, malware generation and more), generators (connectors to the model or app under test), detectors (decide whether a response shows the failure), and a report with the failure rate per probe. Its README compares it to network tools such as nmap and Metasploit, but for LLMs.
- Best at: a broad, repeatable sweep of known weaknesses before launch and after every model swap.
python -m pip install -U garak
export OPENAI_API_KEY="..."
# run the encoding-based prompt-injection probes against one hosted model
python -m garak --model_type openai --model_name gpt-4o-mini --probes encoding
# flag names change between releases (newer ones also accept --target_type and
# --target_name); check `python -m garak --help` for your installed version
PyRIT
Maker: Microsoft (its AI Red Team). "The Python Risk Identification Tool for generative AI", open source (repository microsoft/PyRIT). Language: Python library, usually driven from notebooks.
- Core abstractions: targets (the model, app or endpoint), converters (transform a prompt: encodings, translation, rephrasing, and other modalities), scorers (LLM judges or classifiers that decide whether an attack succeeded), memory (every exchange stored for later analysis), and orchestrators or attack strategies that run single-turn batches or multi-turn attacks such as Crescendo, where an attacker model escalates step by step. Recent releases have reorganized these names, so follow the current docs.
- Best at: helping a human red team scale up: automating the boring parts, composing attacks, and keeping a searchable record. Multi-turn attacks matter for agents, which are usually broken over several turns, not one.
Attack success rates from different scanners are not comparable: they use different attack sets, different detectors and different definitions of "success". Use a scanner as a discovery tool. The failures it finds become cases in your own regression suite (run by Inspect, promptfoo or DeepEval), graded by a detector you have checked against human labels. promptfoo's red-team mode and Giskard's scan, covered above, play the same role inside tools you may already use.
Transcript analysis
Once agent evals produce thousands of long transcripts, reading them all is impossible and reading ten at random misses rare problems. A new kind of tool helps a human search and summarize transcripts at scale. This is error analysis (Module 12) with power tools.
Docent (Transluce)
Maker: Transluce, a non-profit AI research lab. What it is: a tool for analyzing large collections of agent transcripts, as described on its site: you load the runs from an eval, then ask questions in plain language ("find runs where the agent edited the tests", "which runs gave up after a tool error?"), cluster similar behaviors, and jump to the exact moments that match.
- Best at: finding what the score hides: broken tasks, environment bugs, reward hacking, agents that found an answer key, or a failure mode that only appears in 2% of runs. These are exactly the problems that make a benchmark number lie (Module 18).
- How it fits: it complements your eval harness rather than replacing it. Inspect Scout (in the Inspect card above) and Patronus Percival (judge libraries, above) aim at related problems. Whatever the tool, an LLM that searches transcripts can miss or invent matches, so open and read the transcripts it points you to before you believe a pattern.
Third-party measurement
Finally, some sources are not tools you run at all: they are organizations that run evals and publish the numbers. They are useful for a shortlist and dangerous as a final answer.
Artificial Analysis
An independent company that runs its own evaluations of models and of the API endpoints that serve them. It publishes a composite Intelligence Index (built from about ten evals across agentic tasks, coding, scientific reasoning and general knowledge, with weights and versions documented on its methodology page), and it measures output speed, latency and price per provider. Good for "which three models should I test?". Remember that a composite index reflects its authors' choice of evals and weights, that the index version changes over time, and that its harness is not yours.
OpenRouter
An API router: one endpoint and one bill for many models from many providers. Its public rankings show which models and apps consume the most tokens through OpenRouter. That is a usage signal (popularity, price-performance as judged by real buyers), not a quality score, and it covers only OpenRouter's own traffic. A second lesson it makes visible: the same open-weights model can be served by several providers, and endpoints can differ (for example in quantization, context limits or tool-call handling), so evaluate the exact endpoint you will use.
What changed recently
Tool choice is partly a bet on who will still maintain the tool in two years. The last two years saw acquisitions, handovers and one shutdown.
The comparison matrix
Legend: Y first-class, P partial or via integration, – not a focus, ? not verified from a primary source (treat as unknown, not as "no"). Sources are the per-tool cards above and the list at the end.
| Tool | License | Lang | Primary use | Agents / tools | Multimodal | LLM judge | Tracing | CI hook | UI |
|---|---|---|---|---|---|---|---|---|---|
| Inspect | MIT | Py | Research and safety evals of models and agents | Y react, sandboxes, MCP, bridge | Y | Y | Log viewer + Scout | CLI | Local viewer |
| lm-eval-harness | MIT | Py | Few-shot academic benchmarks | – | P prototype | – | – | CLI | – |
| HELM | Apache-2.0 | Py | Holistic standardized leaderboards | – | Y VHELM | ? | – | CLI | Static leaderboard |
| Harbor | Apache-2.0 | ? | Containerised CLI-agent benchmarks | Y | – | ? | – | CLI | – |
| simple-evals | MIT | Py | Reference benchmark code (frozen) | P BrowseComp | – | ? | – | – | – |
| promptfoo | MIT (OpenAI-owned) | TS / YAML | Regression matrices + red teaming | P | ? | Y llm-rubric | ? | Y GH Action | Local viewer |
| DeepEval | Apache-2.0 | Py | Pytest-style metric tests | Y ToolCorrectness etc. | Y | Y G-Eval | Y @observe | Y pytest | Confident AI SaaS |
| Braintrust | Closed; autoevals MIT | Py / TS | Experiments + production logging | P | ? | Y autoevals | Y | Y GH Actions | SaaS |
| LangSmith | SDK MIT; platform closed | Py / TS | Tracing + datasets + experiments | P | ? | Y openevals | Y | Y pytest, vitest, jest | SaaS |
| Langfuse | MIT except ee | Py / TS | OSS observability + evals | P | ? | Y | Y OTel | ? | Self-host or cloud |
| Arize Phoenix | ELv2 (source-available) | Py / TS | OTel tracing + evals | Y integrations | ? | Y | Y OpenInference | ? | Self-host |
| W&B Weave | Apache-2.0 | Py / TS | Tracing + Evaluation objects | P | ? | ? | Y @weave.op | ? | SaaS |
| Opik | Apache-2.0 | Py / TS | OSS tracing + evals + optimizer | P | ? | Y | Y | Y pytest | Self-host or cloud |
| MLflow GenAI | Apache-2.0 | Py (+TS, Java) | Eval + tracing + monitoring | Y | ? | Y built-in judges | Y OTel | ? | Self-host or managed |
| Ragas | Apache-2.0 | Py | RAG metrics, test-set generation | ? | ? | Y | – | ? | – |
| TruLens | MIT | Py | RAG triad + agent evaluators | Y | ? | Y | Y OTel | ? | Local dashboard |
| Patronus AI | Closed | ? | Judge models, agent trace debugging | Y Percival | Y image-to-text | Y | Y | ? | SaaS |
| OpenAI Evals API | Closed, ends 2026-11-30 | API | Hosted evals + RFT graders | P | ? | Y score / label model | – | API | Dashboard |
| Google Gen AI eval / ADK | Closed service | Py | Rubric + agent trajectory evals | Y trajectory metrics | ? | Y rubrics | ? | Y pytest AgentEvaluator | Cloud console |
| Inspect Evals | Open source | Py | 200+ ready-made benchmark implementations for Inspect | Y agentic benchmarks | ? | P via Inspect scorers | Inspect logs | CLI | Inspect View |
| Giskard | Open-source library; hub commercial | Py | Vulnerability scan, RAG test-set generation | P | ? | Y | ? | ? | Hub |
| Strands Evals | Open source | Py | Evals for agents built on Strands | Y trajectory checks | ? | ? | ? | ? | ? |
| Galileo | Closed | ? | Observability + evals, Luna evaluator models | P | ? | Y Luna | Y | ? | SaaS |
| garak | Open source (NVIDIA) | Py | LLM vulnerability scanning | ? | ? | P detectors | – | CLI | Report files |
| PyRIT | Open source (Microsoft) | Py | Red-team orchestration, multi-turn attacks | Y multi-turn | P converters | Y scorers | Memory store | ? | Notebooks |
| Docent | ? | ? | Searching and clustering agent transcripts | Y transcripts | ? | P LLM-powered search | Ingests runs | – | Web UI |
| Anthropic Console | Closed | UI | Test-case generation + side-by-side | – | ? | Human 5-point grading | – | – | Console |
A question mark means the feature was not confirmed on the tool's own docs or README when this page was written. Several of these tools very likely do support multimodal inputs or CI in some form. Before you rule a tool in or out on one of those cells, check its current docs yourself: vendors ship monthly.
Same eval, five tools
The fastest way to understand a tool is to write the same tiny eval in it. Here is the spec, in plain English:
- Dataset: two questions, "What is the capital of France?" (expected: Paris) and "What is the capital of Australia?" (expected: Canberra). Australia is a classic trap: models sometimes say Sydney.
- System under test: a model answering the question.
- Grader: an LLM judge that decides whether the answer is correct compared with the expected answer (a model-graded rubric, see Module 13). Where cheap, also a code check that the expected word appears.
- Metric: fraction of samples passing.
1. Inspect
A Python function decorated with @task returns a Task. The dataset can be a plain list of Sample objects. model_graded_qa() asks a judge model whether the output answers the question correctly given the target.
from inspect_ai import Task, task
from inspect_ai.dataset import Sample
from inspect_ai.scorer import model_graded_qa
from inspect_ai.solver import generate
@task
def capitals():
return Task(
dataset=[
Sample(input="What is the capital of France?", target="Paris"),
Sample(input="What is the capital of Australia?", target="Canberra"),
],
solver=generate(), # the system under test: one model call
scorer=model_graded_qa(), # LLM judge: is the answer correct vs target?
)
# Run from a shell (the model is chosen at run time, not in the file):
# inspect eval capitals.py --model openai/gpt-4o
# then open the log in Inspect View: inspect view
Notice what is not in the file: the model. Inspect treats the model as a run-time parameter, because its users mostly compare many models on the same task. To turn this into an agent eval you would change one line, the solver, to an agent such as react() with tools and a sandbox.
2. promptfoo
No code at all. The YAML file declares prompts, providers (models) and tests. Every test is run against every prompt × provider combination.
# promptfooconfig.yaml
prompts:
- "Answer in one short sentence: {{question}}"
providers:
- openai:gpt-4o
tests:
- vars:
question: What is the capital of France?
assert:
- type: contains # cheap code check first
value: Paris
- type: llm-rubric # LLM judge with a plain-English rubric
value: Correctly states that Paris is the capital of France, with no false claims
- vars:
question: What is the capital of Australia?
assert:
- type: contains
value: Canberra
- type: llm-rubric
value: Correctly states Canberra, and does not claim Sydney is the capital
# Run: npx promptfoo eval (then: npx promptfoo view)
The grid is the point: add a second prompt and a second provider and you get a 2 × 2 × 2 comparison for free. This is why promptfoo is popular for "which model should we switch to?" questions and for CI diffs on pull requests.
3. DeepEval
Each sample becomes a pytest test. The judge is a GEval metric (G-Eval: the judge writes evaluation steps from your criteria, then scores). A test fails when the score is below threshold.
# test_capitals.py
import pytest
from deepeval import assert_test
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCase, SingleTurnParams
from my_app import answer # your system under test: str -> str
correctness = GEval(
name="Correctness",
criteria="Determine if the 'actual output' is correct based on the 'expected output'.",
evaluation_params=[SingleTurnParams.ACTUAL_OUTPUT, SingleTurnParams.EXPECTED_OUTPUT],
threshold=0.5,
)
@pytest.mark.parametrize("question,expected", [
("What is the capital of France?", "Paris"),
("What is the capital of Australia?", "Canberra"),
])
def test_capital(question, expected):
tc = LLMTestCase(input=question, actual_output=answer(question), expected_output=expected)
assert_test(tc, [correctness])
# Run: deepeval test run test_capitals.py
If your team already lives in pytest, this feels native. The trade-off: pytest thinks in pass/fail per test, while evals think in rates across a dataset (Module 04). One flaky judge call fails the build, so thresholds and repeats need care.
4. Braintrust
One call to Eval() with data, task and scores. The result is uploaded as an Experiment that the UI compares with previous experiments row by row.
# capitals_eval.py
from braintrust import Eval
from autoevals import Factuality # an LLM-as-judge scorer from autoevals
from my_app import answer
def task(input):
return answer(input) # the system under test
Eval(
"Capitals", # project name
data=[
{"input": "What is the capital of France?", "expected": "Paris"},
{"input": "What is the capital of Australia?", "expected": "Canberra"},
],
task=task,
scores=[Factuality], # judge compares output with expected
)
Langfuse (run_experiment(data, task, evaluators)), LangSmith (evaluate(target, data, evaluators)), MLflow (genai.evaluate(data, predict_fn, scorers)), Weave (Evaluation(dataset, scorers).evaluate(model)) and Opik (evaluate(dataset, task, scoring_metrics)) all have this same three-argument shape. Learn one and you can read the others.
5. OpenAI Evals API (for migration and reading old code)
The hosted Evals platform becomes read-only on 2026-10-31 and shuts down on 2026-11-30. OpenAI's own migration guide moves users to promptfoo. The code is shown because its split between schema, graders and runs is a clean design, and because you may inherit it.
from openai import OpenAI
client = OpenAI()
# 1) The Eval: what a row looks like + how to grade. No data, no model yet.
eval_obj = client.evals.create(
name="Capitals",
data_source_config={
"type": "custom",
"item_schema": {
"type": "object",
"properties": {"question": {"type": "string"}, "answer": {"type": "string"}},
"required": ["question", "answer"],
},
"include_sample_schema": True,
},
testing_criteria=[{
"type": "score_model", # LLM judge that returns a number
"name": "correct_capital",
"model": "o4-mini-2025-04-16",
"input": [
{"role": "system", "content": "You are an expert grader. Score 1 if the model answer names the reference city as the capital, else 0."},
{"role": "user", "content": "Reference: {{ item.answer }}. Model answer: {{ sample.output_text }}"},
],
"range": [0, 1],
"pass_threshold": 0.5,
}],
)
# 2) The Run: this data + this model + this prompt, graded by the Eval above.
run = client.evals.runs.create(
eval_obj.id,
name="gpt-4o baseline",
data_source={
"type": "responses",
"model": "gpt-4o",
"input_messages": {"type": "template", "template": [
{"role": "user", "content": "{{ item.question }}"},
]},
"source": {"type": "file_id", "id": "YOUR_FILE_ID"}, # uploaded JSONL of items
},
)
What the five shapes teach
| Tool | Where the model is chosen | Where the judge prompt lives | Natural unit of result |
|---|---|---|---|
| Inspect | Command line at run time | Inside the scorer (default template, overridable) | An eval log per task × model |
| promptfoo | providers list in YAML | The llm-rubric value | A grid of prompt × provider × test |
| DeepEval | Inside your app code | criteria of the GEval metric | Pass or fail per pytest test |
| Braintrust | Inside your task | The autoevals scorer | An Experiment, compared with earlier ones |
| OpenAI Evals API | The Run's data_source | The score_model grader's messages | A Run on the server |
Rosetta stone: the same concepts, different names
Every tool has the same five or six concepts under different names. This table is worth bookmarking; it lets you read any tool's docs in minutes.
| Tool | One row of data | The eval definition | System under test | Grader | One execution | Recorded steps |
|---|---|---|---|---|---|---|
| This course | sample | task / eval | system (model + scaffold) | grader | run / trial | transcript / trace |
| Anthropic (agent-eval post) | task | evaluation suite | agent in a harness | grader | trial | transcript |
| Inspect | Sample in a Dataset | Task | Solver (e.g. react()) | Scorer | eval log (epochs = repeats) | transcript in Inspect View |
| promptfoo | test (vars) | config file | prompt × provider | assert | eval | result row |
| DeepEval | LLMTestCase | test file | your app | metric (e.g. GEval) | test run | @observe trace |
| Braintrust | row / Dataset record | Eval(...) | task | scorer | Experiment | trace / span |
| LangSmith | example in a Dataset | evaluate(...) | target function | evaluator | experiment | run tree / trace |
| Langfuse | dataset item | run_experiment(...) | task | evaluator → Evaluation (score) | experiment | trace / observation |
| Phoenix | dataset example | experiment | task | evaluator | experiment | span (OpenInference) |
| Weave | dataset row | Evaluation | Model.predict | scorer (@weave.op) | evaluation run | call (@weave.op) |
| MLflow | row with inputs / expectations | genai.evaluate(...) | predict_fn | scorer / judge | evaluation run | trace |
| Pydantic Evals | Case | Dataset | task function | Evaluator / LLMJudge | report | spans (OTel) |
| OpenAI Evals API | item (item_schema) | Eval | model + prompt in the Run | grader (testing_criteria) | Run | – |
In Braintrust, LangSmith, Langfuse and Phoenix, an experiment is one execution of a dataset through a version of your system, stored so you can diff it against another. In science, an experiment is the whole comparison. When someone says "run an experiment", ask whether they mean one run, or a controlled comparison of two runs with a significance test (Module 04). Most platforms show you the diff but leave the statistics to you.
Which tool should I use?
Start from the question you need answered, not from a feature list. The tree below covers most real situations.
The same tree, as rules of thumb
Research on frontier models or safety
Inspect. It is what government AI safety institutes use, it has sandboxes and agent tooling built in, and 200+ ready-made evals. Add Harbor if your agent is a full CLI agent on Terminal-Bench style tasks. See Module 16.
Classic benchmarks on open weights
lm-evaluation-harness (the Open LLM Leaderboard backend), Lighteval, or HELM if you want its holistic metrics and leaderboards.
CLI + CI + red teaming
promptfoo. Config in YAML, a GitHub Action that comments diffs on pull requests, and a strong red-teaming feature set. Also the migration path off the OpenAI Evals API.
Pytest-style unit tests
DeepEval (large metric catalog including agent metrics) or Pydantic Evals (lightweight, OpenTelemetry span-based). LangSmith and Opik also offer pytest integrations.
Production tracing + experiments UI
Hosted and polished: Braintrust or LangSmith (especially on LangChain/LangGraph), or Weave if you already use W&B. Self-hosted or open: Langfuse, Phoenix, Opik, MLflow.
RAG quality
Ragas or TruLens metrics (faithfulness, context relevance, the RAG triad), called from whatever harness you already run.
Single-vendor stack
On Google: ADK eval and the Gen AI evaluation service. On Azure: Foundry evaluation. OpenAI-only: the hosted Evals API is ending, so use promptfoo (now OpenAI-owned) instead.
Red teaming and security scans
garak for a broad sweep of known attack families; PyRIT for orchestrated, multi-turn and human-in-the-loop red teaming; promptfoo or Giskard if you want scans inside the tool that already runs your tests. Turn every finding into a regression case (Module 25).
Too many transcripts to read
Docent or Inspect Scout to search and cluster agent runs; your trace platform's filters for production. Then read the transcripts they surface yourself (Module 12).
Caveats
No tool fixes a bad dataset or an unvalidated judge. Most of the value comes from error analysis and judge calibration, which you can do in any of these tools, or in a spreadsheet.
If only engineers read results, a CLI and CI output are enough. If product managers, domain experts or annotators need to read transcripts and label them, you want a platform with a UI and annotation queues. Hamel-style error analysis (Module 12) depends on people actually reading traces, so the viewing experience matters more than the metric catalog.
How tools compose
In a mature team the families click together into a loop. Production traces become datasets; datasets feed offline evals; offline evals gate deploys in CI; online judges score live traffic; failing traces become new dataset rows. Each box can be a different tool.
Three concrete, common stacks:
- Lean open-source stack: OpenTelemetry tracing into self-hosted Langfuse or Phoenix; datasets exported from failing traces; promptfoo or DeepEval in GitHub Actions as the gate; Ragas metrics if retrieval matters.
- All-in-one hosted: Braintrust or LangSmith for tracing, datasets, experiments, CI evals and online scoring, with
autoevalsoropenevalsjudges. - Research lab style: Inspect tasks with sandboxes for capability and safety evals, Inspect Scout to scan transcripts for anomalies, and Harbor for Terminal-Bench style CLI-agent runs. No production tracing at all, because the "product" is a model.
Phoenix (OpenInference), Langfuse, MLflow, TruLens, Pydantic Evals, Opik and Microsoft Foundry all speak OpenTelemetry (OTel), the open standard for traces and spans. If your application emits OTel spans, you can switch trace stores, or send the same spans to two of them, without rewriting instrumentation. Vendor-specific decorators are convenient but are the first place lock-in creeps in. Standard naming for GenAI spans is still settling, so check exactly which attributes each tool reads.
Open source vs hosted: licenses, lock-in, privacy
Licenses are a spectrum, not a switch
Where your data goes
Eval data is often your most sensitive data: real user conversations, internal documents retrieved by RAG, customer records seen by tools. Before choosing, trace the path each byte takes.
Open source / self-host wins when
- Data residency or regulation forbids sending traces to a third party.
- You want to read and patch the scorer code (reproducibility for research).
- You fear vendor churn: an MIT project can be forked if its owner changes course.
- Scale makes per-trace SaaS pricing expensive.
Hosted wins when
- You have no one to run a database, upgrades and backups.
- Non-engineers need a polished UI for review and annotation today.
- You value integrated features (online scoring, playgrounds, in-app assistants) over control.
- Your security team has already approved the vendor.
Lock-in: what actually traps you
Switching tools is usually cheap for code and expensive for history. Rank the lock-in risks:
- Your datasets and labels. Months of curated failure cases and human annotations are the real asset. Make sure you can export them (JSONL or CSV) and keep a copy in your own repo or bucket.
- Experiment history. Baselines you compare against. If you switch, re-run your current best system on the new tool to create a new baseline; do not compare scores across tools, because graders and prompts differ.
- Instrumentation. Vendor decorators across your codebase. Prefer OpenTelemetry where offered.
- Judge prompts. A built-in "Factuality" or "Correctness" judge is someone else's prompt, and it may change between versions. For anything you gate a release on, own the judge prompt and version it (Module 13).
- Eval code shape. The least sticky: as the Rosetta table shows, the
data, task, scorersshape ports in an afternoon.
Teams that defined evals on OpenAI's hosted platform in 2025 now have until 2026-11-30 to migrate, with OpenAI's cookbook guide pointing to promptfoo. Their eval logic (schemas, grader prompts) ports; their run history on the platform does not come along automatically. The lesson is not "never use hosted tools". It is: keep datasets and grader definitions in version control you own, whatever tool runs them.
Key takeaways
- Eval tools fall into five families (research harnesses, developer test and CI tools, observability plus eval platforms, metric and judge libraries, cloud services), and each answers a different question.
- Every tool is the same four boxes with different names: a row of data, a system under test, a grader, and a stored run. Learn the mapping and any tool's docs become readable.
- Tools from different families usually complement each other. A common stack is one offline harness in CI plus one platform for production traces.
- Pick by the question you need answered and by who reads the results, not by the length of the metric catalog.
- Licenses are a spectrum: permissive open source, open core or source-available (Langfuse, Phoenix), open SDK with a hosted platform, and fully closed services.
- An LLM judge sends graded text to its model provider even when the eval library runs locally. Privacy reviews must cover that path.
- The real lock-in is your datasets, labels and judge prompts. Keep them in version control you own; the OpenAI Evals shutdown shows why.
- Next to the five families sit red-teaming scanners (garak, PyRIT), transcript analysis (Docent, Inspect Scout) and third-party measurement (Artificial Analysis, OpenRouter rankings). Scanners discover failures, analysis tools find patterns, public numbers build a shortlist; none of them replaces your own eval.
- A score from a shared implementation or a public index is "benchmark as implemented by X, version Y". Pin and report the version, and do not compare attack success rates across different scanners.
Check yourself
1. A startup with a customer-support agent in production wants to see real conversations, have a PM label bad ones, and turn them into a regression set. Which family should they look at first?
2. In Inspect, which component would you change to turn a single-turn QA eval into an agent eval with bash access in a Docker sandbox?
generate() to a full react() agent with tools. The dataset and scorer can stay the same.3. What is the license status of Arize Phoenix?
4. Your company runs its evals on OpenAI's hosted Evals API. What is the situation as of late 2026?
5. You use a fully local, open-source eval library with an LLM-as-judge metric that calls a hosted model API. Does sensitive data leave your machine?
6. Braintrust calls it an Experiment, LangSmith an experiment, Inspect an eval log, OpenAI a Run. What are they all?
7. Before launch, you want to throw hundreds of known jailbreak, encoding and prompt-injection attacks at your agent and see which get through. Which tool is built for that?
8. A model tops OpenRouter's rankings this month. What does that tell you?
Interview questions on eval tooling (with model answers)
Q: Why would a frontier-safety team use Inspect rather than an observability platform?
Their system under test is a model, not a deployed app, so there is no production traffic to trace. They need sandboxed agent environments (Docker, Kubernetes), reproducible logs, many models per task, and a shared library of evals that other institutes also run. Inspect is built for exactly that; observability platforms are built around production traces and team dashboards.
Q: You are asked to migrate 40 evals off the OpenAI Evals API. What is your plan?
Export the item schemas, data files and grader definitions. Map each grader type: string_check becomes a code assertion, score_model or label_model becomes an llm-rubric or custom judge with the same prompt. Re-run the current production system on the new tool to set a fresh baseline before comparing anything, because judge templates differ. Store datasets and grader prompts in your repo so the next migration is cheaper.
Q: Two tools report different faithfulness scores for the same outputs. Which is right?
Possibly neither. Same-named metrics in different libraries use different judge prompts, models and aggregation. Validate each against a small human-labeled set (agreement, false positive and negative rates; Module 13) and trust the one that agrees with your humans on your data.
Q: What is the main lock-in risk with an eval platform, and how do you mitigate it?
Datasets, labels and history, not code. Keep canonical datasets and judge prompts in version control, export regularly, and use OpenTelemetry instrumentation so traces can be redirected.
Sources and further reading
- UK AISI and Meridian Labs, Inspect documentation; Agents; ReAct agent; inspect_ai on GitHub; Meridian Labs, About.
- OpenAI, Evals guide (deprecation notice), Graders, Deprecations, Moving from OpenAI Evals to Promptfoo; openai/evals; openai/simple-evals.
- OpenAI, OpenAI to acquire Promptfoo (2026-03-09); TechCrunch, coverage.
- promptfoo, GitHub, Configuration guide, GitHub Action.
- Braintrust, Eval SDK quickstart; autoevals.
- LangChain, LangSmith evaluation quickstart; langsmith-sdk.
- Langfuse, GitHub, Experiments via SDK.
- Arize, Phoenix on GitHub, Phoenix license, arize-phoenix-evals.
- Confident AI, DeepEval on GitHub.
- Ragas on GitHub; TruLens on GitHub, TruLens quickstart.
- Weights & Biases, Weave on GitHub, Weave evaluations.
- Comet, Opik on GitHub, Opik evaluation docs.
- MLflow, GitHub, GenAI evaluation quickstart.
- EleutherAI, lm-evaluation-harness; Stanford CRFM, HELM; Laude Institute, Harbor; Hugging Face, Lighteval; Groq, OpenBench.
- Pydantic, Pydantic Evals; Google, ADK evaluation, Gen AI evaluation overview, python-aiplatform; Microsoft, Foundry observability and evaluation.
- Anthropic, Demystifying evals for AI agents (2026-01-09); Evaluate prompts in the Console (2024-07-09); Petri; Bloom.
- Patronus AI, Products.
- UK AISI, inspect_evals on GitHub (community collection of Inspect evals).
- NVIDIA, garak: the LLM vulnerability scanner.
- Microsoft, PyRIT on GitHub and PyRIT documentation.
- Giskard, giskard-oss on GitHub and library documentation.
- Galileo, Galileo platform; Galileo introduces evaluation foundation models (Luna); Galileo announces free agent reliability platform.
- Strands Agents, Strands Agents documentation (see its evaluation section for Strands Evals).
- Transluce, Docent.
- Artificial Analysis, Intelligence benchmarking methodology; OpenRouter, Rankings.
- OpenAI, Trace grading, Evaluate agent workflows, Introducing AgentKit (Oct 2025).