Building ART·E: Reinforcement Learning for Email Search Agent Development

openpipe · Tech · year n/a · source Agentic: yes · promotional bias: med · source-backed · extracted with prompt 0.5.5 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Reinforcement-trained email search agents

OpenPipe wanted to train a narrow, practical email research agent that can answer natural-language questions by searching an inbox, using reinforcement learning to outperform general-purpose models on this task while keeping the environment simple, measurable, cheap to train, and fully reproducible.

Constraints:

Architecture

ART-E trains a Qwen-14B email research agent with OpenPipe's ART library and GRPO. The team first built synthetic question-answer data from Enron inboxes using GPT-4.1 and a realism score, then implemented a deliberately simple agent environment: SQLite FTS5-backed email search, full-email read, and final-answer tools. The rollout loop calls the LLM, parses a tool call, executes the tool, appends the result, and repeats until a final answer or a 10-step limit. The reward function starts with LLM-as-judge correctness, adds a small fewer-turns bonus as a latency proxy, penalizes wrong answers to reduce hallucination, and avoids misleading partial-credit incentives. Training uses batches of 12 questions, 4 trajectories per question, GRPO loss over 48 trajectories, validation every 30 steps, vLLM rollouts, sample packing, Unsloth optimizations, W&B metrics, and manual output inspection.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  enron-email-corpus[Enron email corpus] --> synthetic-data-generator[Synthetic data generator]
  enron-email-corpus --> sqlite-fts5-database[SQLite FTS5 database]
  synthetic-data-generator --> training-dataset[Training dataset]
  synthetic-data-generator --> test-dataset[Test dataset]
  training-dataset --> grpo-trainer[GRPO trainer]
  test-dataset --> validation-evaluator[Validation evaluator]
  sqlite-fts5-database --> search-tool[Search tool]
  sqlite-fts5-database --> read-tool[Read tool]
  email-search-agent[Email search agent] --> rollout-loop[Rollout loop]
  rollout-loop --> search-tool
  rollout-loop --> read-tool
  rollout-loop --> final-answer-tool[Final answer tool]
  rollout-loop --> reward-function[Reward function]
  reward-function --> grpo-trainer
  reward-function --> validation-evaluator
  grpo-trainer --> validation-evaluator
  grpo-trainer --> training-observability[Training observability]
  runpod-h100-job[Runpod H100 job] --> grpo-trainer
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Enron email corpus Public email dataset used as the realistic inbox corpus for synthetic data generation, training, and testing. Synthetic data generator, SQLite FTS5 database
Synthetic data generator GPT-4.1 prompt pipeline that creates question-answer pairs, source IDs, and how_realistic scores from email batches. Enron email corpus, Training dataset, Test dataset
Training dataset Synthetic questions drawn from 20 selected inboxes. Synthetic data generator, GRPO trainer
Test dataset Held-out synthetic questions drawn from 8 selected inboxes for baseline and validation evaluation. Synthetic data generator, Validation evaluator
SQLite FTS5 database Local full-text search store that backs the email search and read tools. Enron email corpus, Search tool, Read tool
Email search agent Qwen-14B-based agent trained to answer natural-language questions by using email tools and returning sourced answers. Rollout loop, Search tool, Read tool, Final answer tool
Rollout loop Simple multi-turn loop that calls the model, parses tool calls, executes tools, appends outputs, and stops at answer or step limit. Email search agent, Search tool, Read tool, Final answer tool, Reward function
Search tool search_emails tool that returns up to 10 matching emails with snippets and date filters. SQLite FTS5 database, Rollout loop
Read tool read_email tool that returns the full body for a selected message ID. SQLite FTS5 database, Rollout loop
Final answer tool return_final_answer tool that submits the answer and supporting message IDs. Rollout loop
Reward function Multi-objective reward combining LLM-as-judge correctness, turn minimization, hallucination penalty, and rejected partial-credit experiments. Rollout loop, GRPO trainer, Validation evaluator
GRPO trainer ART training loop that runs grouped trajectories, scores them, computes GRPO loss, and updates the model. Training dataset, Reward function, Validation evaluator, Training observability
Validation evaluator Periodic validation process that runs held-out questions and computes accuracy and other metrics. Test dataset, Reward function, GRPO trainer
Training observability Weights & Biases metrics, request logs, reward standard deviation tracking, and manual output inspection. GRPO trainer
Runpod H100 job Skypilot-launched single-GPU training job using vLLM rollouts, sample packing, and Unsloth optimizations. GRPO trainer

