๐Ÿงฉ Agentic Scaling how consumer AI scales ยท 1 โ†’ 1B

Tools โ€” letting the model act, safely

An assistant that can only talk is limited to what it already knows. Tool use lets it do things mid-turn: search the person's own memories, run a calculation, check a calendar, search the web. This chapter is about the shape of that capability and the fences around it. The thesis, said the tools way: an assistant becomes personal by acting on one person's behalf inside one person's boundary โ€” and scale is a hundred million such boundaries enforced by the same loop.

๐Ÿ“– Story: the day the controller stopped being yours

An engineer who has built web services for years knows exactly how a request flows: they wrote the controller, so the downstream calls and their order are fixed before the code ships. Then they wire a model into the middle of a turn and hand it a list of tools. The first time the model calls a tool they did not anticipate, in an order they did not write, twice because the first result was empty โ€” something shifts. The path through the request is now decided at runtime by a model, not at compile time by a person. Everything in this chapter follows from accepting that, then deciding deliberately how much of the wheel the model may hold.

What changes when the model can act?

In a conventional service you are the router. In the agentic loop the model is the router: at each step it reads the context pack and the tool catalog and decides whether to call a tool; the loop executes the call and feeds the result back. Three things a web engineer takes for granted are no longer true:

In a web service In the agentic loop
The call graph is fixed at build time The model chooses tools, order, and count at runtime
A downstream failure is an exception that ends the request A tool failure is data the model reasons about
One request โ‰ˆ one pass through the code One turn is a loop of model calls under caps

None of this makes the system uncontrollable. Control moves from the code path to three places: the catalog (what exists), the scope (what this turn may touch), and the caps (how long it may try).

What does one iteration of the loop look like?

The loop within the turn is four verbs repeated: decide โ†’ call โ†’ observe โ†’ decide. The model decides whether it needs a tool; the loop calls it; the model observes the result as a new message; it decides again โ€” answer, or call something else.

flowchart TD
  P[Context pack + tool catalog] --> D{Model decides}
  D -->|final answer| G[Generate + output guardrail]
  D -->|tool call| S[Scope + validate args]
  S --> C[Call tool]
  C --> O[Observe result
ok or error, as data] O --> K{Caps left?} K -->|yes| D K -->|no| G

Every iteration is one model call plus zero or more tool calls, each written to the turn's trace with its tokens, latency and outcome โ€” the observability the rest of the system depends on. The loop ends for a named reason: the model stopped calling tools, or a cap tripped. The stop reason is itself a metric; a rising share of "cap tripped" endings reveals a broken tool before users do.

๐Ÿชค Misconception โ€” "the model runs the tool." It never does. The model emits a request (a tool name and arguments as structured text); trusted code executes it and decides what the model may see of the result. The model holds the pen; the loop holds the keys.

How does the model know what tools exist?

The model is told, every turn, in the prompt: a catalog of tool names, one-line descriptions, and a schema for each tool's arguments. The design question is where that catalog is defined. Two answers; one does not scale.

Bespoke integration. Each client (every assistant, every internal agent) hard-codes each tool's shape. With N clients and M tools that is Nร—M integrations, each drifting independently when a tool changes.

Self-describing tools. The tool's author publishes its description and schema with the tool, and clients discover them at startup through a standard protocol. MCP is the open protocol for exactly this: a client asks a tool server "what do you offer?", receives the catalog, and later says "call this one with these arguments". Any conformant client speaks to any conformant server, so the count becomes N+M.

flowchart LR
  subgraph NM["Bespoke: N ร— M"]
    A1[Client A] --- T1[Tool 1]
    A1 --- T2[Tool 2]
    B1[Client B] --- T1
    B1 --- T2
  end
  subgraph NpM["Self-describing: N + M"]
    A2[Client A] --> H[One protocol
discover + call] B2[Client B] --> H H --> T3[Tool 1 + schema] H --> T4[Tool 2 + schema] end

Two properties matter beyond the arithmetic. The schema lives with the tool author, the only one who knows when it changes. And a tool error comes back as a normal result marked as an error โ€” not a transport failure โ€” which is what lets the loop treat failure as data. Discovery happens once when a worker starts, not per turn; a per-turn handshake would add idle latency in front of every first token.

โš ๏ธ Pitfall โ€” a catalog the model cannot read. Descriptions written for engineers ("wraps the v2 endpoint") produce a model that calls the wrong tool or none. The description is a prompt: say what the tool is for, when not to use it, and what a good argument looks like.

