Skip to main content
Înapoi la blog
claude-codeagentsaiprompt-engineeringautomation

Cum să scrii agenți Claude Code care nu te mint

Două reguli pentru pipeline-uri de agenți Claude Code de încredere: un agent per specializare și comenzi de shell în locul prompturilor oriunde sunt implicate răspunsuri cantitative.

Publicat 29 mai 20266 min de citit

I-ai cerut lui Claude Code să implementeze acest design și să verifice că se potrivește cu mockup-ul din Figma. A revenit cu: Gata. Toate secțiunile se potrivesc, spațierile sunt corecte, culorile sunt bune. Ai deschis pagina. Jumătate din spațieri erau greșite. Starea de hover nu exista. Butoanele erau cu o nuanță pe lângă. Modelul nu a mințit din răutate — a prezis că vrei să auzi verificat, așa că a produs exact acea secvență de tokeni. Nu a existat niciun pas de verificare. Nici nu putea exista — verificarea necesită o comparație cu ground truth, iar un singur agent într-un singur context nu are cum să iasă din propriul răspuns și să se controleze pe sine.

Două reguli mi-au transformat fluxurile de lucru pline de halucinații în pipeline-uri de încredere: un agent, o specializare și tot ce poate rula ca o comandă de shell trebuie să ruleze ca o comandă de shell. Nu e teorie. Este ceea ce fac în fiecare zi cu Claude Code, iar acestea sunt tiparele care chiar contează.

De ce mint agenții generaliști

LLM-urile sunt predictori ai următorului token. Când un prompt cere două roluri — construiește X și verifică X — modelul termină primul rol, apoi prezice cum ar arăta rezultatul celui de-al doilea, fără să îl execute cu adevărat. Autoverificarea este slabă din punct de vedere structural: același context, același model, aceleași puncte oarbe. Trecut la verificare corelează cu trecut la construire — eșuează împreună.

Modelul nu știe că minte. Din perspectiva lui, a povesti am verificat totul cu atenție este o continuare coerentă a faptului că a scris codul. Din același motiv prompturile de tip ești sigur? nu prind halucinațiile: modelul este la fel de sigur la a doua trecere. Încrederea nu corelează cu corectitudinea — corelează cu cât de plauzibil sună propoziția următoare.

Soluția nu sunt prompturi mai bune. Fii atent, verifică din nou, nu halucina — aceste instrucțiuni nu fac nimic. Soluția este structurală: specializează agentul astfel încât să nu poată pretinde fizic că a făcut ceva și direcționează munca cantitativă prin shell, astfel încât răspunsul să vină din starea reală, nu din probabilitatea tokenilor.

Regula 1: un agent, o specializare

Împarte munca în agenți separați cu contexte separate. Fiecare agent are o singură responsabilitate și un set restrâns de unelte. Întregul flux devine o ștafetă în loc de un singur agent care aleargă în cerc:

  • Agentul builder: ia specificația, scrie codul. Asta e toată treaba lui. Are Read, Edit, Write, Bash.
  • Agentul reviewer: ia specificația plus diff-ul, verifică criteriile de acceptanță. Context nou. Nu știe cum a fost scris codul, doar ce a ieșit. Are Bash, Read, Grep, Glob — niciun fel de unelte de scriere.
  • Agentul de analytics: răspunde la întrebări despre date construind și rulând interogări. Doar Bash. Nu poate ajunge la răspuns fără să ruleze o comandă reală.
  • Orchestratorul: sesiunea principală care trimite fiecare agent pe rând și niciodată nu cere unui agent să facă treaba altuia.

Exemplu concret: implementarea unui UI plus o verificare vizuală față de un mockup Figma. Builderul scrie componentele și face commit la diff. Apoi orchestratorul invocă reviewerul cu URL-ul designului, diff-ul și criterii de acceptanță explicite. Reviewerul rulează Playwright, face capturi de ecran, le compară cu referința și returnează PASS sau FAIL cu căile reale ale capturilor și diferențele la nivel de pixel. Builderul nu se apropie niciodată de pasul de verificare — și tocmai de aceea verificarea este reală.

Antitiparul este mega-agentul: un singur prompt care spune construiește acest UI și asigură-te că se potrivește cu mockup-ul. Îți garantez că va raporta că totul se potrivește. Nu se potrivește. Narațiunea am verificat este pur și simplu cea mai probabilă secvență de tokeni după l-am construit.

Regula 2: shell în loc de prompt, întotdeauna

Orice este cantitativ, orice atinge starea reală, orice unde răspunsul poate fi greșit într-un fel care pare corect — trimite-l prin sh. Treaba agentului este să construiască și să ruleze comanda, apoi să îi citească rezultatul. Agentul nu este sursa adevărului. Rezultatul shell-ului este.

  • Numărare: wc -l logs.txt este adevărat. Sunt aproximativ 47 de linii de log spus de un model este o halucinație.
  • Analytics: psql -c "SELECT count(*) FROM events WHERE created_at > now() - interval '30 days'". Nu estimează volumul.
  • Teste: pnpm test --reporter=json | jq '.numFailedTests'. Nu rezumă ce a eșuat.
  • Starea Git: git rev-list --count main..HEAD, git diff --stat. Nu numără commit-urile sau descrie modificările.

