---
title: Quickstart
description: Get up and running with EZVals in under 5 minutes
---

## Your First Evaluation

Create a file called `evals.py`:

### Target function

The target function represents the thing you are evaluating. If you are evaluating an agent, your target function would run
the agent and return the results. If you are evaluating a single LLM call, the target would just invoke the LLM and return those results.

Using a `target` function function comes with the added benefits of:

- **Latency Tracking** - Target function latency will be tracked separately from evaluation latency and is handled automatically
- **Reusability** - Write one target function and reuse it across many evals
- **Prepopulates Context** - Useful for injecting data into the context (similar to `beforeEach`)

```python
from ezvals import eval, EvalContext

async def my_agent_target(ctx: EvalContext):
    # Run your agent using your own custom logic.
    # Use the injected `input` from the evals.
    agent_results = run_agent(ctx.input)

    # Inject output into context using store()
    ctx.store(output=agent_results["content"])

    # You can also inject anything you might need in other tests
    # For example, we can inject the RAG search results for future RAG evals
    ctx.my_rag_search_results = agent_results["documents"]
```

Now that we have a universal target function, we can point our evals at it:

```python
@eval(
  input="Hello, how are you?",
  target=my_agent_target
)
async def test_greeting(ctx: EvalContext):
    """Evaluate the agent's greeting ability"""

    # ctx is already populated so we can just focus on evaluation logic
    # Use assertions to score - just like pytest!
    assert "hello" in ctx.output.lower(), "Response should contain a greeting"
```

That's it! Assertions work like pytest - if they all pass, your eval passes. If they fail, the assertion message becomes the failure reason.

Non-assertion errors are caught as errors.

## Run Your Evaluations

Start the web UI to run evals and review results:

```bash
ezvals serve evals.py
```

This opens a browser at `http://127.0.0.1:8000` where you can:

- Run, filter, and rerun specific evals
- Review eval results for analysis
- Annotate results inline
- Export results to JSON or CSV

<img src="/assets/ui-screenshot.png" alt="EZVals Web UI" />

### Agent Mode

When coding agent needs to run evals programmatically, use `run`:

```bash
ezvals run evals.py
```

This outputs compact results to stdout—perfect for when an AI agent needs to parse results.

<img
  src="/assets/terminal-output.svg"
  alt="Terminal output showing eval results"
/>

## Add More Test Cases

Use `cases=` to generate multiple evaluations from one function:

```python
from ezvals import eval, EvalContext

@eval(
  dataset="greetings", 
  labels=["production"],
  target=run_tone_agent,
  cases=[
      {"input": "Hello!", "reference": "friendly"},
      {"input": "I need help urgently", "reference": "helpful"},
      {"input": "What's your return policy?", "reference": "informative"},
  ],
)
async def test_response_tone(ctx: EvalContext):
    assert ctx.output == ctx.reference, f"Expected {ctx.reference} tone, got {ctx.output}"
```

Cases are list-of-dict overrides for `@eval` fields. Put any custom data inside `input` (e.g., a dict) and read it from `ctx.input`.

## Track Progress with Sessions

Use sessions to group related runs together—useful for comparing models, tracking iterations, or A/B testing:

```bash
# Name your session and run
ezvals serve evals.py --session model-upgrade --run-name baseline

# Continue the session with another run
ezvals serve evals.py --session model-upgrade --run-name after-tuning
```

Results are saved to `.ezvals/runs/` with session metadata, so you can compare runs over time.

## Configuration with ezvals.json

Create a `ezvals.json` in your project root to set defaults:

```json
{
  "concurrency": 4,
  "results_dir": ".ezvals/runs"
}
```

This saves you from passing the same flags repeatedly.

## Filter and Run Specific Tests

```bash
# Run a specific function
ezvals serve evals.py::test_greeting

# Filter by dataset
ezvals serve evals.py --dataset greetings

# Filter by labels
ezvals serve evals.py --label production

# Run with concurrency
ezvals serve evals.py --concurrency 4
```


## Next Steps

<CardGroup cols={2}>
  <Card title="EvalContext" icon="code" href="/core-concepts/eval-context">
    Learn about the builder pattern that powers EZVals
  </Card>
  <Card title="Decorators" icon="at" href="/core-concepts/decorators">
    Master the @eval decorator and its options
  </Card>
  <Card title="Scoring" icon="chart-simple" href="/core-concepts/scoring">
    Understand flexible scoring systems
  </Card>
  <Card title="Patterns" icon="diagram-project" href="/guides/patterns">
    See common evaluation patterns
  </Card>
</CardGroup>