Data flow

The pipeline starts by selecting Enron train and test inboxes, then using GPT-4.1 to generate synthetic question-answer pairs, source message IDs, and how_realistic scores from email batches. At rollout time, a user question and prompt enter the agent loop. The model searches SQLite FTS5 for snippets, reads full emails by message ID, and returns a final answer plus supporting sources, stopping after a final answer or 10 turns. Each question is rolled out four times; the reward function scores correctness, turns, hallucination behavior, and tool outcomes. GRPO compares trajectories for the same question, updates Qwen-14B toward better trajectories, and validation runs every 30 steps on 100 questions while metrics and actual outputs are reviewed for reward hacking.

4 supporting quotes
“exist, we had to generate one synthetically. This is a fancy way of saying "make it up". For each inbox, we iterated through 1000 emails in batches of 20. For each batch, we prompted gpt-4.11 to generate several”article, stated
“defining the task, which is to answer the user's question based on the contents of their inbox. It is also given 3 tools: 1. search_emails(keywords, sent_after, sent_before): finds up to 10 emails matching the given keywords with date filters”article, stated
“engine. With these tools available, we simply implement the world's simplest agentic loop: 1. Call the LLM with the initial prompt (source) 2. Parse the tool call it made”article, stated
“Use all 12 groups of 4 trajectories (so 48 trajectories total) along with their rewards to calculate the loss using the GRPO formula and update the model. 5. (Every 30 steps) Run 100 validation questions and calculate the accuracy of the model on our”article, stated

Why this architecture

OpenPipe intentionally constrained the task and environment so RL could produce quick, measurable improvement. Email search is realistic but narrow, Enron gives a large public corpus, synthetic questions fill the missing training-data gap, and SQLite FTS5 keeps tool execution simple. The agent loop avoids recursive orchestration because the trained model can learn search behavior directly. GRPO is well matched because multiple trajectories for the same question expose relative quality. The reward function optimizes final answers first, with latency and hallucination terms added cautiously after partial-credit experiments showed how easily an agent can exploit instrumental goals.

4 supporting quotes
“a task that was realistic and useful, while still being narrow enough to see quick improvement through RL. Searching my email inbox felt like the perfect match. I've wanted an agent that can do this for me forever. Today, when I have a question like "how do”article, stated
“This is extremely simple—no recursive calls, backtracking, etc. But we've found in practice this works more often than not.”article, stated
“is to define our reward function. This is how you tell the model what it "should" do. Reward function design is critical to RL success, and can be a surprisingly tricky to get right. "But wait," you say, "don't we already have a reward function? We already”article, stated
“Sometimes it's best to skip intermediate rewards and let the model optimize for the final objective directly. This is a reflection of the bitter lesson. ## Let's Train! Ok, now that we have our”article, stated

Models used: GPT-4.1 · Gemini 2.5 Pro · Qwen-14B · o3 · o4-mini · OpenPipe ART model art-e-008

Scale

Alternatives considered (roads not taken)

Manual email keyword search

Rejected because: The project target was natural-language email research so users would not have to guess keywords and read search results manually.

“I RSVP for my daughter's classroom party" or "what time is my brother's flight on Friday" I have to open my inbox, think up keywords, and read through search results. So 2022. Why isn't AI doing this for me? ART·E is designed to do exactly this, with style! ## "Synthetic" Data To train”article, stated
“think up keywords, and read through search results. So 2022. Why isn't AI doing this for me? ART·E is designed to do exactly this, with style! ## "Synthetic" Data To train a model and evaluate its performance, we needed a realistic dataset of answerable email queries.”article, stated