How is a tool scoped to one person?

This is the most important section in the chapter. Some tools are neutral โ€” arithmetic, the time, public search. Others read personal data: search this person's memories, look up this person's profile. Those must never read across users, and the rule that guarantees it is absolute: the model never chooses the identity.

TEXT
for each tool_call from the model:
    if tool reads personal data:
        args.user = turn.user          # overwrite, never trust the model's value
    result = call(tool, args)          # the tool server also refuses a missing user
    conversation.append(tool_result(result))

The loop injects the identity from the authenticated session, overwriting anything the model produced, and the tool server independently requires it. Two layers, because a shared tool server that trusted a client-supplied identity would be one confused model away from reading a stranger's memory namespace. The memory namespace from the memory chapter is the data boundary; the loop's injection is what makes tools respect it.

Scoping extends beyond identity. A turn carries an allowlist โ€” the subset of the catalog this user, segment and surface may use (a minor's assistant gets no payments tool; a voice surface gets no tool that returns tables). The catalog the model sees is already filtered; the loop rejects calls outside it as a second check.

๐ŸŽฏ At consumer scale, tools are the largest fan-out in the system. A hundred million people making twenty turns a day, a quarter of them calling a tool or two, is a billion tool calls a day โ€” each with its own latency, failure rate and cost. Tool servers are scaled like any tier of the fleet, and the loop's caps keep one misbehaving tool from becoming a billion retries.

What stops the loop from running away?

A loop that can call tools can, in principle, call them forever. Four caps, all cheap, all logged:

Cap What it bounds What happens when it trips
Iteration limit model calls per turn (a handful) loop ends; model answers with what it has
Cost + latency budget tokens spent and wall-clock per turn graceful abort before the next model call
Repeated-failure detection the same tool with the same arguments failing twice that call is refused; the model is told why
Tool-error isolation a tool's exception reaching the turn error is returned as a result; the turn survives

The last one, tool-error isolation, matters most. A tool that throws should never end the turn; it should become a message โ€” "the calendar service did not respond" โ€” that the model can explain, work around, or retry differently. The budget cap is the same per-turn cost budget the model-serving chapter routes on, so a tool-heavy turn also shapes which model tier serves its next iteration.

Where do guardrails wrap the tool calls?

Guardrails sit in three rings; tools live inside the middle one.

flowchart LR
  I[Input guardrail] --> L
  subgraph L[Agentic loop]
    D[Model decides] --> V[Per-call guard:
allowlist ยท schema ยท scope] V --> X[Tool] X --> R[Result filter:
size ยท secrets ยท PII] R --> D end L --> O[Output guardrail]
๐Ÿ” See it happen โ€” Raj asks for a number he only half remembers

Raj types: "What's a quarter of that trip cost I told you about last week?"

Iteration 1 โ€” decide. The context pack has no matching memory (retrieval searched "trip cost", but Raj had said "flights and the cabin"). The model calls search memory with query "trip flights cabin". The loop overwrites the user argument with Raj's own identity and checks the tool is on his allowlist. Observe: one memory โ€” "flights + cabin came to 1,840, split later with Lena".

Iteration 2 โ€” decide. The model calls calculate with "1840 / 4". Observe: 460.

Iteration 3 โ€” decide. No further tools. The model drafts: "A quarter of the 1,840 you mentioned for the flights and cabin is 460." The output guardrail confirms the answer cites a memory that exists in the pack. Stop reason: model finished. Three model calls, two tool calls, well under the caps โ€” all recorded under the turn id.

Had the calculator been down, iteration 2 would have observed an error-as-data, and the model would have done the division itself and said so.

๐Ÿงญ Enterprise mapping โ€” the tool catalog becomes the enterprise's integration surface, and the scoping rule becomes its authorization model: the identity injected into every call is the employee's, carrying their role and the tenant's data boundary, so a tool reads only what that person could read in the source system. Consequential tools (issue a refund, change a limit) get human-in-the-loop confirmation and an audit entry per call; the allowlist is per-tenant policy; and self-describing tools over an open protocol let a bank connect its own systems without a bespoke integration per assistant. Same loop, same caps โ€” with the confirmation ring made mandatory. See the enterprise chapter.

Where to next

Tools introduce a new class of things that can go wrong inside a turn, which is why the next two chapters exist: Quality covers how tool-using turns are scored and traced; Trust expands the three rings sketched above. To see where the loop sits inside the whole request, return to One Turn.