Skip to content

Repository files navigation

@tangle-network/agent-eval

Measure agent behavior, compare changes on the same cases, and improve prompts or skills without showing the final test cases to the optimizer.

npmpypitestslicense: MIT

The evaluation path runs in your TypeScript process. Model calls happen only through the clients and agents you configure.

New to the package? Read concepts first — it takes five minutes and defines every word used here.

Looking for a measured result (a lift, a null, a parity verdict)? The canonical registry is evidence/ — machine-readable records, a generated index, and a freshness gate.

Install

pnpm add @tangle-network/agent-eval

Quickstart

This example is offline and complete. Copy it, run it, then replace the agent and the judge with your product code.

import{defineAgentEval}from'@tangle-network/agent-eval/contract'interfaceSupportCase{id: stringkind: 'support'}constevalKit=defineAgentEval<SupportCase,string>({scenarios: [{id: 'refund',kind: 'support'},{id: 'shipping',kind: 'support'},{id: 'cancel',kind: 'support'},],agent: async(prompt,scenario)=>String(prompt).includes('ticket') ? `Ticket ${scenario.id}: on it.` : 'On it.',judge: {name: 'ticket-id',dimensions: [{key: 'present',description: 'The answer includes the ticket id'}],score: ({ artifact, scenario })=>{constpresent=artifact.includes(scenario.id) ? 1 : 0return{dimensions: { present },composite: present,notes: ''}},},baselineSurface: 'Answer politely.',expectUsage: 'off',})console.log((awaitevalKit.evaluate()).aggregates.byJudge)console.log((awaitevalKit.evaluate({surface: 'Answer politely and cite the ticket id.'})).aggregates.byJudge,)

Each call runs every case, records what the agent produced, applies the same judge, and returns score distributions.

Three words carry this example. A case is one task the agent must do. A surface is the value being changed: a prompt, a skill, or a serialized configuration. A judge is a function that scores one produced result.

expectUsage: 'off' is set because this agent makes no paid calls. The default, 'assert', fails a run whose cells report no cost receipt. Keep the default whenever real model calls happen.

Runnable copy: examples/evaluate-a-change.

Auditable optimization history

Optimization methods may return a bounded SearchHistoryReceipt over Eval's canonical hash-chained SearchLedger. Existing callers keep working and see missing-history coverage. Autonomous and publication-grade runs set searchHistoryPolicy: 'require-complete' to refuse an incomplete planned denominator before the untouched final cases are opened.

The receipt is a small proof envelope, not another event log. Exact candidates, attempts, failures, decisions, and missing ids remain in the ledger. See complete optimization search history.

Which Front Door

Every row is a function you call. Each links to a runnable example.

When to call itWhat you give itWhat you get back
defineAgentEval() — you changed a surface and must know whether it helpedcases, an agent, a judge, a starting surfaceevaluate() for scores, improve() for a search plus a release decision
selfImprove() — you want candidate generation, scoring, and a release decision in one callcases, an agent, a judge, a starting surfacea report, a winner surface, and a gateDecision
analyzeRuns() — the runs already happened and no agent needs to run againRunRecord[]an InsightReport: distributions, paired lift, judge agreement, cost, failure clusters
fromFeedbackTable() (example) / fromOtelSpans() (example) — your data is in a table or an OTel collector, not in RunRecord shapesource rows or spansRunRecord[] ready for analyzeRuns()
planCampaignRun() / runCampaign() — you need direct control of the case grid, or you must see it before paying for itcases, a dispatch function, judges, a run directorya per-cell schedule, then a campaign result with cached cells
loadEvalFixtureScenarios() — agents should add cases as folders on diskevals/<name>/PROMPT.md plus checksScenario[] for runCampaign()
compareOptimizationMethods() — two search methods must be compared at equal budgetmethods, a starting surface, train, selection, and final casesper-method final lift, intervals, pairwise contrasts, and cost
gepaOptimizationMethod() / skillOptOptimizationMethod() — official GEPA or Microsoft SkillOpt should own the searchan objective, a recipe or trainer, an optimizer budgetan optimization method for the comparison above
externalTextOptimizationMethod() — another package owns text search and you keep the scoringthe package identity, limits, and a run callbackthe same, with the final cases never exposed
SurfaceProposer — candidate generation belongs to your producta propose() functioncandidates the campaign executes, scores, and gates
runProfileMatrix() — the same cases must run across models or profilesaxes of models and profiles, casesone row per cell, with an explicit unknown model rather than an invented one
ExperimentTracker — a candidate must beat its parent across N repetitionsreps with scores, run ids, and evidence referencesa KEEP / ITERATE / NOISE / REGRESSION verdict with git provenance
sealExperiment() / openSealedExperiment() — the result must convince someone who does not trust youarms, an admission funnel, an estimand, an interval, a decision tablea hashed rule tree, and executors that can run no other rule
runEquivalenceCheck() / VERIFICATION_STRATEGIES — the work has no held-out test suitea claim, two blind arms, an injected checkera certification that names who vouched and how it can fail
AnalystRegistry.runExact() — a batch of runs failed and you need cited findingsrecorded evidence, a declared analyst listfindings with evidence references, an execution plan, and a receipt
analyzeTraces() — you have one question about a recorded run ("what first caused this failure?")stored traces, the question, a DSPy RLM engine with a cost capan answer, findings with evidence references, and the investigation trajectory
runAnalystBenchmark() — an analyst's accuracy must be measured, not assumedlabeled issues and exact span locationsscored findings, trace reads, model calls, tokens, cost, and runtime
deltaRepair() — a finding must be graded by executing the repair it proposesa trajectory, an analyst finding, a sandboxthe repair's measured effect against a no-fix control
replayVerify() — you must know whether a recorded failure still reproducesa recorded shell trajectory and its pinned imagea re-execution verdict and the divergences found
analyzeSupervisorRun() — a recursive or supervised run directory must be reada run directorycounts that stay missing when a measurement is missing, never zero
buildRlDataset() — scored runs should become training datarun records and preferencesreward, preference, and supervised rows

