Het artikel beschrijft een methode om de kosten en het tokenverbruik van AI-coding agents (specifiek Claude Code) te verlagen. De auteur stelt dat frontier-modellen vaak worden verspild aan routinetaken zoals het lezen van grote bestanden of het genereren van boilerplate-code.
De oplossing is het gebruik van Portal by Spotify en AiKA Modes. Hiermee worden specifieke taken gedelegeerd aan goedkopere 'worker-modellen' (zoals Gemini 2.5 Flash) via twee aangemaakte modi:
- bulk-reader: Voor het analyseren van grote bestanden en het teruggeven van beknopte bullets.
- code-writer: Voor het genereren van voorspelbare code op basis van bestaande patronen.
Om dit proces te automatiseren, is de plugin shunt ontwikkeld. Deze gebruikt hooks om Read-aanroepen te onderscheppen; zodra een bestand een bepaalde grootte overschrijdt, wordt de actie automatisch omgeleid naar de Portal CLI in plaats van direct door Claude te worden gelezen.
Hoewel benchmarks een besparing van 90% op tokens tonen bij bulk-reads, zijn er beperkingen: het systeem is niet geschikt voor complexe redeneringen, directe bewerkingen van code of zeer kleine bestanden vanwege de netwerk-latency.
Portal van Spotify verminderde mijn Claude Code-tokenverbruik met 90%
Het lezen van vijf bestanden om een vraag over één methode te beantwoorden. Het genereren van een testbestand dat exact hetzelfde patroon volgt als de twintig testbestanden ernaast. Het bijwerken van documentatie na een vergadering. Duizenden tokens zijn weg en er is bijna geen sprake van redeneren. De licentiekosten zijn niet het probleem, het zijn de tokens. En je voert dit alles aan een frontier-model dat wild overgekwalificeerd is. Wat als je het routinewerk kon delegeren naar iets goedkopers dat het net zo goed afhandelt, en het dure model kon bewaren voor de problemen die dat echt nodig hebben?
Dit is niet alleen mijn probleem. Tegen 2028 wordt verwacht dat de kosten voor AI-coding het gemiddelde salaris van een ontwikkelaar zullen overstijgen. Een kwart van de engineering-leiders verbruikt nu al $200–$500 per ontwikkelaar per maand aan tokens. Sommigen zitten al ver boven de $2.000. De tooling betaalt zichzelf terug, maar alleen als je stopt met het verspillen van frontier-tokens aan werk dat ze niet nodig heeft.
De oplossing vereiste geen platformteam of een nieuw abonnement. Alleen twee modi.
Twee modi, nul code
Dit is precies het soort use case waar AiKA Modes in Portal by Spotify voor zijn gebouwd. Een 'mode' is een declaratieve agent die draait op een vluchtige runtime — denk aan AWS Lambda, maar dan voor agents. Je definieert de instructies, kiest een model, stelt parameters zoals temperatuur in en koppelt MCP-tools. Portal regelt de rest. Geen infrastructuur om te beheren, geen API-sleutels, geen servers die constant moeten draaien. Modes kunnen worden aangeroepen via de Portal CLI of API. Ze kunnen openbaar zijn (gedeeld met het hele bedrijf) of privé.
Om deze routering te laten werken, heb ik twee modi gemaakt. In de onderstaande voorbeelden gebruiken beide Gemini 2.5 Flash als worker-model, maar het modelveld accepteert elk model dat je in je Portal-instantie hebt geconfigureerd.
Mode 1: bulk-reader
Voor situaties waarin Claude anders meerdere grote bestanden zou lezen om slechts één vraag te beantwoorden.
Configuratie:
- Naam:
bulk-reader
- Beschrijving: Bulk-bestandlezer voor code-analyse - delegeert I/O van Claude Code.
- Instructies: Je bent een nauwkeurige code-analist. Lees de verstrekte bestanden en beantwoord de vraag beknopt. Geef alleen gestructureerde bullets terug. Geen groeten, geen proza, geen inleidingen. Begin elke bullet met de exacte naam, het type of het regelnummer. Gebruik geneste bullets voor details. Sla alles over waar de aanroeper niet om heeft gevraagd.
- Zichtbaarheid: openbaar
- Model:
gemini-2.5-flash
- ResourceLimits:
- Temperatuur: 0.2
- Tags:
coding, delegation
Mode 2: code-writer
Voor tests, config-scaffolding, type-stubs of alles waarbij de output voorspelbaar is op basis van bestaande patronen.
Configuratie:
- Naam:
code-writer
- Beschrijving: Boilerplate-code generator - delegeert output-intensief werk van Claude Code.
- Instructies: Je genereert codebestanden op basis van een specificatie en referentiebestanden. Match de bestaande patronen, conventies, naamgeving en stijl exact. Geef alleen de code terug — geen uitleg, geen markdown-fences, tenzij daarom gevraagd wordt. Als de specificatie ambigu is, maak dan redelijke keuzes die passen bij de patronen van de referentiecode.
- Zichtbaarheid: openbaar
- Model:
gemini-2.5-flash
- ResourceLimits:
- Temperatuur: 0.2
- Tags:
coding, delegation
De instructie "geef alleen de code terug" is essentieel. Zonder deze instructie verpakt het model alles in markdown-fences en verklarend proza, waar Claude vervolgens weer doorheen moet filteren.
Routering
De eerste versie hiervan was een blok routeringsregels in CLAUDE.md. Dit werkte redelijk: Claude las de instructies en routeerde zichzelf naar Portal. Maar er waren problemen. De regels waren adviserend, niet afdwingend; Claude kon ze negeren. Bovendien had elk project zijn eigen kopie van de instructies nodig.
De huidige versie is een Claude Code-plugin genaamd shunt. De delegatie verloopt via de Portal CLI actions registry, waardoor de plugin werkt met elke Portal-instantie waar de AiKA-plugin is ingeschakeld.
Laag 1: Hooks
Claude Code-hooks worden geactiveerd vóór elke tool-aanroep. Shunt registreert twee PreToolUse hooks:
check-file-size: Deze wordt geactiveerd bij elke Read-aanroep. Als het bestand een configureerbare drempelwaarde voor regels overschrijdt (standaard: 350), blokkeert de hook het lezen en vertelt Claude om in plaats daarvan de /bulk-reader skill te gebruiken. Gerichte reads (targeted reads) worden gewoon toegestaan — Claude weet immers al welk gedeelte hij nodig heeft.
check-bash-read: Deze vangt cat, head, tail, less en more op bij grote bestanden. Gepiped commando's (zoals cat file | grep) worden doorgelaten, omdat dit gerichte reads zijn.
De drempelwaarde is configureerbaar via de SHUNTMINLINES omgevingsvariabele. Stel dit in in je shell-profiel of in .claude/settings.json:
{
"env": {
"SHUNT_MIN_LINES": "500"
}
}
Laag 2: Scripts
Ik gebruik twee bash-scripts die de Portal CLI-aanroepen wrappen. Claude roept een script aan met benoemde argumenten. De scripts regelen alles intern: het opbouwen van het verzoek, het aanroepen van de acties, het afhandelen van fouten en het rapporteren van het tokenverbruik naar stderr.
Modes worden aangesproken op naam en opgelost door Portal: ongevoelig voor hoofdletters, waarbij prioriteit wordt gegeven aan je eigen mode, daarna die van je team en vervolgens de openbare modi. Als je de openbare bulk-reader fork je naar een aangepaste versie, krijgt die automatisch voorrang zonder dat er configuratie nodig is.
bulk-read verpakt elk bestand in XML-tags voor duidelijke grenzen en stuurt deze samen met de vraag naar de bulk-reader mode. Voorbeeld: bulk-read --question "Wat doet deze service?" --paths src/Service.java src/Handler.java
Vervolgvraag met dezelfde paden: bulk-read --question "Welke methoden roepen de database aan?" --paths src/Service.java src/Handler.java
Elke delegatie is een 'one shot'. De aanroeping is vluchtig (er wordt niets server-side opgeslagen) en het opnieuw versturen van de bestanden bij een vervolgvraag is kosteloos waar het telt, omdat het corpus naar het worker-model gaat en nooit in de context van Claude terechtkomt.
code-write stuurt een specificatie en een referentiebestand naar de code-writer mode, verwijdert markdown-fences uit de output en kan direct naar schijf schrijven. Claude ziet de gegenereerde code nooit. De referentie is verplicht: zonder een bestand om patronen mee te matchen, zou de worker context-vrije code genereren die nergens in je project bij past. Voorbeeld: code-write --spec "Schrijf tests voor UserService" --reference tests/OrderTest.java --target tests/UserTest.java
Output naar stdout: code-write --spec "Genereer een config stub" --reference config/existing.yaml
Laag 3: Skills
Twee skill-bestanden vertellen Claude wanneer en hoe de scripts moeten worden aangeroepen. Skills zijn markdown-bestanden met een beschrijving en gebruiksvoorbeelden. Wanneer de hook een read-actie blokkeert, verwijst het blokkeringsbericht Claude naar de /bulk-reader skill, waarin de exacte syntaxis voor de aanroep staat.
Deze gelaagdheid zorgt ervoor dat het systeem gracieus degradeert. Zelfs als Claude de skill-beschrijving niet leest, blokkeert de hook nog steeds de dure read-actie. De skill maakt de redirect simpelweg soepeler.
De benchmarks
Getest tegen een Java monorepo over vier scenario's, waarbij de tokens die Claude zou verbruiken bij het direct lezen van bestanden werden gemeten tegenover het verbruik bij het gebruiken van de samenvatting van de bulk-reader of het schrijven van code via de code-writer. De gemiddelde besparing bij bulk-read was maar liefst 90%.
Het code-write scenario is lastiger in tokens te meten, omdat Claude zonder shunt zowel de referentiebestanden leest als de output genereert als dure output-tokens. Met shunt gaat de code direct naar schijf en ziet Claude deze nooit.
Wat niet werkt
- Editing kan niet gedelegeerd worden. De samenvattingen van het worker-model bevatten geen betrouwbare regelnummers. Als Claude bewerkingen moet uitvoeren op basis van de analyse, moet hij het specifieke gedeelte nog steeds direct lezen. De hooks staan gerichte reads toe (met offset/limit) precies om deze reden; delegatie bespaart tokens op het begrijpen.
- Redeneren kan niet gedelegeerd worden. Het worker-model vond oppervlakkige patronen, maar miste een subtiele thread-safety bug tijdens mijn tests. Claude spotte deze binnen enkele seconden zodra hij de juiste context kreeg. De routering sluit debugging, architecturale beslissingen en veiligheidskritieke code expliciet uit.
- Latency telt op. Elke delegatie is een netwerk-roundtrip: Claude Code naar de Portal-backend naar het worker-model en terug. Reacties duren doorgaans 10–30 seconden, en Portal begrenst een enkele aanroep op 30 seconden. Zeer grote generaties moeten daarom worden opgesplitst in kleinere aanroepen. Dit is acceptabel voor grote reads, maar contraproductief voor kleine. De drempelwaarde voor regels bestaat om deze reden; daaronder overstijgt de overhead van delegatie de besparingen.
Tokenbesparing is slechts het begin
De plugin is een Claude Code-artifact, maar het onderliggende idee is model-routering aangedreven door AiKA-modes. De modes zijn het fundament:
- Ze zijn herbruikbaar. Dezelfde
bulk-reader en code-writer modi werken in elk project en met elk hulpmiddel dat de Portal CLI kan aanroepen.
- Ze zijn deelbaar. Beide modi zijn openbaar in AiKA. Iedereen kan ze vandaag gebruiken zonder zelf iets te hoeven maken.
- Ze zijn combineerbaar. Je zou een
doc-writer mode kunnen maken voor documentatie, een reviewer mode voor code-review samenvattingen, of een translator mode voor i18n. Elke nieuwe mode is slechts een paar klikken verwijderd.
- Ze ontkoppelen de routeringsbeslissing van de worker. De plugin beslist wanneer er gedelegeerd wordt. De mode beslist hoe er wordt gereageerd. Vervang Gemini Flash door een goedkoper model, pas de system prompt aan of voeg MCP-tools toe — de plugin hoeft niet te veranderen.
Dit is de echte kracht van AiKA-modes: ze veranderen model-routering van een system engineering-probleem in een configuratie-probleem. Je bouwt geen infrastructuur; je beschrijft wat je wilt en geeft het een naam.
Zelf proberen
Installeer beide plugins vanuit de spotify/portal-ai-plugins marketplace:
claude plugin marketplace add spotify/portal-ai-plugins
claude plugin install portal@portal
claude plugin install shunt@portal
De portal plugin levert de Portal CLI waar shunt viakaliereert. In een nieuwe Claude Code-sessie voer je /portal:setup uit om de Portal CLI in te stellen en te authenticeren tegen je Portal-instantie.
Vervolgens kun je beginnen: stel een vraag die over meerdere bestanden gaat. De bulk-reader en code-writer modi zijn al openbaar, dus je hoeft niets aan te maken. Als je ze wilt aanpassen (ander worker-model, andere instructies), kun je ze forken in Portal; jouw versie krijgt dan automatisch voorrang.
Portal van Spotify verminderde mijn Claude Code-tokenverbruik met 90%
Het lezen van vijf bestanden om een vraag over één methode te beantwoorden. Het genereren van een testbestand dat exact hetzelfde patroon volgt als de twintig testbestanden ernaast. Het bijwerken van documentatie na een vergadering. Duizenden tokens zijn weg en er is bijna geen sprake van redeneren. De licentiekosten zijn niet het probleem, het zijn de tokens. En je voert dit alles aan een frontier-model dat wild overgekwalificeerd is. Wat als je het routinewerk kon delegeren naar iets goedkopers dat het net zo goed afhandelt, en het dure model kon bewaren voor de problemen die dat echt nodig hebben?
Dit is niet alleen mijn probleem. Tegen 2028 wordt verwacht dat de kosten voor AI-coding het gemiddelde salaris van een ontwikkelaar zullen overstijgen. Een kwart van de engineering-leiders verbruikt nu al $200–$500 per ontwikkelaar per maand aan tokens. Sommigen zitten al ver boven de $2.000. De tooling betaalt zichzelf terug, maar alleen als je stopt met het verspillen van frontier-tokens aan werk dat ze niet nodig heeft.
De oplossing vereiste geen platformteam of een nieuw abonnement. Alleen twee modi.
Twee modi, nul code
Dit is precies het soort use case waar AiKA Modes in Portal by Spotify voor zijn gebouwd. Een 'mode' is een declaratieve agent die draait op een vluchtige runtime — denk aan AWS Lambda, maar dan voor agents. Je definieert de instructies, kiest een model, stelt parameters zoals temperatuur in en koppelt MCP-tools. Portal regelt de rest. Geen infrastructuur om te beheren, geen API-sleutels, geen servers die constant moeten draaien. Modes kunnen worden aangeroepen via de Portal CLI of API. Ze kunnen openbaar zijn (gedeeld met het hele bedrijf) of privé.
Om deze routering te laten werken, heb ik twee modi gemaakt. In de onderstaande voorbeelden gebruiken beide Gemini 2.5 Flash als worker-model, maar het modelveld accepteert elk model dat je in je Portal-instantie hebt geconfigureerd.
Mode 1: bulk-reader
Voor situaties waarin Claude anders meerdere grote bestanden zou lezen om slechts één vraag te beantwoorden.
Configuratie:
- Naam:
bulk-reader
- Beschrijving: Bulk-bestandlezer voor code-analyse - delegeert I/O van Claude Code.
- Instructies: Je bent een nauwkeurige code-analist. Lees de verstrekte bestanden en beantwoord de vraag beknopt. Geef alleen gestructureerde bullets terug. Geen groeten, geen proza, geen inleidingen. Begin elke bullet met de exacte naam, het type of het regelnummer. Gebruik geneste bullets voor details. Sla alles over waar de aanroeper niet om heeft gevraagd.
- Zichtbaarheid: openbaar
- Model:
gemini-2.5-flash
- ResourceLimits:
- Temperatuur: 0.2
- Tags:
coding, delegation
Mode 2: code-writer
Voor tests, config-scaffolding, type-stubs of alles waarbij de output voorspelbaar is op basis van bestaande patronen.
Configuratie:
- Naam:
code-writer
- Beschrijving: Boilerplate-code generator - delegeert output-intensief werk van Claude Code.
- Instructies: Je genereert codebestanden op basis van een specificatie en referentiebestanden. Match de bestaande patronen, conventies, naamgeving en stijl exact. Geef alleen de code terug — geen uitleg, geen markdown-fences, tenzij daarom gevraagd wordt. Als de specificatie ambigu is, maak dan redelijke keuzes die passen bij de patronen van de referentiecode.
- Zichtbaarheid: openbaar
- Model:
gemini-2.5-flash
- ResourceLimits:
- Temperatuur: 0.2
- Tags:
coding, delegation
De instructie "geef alleen de code terug" is essentieel. Zonder deze instructie verpakt het model alles in markdown-fences en verklarend proza, waar Claude vervolgens weer doorheen moet filteren.
Routering
De eerste versie hiervan was een blok routeringsregels in CLAUDE.md. Dit werkte redelijk: Claude las de instructies en routeerde zichzelf naar Portal. Maar er waren problemen. De regels waren adviserend, niet afdwingend; Claude kon ze negeren. Bovendien had elk project zijn eigen kopie van de instructies nodig.
De huidige versie is een Claude Code-plugin genaamd shunt. De delegatie verloopt via de Portal CLI actions registry, waardoor de plugin werkt met elke Portal-instantie waar de AiKA-plugin is ingeschakeld.
Laag 1: Hooks
Claude Code-hooks worden geactiveerd vóór elke tool-aanroep. Shunt registreert twee PreToolUse hooks:
check-file-size: Deze wordt geactiveerd bij elke Read-aanroep. Als het bestand een configureerbare drempelwaarde voor regels overschrijdt (standaard: 350), blokkeert de hook het lezen en vertelt Claude om in plaats daarvan de /bulk-reader skill te gebruiken. Gerichte reads (targeted reads) worden gewoon toegestaan — Claude weet immers al welk gedeelte hij nodig heeft.
check-bash-read: Deze vangt cat, head, tail, less en more op bij grote bestanden. Gepiped commando's (zoals cat file | grep) worden doorgelaten, omdat dit gerichte reads zijn.
De drempelwaarde is configureerbaar via de SHUNTMINLINES omgevingsvariabele. Stel dit in in je shell-profiel of in .claude/settings.json:
{
"env": {
"SHUNT_MIN_LINES": "500"
}
}
Laag 2: Scripts
Ik gebruik twee bash-scripts die de Portal CLI-aanroepen wrappen. Claude roept een script aan met benoemde argumenten. De scripts regelen alles intern: het opbouwen van het verzoek, het aanroepen van de acties, het afhandelen van fouten en het rapporteren van het tokenverbruik naar stderr.
Modes worden aangesproken op naam en opgelost door Portal: ongevoelig voor hoofdletters, waarbij prioriteit wordt gegeven aan je eigen mode, daarna die van je team en vervolgens de openbare modi. Als je de openbare bulk-reader fork je naar een aangepaste versie, krijgt die automatisch voorrang zonder dat er configuratie nodig is.
bulk-read verpakt elk bestand in XML-tags voor duidelijke grenzen en stuurt deze samen met de vraag naar de bulk-reader mode. Voorbeeld: bulk-read --question "Wat doet deze service?" --paths src/Service.java src/Handler.java
Vervolgvraag met dezelfde paden: bulk-read --question "Welke methoden roepen de database aan?" --paths src/Service.java src/Handler.java
Elke delegatie is een 'one shot'. De aanroeping is vluchtig (er wordt niets server-side opgeslagen) en het opnieuw versturen van de bestanden bij een vervolgvraag is kosteloos waar het telt, omdat het corpus naar het worker-model gaat en nooit in de context van Claude terechtkomt.
code-write stuurt een specificatie en een referentiebestand naar de code-writer mode, verwijdert markdown-fences uit de output en kan direct naar schijf schrijven. Claude ziet de gegenereerde code nooit. De referentie is verplicht: zonder een bestand om patronen mee te matchen, zou de worker context-vrije code genereren die nergens in je project bij past. Voorbeeld: code-write --spec "Schrijf tests voor UserService" --reference tests/OrderTest.java --target tests/UserTest.java
Output naar stdout: code-write --spec "Genereer een config stub" --reference config/existing.yaml
Laag 3: Skills
Twee skill-bestanden vertellen Claude wanneer en hoe de scripts moeten worden aangeroepen. Skills zijn markdown-bestanden met een beschrijving en gebruiksvoorbeelden. Wanneer de hook een read-actie blokkeert, verwijst het blokkeringsbericht Claude naar de /bulk-reader skill, waarin de exacte syntaxis voor de aanroep staat.
Deze gelaagdheid zorgt ervoor dat het systeem gracieus degradeert. Zelfs als Claude de skill-beschrijving niet leest, blokkeert de hook nog steeds de dure read-actie. De skill maakt de redirect simpelweg soepeler.
De benchmarks
Getest tegen een Java monorepo over vier scenario's, waarbij de tokens die Claude zou verbruiken bij het direct lezen van bestanden werden gemeten tegenover het verbruik bij het gebruiken van de samenvatting van de bulk-reader of het schrijven van code via de code-writer. De gemiddelde besparing bij bulk-read was maar liefst 90%.
Het code-write scenario is lastiger in tokens te meten, omdat Claude zonder shunt zowel de referentiebestanden leest als de output genereert als dure output-tokens. Met shunt gaat de code direct naar schijf en ziet Claude deze nooit.
Wat niet werkt
- Editing kan niet gedelegeerd worden. De samenvattingen van het worker-model bevatten geen betrouwbare regelnummers. Als Claude bewerkingen moet uitvoeren op basis van de analyse, moet hij het specifieke gedeelte nog steeds direct lezen. De hooks staan gerichte reads toe (met offset/limit) precies om deze reden; delegatie bespaart tokens op het begrijpen.
- Redeneren kan niet gedelegeerd worden. Het worker-model vond oppervlakkige patronen, maar miste een subtiele thread-safety bug tijdens mijn tests. Claude spotte deze binnen enkele seconden zodra hij de juiste context kreeg. De routering sluit debugging, architecturale beslissingen en veiligheidskritieke code expliciet uit.
- Latency telt op. Elke delegatie is een netwerk-roundtrip: Claude Code naar de Portal-backend naar het worker-model en terug. Reacties duren doorgaans 10–30 seconden, en Portal begrenst een enkele aanroep op 30 seconden. Zeer grote generaties moeten daarom worden opgesplitst in kleinere aanroepen. Dit is acceptabel voor grote reads, maar contraproductief voor kleine. De drempelwaarde voor regels bestaat om deze reden; daaronder overstijgt de overhead van delegatie de besparingen.
Tokenbesparing is slechts het begin
De plugin is een Claude Code-artifact, maar het onderliggende idee is model-routering aangedreven door AiKA-modes. De modes zijn het fundament:
- Ze zijn herbruikbaar. Dezelfde
bulk-reader en code-writer modi werken in elk project en met elk hulpmiddel dat de Portal CLI kan aanroepen.
- Ze zijn deelbaar. Beide modi zijn openbaar in AiKA. Iedereen kan ze vandaag gebruiken zonder zelf iets te hoeven maken.
- Ze zijn combineerbaar. Je zou een
doc-writer mode kunnen maken voor documentatie, een reviewer mode voor code-review samenvattingen, of een translator mode voor i18n. Elke nieuwe mode is slechts een paar klikken verwijderd.
- Ze ontkoppelen de routeringsbeslissing van de worker. De plugin beslist wanneer er gedelegeerd wordt. De mode beslist hoe er wordt gereageerd. Vervang Gemini Flash door een goedkoper model, pas de system prompt aan of voeg MCP-tools toe — de plugin hoeft niet te veranderen.
Dit is de echte kracht van AiKA-modes: ze veranderen model-routering van een system engineering-probleem in een configuratie-probleem. Je bouwt geen infrastructuur; je beschrijft wat je wilt en geeft het een naam.
Zelf proberen
Installeer beide plugins vanuit de spotify/portal-ai-plugins marketplace:
claude plugin marketplace add spotify/portal-ai-plugins
claude plugin install portal@portal
claude plugin install shunt@portal
De portal plugin levert de Portal CLI waar shunt viakaliereert. In een nieuwe Claude Code-sessie voer je /portal:setup uit om de Portal CLI in te stellen en te authenticeren tegen je Portal-instantie.
Vervolgens kun je beginnen: stel een vraag die over meerdere bestanden gaat. De bulk-reader en code-writer modi zijn al openbaar, dus je hoeft niets aan te maken. Als je ze wilt aanpassen (ander worker-model, andere instructies), kun je ze forken in Portal; jouw versie krijgt dan automatisch voorrang.