Odată ce interiorizezi asta, începi să observi fiecare loc unde agentul era pe cale să inventeze un număr. Se pare că sunt vreo 200 de înregistrări... — nu. Rulează SELECT count(*). Majoritatea testelor trec... — nu. Rulează suita de teste, parsează JSON-ul. Modelul este excelent la construirea comenzii. Este nesigur când vine vorba să fie comanda.

Moduri de eșec pe care le-am întâlnit chiar eu

Nu sunt scenarii ipotetice. Fiecare dintre acestea m-a costat timp real înainte să schimb tiparul:

  • Verificare fantomă. Agentul a spus am verificat toate cele 14 secțiuni față de mockup. Nu a deschis mockup-ul. Nu a făcut nicio captură de ecran. Verificarea a fost un pas halucinat din narațiune.
  • Numere greșite spuse cu încredere. Am cerut monthly active users din datele de analytics. Am primit un număr greșit de aproximativ 3×. Modelul a interpolat din rânduri de eșantion în loc să ruleze interogarea reală.
  • Modificări de fișiere inventate. Agentul a spus am actualizat config/feature-flags.json. Nu o făcuse. Doar intenționase. git diff era gol.
  • Rulări de teste false. Toate testele trec. Niciun test nu a fost executat. Agentul nu a invocat niciodată test runner-ul — a prezis cum ar fi arătat rezultatul acestuia.

Toate patru se rezolvă cu aceleași două reguli: împarte agentul, împinge în shell. Reviewerul nu are Write, deci nu poate falsifica editarea fișierelor. Agentul de analytics are doar Bash, deci nu poate returna un număr care nu a venit dintr-o interogare. Imposibilitatea structurală bate bunele intenții de fiecare dată.

Cum structurezi asta în Claude Code

Claude Code acceptă sub-agenți definiți în .claude/agents/*.md. Fiecare fișier de agent declară un nume, o descriere, un set de unelte permise și un system prompt. Orchestratorul (sesiunea ta principală) îi trimite folosind unealta Agent. Iată genul de definiție pe care îl folosesc pentru reviewer — scurtă, îngustă și incapabilă fizic să scrie cod:

.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

Observă setul de unelte: Bash, Read, Grep, Glob. Niciun Write, niciun Edit, niciun Agent. Reviewerul poate rula comenzi, citi fișiere, căuta tipare — și nimic altceva. Dacă încearcă să dea un diff halucinat drept verificat, forma apelurilor lui de unelte face asta evident: nu au existat verificări reale. Poți audita apelurile de unelte și vezi exact ce a fost inspectat.

Tiparul de orchestrare: sesiunea principală apelează Builderul → așteaptă → rulează ea însăși git diff pentru a captura modificarea reală → apelează Reviewerul cu specificația și diff-ul → citește verdictul. Sesiunea principală nu cere niciodată unui singur agent să facă ambele. Restricțiile de unelte sunt mai puternice decât instrucțiunile din prompt: nu falsifica verificarea este o dorință. Faptul de a nu avea Write este un fapt.

Antitipare de abandonat

Lucruri pe care le văd în prompturi și care nu fac nimic — sau, mai rău, dau un fals sentiment de siguranță:

  • Fii atent și verifică-ți munca din nou. Nu generează niciun comportament suplimentar. Modelul produce deja ceva ce arată ca muncă atentă.
  • Asigură-te că verifici cu adevărat. Cuvintele cu adevărat nu adaugă o semantică pe care modelul să poată acționa. Va pretinde cu adevărat că a verificat.
  • Nu halucina. Un meme din prompt engineering. Halucinația nu este un întrerupător pe care modelul îl poate opri.
  • Să te încrezi în agent la numerele mici. La numerele mici minte cu cea mai mare încredere. Nu există un prag minim de onestitate.
  • Să adaugi mai multe reguli în prompt pentru a forța onestitatea. Corecțiile structurale (împărțire + shell) bat ajustările de prompt de fiecare dată. Dacă o regulă trebuie impusă, codific-o în accesul la unelte, nu în limba română.

Dacă strategia ta de a prinde halucinațiile este o formulare mai emfatică, nu ai o strategie. Ai o speranță.

Modelul mental

Un agent nu este un coleg. Este o funcție: prompt → tokens. Funcția este excelentă la scrierea codului și groaznică la a introspecta dacă a făcut lucrul corect. Tratează afirmațiile ei despre propria muncă drept o ipoteză. Diff-ul, codul de ieșire, captura de ecran, numărul de rânduri — acestea sunt dovezile. Rezumatul de la finalul turei este suprafața cea mai predispusă la minciună din tot sistemul.

Specializarea este asigurarea ta împotriva derivei narative. Shell-ul este singura ta sursă de adevăr. Builderul scrie. Reviewerul verifică. Bash decide.

Concluzie

Dacă reții un singur lucru: nu lăsa un singur agent să își producă și să își judece propriul rezultat și nu lăsa niciun agent să răspundă la o întrebare cantitativă fără să ruleze o comandă. Tot restul decurge din aceste două reguli. Configurează accesul la unelte agresiv, auditează apelurile de unelte în loc de rezumate, iar suprafața halucinațiilor se micșorează de la peste tot la câteva locuri specifice pe care deja știi să le verifici.