Step-by-step: Evaluate Agents with Simulated Users
How to implement τ²-bench for your own use case
This is my longest post so far. If you struggle with articles longer than five minutes, like I do, no worries. I hosted a live demo on Maven to walk through user simulation step by step.
This free lightning lesson is part of my Maven course, AI Evals & Analytics Playbook.
Check out the recording here:
No one working on agent evaluation can resist the temptation to try user simulation.
Yes, myself included.
User simulation is becoming an increasingly common feature in AI evaluation and observability platforms. For example, Google Cloud’s agent evaluation service, MLflow’s synthetic conversation simulation, and Microsoft’s AI Red Teaming Agent.
It can feel a little like magic. But as someone who does not completely trust systems I do not understand, I decided to implement it myself first.
In this post, I’ll walk through what I built and my observations.
Building it for your own use case: FAFSA
The use case I had in mind was a chatbot that answers students’ questions about financial aid, scholarships, and student loans. Let’s call it FAFSA.
The chatbot should answer transactional questions, like the remaining balance on the account, scholarship status, and etc.
To answer this type of question, the chatbot must access a financial database and retrieve student-specific information. That makes it an agent rather than a simple question-answering chatbot.
My goal was to evaluate whether the agent could answer these questions correctly while following the appropriate policies.
Understanding the User Simulation Framework
I chose τ²-bench for this implementation.
The τ-bench family was developed by Sierra’s research team to evaluate conversational agents that interact with users, tools, databases, and domain-specific policies. The original τ-bench focused on tool-agent-user interactions in domains such as airlines and retail. τ²-bench extended this setup to dual-control environments, where both the agent and the user may need to take actions. The repository has since evolved into τ³-bench, which adds areas such as banking, knowledge-based evaluation, and voice interactions.
For my use case, τ²-bench was sufficient. FAFSA is text-only, and the initial version does not require retrieval from an unstructured knowledge base.
The τ²-bench repo includes four example domains:
Airline
Banking
Retail
Telecom
Below is an example of an interaction between an agent and a simulated user in the telecom domain. My goal was to adapt this framework to a higher-education financial-aid domain.

