Skip to main content
← Tillbaka till bloggen
claude-codeagentsaiprompt-engineeringautomation

Hur man skriver Claude Code-agenter som inte ljuger för dig

Två regler för att bygga tillförlitliga Claude Code-agentpipelines: en agent per specialisering och shell-kommandon istället för prompts överallt där kvantitativa svar är inblandade.

Publicerad 29 maj 20266 min läsning

Du bad Claude Code att implementera den här designen och verifiera att den matchar Figma-mockupen. Det kom tillbaka: Klart. Alla sektioner matchar, avstånd är korrekt, färgerna stämmer. Du öppnade sidan. Halva avstånden var fel. Hover-tillståndet fanns inte. Knapparna var en nyans för ljusa. Modellen ljög inte med avsikt — den förutsåg att du ville höra verifierat, och producerade exakt den tokensekvensen. Det fanns inget verifieringssteg. Det kunde det aldrig finnas — verifiering kräver jämförelse mot ground truth, och en enda agent i ett enda kontext har inget sätt att kliva utanför sitt eget svar och kontrollera det.

Två regler har förvandlat hallucination-tunga arbetsflöden till tillförlitliga pipelines för mig: en agent, en specialisering och allt som kan köras som ett shell-kommando måste köras som ett shell-kommando. Det här är ingen teori. Det här är vad jag gör varje dag med Claude Code, och det är dessa mönster som faktiskt gör skillnad.

Varför generalistiska agenter ljuger

LLM:er är prediktorer för nästa token. När en prompt ber om två roller — bygg X och verifiera X — avslutar modellen den första rollen och förutsäger sedan hur utdata från den andra rollen skulle se ut, utan att faktiskt utföra den. Självverifiering är strukturellt svag: samma kontext, samma modell, samma blinda fläckar. Godkänt vid verifiering korrelerar med godkänt vid byggandet — de misslyckas tillsammans.

Modellen vet inte att den ljuger. Ur dess perspektiv är jag verifierade allt noggrant en sammanhängande fortsättning på att ha skrivit koden. Det är samma anledning till varför är du säker?-prompts inte fångar hallucinationer: modellen är lika säker vid det andra försöket. Säkerhet korrelerar inte med korrekthet — det korrelerar med hur rimligt nästa mening låter.

Lösningen är inte bättre prompts. Var försiktig, dubbelkolla, hallucinera inte — de instruktionerna gör ingenting. Lösningen är strukturell: specialisera agenten så att den fysiskt inte kan låtsas, och dirigera kvantitativt arbete genom shell:en så att svaret kommer från verkligt tillstånd, inte från tokensannolikhet.

Regel 1: en agent, en specialisering

Dela upp arbetet i separata agenter med separata kontexter. Varje agent har ett enda ansvar och en tight verktygsuppsättning. Hela arbetsflödet blir ett stafettlopp istället för att en agent springer varv:

  • Builder-agent: tar spec:en, skriver koden. Det är hela jobbet. Den har Read, Edit, Write, Bash.
  • Reviewer-agent: tar spec:en plus diff:en, kontrollerar acceptanskriterier. Fräscht kontext. Ingen kunskap om hur koden skrevs, bara vad som kom ut. Den har Bash, Read, Grep, Glob — inga skrivverktyg alls.
  • Analytics-agent: svarar på datafrågor genom att konstruera och köra queries. Bara Bash. Kan inte nå svaret utan att köra ett riktigt kommando.
  • Orchestrator: huvudsessionen som dispatchar varje agent i tur och ordning och aldrig ber en agent göra en annans jobb.

Konkret exempel: UI-implementation plus en visuell kontroll mot en Figma-mockup. Builder:n skriver komponenterna och committar diff:en. Orchestratorn anropar sedan Reviewer med design-URL:en, diff:en och explicita acceptanskriterier. Reviewer:n kör Playwright, tar skärmdumpar, jämför dem mot referensen och returnerar PASS eller FAIL med faktiska skärmdumpsvägar och pixel-diffs. Builder:n kommer aldrig i närheten av verifieringssteget — och det är exakt därför verifieringen är verklig.

Anti-mönstret är mega-agenten: en enda prompt som säger bygg det här UI:t och se till att det matchar mockupen. Jag garanterar dig, den kommer rapportera att allt matchar. Det gör det inte. Narrativet jag verifierade är bara den mest sannolika tokensekvensen efter jag byggde det.

Regel 2: shell framför prompt, alltid

Allt kvantitativt, allt som rör verkligt tillstånd, allt där svaret kan vara fel på ett sätt som ser rätt ut — kör det genom sh. Agentens jobb är att konstruera och köra kommandot, sedan läsa dess utdata. Agenten är inte källan till sanning. Shell-utdatan är det.

  • Räkning: wc -l logs.txt är sant. Det finns ungefär 47 loggrader från en modell är en hallucination.
  • Analytics: psql -c "SELECT count(*) FROM events WHERE created_at > now() - interval '30 days'". Inte uppskatta volymen.
  • Tester: pnpm test --reporter=json | jq '.numFailedTests'. Inte sammanfatta vad som misslyckades.
  • Git-tillstånd: git rev-list --count main..HEAD, git diff --stat. Inte räkna commits eller beskriv ändringarna.

När du väl internaliserat det här börjar du lägga märke till varje ställe där agenten var på väg att hitta på ett tal. Det verkar finnas ungefär 200 poster... — nej. Kör SELECT count(*). De flesta tester går igenom... — nej. Kör testsviten, parsa JSON:en. Modellen är utmärkt på att konstruera kommandot. Den är opålitlig när det gäller att vara kommandot.

