Skip to content
← All TILs
TIL

TIL : constraining an agent's tools beats instructing it

tool-usemodel-routingopencode-go

Building the model layering for my pi setup, I wanted a high-volume preset to avoid complex tool calls — the model on it has fragile tool-calling. First instinct: write it in the prompt. “Only read and write, avoid complicated bash commands.”

Bad idea. A model in a long run always ends up forgetting the instruction, or reasoning its way around it (“I need to just output text without tool calls”). A prompt instruction is an intention, not a guarantee.

The right way: technically restrict the tool list. In pi, a preset declares exactly what the model can access:

{
  "bulk": {
    "tools": ["read", "write"]
  }
}

The model physically has no bash, edit, grep. It can’t misfire them, since they don’t exist for it. The constraint holds, whatever the model “decides.”

The lesson goes beyond this case: when a behavior really matters — budget, security, scope — enforce it, don’t ask for it. The same principle drives my rm -rf guardrails, which block the command instead of trusting the agent not to type it. A limit you hope is respected isn’t a limit.

Further reading