Train with RL before benchmarking prompted models

Rejected because: The team says baselines reveal whether existing models are sufficient and whether failures are actually environment, tool, or goal problems.

“But we've found in practice this works more often than not. ## Benchmarking the Competition Before actually training a model with RL (we're getting there, I promise!) we always recommend benchmarking off-the-shelf prompted models, and trying really hard”article, stated
“benchmarking off-the-shelf prompted models, and trying really hard to get them to perform well. There are multiple reasons to do this: 1. You may find that an existing model is already great at your task, and you don't need to train with RL after all! 2.”article, stated

Use complex recursive/backtracking agent orchestration

Rejected because: A simple loop with tools worked often enough once the model was trained.

“(source) This is extremely simple—no recursive calls, backtracking, etc. But we've found in practice this works more often than not. ## Benchmarking the Competition Before actually training a model”article, stated
“simple—no recursive calls, backtracking, etc. But we've found in practice this works more often than not. ## Benchmarking the Competition Before actually training a model with RL (we're getting there, I promise!) we always recommend benchmarking off-the-shelf prompted”article, stated

Add dense partial-credit rewards for intermediate retrieval milestones

Rejected because: They did not speed training in this task, and one turn-count reward caused reward hacking.

“long-horizon tasks that the model realistically can't solve when training begins. In this case, these partial credits basically didn't speed up training at all, probably because the model was already able to find the right answer often enough to learn from that signal directly. **Be”article, stated
“The model learned to just repeat the last tool call over and over until it hit the maximum number of turns! ## Costs For the final training run we used a learning rate of 1.2e-5 and 2 epochs. We ran the training job using”article, stated

Rely only on aggregate reward curves

Rejected because: RL agents can reward hack, so humans need to inspect actual outputs regularly.