Configure Model Calls

Benchmarks, user drivers, executors, built-in judges, completion checkers, and judge adapters all take the same ChatClient. You own model execution: Agent Eval issues no provider request and never receives a provider credential.

import{createChatClient}from'@tangle-network/agent-eval'constchat=createChatClient({transport: 'custom',defaultModel: 'openai/gpt-4.1',maximumAttempts: 3,chat: async(request,opts)=>myProviderClient(request,opts),})

On Agent Runtime, profileChatClient({ profile, executor, context }) from @tangle-network/agent-runtime/kernel is that transport: every call runs one exact AgentProfile and reports its measured usage, retries, and served model identity. Use sandbox-sdk for Sandbox and mock in tests. A custom adapter must return a ChatResponse and declare maximumAttempts before a capped cost account can dispatch it.

ChatResponse carries the whole execution record across that boundary: the served model id, measured input/output/reasoning/cached tokens, billed USD or an explicit unknown, the finish reason, and the per-token log probabilities the expectation judge scores on.

The official GEPA and SkillOpt optimizers run through a Python bridge. Install commands, version pins, and the reason for each pin: GEPA, SkillOpt, and DSPy.

Entry Points

ImportUse
@tangle-network/agent-eval/contractDefine an evaluation, run it, improve it, and analyze existing runs.
@tangle-network/agent-eval/campaignCampaigns, optimization methods, comparisons, storage, and release rules.
@tangle-network/agent-eval/experimentExperiments as sealed objects: registered rules, funnels, estimands, refusals.
@tangle-network/agent-eval/analystBuilt-in and custom trace analysts, labeled comparison, costs, and reports.
@tangle-network/agent-eval/trace-repairGrade one analyst finding by executing the repair it proposes.
@tangle-network/agent-eval/trajectory-replayRe-execute a recorded shell trajectory and check whether its failure reproduces.
@tangle-network/agent-eval/tracesStore, replay, and inspect structured traces.
@tangle-network/agent-eval/reportingStatistical comparisons and report rendering.
@tangle-network/agent-eval/supervisor-runRead recursive run directories without collapsing missing measurements to zero.
@tangle-network/agent-eval/profile-cellCreate and validate portable agent-profile identities.
@tangle-network/agent-eval/ledger-coreAppend-only hash-chained journal with idempotent append and chain verification.
@tangle-network/agent-eval/benchmarksBenchmark adapters and retrieval metrics.
@tangle-network/agent-eval/rlExport rewards, preferences, and training rows.
@tangle-network/agent-eval/wireHTTP and RPC schemas for other languages.
@tangle-network/agent-eval/adapters/httpRun campaign cells on remote workers over HTTP.

Use the root import for common primitives. Use a subpath when you want an explicit capability boundary.

Documentation

QuestionRead
What do these words mean?docs/concepts.md
Why does this package exist, and where is it going?docs/charter.md
Which run* function do I want?docs/eval-surface-map.md
How do I choose a candidate-generation method?docs/campaign-proposers.md
What is in an InsightReport?docs/insight-report.md
How do I register an experiment as a sealed object?docs/experiment.md
How is something certified without an answer key?docs/verification-strategies.md
Where does every verifier land its result?docs/verdicts.md
How do I turn a coding-agent session log into runs?docs/code-agent-intake.md
How do I score a string from another language?docs/wire-protocol.md

The example index lists every runnable example.

Development

pnpm install
pnpm typecheck
pnpm typecheck:examples
pnpm test
pnpm build

Python compatibility tests use the locked dependencies:

cd clients/python
uv sync --frozen --extra dev --group gepa-release
AGENT_EVAL_EXPECT_GEPA_RELEASE=1 \
uv run --frozen --extra dev --group gepa-release \
pytest tests/test_gepa_release_compatibility.py tests/test_gepa_bridge.py
uv sync --frozen --extra dev --group skillopt-source --group gepa-source
uv run --frozen pytest
uv sync --frozen --extra dev --extra dspy
uv run --frozen pytest tests/test_dspy_metric.py

License

MIT.

About

Evaluate and improve AI agents from the data they produce.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages