skip to content

How do you decide which tools a Koog agent's ToolRegistry exposes as the set grows?

level: principalimportance: should knowfreq 32%

answer

  1. registry is a reviewed surface
  2. paid per turn, every turn
  3. selection degrades with overlap
  4. registration equals capability grant
  5. allowlist imported tools

basics

~20 s

Treat the registry as a reviewed API surface, not a bucket. Every entry costs prompt budget on each request and widens what the model can reach, so scope registries per agent, filter imported MCP tools, and validate arguments inside the tool rather than trusting the schema.

solid answer

~50 s

Three forces push back on a big registry. Cost: every tool's name, description and schema is serialized into every request, so the tool surface is a per-turn tax that grows linearly. Accuracy: the more near-duplicate descriptions the model must choose between, the worse selection gets, and the fix is usually sharper wording or fewer tools rather than a bigger model. Blast radius: registration is the capability grant, so anything registered is reachable at any point in a run. Practically that means building a narrow registry per agent instead of one global one, constructing registries from configuration per run when the surface is tenant-specific, allowlisting and renaming tools imported from an MCP server so foreign names cannot collide with yours, and validating arguments inside the tool because a schema constrains the model but never guarantees it. Tool choice via LLMParams.ToolChoice is a per-request lever, not a substitute for scoping.

go deeper

for a junior

Know that adding a tool is not free: it is sent with every request and becomes something the model may call at any point during a run.

for a middle

Explain the two costs concretely, namely tokens per turn and worse selection among overlapping descriptions, and know tool choice exists as a per-request lever.

for a senior

Show how you scope registries per agent or per run, filter imported MCP tools, and guard side-effecting tools inside the implementation rather than trusting the schema.

for a principal

Own the surface as policy: who may add a tool, how descriptions are reviewed and regression-tested, how tenant-specific registries are built, and what the blast radius of each grant is.

## Why the registry is a design artifact In Koog, ToolRegistry is the only thing that decides what an agent can do. That makes it three things at once: a cost centre, a correctness input, and a security boundary. Teams that treat it as a place to accumulate useful functions discover all three at the same time, usually in production. ## The per-turn tax Every registered tool contributes a name, a description and a parameter schema to every model request in the run. Twenty well-documented tools is a meaningful block of tokens paid on every single turn of a multi-step agent, and it is paid whether or not any of them are relevant to the current task. Because agent loops make several calls per user request, this is one of the few costs in an agent that multiplies rather than adds. It also competes with the conversation itself for context. ## The accuracy tax Selection quality degrades as tools multiply, especially when descriptions overlap. Two tools that both plausibly answer a question mean the model has to guess, and the failure is silent: a wrong-but-successful tool call. The first remedy is editorial, namely sharper descriptions that say when not to use a tool rather than only what it does. The second is structural: fewer tools in front of any one decision. Splitting a sprawling agent into several agents with narrow registries usually beats prompt-engineering a twenty-tool menu. ## The capability grant Registration is the moment you hand a capability to a model that will invoke it if a description sounds relevant. There is no per-call authorization layer in the registry itself, so tools that spend money, mutate production state or touch the filesystem need their own guards inside the implementation: argument validation, allowlists, quotas, and where appropriate a human approval step before the effect. The schema is a constraint on generation, not a guarantee about what arrives; assume any syntactically valid argument can appear, including one produced by an instruction injected into retrieved content. ## Imported tools deserve more scepticism Tools pulled from an MCP server arrive with names and descriptions written by someone else, on their release schedule. Two rules keep that manageable. Allowlist rather than merge wholesale, so the surface is a decision you made rather than whatever the server currently advertises. And control naming, because a foreign tool colliding with one of yours is a resolution problem you never want decided implicitly. ## Composition patterns that work Build registries as values, per agent and per run, rather than one shared singleton. Derive them from configuration when the surface varies by tenant or plan. Where a workflow has clearly separate phases, giving each its own agent and registry keeps each decision small. And keep descriptions under change control with a few regression prompts, since a reworded description silently changes routing. ## What tool choice does and does not solve LLMParams.ToolChoice, with its Auto, None, Required and Named variants, is the per-request lever: forbid tools for one call, force a tool when you know one is needed, or pin a specific one. It is genuinely useful for deterministic steps. It does not reduce the declarations sent, and forcing a call when the model should have answered or stopped creates its own failure mode, so it complements a scoped registry rather than replacing it.

  • What does LLMParams.ToolChoice let you control, and what does it not fix?
    It controls the current request: Auto lets the model decide, None forbids tool calls, Required forces some tool, and Named pins a specific one. It is the right lever for a step you want deterministic. It does not shrink what is sent, since all declarations still go out, and forcing a call when the model should have answered or terminated can push the loop into calling tools it does not need.
  • An agent keeps choosing the wrong one of two similar tools. What do you change first?
    The descriptions, before anything else. Say explicitly when each tool should not be used and what distinguishes their inputs, since the model chooses on that text alone. If they remain genuinely overlapping, merge them into one tool with an enum parameter, or split the work across agents so only one is in front of the decision. Reach for a bigger model last.
  • Why is schema validation not enough for a tool that mutates production state?
    The schema constrains what the provider is asked to generate; it is not a guarantee about what arrives, and a model steered by injected text in retrieved content can still emit well-formed arguments. Validate inside the tool, enforce allowlists and quotas there, and put irreversible actions behind an explicit approval step. Registration is the grant, so the guard belongs where the effect happens.

saying these in an interview costs you the question

  • Treating one global registry as the default design
  • Assuming tool declarations are sent only once per run
  • Believing the schema guarantees safe arguments
  • Merging every MCP-advertised tool unfiltered
  • Using forced tool choice to paper over a bloated registry

context