Research / September 28, 2026
Deep Agents SFT from traces
We fine-tuned a LangChain Deep Agents code reviewer on its own LangSmith traces with smithtune, changing only which traces it learned from. In a rerun built the way smithtune recommends, with rules published first and three training runs a side, the traces While. chose got 52% of SWE-bench Verified reviews right against 36%.
The short version. We fine-tuned a LangChain Deep Agents code reviewer on its own LangSmith traces with LangChain's smithtune, changing only which traces it learned from. LangChain's team pointed out that our first try skipped smithtune's main step: reading traces and writing the rubric together. So we reran it their way and published the rules before training. The traces While. chose still won, 52% of reviews right on a public benchmark against 36%, on every training run. Doing it smithtune's way helped too: the two choices now share most of their traces.
Same 262 traces, each side keeps 174, same trainer and server. Each bar pools three training runs with different seeds.
| Item | Value |
|---|---|
| smithtune skill path, SWE-bench Verified | 35.6% |
| While's pick, SWE-bench Verified | 52.0% |
| smithtune skill path, held-out repos | 58.1% |
| While's pick, held-out repos | 67.9% |
Five steps from traces to a fair comparison
- Run the stock agent and keep its runs. A stock Deep Agents agent [1] on Qwen3.8-27B, an open model, reads a proposed patch for a real GitHub issue and answers approve or reject. Each run is recorded step by step (a trace) in LangSmith [2]. Hidden tests already decided whether each patch works, so the right answer is known.
- Choose the training traces two ways. Without While., we follow the smithtune skill [3]: read 20 varied traces, write the rubric from what they show, check it on a 20-trace trial, then let smithtune's panel of model judges (its council) keep or drop each trace. With While., a trace is kept only if it is correct and used at most eight model calls.
- Hold everything else equal. Both sides keep 174 traces and are fine-tuned with smithtune's own renderer and split for 2 passes over the data, three times each with different seeds.
- Score on tests nobody here built. SWE-bench Verified [4] patch review, and 84 repos the traces never touched. One server, same sampling.
- Publish the rules first. Every rule was merged before training [8].
- Start: The same 262 correct traces (one LangSmith pool).
- Without While: Read 20 traces, write a rubric (the smithtune skill's path), then Trial on 20, then the council (kept 184 of 260).
- With While: Score every trace (correct, 8 model calls or fewer), then Keep a spread of tool habits (kept 174).
- Both arms: Cut both to 174 traces (random sample, seed 0), then Fine-tune 2 epochs, three seeds (smithtune renderer and split), then Score on two benchmarks (paired by review).
Only the choice of traces differs. Our first rubric, written without reading traces, kept 258 of 260.
The short traces won on every run
Reading the traces mattered. The council kept 184 traces instead of 258, and its choice shares 142 traces with the While. pick. The gap comes from the rest: the council still keeps long correct reviews, and a model trained on them keeps reading files until it runs out of steps without an answer. The eight-call budget in the While. pick teaches it to finish.
SWE-bench Verified. A review that runs out of steps gives no verdict and scores as wrong.
| Item | Value |
|---|---|
| smithtune skill path | 48.5% |
| While's pick | 22.0% |
Paired by review, three seeds a side, 95% intervals. Every While seed beats every smithtune seed in experiment 1, and 8 of 9 pairs in experiment 2.
| Item | Value | 95% interval |
|---|---|---|
| Experiment 1, SWE-bench Verified | +16.4 pts | +12.5 pts to +20.3 pts |
| Experiment 1, held-out repos | +9.8 pts | +6.5 pts to +13.1 pts |
| Experiment 2, SWE-bench Verified | +17.3 pts | +13.9 pts to +20.9 pts |
| Experiment 2, held-out repos | +13.7 pts | +10.3 pts to +17.4 pts |
Spending 400 more runs did not help either side
A second experiment gave each side 400 more agent runs on unused tasks. smithtune cannot aim, so its side drew them at random. While. aimed its draw at the kinds of patches the stock agent got wrong. Each side then picked its own way. The While. side won again, but neither side beat its own result from the first experiment, so the extra runs did not pay off here.
- Start: 756 unused review tasks (real repos, known verdicts).
- Without While: Draw 400 at random (smithtune cannot aim), then Run the agent, add to the pool (same rubric and council).
- With While: Draw 400 aimed at weak spots (weighted by failure rate), then Run the agent, add to the pool (same scoring rule).
- Both arms: Cut both to 317 traces (as in experiment 1), then Score on two benchmarks (paired by review).
Both sides spend the same 400 agent runs on real tasks with hidden tests.
One mistake we fixed on the way
We first trained with smithtune's default stopping rule, which keeps the pass with the lowest validation loss. The first and second passes scored almost the same on that check, so the rule picked close to at random, and first-pass models mostly loop. Scores then swung with luck more than with traces. We published that result as registered, changed the rule to exactly two passes before scoring the second experiment, and reran both [8]. The registered result pointed the same way.
What this teaches about post-training
Fine-tuning copies behavior, all of it. A correct review that took twenty calls is a lesson in taking twenty calls. Filtering outputs by a score and training on the survivors is rejection sampling [5]; a budget on calls turns efficiency into data.
The LangChain team was right that reading traces matters. It moved the council most of the way to the same answer. A rule that encodes what the reader noticed finishes the job, and runs again on the next batch of traces without anyone reading them.
The pipeline stayed LangChain's. Deep Agents ran the agent, LangSmith kept the traces and smithtune trained the model. While. decided what to train on and whether it worked.
For researchers
| Setting | Value |
|---|---|
| Agent | LangChain Deep Agents create_deep_agent, read-only filesystem over a tarball of the base commit, Qwen3.8-27B |
| Training pool | 400 reviews from nebius/SWE-agent-trajectories and nebius/SWE-bench-extra [6], split by repository, 262 correct and usable |
| smithtune side | rubric_codesigned.md written after reading 20 traces, 20-trace trial kept 13 of 19, then smithtune dataset triage with the default council (DeepSeek V4.1 Flash, GLM-5.3-Flash on Baseten), 184 of 260 kept |
| While. side | wai.optimize(mode="sft"), reward 1 only for a correct verdict within 8 model calls, round-robin over tool-call signatures, 174 kept |
| Equal size | both cut to 174 by random.Random(0).sample; 142 traces in both sets |
| Rows | smithtune prepare_sft_rows (reasoning omitted), split_rows 80/10/10, render_row_tokens |
| Schedule | LoRA rank 8, batch 32, lr 1e-4, exactly 2 epochs, seeds 42, 43, 44, one Modal H200 per run |
| Experiment 2 | 400 new tasks per side from 756 unused, uniform vs weighted by the stock agent's failure rate per task type (aim.py), each side's own pick, both cut to 317 |
| Serving | one vLLM 0.26 server, all twelve adapters, enable_thinking=false, same sampling |
| Benchmarks | SWE-bench Verified [4], 250 reviews on 125 issues, 50/50 approve and reject; 246 reviews on 84 held-out repositories |
| Paired test | wai.compare_runs on the three seeds pooled, paired by review, 95% bootstrap interval |
| Registered schedule | early stop on validation loss kept epoch 1 on 10 of 12 runs; experiment 1 under it, +9.5 (+6.4 to +12.8) on SWE-bench Verified |
| First result, 2026-09-28 | one seed, rubric written without reading traces, council kept 258; 46.0% vs 56.8%, +10.8 (+4.8 to +16.8) |
The metric is accuracy, for review under seed , and the comparison is the paired mean difference over reviews, seeds pooled, with a bootstrap interval over reviews:
Seed spread inside one side is up to 18 points, which a bootstrap over reviews does not see. The seed-pair count in the chart above is the check that does not lean on it. Every number is in the recipe's results.json [7].
References
- LangChain (2025). Deep Agents [software]. github.com/langchain-ai/deepagents. Accessed September 28, 2026.
- LangChain (2026). LangSmith documentation. docs.langchain.com/langsmith. Accessed September 28, 2026.
- LangChain (2026). smithtune v0.1.0 [software], including the smithtune skill. github.com/langchain-ai/smithtune. Accessed October 1, 2026.
- Jimenez, C. E., Yang, J., Wettig, A., Yao, S., Pei, K., Press, O. and Narasimhan, K. (2024). SWE-bench: Can language models resolve real-world GitHub issues? ICLR 2024. arXiv:2310.06770. SWE-bench Verified subset: OpenAI (2024), Introducing SWE-bench Verified, openai.com/index/introducing-swe-bench-verified.
- Lambert, N. (2025). Reinforcement Learning from Human Feedback, chapter Rejection Sampling. arXiv:2504.12501. Online at rlhfbook.com.
- Nebius (2024). SWE-agent-trajectories and SWE-bench-extra [datasets]. huggingface.co/datasets/nebius/SWE-agent-trajectories.
- whilehq (2026). deepagents-review-four-arms recipe, whileai SDK [code and data]. github.com/whilehq/whileai-sdk/tree/main/recipes/community/deepagents-review-four-arms.
- whilehq (2026). Pre-registration of the fair rerun and amendment 1, deepagents-review-four-arms recipe [code and data]. github.com/whilehq/whileai-sdk/blob/main/recipes/community/deepagents-review-four-arms/PREREGISTRATION.md.
Run it
pip install whileai
git clone https://github.com/whilehq/whileai-sdk
cd whileai-sdk/recipes/community/deepagents-review-four-arms
python run.py --dry-run # the comparison and the selection rule on fixture rows, no keys
python make_results.py # every number above, from the committed rowsEvery command for the rerun, from the smithtune pull to scoring all twelve models, is in the recipe README.