Test It Out
Let’s get started.
Step 1: Clone the repository
git clone https://github.com/sierra-research/tau2-benchStep 2: Run an existing domain
Follow the Quick Start instructions in README.md, configure the required API keys, and run a test using the airline domain, or any other domain you prefer.
Step 3: Inspect the simulation results
The results are saved under data/simulations/.
Each result contains the conversation, tool calls, environment changes, and evaluation outcome from the simulation.
For readability, I extracted the messages from one simulation run and visualized the interaction below.
Now that we know what a completed simulation looks like, we can examine how to adapt the framework to our own use case.
Step 4: Identify the files required for a new domain
I inspected the repo to determine which files and components were required for a new student financial-aid domain.
I used Codex (or your fav coding agent) to help me understand the repository structure and create an implementation plan.
Step 5: Identify the files required for a new domain
I inspected the repository to determine which files and components were required for a new student financial-aid domain.
I used Codex to help me understand the repository structure and create an implementation plan.
tasks.json defines the test scenarios.
Each task specifies the scenario, the simulated user’s instructions, and the criteria used to evaluate the interaction.
This is arguably the most important part of building a user simulation system, and it is where you should spend most of your time.
The user scenario contains information such as the simulated user’s persona and the reason they are contacting the agent. These fields become part of the instructions given to the user-simulation model.
For example, the simulator might be told that it is acting as a student who wants to check a financial-aid balance but should not volunteer sensitive information unless the agent requests it.
The evaluation criteria define what must happen for the task to pass.
In an airline cancellation scenario, the evaluator might check that the agent correctly refuses an invalid cancellation request. In a telecom scenario, it might check whether the customer’s issue was successfully resolved.
The reward_basis field identifies which types of checks should be performed. For example:
DB checks whether the final database state matches the expected state, such as confirming that a reservation was not canceled.
COMMUNICATE checks whether the agent communicated the required information to the user.
db.json provides the structured data that supports the scenarios.
For example, when an airline customer asks about a flight, the agent can query the database to retrieve the reservation and flight status.
Together, tasks.json and db.json create the test environment:
tasks.json defines what should happen.
db.json defines the world in which it happens.
These are the files where most of the domain-specific work takes place.
Step 6: Create the FAFSA domain
I created a new folder under data/tau2/domains/fafsa/.
Before running the simulation, we need an agent to evaluate.
In a real project, you would already have a product and could focus directly on building the simulator and evaluation environment. In this experiment, however, I did not have an existing financial-aid agent, so I needed to create one first.
Luckily, τ²-bench already provides most of the scaffolding.
The main domain-specific component is policy.md, which describes what the FAFSA agent should and should not do.
For example, the policy can specify:
how students must be authenticated;
which information the agent may disclose;
which tools the agent may use;
when the agent should refuse a request;
how financial information should be communicated.
I used AI to generate an initial version of policy.md, then reviewed and refined it.
Step 7: Build the tasks
Next, I created the tasks.
Again, this is the most manual and important part of the process.
You can provide policy.md to an AI coding assistant and ask it to generate initial tasks. That is completely reasonable for a quick experiment. For a serious evaluation project, however, you should carefully review every AI-generated test case.
You should also mine historical conversations, support tickets, product logs, and input from domain experts to identify realistic scenarios.
For FAFSA, example tasks include:
checking whether the agent authenticates a student before accessing student-specific information;
asking for the remaining balance on a student account;
checking a FAFSA status;
asking about an expected scholarship;
asking why financial aid has not yet been disbursed.
Once tasks.json is ready, you can use it to guide the creation of db.json.
Step 8: Implement the domain
Next, use your favorite coding agent to implement the domain. Who still writes every file manually today?
These are the “Core Files” shown in the implementation plan.
Because the τ²-bench repository is well structured and documented, a coding agent can follow the existing domains and create src/tau2/domains/fafsa/.
It can then add the domain models, tools, environment logic, data loaders, and other required files.
Run FAFSA Simulation
At this point, all the pieces are ready.
I ran the new domain using:
tau2 run --domain fafsa \
--agent-llm gpt-5.5 \
--user-llm gpt-5.5 \
--num-trials 1 \
--num-tasks 5Here is the simulation output:
Next, let’s inspect an interaction between the FAFSA agent and a simulated student.
One task asks the student to check their FAFSA status.
The agent is expected to: 1) request an approved form of authentication before disclosing student-specific information; 2) authenticate the student; 3) query the appropriate data; 4) return the correct FAFSA status.
In this scenario, the student is Maya Patel. The agent should not reveal Maya’s information before authentication, even if the simulator provides some identifying information.
Below is a visualization of the simulated conversation.
And now we have a working user simulation for FAFSA.
Easier than expected, right?
The engineering is relatively manageable. The difficult part is building realistic and effective test scenarios.
That is not purely an engineering problem. It requires understanding the product, business rules, operational processes, and the many ways real users behave.
Honestly, this reflects a broader shift in the skills required to build AI products: writing the code is increasingly the easy part. Understanding what should be tested, and why, is much harder.
Caveats
User simulation is useful, but it is not a substitute for real-user evaluation.
Simulated users may be too cooperative, especially when they receive structured task instructions. The agent and simulator may also communicate unusually well when they use related models. Finally, a correct final state does not guarantee a good interaction.
Where User Simulation Fits
τ²-bench provides a controlled test of agent behavior under a particular simulated-user distribution. It should not be treated as a validated substitute for evaluation with real users.
Despite these limitations, it is still a strong option for repeatable regression testing and trace diagnostics.
A practical evaluation strategy is to use τ²-bench-style simulations for broad, repeatable coverage, then supplement them with:
multiple simulator models;
adversarial and less cooperative personas;
reviews of simulator failures;
interaction-quality metrics;
historical production scenarios;
a smaller human evaluation.
User simulation is not the complete answer to agent evaluation.
But it gives us something extremely valuable: a repeatable environment in which agents can fail before real users encounter those failures.
Thank you for sticking with me to the end. If you’re interested in AI evals or user simulation, check out our AI Evals & Analytics Playbook course on Maven.













Thank you Stella! Such a great article ❤️ It’s practical and easy to follow. I wish I had read it before my interview. Really enjoyed reading it 🥰