PATCHBOOK SERIES Part of the Patchbook Series

Chapter 4: The first way to act

Chapter 3 ended with the knowledge in the loop and the hands missing. The loop can read your world: it quotes your policies, cites your code, summarizes your spreadsheets. It cannot touch any of them. Words are the model's one exit, and words cannot open a file. This chapter gives the loop its first pair of hands, and the trick is almost disappointing: the model could always act. It was waiting for someone to take its words literally.

One small task carries the whole chapter: a failing test. You paste it into a chat and ask for the fix. The reply comes back as a beautiful plan: open this file, change this line, run the suite. Then the model stops and waits, and you are the one who reaches for the keyboard. The plan is right. The instructions are precise. Doing them was never its part to play. By the end of this chapter, the model will not write you the plan. It will run it.

The homemade actor

The first way to act is a hack, and it predates every official feature for it. You add one instruction to the system prompt: when you want to run a command, reply with JSON, like {"run": "pytest"}. That is the whole change. Ask for the failing test fix, and the model does what it always does: it writes the plan, and at the bottom rides the JSON.

The new behavior lives on your side of the API. Your code, the host, reads every reply before displaying it, hunting for the JSON. When it finds one, it does not display. It runs the command, pastes the output into the array as the next message, and calls the model again. Now the loop acts on the test: the model says what to do, the host does it, and the model reads what happened before writing its next word.

The first actor, homemade: the host cuts the JSON payload and runs the command

It works, and it shipped products. The insight underneath it is small enough to miss: the model never needed a body. It needed a butler, and the butler was forty lines of your code.

Then the seams show. The model wraps its JSON in a polite sentence, or a code fence, or both. It invents fields the format never had. The longer the conversation runs, the more the format drifts, because the model is a writer, and writers improvise. Your parser is string surgery against a poet. The fix is not a better parser. It is a contract, and the contract has a name.

The tool contract

The vendors watched a thousand teams build that hack, then standardized it. The feature is called tool calling, and it moves the whole arrangement into the API. Before the conversation starts, you declare your tools: each one a name, a plain-language description, and a schema for its arguments, types and all. The model is trained on that contract, and when it wants to act, it emits a tool request: a structured field, separate from the prose, naming the tool and carrying a JSON object of arguments.

The host's job barely changed. Receive the request, execute the tool, return the result. The difference is what returns: the result comes home as a content block, appended to the array, exactly like the screenshot in chapter 2 and the PDF in chapter 3. This is the door those chapters kept mentioning. Tool results use it every time.

The first way to act: the host gains a tool

Readers of the first book met the four-step heartbeat: collect the input, call the model, append the reply, show it. The handshake threads a second beat inside the first. When the model requests a tool, the host executes and calls the model again before anything reaches your screen. Your one sentence about a failing test can hide a dozen heartbeats, which is why a coding agent seems to think for so long: it is not thinking. It is running errands.

The tool-call round trip as the message array sees it

The contract has two signatures. The model promises to request only declared tools, with arguments that match the schema. The host promises to execute and to return every result as a block, so the model always learns what its request did. Keep both promises and the loop can act all day. And notice what the contract reveals: the model never runs anything. It requests. The host runs. The agency was never inside the model. It lives in the deal between two programs.

Contracts break quietly, though. The model hands over a path that does not exist, or a number where the schema asked for a string. The schema drifts from the code: someone renames a function and the description still promises the old one. The fix is the same on both sides, and streaming taught it in chapter 2: validate before acting. The host checks every request against the schema, rejects what does not match, and returns the rejection as a block, so the model can correct itself and try again.

Try it

The problem with this

Look at the diagram again. The machine has two cycles now, and the model can act through both of them. But look at the new block inside the host. It is a single tool. The machine can act, and nothing has decided what it should be able to do.

That decision is the whole game. A read tool makes the agent a researcher. A write tool makes it an editor. A shell makes it an operator. The character of an agent is not in the model; it is in its toolbox. The next chapter builds one.