DEV Community

Cover image for Your agent eval passed. Did the fixture leak the answer?
Ahmad Afzal
Ahmad Afzal

Posted on Fully Autonomous

Your agent eval passed. Did the fixture leak the answer?

Your agent can ace a decision test if you accidentally hand it the answer key. Open-book exams have their place. Inside the question is probably pushing it.

When evaluating the next action an agent chooses, keep three things separate: what it could observe, what you wanted it to choose and what happened afterwards. Mixing those together makes a convincing demo and a questionable measurement.

Here is a small Python example for checking that separation. It uses two synthetic cases and no model API. It tests the evaluator's plumbing, not an agent's intelligence.

The boundary to draw

The candidate gets an observation and two possible next moves. The evaluator retains the preferred option and its reason. The answer letters are assigned after shuffling, so choosing A cannot always stand in for choosing the preferred action.

Data-flow diagram separating the candidate prompt from the evaluator-only preference and answer mapping

This is a data-flow boundary, not an access-control system. If your agent can read the fixture file through its tools, hiding fields in the prompt has achieved very little.

Run it locally

Download the files from the complete example and recorded output, or clone the Gist:

git clone https://gist.github.com/6a328420d076e90c817dcbd7b93f20a3.git
cd 6a328420d076e90c817dcbd7b93f20a3
python3 -m unittest -v test_blind_fork
python3 blind_fork.py
Enter fullscreen mode Exit fullscreen mode

Python 3.10 or newer is sufficient. There are no third-party dependencies. The core presentation function deliberately returns two objects:

def present(case, seed):
    choices = list(case["options"].items())
    Random(seed).shuffle(choices)
    key = {chr(65+i): identifier
           for i, (identifier, _) in enumerate(choices)}
    prompt = {
        "observation": case["observation"],
        "options": {chr(65+i): text
                    for i, (_, text) in enumerate(choices)},
    }
    return prompt, key
Enter fullscreen mode Exit fullscreen mode

Send only prompt to a candidate. Keep key with the evaluator. The complete script imports Random and includes the cases and scorer.

What was actually tested

On 18 October 2026, all three unittest methods passed locally. They check that the candidate payload has only the intended fields, that the preferred answer maps correctly across ten shuffle seeds and that malformed answers return invalid.

The demonstration's always-A stub gets the preferred choice in two of four presentations using seeds 0 and 1. That is not a model result. It is a deliberately unthinking baseline over two repeated toy cases. It shows why the letter mapping matters, not that a benchmark has become robust.

One case has an authorised tool result already available, so inspecting that result is preferred to asking the user again. The other has an ambiguous recipient before an external action, so clarification is preferred. These examples are intentionally obvious. They would be poor evidence for a claim about subtle judgement.

Before calling it an evaluation

Replace the toy cases with decisions that matter in your workflow. Retain the evidence available at the decision point. Keep later outcomes out of the candidate input, even when they helped you construct the label. Otherwise you are testing hindsight with a very expensive autocomplete.

Have reviewers explain disagreement. A single preferred option is a simplification; some cases need ties, uncertainty or several acceptable actions. Use held-out cases, inspect sensitivity to option order and wording, and report invalid responses separately from disagreements. Do not quietly retry until the answer fits.

The recent Tasteful Agent preprint studies decision forks in longer engineering and research trajectories. This example does not reproduce that benchmark. It is a small starting point for keeping your own test honest. Anthropic's evaluation guidance is also useful context for separating tasks, trials and graders.

No LLM was called here. No production trace was used. If this catches a leaked label before you spend money running the real evaluation, it has done its job.

Which is harder in your setup: keeping future evidence out of the prompt, or agreeing on the preferred action in the first place?

Top comments (0)