SLM Agents & Tool Use
Why tool use is where the capability gap shows up most, and the three techniques that make a small model a reliable agent anyway
SLM Agents & Tool Use
TL;DR
Multi-step planning and reliable tool calling are exactly where a small model's capability ceiling shows up most visibly — a vague prompt asking for well-formed JSON simply doesn't get one reliably enough at this scale. Three things compensate: constrained decoding (make malformed output impossible, not just discouraged), tool-use fine-tuning on your exact schema, and routing the cases that are genuinely too hard up to a larger model.
| Property | Value |
|---|---|
| Level | Intermediate |
| Reading time | ~17 minutes |
| Prerequisites | Speculative Decoding |
| You will understand | Why small models struggle at tool use specifically, and the three techniques that fix it |
Where the Gap Actually Shows Up
Small models are often surprisingly competent at single-turn tasks — answering a question, summarizing a passage, classifying text. The gap to large models widens sharply on tasks that require holding a plan across several steps and producing output another program has to parse correctly. Tool use is exactly that: pick the right tool, produce syntactically valid arguments, and do it consistently across many calls, not just most of the time.
"Mostly valid JSON" is not valid JSON. A large model that gets the tool-call format right 98% of the time is annoying at scale. A small model that gets it right 85% of the time will break your parser on a meaningful fraction of real traffic, and prompting harder ("please output ONLY valid JSON") rarely closes that gap on its own.
Fix One: Constrained Decoding
Instead of hoping the model produces valid output, make invalid output impossible to generate. Constrained (or structured) decoding restricts which tokens are allowed at each step of generation, so that the output is forced to conform to a grammar — typically a JSON Schema describing the tool's exact argument shape.
Prompting for JSON vs constraining the output
Prompting alone
"Please respond with valid JSON matching this schema." The model can still emit a stray comma, an unquoted key, a hallucinated field, or prose before the JSON — and at small scale, it sometimes will.
Constrained decoding
RecommendedAt each generation step, only tokens that keep the output on a valid path through the schema are allowed. A malformed tool call isn't unlikely — it's unreachable. The model still chooses which valid tool call to make; it just can't produce an invalid one.
This single change closes most of the reliability gap that makes small models feel untrustworthy for tool use — the model doesn't need to get smarter about formatting, because formatting is no longer something it has discretion over.
Fix Two: Tool-Use Fine-Tuning
Constrained decoding guarantees the shape of a tool call is valid. It says nothing about whether the model picked the right tool, with the right arguments, for the situation. That's a task-competence problem, and it responds to the same fix covered in Fine-Tuning Small Models: train on examples of your exact tools and your exact typical call patterns.
A small model fine-tuned on your specific tool schema reliably beats a general frontier model prompted zero-shot with the same tools. This is the tool-use version of the SLM value proposition from the crash course: narrow and specialized beats broad and general, on the narrow task, every time the comparison has been fine-tuned for.
A practical fine-tuning set for tool use looks like transcripts: a user message, the correct tool call (or sequence of calls), the tool's result, and the model's final response — enough examples covering your actual tool surface that the model learns the pattern of when each tool applies, not just memorizes individual examples.
Fix Three: Route What You Can't Fix
Some tasks are genuinely too hard for a small model regardless of constraints or fine-tuning — deep multi-step reasoning, ambiguous instructions needing real judgment, tools whose correct use depends on world knowledge the small model simply doesn't have. For those, the answer isn't a bigger fine-tuning set — it's not asking the small model to do it alone.
Request arrives
│
▼
Small model attempts it (fast, cheap, constrained decoding on)
│
├── Confident, tool calls valid, task fits the trained pattern → done
│
└── Low confidence, unfamiliar request shape, or repeated tool failures
│
▼
Escalate to a larger model (or a human)This routing pattern is covered in full in Production & Operations — it's introduced here because tool use is where the need for it is most obvious: a malformed or wrong tool call is a much costlier mistake than a slightly-worse prose answer, so the threshold for escalating should be lower for agentic tasks than for plain generation.
Choosing an Agent Framework for a Small Model
smolagents offers two patterns worth distinguishing at this scale:
CodeAgent vs ToolCallingAgent, for a small model specifically
ToolCallingAgent
RecommendedClassic JSON tool calling — the model picks a tool and produces arguments. This is a much easier target for a small model to hit reliably, especially combined with constrained decoding, since the output shape is simple and well-defined.
CodeAgent
The model writes and executes Python to take actions. More expressive, but asking a smaller, less capable model to write and self-debug correct code raises the failure surface considerably — a malformed tool call is a rejected JSON object; malformed code is a stack trace the model then has to reason about and recover from.
Sandboxing matters more, not less, with a smaller model. A less reliable model is more likely to produce an unexpected action, whether that's a CodeAgent writing something you didn't anticipate or a ToolCallingAgent invoking a destructive tool in an unintended situation. Run agentic small models in a sandbox (e.g. smolagents' DockerSandbox) and keep the same authority boundaries you'd enforce for a larger model — a smaller model earns more scrutiny at the execution boundary, not less.
Concept Checks
Check yourself
Why does constrained decoding fix small-model tool-call reliability more effectively than a better-worded prompt?
Because prompting only makes valid output more likely, while constrained decoding makes invalid output structurally impossible — at each generation step, only tokens that keep the output on a valid path through the schema are allowed. A small model's weaker instruction-following means prompt-only guidance fails often enough to matter; removing the model's ability to go off-schema at all closes that gap regardless of the model's underlying reliability.
Constrained decoding guarantees a tool call is well-formed JSON. Does it guarantee the tool call is correct?
No. Constrained decoding only guarantees the shape is valid — it says nothing about whether the model picked the right tool or the right arguments for the situation. That's a task-competence problem, fixed by tool-use fine-tuning on your specific schema and call patterns, not by decoding constraints.
Why is ToolCallingAgent generally the safer default for a small model compared to CodeAgent?
Because ToolCallingAgent's output — a structured tool call — is a much simpler, more constrainable target than CodeAgent's output, which is arbitrary Python the model must also get right and potentially self-debug. A smaller model is less reliable at that broader, self-correcting task, so the failure surface is considerably larger with CodeAgent at this scale.
Key Concepts Recap
| Concept | One-line summary |
|---|---|
| Where the gap shows up | Multi-step planning and reliable, parseable tool calls, more than single-turn generation |
| Constrained decoding | Makes malformed tool-call output impossible to generate, not just discouraged |
| Tool-use fine-tuning | Training on your exact schema and call patterns fixes correctness, not just formatting |
| Routing/escalation | Send genuinely hard cases to a larger model or a human instead of forcing the small model through them |
| ToolCallingAgent vs CodeAgent | JSON tool calling is a more reliable target for a small model than self-debugged code |
| Sandboxing matters more here | A less reliable model deserves tighter execution boundaries, not looser ones |
Next
With tool use covered, the next page addresses a different gap — a small model's narrower world knowledge — and the technique built to fix it: SLM RAG.
Speculative Decoding
How a small draft model makes a large target model faster — the mechanism, why it works, and the alternatives that don't need a second model at all
SLM RAG
Why retrieval and small models pair naturally, how to build a fully local RAG stack, and the tighter context budget a small model needs