What you’ll build
Beam is a strong reasoning model, and that makes it a strong teacher. The thoughts it writes can be distilled into a much smaller model, and a student that has learned to think briefly and to the point before acting spends far fewer tokens than one left to think on its own. The recipe applies Beam to existing tool-calling datasets: Beam rewrites each conversation with a short thought before every assistant turn and changes nothing else. A thought is about 350 characters on average. What Beam adds is judgement in context. The teacher sees the whole conversation at once, so each thought is written with the later turns in sight: it names the function it is about to call, justifies each argument, and says why a result settles the question or why another call is needed.What you’ll learn
- Whole conversations, not single turns. A thought that cannot see a later result cannot justify the call that uses it, so Beam writes every thought in one pass, and each tool call must come back verbatim.
- Two rules shape the behaviour. ToolACE conversations must act, not ask: a text reply with no tool result to draw on drops the conversation. Nemotron conversations must look up, then act: a call argument has to come from an earlier result. A good tool-calling assistant acts when it has what it needs, asks only when it must, and uses what it just learned.
- The audit catches cheating thoughts. A value quoted from the next tool result, or a mention of “the example” or “the rewrite”, drops the whole conversation.
What you need
- A Reflection API key in a
.envfile in this folder, asREFLECTION_API_KEY=<your key>; the cookbook’s.env.examplelists the variables, and the other two default to the API and Beam. - A Linux machine with Python 3.12, 16 GB of RAM and 3 GB of disk, no GPU.
requirements.txtpins the dependencies andconfig.pypins the two public dataset revisions.
The recipe skips the 1,302 conversations without a call that our run sent, so a full run sends about 1,635 ToolACE conversations and about 55M tokens in total; at 32 concurrent requests (
WORKERS=32 bash run.sh; the default is 16) the teacher stage takes about 3 hours.
Run it
Try it in two minutes
run.sh runs the six stages into work/, keeping 20 conversations of each source spread evenly over the selection. One line per stage tells you it worked:
assemble kept 12 of the 20 ToolACE conversations (8 replied in text without a result to draw on) and 19 of the 20 Nemotron ones (one lost a turn to the audit), and mix wrote 31 conversations with a mean thought of 342 characters. A progress bar runs during the teacher stage.
ok_turns counts assistant turns that received an accepted thought; bad counts conversations that failed every attempt. Those are retried the next time you run the same command, and completed conversations are matched to their rows by id, so a changed LIMIT or selection cannot mix thoughts up.
</details>
Build the full set
LIMIT, about 3 hours with WORKERS=32 (the default is 16). The teacher stage appends to its output and resumes after an interruption, so after an outage you run the same command again. Its thought style is one sentence of the prompt in teacher.py:
Write the thought the way a careful engineer thinks before acting: enough to justify the decision and each parameter value, and nothing that does not change the decision.
Check the data
REFLECTION_API_KEY set it also sends one conversation to the teacher and checks that both assistant turns received an accepted thought.
</details>
Common fixes
COMMON_FIXES.md lists the symptoms we hit, their causes and the fix for each: a missing API key, dropped requests in the teacher stage, a slow teacher stage, a failed pool stream, a failed ToolACE download, and fewer rows than expected afterassemble.
Next steps
- Fine-tune on
work/train.jsonl. The TRL fine-tuning recipe in this cookbook trains Gemma 4 on this file and evaluates before and after. - Use your own conversations. Write them in the ToolACE row format or in OpenAI chat format and convert them with
nemotron.to_toolace_row, then runenrich,audit,assembleandmixunchanged. To draw more data, raise the sample sizes inconfig.pyand keep the audit. - Change the thought style with
--thought-style verboseorconcise: verbose matched the recipe’s accuracy at 25 to 30% more output tokens, concise saved another 25% of tokens but cost the 12B five points. - Related reading. The ToolACE paper describes how its conversations and APIs were generated; the Nemotron-SFT-Agentic-v2 card describes the customer-service trajectories; BFCL is the benchmark the SFT recipe reports.