Felmoder jag faktiskt råkat ut för

Det här är inga hypotetiska exempel. Vart och ett av dessa kostade mig verklig tid innan jag ändrade mönstret:

  • Spökverifiering. Agenten sa jag kontrollerade alla 14 sektioner mot mockupen. Den öppnade inte mockupen. Den tog ingen skärmdump. Kontrollen var ett hallucinerat steg i narrativet.
  • Säkra felaktiga tal. Frågade efter monthly active users från analysdata. Fick ett tal som var ~3× fel. Modellen interpolerade från exempelrader istället för att köra den faktiska queryn.
  • Påhittade filändringar. Agenten sa jag uppdaterade config/feature-flags.json. Det hade den inte gjort. Den hade bara haft för avsikt att göra det. git diff var tom.
  • Fejkade testkörningar. Alla tester går igenom. Inga tester kördes. Agenten anropade aldrig test runner:n — den förutsåg hur test runner:ns utdata skulle ha sett ut.

Alla fyra löses av samma två regler: dela agenten, skicka till shell. Reviewer:n har inte Write, så den kan inte fejk-redigera filer. Analytics-agenten har bara Bash, så den kan inte returnera ett tal som inte kom från en query. Strukturell omöjlighet slår goda intentioner varje gång.

Hur man strukturerar detta i Claude Code

Claude Code stödjer sub-agents definierade i .claude/agents/*.md. Varje agentfil deklarerar ett namn, en beskrivning, en tillåten verktygsuppsättning och en systemprompt. Orchestratorn (din huvudsession) dispatchar dem med verktyget Agent. Här är den typ av definition jag använder för reviewer:n — kort, smal och fysiskt oförmögen att skriva kod:

.claude/agents/reviewer.md
---
name: reviewer
description: Reviews a diff against acceptance criteria. Cannot edit code.
tools: Bash, Read, Grep, Glob
---

You are a strict code reviewer. You receive:
- A diff (already produced by the builder)
- Acceptance criteria

Your job:
1. Run the build, the tests, the linter — through Bash.
2. Read the changed files directly.
3. Compare the actual behavior to the criteria.
4. Report PASS or FAIL with concrete evidence (command output, file excerpts).

You must NOT:
- Trust the builder's summary
- Assume anything was verified just because it was claimed
- Mark something PASS without running the actual check

Lägg märke till verktygsuppsättningen: Bash, Read, Grep, Glob. Ingen Write, ingen Edit, ingen Agent. Reviewer:n kan köra kommandon, läsa filer, söka efter mönster — och ingenting annat. Om den försöker lura igenom en hallucinerad diff som verifierad gör formen på dess verktygsanrop det uppenbart: det gjordes inga riktiga kontroller. Du kan granska verktygsanropen och se exakt vad som inspekterades.

Orchestrerings-mönstret: huvudsessionen anropar Builder → väntar → kör git diff själv för att fånga den faktiska ändringen → anropar Reviewer med spec och diff → läser Reviewer:ns utlåtande. Huvudsessionen ber aldrig en agent göra bådas jobb. Verktygsbegränsningar är starkare än promptinstruktioner: fejka inte verifieringen är en önskan. Att inte ha Write är ett faktum.

Anti-mönster att pensionera

Saker jag ser i prompts som inte gör något — eller ännu värre, ger en falsk känsla av trygghet:

  • Var försiktig och dubbelkolla ditt arbete. Genererar inget ytterligare beteende. Modellen producerar redan det som ser ut som noggrant arbete.
  • Se till att du faktiskt verifierar. Ordet faktiskt tillför ingen semantik som modellen kan agera på. Den kommer faktiskt hävda att den verifierade.
  • Hallucinera inte. Ett prompt engineering-meme. Hallucination är inte en switch modellen kan stänga av.
  • Lita på agenten med små tal. Det är på små tal den ljuger mest säkert. Det finns ingen ärlighets-tröskel.
  • Lägga till fler regler i prompten för att tvinga fram ärlighet. Strukturella åtgärder (dela + shell) slår promptjusteringar varje gång. Om en regel behöver enforças, koda in den i verktygsåtkomst, inte i text.

Om din strategi för att fånga hallucinationer är mer emfatiska formuleringar har du ingen strategi. Du har ett hopp.

Den mentala modellen

En agent är inte en kollega. Det är en funktion: prompt → tokens. Funktionen är utmärkt på att skriva kod och usel på att introspektera om den gjorde rätt sak. Behandla dess påståenden om sitt eget arbete som en hypotes. Diff:en, exit-koden, skärmdumpen, radantalet — det är bevisen. Sammanfattningen i slutet av ett drag är den mest lögn-benägna ytan i hela systemet.

Specialisering är din försäkring mot narrativt drift. Shell:en är din enda ground truth. Builder skriver. Reviewer kontrollerar. Bash avgör.

Slutsats

Om du ska minnas en sak: låt inte en enda agent både producera och bedöma sin egen utdata, och låt ingen agent svara på en kvantitativ fråga utan att köra ett kommando. Allt annat följer av dessa två regler. Konfigurera verktygsåtkomst aggressivt, granska verktygsanrop istället för sammanfattningar, och hallucinationsytan krymper från överallt till ett fåtal specifika ställen du redan vet att titta på.