Skip to main content
The eval harness runs a single agent execution with mock LLM and mock tools, then prints structured JSON to stdout. Use it to catch breaking changes in CI and as a reference for wiring your own agents into eval tools like PromptFoo and DeepEval. No LLM API key is required for default tests.

Prerequisites

Clone the SDK repository and run commands from the repository root (agent-sdk-go/), not from examples/:
Requires Go 1.26+ (same as the SDK). Temporal mode needs a running Temporal server on localhost:7233.

What it verifies

Each run exercises the real SDK agent loop (agent.NewAgent, Run) and outputs: Assertions typically check telemetry.run.finish_reason, telemetry.tools.breakdown, telemetry.tools.failed_calls, and llm_usage.total_tokens.

Run the harness

From the repository root:
Or use the Task shortcut:
CI runs PromptFoo and DeepEval on pull requests — see the eval-harness job in .github/workflows/ci.yml.

CLI flags

config.yaml

Default path: eval-harness/runner/config.yaml Temporal mode uses an embedded local worker. Restate mode embeds the SDK endpoint in the runner process.

Memory scenarios

Enable memory tests in config or via helper scripts:
When memory.scenario: store_recall is active, output includes a memory_scenario object with separate store and recall results.

Output format

Stdout is always JSON:
Parse this in your eval framework and assert on telemetry fields — the same contract used by PromptFoo and DeepEval integrations in the repo.

Sample output

A successful run prints structured JSON to stdout:
Good results: finish_reason === "complete", failed_calls === 0, all mock tools called exactly once, token counts match mock config.

Run against a real LLM provider

The default harness uses a mock LLM for reproducible, zero-cost runs. To validate against a real provider:
  1. Copy and adapt the runner setup — swap the mock client for a real one:
  1. Set your API key and run:
  1. Assert on content text quality with your scoring framework (PromptFoo / DeepEval) alongside the behavioral telemetry assertions.
To compare providers, run the same prompt against multiple configs and diff the JSON output:

PromptFoo integration

Config: eval-harness/promptfoo/config.yaml PromptFoo runs the harness as an exec provider. Each test invokes the runner once, parses JSON stdout, and asserts with JavaScript.
Requires Node.js >=22.22.0 (24 LTS recommended). PromptFoo installs on demand via npx. Example assertions: all mock tools called once, finish_reason === "complete", zero failed tool calls, token usage reported.

DeepEval integration

Python tests in eval-harness/deepeval/:
Requires Python 3.10+ and Go.
  1. harness.run_agent() calls eval-harness/run_agent.sh and parses JSON
  2. Tests assert on content, llm_usage, and telemetry
  3. ToolCorrectnessMetric uses telemetry.tools.breakdown keys as tools_called
Example extraction:

Build your own evals

The harness pattern applies to any framework:
  1. Run the agent with deterministic mocks (or a fixed LLM in staging)
  2. Capture AgentRunResult fields — Content, LLMUsage, Telemetry
  3. Assert on behavioral signals, not just text match
For live LLM evals, swap the mock client in eval-harness/runner/setup/ with a real provider and keep the same output envelope.

Telemetry

Fields available for assertions

Benchmarks

Load and concurrency testing