Een goede Claude Code subagent schrijven
6m leestijd

Een goede Claude Code subagent schrijven

Bijna elke custom subagent opent met een persona-alinea, en dat is de minst belangrijke regel in het bestand. Een gids voor de drie keuzes die er wél toe doen: de trigger, de tools-allowlist en het antwoordcontract.

Eergisteren liet ik zien hoe je een goede skill schrijft. Zelfde plank, één gereedschap verder: de custom subagent. Je hebt hem uit de beslisboom gekozen omdat de klus zijn eigen context nodig heeft, en nu staart een leeg bestand in .claude/agents/ je aan.

Dit is wat bijna iedereen als eerste typt:

You are a senior security engineer with fifteen years of experience in application security. You are meticulous, thorough, and detail-oriented.

Ik snap de reflex. Het voelt als iemand aannemen. Je bouwt een specialist, dus je schrijft een cv.

Die alinea is de minst belangrijke regel in het bestand. Vijftien denkbeeldige jaren ervaring veranderen niets aan de weights van het model, en "thorough" is geen instructie die iemand kan opvolgen of controleren. Eén zin die de rol neerzet is prima als anker voor de toon. Alles daarna is decor.

De waarde van een subagent zit in drie andere keuzes, en het bestandsformaat maakt het makkelijk om ze alle drie over te slaan.

Wat een subagent eigenlijk is

De verpakking is net zo saai als bij een skill. Een subagent is een markdown-bestand met YAML-frontmatter: een name, een description, eventueel een tools-lijst en een model, en daarna een body. Zet hem in .claude/agents/ om hem met het project te delen, of in ~/.claude/agents/ zodat hij in al je projecten meegaat. Beide mappen worden recursief doorzocht, dus submapjes mogen, en met het commando /agents beheer je de hele verzameling.

De body is de system prompt van de subagent. En dit is het mentale model waar al het andere uit volgt: de subagent ziet jouw gesprek nooit.

Hij weet niets van de bug waar je twintig minuten over hebt zitten praten. Hij heeft het bestand dat je net aanpaste niet gezien, en het plan dat jullie afspraken ook niet. Hij wordt wakker met precies twee dingen: de body van jouw bestand, en de ene taakomschrijving die de hoofdagent meegeeft bij het delegeren. Hij doet zijn werk in een eigen context window, en zodra hij klaar is gaat dat hele window de prullenbak in. Alleen zijn laatste bericht komt terug.

Dat is het hele product. Een subagent is een firewall voor context: de vierduizend regels stacktraces, de doodlopende zijpaden, alle ruis blijft in de andere kamer, en alleen de conclusie komt de deur door. Elke regel in dat bestand hoort dus één van drie taken te dienen: de juiste klussen naar binnen sturen, begrenzen wat er binnen gebeurt, en vormgeven wat er terugkomt.

De description bepaalt wanneer hij draait

De hoofdagent leest het veld description op het moment dat hij beslist of hij gaat delegeren. Het is dus een routeringsregel, en de meeste mensen schrijven er een functietitel in.

Fout, en je ziet het overal:

yaml
description: Expert code reviewer

Dat vertelt de hoofdagent wat de subagent is. Hij moet weten wanneer hij hem moet gebruiken:

yaml
description: Use after writing or changing code, before committing. Reviews
  the working diff for bugs and security issues. Use proactively when a task
  involved more than trivial edits. NOT for reviewing whole files or
  auditing the repo, and it never applies fixes: read-only.

In die paar regels doen drie dingen het werk. De concrete momenten waarop hij moet aanslaan, zodat het delegeren ook echt gebeurt. De frase "use proactively", die niet voor niets in de documentatie staat: daarmee weet de hoofdagent dat hij niet hoeft te wachten tot jij erom vraagt. En het nadrukkelijke NOT aan het eind, zodat de subagent niet aanslaat op klussen die hij slecht doet. Wordt jouw subagent nooit gebruikt, dan ligt het vrijwel altijd aan de description.

De tools-regel is de echte handhaving

Dit is de regel waar mensen overheen lezen, en het is de belangrijkste van het bestand:

yaml
tools: Read, Grep, Glob

Dat is een allowlist. Een tool die niet op de lijst staat, bestaat voor deze agent niet. Je reviewer kán simpelweg geen bestand aanpassen, dus je hoeft nergens "pas alsjeblieft de code niet aan" te schrijven. Dat is een beleefd verzoek dat het model bijna elke run netjes opvolgt, behalve die ene keer dat het ertoe doet. Het is dezelfde grens die de hooks-gids trekt: een instructie vraagt, een mechanisme dwingt af. De tools-lijst is het mechanisme.

