[{"data":1,"prerenderedAt":136},["ShallowReactive",2],{"blog-en-i-gave-the-agent-the-button-i-built":3,"header-blog-translations-\u002Fen\u002Fblog\u002Fi-gave-the-agent-the-button-i-built":133},{"id":4,"title":5,"author":6,"body":7,"date":115,"description":116,"draft":117,"extension":118,"image":119,"meta":120,"navigation":121,"path":122,"seo":123,"stem":124,"tags":125,"translationKey":131,"__hash__":132},"blog_en\u002Fblog\u002Fen\u002Fi-gave-the-agent-the-button-i-built.md","I Gave the Agent the Button I Built","Patrick Hofmann",{"type":8,"value":9,"toc":107},"minimark",[10,14,17,22,38,47,50,54,57,60,63,67,83,93,100,104],[11,12,13],"p",{},"A few weeks ago I built a destroy button to get rid of an agent without logging in as root. That was work I did for myself — a danger zone in the UI, a button, a confirmation.",[11,15,16],{},"Now the same button exists a second time. This time it isn't a human holding it, but an agent. As a tool.",[18,19,21],"h2",{"id":20},"what-the-agent-can-do-now","What the agent can do now",[11,23,24,25,29,30,33,34,37],{},"There are two new tools in the agent runtime: ",[26,27,28],"code",{},"agent.spawn"," and ",[26,31,32],{},"agent.destroy",". The first creates a new agent — name, optionally a recipe, a system prompt, and above all: a model and a ",[26,35,36],{},"reasoning_effort"," for exactly this agent. The second clears it away again.",[11,39,40,41,43,44,46],{},"The agent that uses these tools is an orchestrator. It pulls tasks from a backlog, sizes them up, and spawns its own workers to do the work. A simple task goes to a small model with little ",[26,42,36],{},". A hard one to a large model with a lot. When the worker is done and has delivered its result, the orchestrator calls ",[26,45,32],{},", and the worker is gone.",[11,48,49],{},"No worker standing around idle, waiting for the next task. Each lives for exactly one job.",[18,51,53],{"id":52},"why-ephemeral","Why ephemeral",[11,55,56],{},"The obvious instinct with worker agents is to keep them alive. Once spun up, they wait for the next job — saves creating them again. I built it the other way around: workers are created per task and destroyed after it.",[11,58,59],{},"There are two reasons. The first is cost: a worker only consumes something while it works. The second is cleanliness. An idle worker is a process with state I won't understand later — was it busy before, is it stuck, is it waiting on something? An ephemeral worker has no history. It's created, does one thing, and disappears. When something goes wrong, there's no \"since when has it been like this\" to untangle.",[11,61,62],{},"The per-agent tiering is the other half. Before, every agent ran on the same model, because there was only one global one. Now whoever creates the worker decides what the worker runs on — and that's usually not the largest model, but the one that's enough for this one task.",[18,64,66],{"id":65},"what-this-actually-is","What this actually is",[11,68,69,70,29,72,74,75,78,79,82],{},"It's the same button as before, one level up. When I built the destroy button, the admission was: managing many agents isn't a prompting problem anymore, it's an ops problem. ",[26,71,28],{},[26,73,32],{}," are the consequence. If creating and clearing away are the real work, then those are operations — and operations I can hand an agent as a tool, just like ",[26,76,77],{},"bash"," or ",[26,80,81],{},"http",".",[11,84,85,86,88,89,92],{},"That moves a boundary worth thinking about for a moment. An agent can now destroy another agent. Which is why ",[26,87,32],{}," doesn't hang free in the air but on a scope — ",[26,90,91],{},"troop:destroy-agent"," — that the calling agent first has to exchange against its own token. Not every agent may clear away every other one. It's the same delegation as everywhere in the protocol: the agent acts with a mandate, not with omnipotence.",[11,94,95,96],{},"One gap is still open, and I'll write it down because it honestly belongs here: the local teardown removes the worker from the host, but its identity at the IdP stays for now. Anyone wanting to reuse the same name right away runs into a conflict. That's a follow-up task, not a solved problem. ",[97,98,99],"span",{},"VERIFY: confirm IdP hard-delete status before publishing",[18,101,103],{"id":102},"closing","Closing",[11,105,106],{},"I built myself a button to get rid of agents and thought that was the end of the story. It was the beginning. The moment creating and clearing away are operations, they belong where the other operations are: in the tool list. In the end the difference between me and the orchestrator agent is only whose token holds the scope.",{"title":108,"searchDepth":109,"depth":109,"links":110},"",2,[111,112,113,114],{"id":20,"depth":109,"text":21},{"id":52,"depth":109,"text":53},{"id":65,"depth":109,"text":66},{"id":102,"depth":109,"text":103},"2026-06-15","First I built myself a destroy button to get rid of agents. Then I handed the same button to an agent — as a tool. A note from building an agent that creates other agents, gives each a model tier per task, and clears them away once the work is done.",false,"md",null,{},true,"\u002Fblog\u002Fen\u002Fi-gave-the-agent-the-button-i-built",{"title":5,"description":116},"blog\u002Fen\u002Fi-gave-the-agent-the-button-i-built",[126,127,128,129,130],"OpenApe","AI Agents","Multi-Agent","Infrastructure","Building in Public","i-gave-the-agent-the-button-i-built","LiKURm-6S4TeD21n6EUQ9SCBci94e8103uZ52MdLh4U",{"en":134,"de":135},"\u002Fen\u002Fblog\u002Fi-gave-the-agent-the-button-i-built","\u002Fde\u002Fblog\u002Fden-knopf-den-ich-gebaut-hatte-gab-ich-dem-agent",1781706958410]