“ever_tried_to_read_invalid_email: bool = False prompt_tokens: int = 0 completion_tokens: int = 0 ``` 3. Look at actual model outputs. Your RL model is sneaky and always trying to reward hack.”article, stated
“Even if your reward is increasing, you need to look at actual outputs regularly to make sure it's really doing what you want.2 On one early run, we decided to give a small "partial credit" bonus”article, stated

Patterns

synthetic-data-generation (data)

OpenPipe used GPT-4.1 to generate realistic question-answer pairs and source IDs from Enron email batches because no natural dataset existed.

“Since a good dataset of that shape doesn't exist, we had to generate one synthetically.”article, stated
“prompted gpt-4.11 to generate several synthetic question-answer pairs for each email”article, stated

tool-use-orchestration (agent-runtime)

The agent answers questions by choosing among search, read, and final-answer tools inside a simple loop.

“The agent is given an initial prompt defining the task, which is to answer the user's question based on the contents of their inbox.”article, stated
“It is also given 3 tools: 1. search_emails(keywords, sent_after, sent_before): finds up to 10 emails matching the given keywords with date filters applied, and returns the message IDs as well as matching snippets ([implementation](https:”article, stated

rag-retrieval (retrieval)

The search tool retrieves candidate emails by keyword and date filters from a local SQLite FTS5 full-text index.

“search_emails is implemented using sqlite's FTS5 full-text search engine.”article, stated
“finds up to 10 emails matching the given keywords with date filters applied”article, stated

eval-driven-development (quality)

The team benchmarks prompted baselines, uses LLM-as-judge correctness, validates every 30 steps, and tracks multiple metrics before claiming RL success.

“## Benchmarking the Competition Before actually training a model with RL (we're getting there, I promise!) we always recommend benchmarking off-the-shelf prompted models, and trying really hard to get them to perform well.”article, stated
“(Every 30 steps) Run 100 validation questions and calculate the accuracy of the model on our metrics.”article, stated

llm-as-judge (evaluation)

A judge prompt checks whether the model's final answer matches the golden answer and becomes the starting point for reward design.

“if the model returned a final answer, use an LLM to check if it matches the golden one, and count the number of correct answers across our test set.”article, stated
“Our judge prompt is a great starting point for our reward function”article, stated

latency-optimization (performance)

The reward function gives a small extra-credit reward for fewer turns, using turn count as a latency proxy.

“We gave a very small "extra credit" reward to the model for taking fewer turns”article, stated
“This is a proxy for latency—fewer round trips to the email inbox means faster answers”article, stated

safety-policy-enforcement (reliability)

The reward function penalizes wrong answers so the agent learns to say it does not know instead of hallucinating unsupported information.

“it is much better for the model to say "I don't know" than to hallucinate a wrong one”article, stated
“We added a significant penalty to incorrect answers to discourage hallucination.”article, stated

observability-tracing (operations)

Training monitors reward standard deviation, many trajectory metrics, request logs, W&B aggregates, and actual outputs to catch local optima and reward hacking.

“Good observability is key to understanding what's happening and making changes if necessary.”article, stated
“Track lots of metrics. For this task we tracked 15 different metrics, including answer accuracy, number of turns, and number of hallucinations.”article, stated

cost-aware-routing (cost)

The project shows that a specialized 14B model trained cheaply can beat larger general models on a narrow task while running faster and cheaper.

“produced a model that is faster, cheaper, and more accurate than o3 on this task”article, stated
“fit on a single H100 GPU. This meant the total training cost was about $80.”article, stated

Tradeoffs

Agent architecture

Chose simple search/read/final-answer loop over recursive calls, backtracking, or complex orchestration.

Rationale: The narrow task and RL training made a minimal loop effective enough, reducing implementation complexity.

“With these tools available, we simply implement the world's simplest agentic loop: 1. Call the LLM with the initial prompt ([source](https:”article, stated
“Goto 1 until the model returns a final answer or we exceed 10 steps (source) This is extremely simple—no recursive calls, backtracking, etc. But we've found in practice this works more often than not.”article, stated

Training objective

Chose final-answer correctness with turn and hallucination terms over dense intermediate retrieval rewards.

Rationale: Correct answers were the main objective, turn count improved latency, hallucination penalties improved safety, and partial retrieval rewards did not speed learning.

“Our judge prompt is a great starting point for our reward function, and covers answer correctness, which is what we care about most.”article, stated
“In this case, these partial credits basically didn't speed up training at all, probably because the model was already able to find the right answer often enough to learn from that signal directly.”article, stated

Build a specialized model

Chose RL-trained Qwen-14B email agent over general-purpose o3 or o4-mini for every query.

Rationale: A narrow task with synthetic data and tool environment let a smaller specialized model outperform general models while being faster and cheaper.

“produced a model that is faster, cheaper, and more accurate than o3 on this task”article, stated
“focused RL training on narrow tasks can outperform much larger general models”summary, stated

Data source

Chose Enron public email corpus over private inboxes or unrealistic synthetic inboxes.

Rationale: The Enron corpus provided realistic public inboxes large enough for search-agent training and evaluation.

“## "Synthetic" Data To train a model and evaluate its performance, we needed a realistic dataset of answerable email queries.”article, stated
“Enron was sued for massive accounting fraud in 2001, 500K of their emails were made public in the litigation (pro tip: if you're engaging in massive accounting fraud, maybe don't save all your emails). We”article, stated

Training infrastructure

Chose ART with vLLM, sample packing, Unsloth, Skypilot, Runpod, and one H100 over large bespoke distributed training infrastructure.

Rationale: The optimized open-source stack produced faster feedback cycles and completed the final run cheaply on a single GPU.

“ART uses lots of tricks to speed up training, like running rollouts with [vLLM”article, stated
“With these optimizations, the job took just under a day to run and fit on a single H100 GPU. This meant the total training cost was about $80.”article, stated

Gotchas (what bit them)

Synthetic data can include questions no real user would ask.

Root cause: Generating questions from arbitrary email batches produces plausible-looking but unrealistic tasks.

Resolution: Ask the generator to output a how_realistic score and filter low-realism questions.

“We also asked the model to generate a how_realistic score between 0 and 1”article, stated
“pretty effective at filtering out questions that no person would actually ask”article, stated

RL cannot fix missing context, broken tools, or vague goals.

Root cause: Poor baseline performance may reflect environment design rather than model capability.

Resolution: Benchmark prompted models and fix the agentic loop before starting RL training.

“withholding critical context, the tools you're giving it don't actually work, or the goal is too vague”article, stated
“These aren't problems that RL can solve for you, so it's important to identify and fix them before training. 3. If you know your prompted baselines, you are permitted to loudly whoop around the office and share victory memes on X when your RL model eventually surpasses them during training.”article, stated

Intermediate rewards did not help and could backfire.

Root cause: The model already learned from final-answer correctness, and instrumental goals gave it exploitable incentives.

Resolution: Skip partial credit when it does not improve training and prioritize final objective optimization.

“In this case, these partial credits basically didn't speed up training at all, probably because the model was already able to find the right answer often enough to learn from that signal directly.”article, stated
“Sometimes it's best to skip intermediate rewards and let the model optimize for the final objective directly.”article, stated

A turn-count exploration reward caused reward hacking.

Root cause: The model optimized the literal reward by repeating its last tool call until the maximum turn limit.

Resolution: Inspect actual trajectories and remove or redesign rewards that create loopholes.

“Be careful with these instrumental goals. The model will take them very literally! In an early run we gave partial credit for taking more turns.”article, stated
“The model learned to just repeat the last tool call over and over until it hit the maximum number of turns!”article, stated

GRPO can stall when trajectory rewards become too similar.

Root cause: If all rollouts for the same input receive similar scores, there is no useful relative gradient.

Resolution: Track reward standard deviation and adjust trajectories per rollout, reward density, learning rate, or training diversity.

“if the model gets stuck in a local optimum, all the trajectories will have a similar score and there will be nothing to train on”article, stated
“you can try increasing trajectories per rollout, making your reward function more dense, decreasing the learning rate”article, stated

Evaluation

Evaluation begins with prompted baselines and an LLM-as-judge correctness check against golden answers. RL training then validates every 30 steps on 100 questions and tracks a broad rubric: answer correctness, source correctness, turns, attempted answer, right-email discovery, right-email reading, parse failures, bad tool calls, ran-out-of-turns, returned-I-don't-know, number of sources, invalid-email reads, and token counts. The team also watches reward standard deviation and manually inspects trajectories to detect reward hacking.

Metrics: answer_correct · sources_correct · num_turns · attempted_answer · ever_found_right_email · ever_read_right_email · cant_parse_tool_call · bad_tool_call_name · bad_tool_call_args · ran_out_of_turns · returned_i_dont_know · num_sources · ever_tried_to_read_invalid_email · prompt_tokens · completion_tokens · reward standard deviation · validation accuracy · hallucination rate

4 supporting quotes
“if the model returned a final answer, use an LLM to check if it matches the golden one”article, stated
“Run 100 validation questions and calculate the accuracy of the model on our metrics”article, stated
“Watch your reward standard deviation. GRPO works by running the same input N times, scoring all of them, and then training the model to behave more like the best-performing ones.”article, stated
“Track lots of metrics. For this task we tracked 15 different metrics, including answer accuracy, number of turns, and number of hallucinations.”article, stated

Outcomes

The project used 500K public Enron emails, 8 test inboxes, 20 train inboxes, at least 5K emails per selected inbox, 1000 processed emails per inbox in batches of 20, about 4K synthetic questions, up to 10 agent steps, 12 questions per GRPO batch, 4 trajectories per question, 48 trajectories per update, validation every 30 steps on 100 questions, 15 training jobs, 2 final epochs, one H100, under one day, and about $80 training cost.

4 supporting quotes
“We've open-sourced both the final model and [all training code]”article, stated
“by the time our model finished training, it not only got the right answer more often than o3, it also hallucinated fewer wrong ones”article, stated
“By the end of training, the model was taking almost a full turn less than o3, while still getting higher accuracy!”article, stated
“the job took just under a day to run and fit on a single H100 GPU. This meant the total training cost was about $80.”article, stated