Eén kanttekening: Bash is het lek in elke allowlist. Een subagent met shell-toegang kan bijna alles, lijst of geen lijst. Behandel Bash dus als het ene item op de lijst dat je moet kunnen verdedigen. Een testanalist heeft hem nodig om de suite te draaien, een code reviewer heeft er niets te zoeken.

De frontmatter kent nog een paar nuttige begrenzers. Met model draai je routinewerk op een goedkoper model dan je hoofdsessie. maxTurns zet een hard budget op een agent die op hol slaat. En met mcpServers geef je een MCP-server aan precies één subagent: een browser-tester kan zijn eigen Playwright-server meenemen, die verbinding maakt zodra de agent start en weer verbreekt zodra hij klaar is. Die twintig browser-tools vervuilen je hoofdsessie dan nooit.

Het antwoordcontract bepaalt wat terugkomt

Onthoud: alleen het laatste bericht overleeft. Als de body niet zegt hoe dat bericht eruit moet zien, krijg je de samenvatting waar het model toevallig zin in had. Meestal een opstel, terwijl je aan drie regels genoeg had.

Sluit de body dus af met een contract, dezelfde zet waarmee een goede skill eindigt:

markdown
Report back in exactly this shape:

- Verdict: one line, "N failures, M root causes".
- Root causes: one bullet per cause, with file:line evidence.
- Fix direction: one line per cause. No diffs, no code.

If everything passes, say so in one line. A short answer is a good answer.

Zonder die laatste regel gaat het model uitweiden. Een agent die met lege handen terug mag komen, is een agent die je kunt vertrouwen wanneer hij wél met iets terugkomt.

Het hele bestand

De test-analyst uit de beslisboom-post, maar dan goed geschreven:

markdown
---
name: test-analyst
description: Use when the test suite fails and the output is too long to
  read in the main conversation. Triggers: a failing CI run, "why are the
  tests failing", any test output over ~50 lines. NOT for writing tests or
  fixing code. It diagnoses only.
tools: Read, Grep, Glob, Bash
model: sonnet
maxTurns: 15
---

You are a test-failure analyst. You have no memory of the conversation
that spawned you. Everything you need is in the task you were given; if
the test command is not named there, find it in package.json or the CI
config before guessing.

Run the suite once. Group the failures by root cause, not by test file.
Trace each group to the change or config that broke it, and read the
actual source before blaming it.

You never edit anything. You have Bash to run tests, nothing else.

Report back in exactly this shape:

- Verdict: one line, "N failures, M root causes".
- Root causes: one bullet per cause, with file:line evidence.
- Fix direction: one line per cause. No diffs, no code.

If everything passes, say so in one line.

Een regel of twintig. Eén zin voor de rol. De rest is routering, begrenzing en contract. Kijk naar de tweede alinea van de body: die bestaat puur omdat de agent aan geheugenverlies lijdt. Hij spelt uit waar de informatie te vinden is die het gesprek anders had aangeleverd.

Wat je concreet doet

  • Schrijf de description als delegatie-trigger. Concrete momenten waarop hij moet aanslaan, "use proactively" als je dat meent, en de klussen die hij moet weigeren.
  • Kort de persona in tot één zin. Als het schrappen van een regel het gedrag van de agent niet verandert, schrap die regel.
  • Houd de tools-lijst zo kort als de klus toelaat. Behandel Bash als de uitzondering waarvoor je moet pleiten, en gebruik model en maxTurns om de schade van een slechte run te begrenzen.
  • Schrijf de body voor iemand zonder geheugen. Benoem waar de agent alles vindt wat normaal uit jouw gesprek zou komen: het testcommando, de conventies, de entrypoints.
  • Eindig met een antwoordcontract. Vaste vorm, bewijs verplicht, en toestemming om met een kort antwoord terug te komen.
  • Commit het bestand. Een subagent in .claude/agents/ is gedeelde vakkennis. Eentje in je hoofd is een gewoonte waar je teamgenoten niets aan hebben.

Een persona-alinea vraagt het model om zich als specialist te gedragen. De drie andere regels in het bestand maken elk ander gedrag onmogelijk. Zodra je dat ziet, verdwijnt de cv-reflex vanzelf, en worden de bestanden korter, strenger en een stuk bruikbaarder.

serie: Claude Pro(15 van 15)