Træk fra, tilpas, bevis: Tre færdigheder der forhindrer AI-agenter i at gøre dit repo til spaghetti

Udgivet den Jul 1, 2026 af Štefan Moravík.
AI Agents Developer Productivity Agentic Workflows Code Review
På denne side 11 min læsning
  1. 1Del 1 · HVAD — entropi er standarden
  2. 2Del 2 · HVAD SÅ — fem PR’er, ét instinkt hver
  3. 3Del 3 · HVAD NU

Vi giver hver dag kodeagenter rigtige tickets, og de leverer næsten altid noget, der virker. Det var aldrig bekymringen. Bekymringen er hvordan de arbejder: en ny helper ved siden af tre, der allerede løser opgaven, en frisk abstraktion til én enkelt kalder, en rettelse der lapper den ene vej, ticketen nævnte, og efterlader fire søskende i stykker, et fund der er “sandsynligvis en bug” uden bevis i nogen retning. Hver ændring er lokalt rimelig. I sum er de entropi.

TL;DR: På tværs af fem Tier-3 pull requests på vores agentorkestrerings-kerne fjernede tre komponerbare færdigheder — ponytail (træk fra), grain (tilpas) og review-proof (bevis) — 821 linjer, mens de shippede fem funktioner, fangede et tavst kontraktbrud, som plausibilitet alene ville have merget, og holdt hver ændring i tråd med den eksisterende arkitekturs årer. Her er, hvad hver af dem gør, med de rigtige diffs som belæg.

Fjerner man guardrails, er en kodeagent en meget hurtig generator af troværdigt udseende byrder. Derfor læner vi os op ad tre små færdigheder, der skubber den anden vej — ét instinkt hver: træk fra, tilpas, bevis.

  • ponytail — skriv det dovneste, der faktisk virker. Slet før du tilføjer. (Vi har ikke skrevet denne — det er en open source-færdighed af Dietrich Gebert , som vi tilpassede til vores stack.)
  • grain / grain-review — placér det, hvor kodebasen allerede har besluttet, at det hører til. Opfind ikke en anden måde.
  • review-proof — tro ikke på et fund, før det kan genskabes som en fejlende test.

grain og review-proof byggede vi i samme ånd som ponytail, tunet til vores arkitektur. Hver af de fem PR’er nedenfor rører vores agentorkestrerings-kerne — det dyreste sted i repoet at være sjusket — og hver enkelt er klassificeret Tier 3: ekstra testdækning og menneskelig gennemgang oven på den automatiserede reviewer, uden undtagelser.

Tre kodeagent-færdigheder, ét instinkt hver: ponytail trækker fra, grain tilpasser, review-proof beviser — med hvad hver enkelt dræber, og hvad det giver

De tre færdigheder på et blik: ponytail trækker fra, grain tilpasser, review-proof beviser.

Del 1 · HVAD — entropi er standarden

Her er det, ingen advarer dig om, når du giver et repo til AI-agenter: hver agent optimerer lokalt og husker intet. Den ser ticketen, ikke de måneders konventioner, dit team har konvergeret på. Den har ingen grund til at foretrække din eksisterende e-mailtjeneste frem for en ny, ingen erindring om, at redirect-status-sættet allerede er defineret tre filer væk, ingen instinkt for at “rettelsen hører i den delte funktion, ikke i denne ene kalder”. Får N agenter lov at køre, producerer de N lidt forskellige måder at gøre det samme på. Det er ikke et kodekvalitetsproblem, du kan lint’e væk — det er en strukturel drift, der forstærker sig selv.

De tre færdigheder rammer hver sin akse af den drift.

ponytail — det dovneste, der virker

Ponytail er en seniorudvikler, der er blevet kaldt op kl. 3 om natten på grund af en andens smarte abstraktion og nægter at skrive den næste. Den kører en stige og stopper på første trin, der holder: behøver dette overhovedet at eksistere (YAGNI) → findes det allerede i denne kodebase → klarer standardbiblioteket det → native platformfunktion → allerede installeret afhængighed → kan det være én linje → først da, den minimale kode, der virker.

Trinnet, der betyder mest for agenter, er “findes det allerede i denne kodebase?” At genimplementere noget, der ligger få filer væk, er den mest almindelige form for agent-slop. Og ponytails bugfix-regel holder diffs ærlige: ret rodårsagen, ikke symptomet. Grep hver kalder af den funktion, du er ved at røre; én guard i den delte funktion er en mindre diff end en guard i hver kalder — og den efterlader ikke søskendene i stykker.

grain / grain-review — gå med årerne

Hvis ponytail styrer hvor lidt du skriver, styrer grain hvor det lander, og hvilken form det får. Dens ene regel: find det nærmeste eksisterende eksempel, kopiér dets form, navngiv hvad du kopierede. Ny kode bør læse, som om personen, der skrev filen ved siden af, også skrev denne.

Grain er også der, arkitekturen håndhæves. Vores backend er en ret standard vertical-slice + hexagonal opbygning — præsentation kalder applikation kalder domæne, infrastruktur afhænger indad, og domænet rækker aldrig ud igen. Et fund som “denne route springer sin controller over og henter servicen direkte” er ikke pedanteri — det er forskellen på en kodebase, en agent kan navigere i næste måned, og en, den ikke kan. grain-review jagter præcis disse: duplikerede helpers, krydsede laggrænser, indgreb i en anden funktions indre, en anden konvention for noget, der allerede gøres på én måde.

review-proof — gør dig fortjent til fundet

Standard AI-kodegennemgang producerer plausible fund. Nogle er rigtige; nogle er selvsikker nonsens; udefra ser de identiske ud. review-proof nægter at stole på sig selv: den gennemgår, og tvinger derefter hvert korrekthedsfund til at reproducere som en rigtig fejlende test eller et kørbart repro, og dropper alt, der ikke kan. Den slutter af med en grain-review-runde for strukturel pasform. Det, der shippes, er en gennemgang, hvor hvert punkt kommer med eksekverbart bevis — ikke en fornemmelse.

Hvad vi bør se, hvis det virker

  • H1 — Sletning dukker op i feature-PR’er. Hvis ponytail + grain virker, bør det at tilføje en funktion ofte fjerne netto-struktur, ikke kun tilføje den.
  • H2 — Rettelser lander ét sted, på det delte sted. Rodårsagsrettelser bør kollapse mange kaldesteder ind i én guard, ikke drysse guards ud pr. kalder.
  • H3 — Gennemgangen fanger kontraktbrud, som et menneske skimmer forbi. Bevis-understøttet gennemgang bør overflade bugs, som en “ser fint ud”-gennemgang misser — især den tavse slags.

Del 2 · HVAD SÅ — fem PR’er, ét instinkt hver

Fem rigtige ændringer af vores agentkerne. Vi holder med vilje de interne detaljer vage — repoet er privat — men tallene er beregnet ud fra de faktiske diffs, og lektionerne er den del, der kan overføres.

Træk fra: én guard til et dusin fetch-steder

Én familie af flow-trin hentede brugerleverede URL’er uden et DNS-opløsende sikkerhedstjek, så et hostnavn, der blev opløst til en intern adresse, kunne nå cloud-metadata fra backenden. Den fristende rettelse tilføjer et tjek på hvert af de mere end et dusin fetch-steder. Ponytails svar var det modsatte: én delt, guardet fetch-helper, brugt overalt — og vi slettede en håndrullet privat-netværkstabel, som et wildcard-DNS-trick gik lige forbi, plus tre duplikerede redirect-loops og et netværkstjek copy-pastet ind i flere filer.

Diffen tilføjede den delte helper og fjernede ~90 linjer duplikering på tværs af 22 filer. Den sletning er historien: dette er H2 i kød og blod — rodårsagsrettelsen sendte hver kalder gennem én guard i stedet for at lappe den ene vej, ticketen nævnte.

Et dusin bruger-URL-fetch-steder, hver med sit eget omgåelige tjek, samles i én delt, guardet fetch-helper

Rodårsagsrettelsen: et dusin ad-hoc fetch-steder kollapser ind i én delt, guardet helper. Den dovne rettelse og den sikre rettelse er den samme rettelse.

Træk fra + bevis: én shape-guard, bevist på det virkelige runtime

Vores worker-runtime gemmer et kørselsresultat som en serialiseret streng, nogle gange pakket i en liste med ét element. Forbrugere, der forventede et almindeligt objekt, crashede på det. Den forkerte rettelse spreder defensive type-tjek ud hos hver forbruger. I stedet: én lille shape-normaliserende helper, og hver forbruger peget om mod den — en næsten ren tilføjelse af én guard, der erstatter de N ad-hoc-guards, en mindre disciplineret agent ville have skrevet (+558 / −24, 7 filer).

Det, der gør dette til en review-proof-historie, er testen. I stedet for at assertere mod en antaget serialiseringsform kørte vi en rigtig workflow gennem det faktiske runtime og lager — ingen mocks — og beviste den form, runtimem faktisk gemmer. Det åbne spørgsmål i ticketen var bogstaveligt talt hvad serialiserer runtimem her? — og det eneste ærlige svar er et, du kan køre.

Bevis: gennemgangen fangede et tavst kontraktbrud

Funktion: en fallback-model pr. node, så et flow låst til én udbyder degraderer elegant under et nedbrud. Den oplagte første version pakkede modellen ind i frameworkets indbyggede fallback-kombinator.

Den virkede på happy path. Den slukkede også tavst for to udbyderfunktioner, der gater på den konkrete modeltype via isinstance — et indpakket objekt er ikke længere den type, så native struktureret output og prompt-caching blev begge stille slået fra. Ingen fejl. Ingen fejlende happy-path-test. Præcis den slags, en menneskelig gennemgang skimmer forbi, og en “ser fint ud”-agent godkender.

review-proof godkendte den ikke — den genskabte begge brud som fejlende tests, hvilket tvang et redesign: anvend fallbacken længere nede, på eksekveringstidspunktet, så hver model forbliver sin konkrete type, og de type-gatede funktioner fortsætter med at virke. H3, bekræftet med eftertryk: bevis fangede en bug, som plausibilitet ville have shippet.

Tilpas: én picker, ikke to kopier

At tilføje en anden notifikationskanal betød, at kanal-vælgerens UI nu havde to hjem — en opret-wizard og et indstillingsmodal. Agentens standardtræk tilføjer den nye gren begge steder og dyrker to kopier af samme state machine. grain sagde: der er allerede én måde, dette bør formes på — gør det delt. Vi udtrak ét enkelt picker-hook og kørte begge skærme gennem det, satte den nye kanal ind i den eksisterende config-union og genbrugte den eksisterende e-mailtjeneste i stedet for at tilføje ny send-mekanik.

+1.735 / −340 på tværs af 24 filer. At en funktion af denne størrelse fjerner 340 linjer er H1 gjort synlig: dedupen af to picker-kopier til én betalte for en god del af den nye kanal.

Tilpas + bevis: genbrug endepunktet, spejl stien

At lade brugere vedhæfte filer ved oprettelse af en sag kunne have betydet et nyt upload-endepunkt, en ny dispatch-mekanisme, en ny prompt-sti. grain sendte næsten det hele ind på eksisterende skinner: det eksisterende upload-endepunkt, en frontend-acceptliste der spejler backendens whitelist præcist, og en deferred-dispatch-rettelse der genbrugte den eligibility-mekanisme, planlagt arbejde allerede brugte. Det blev shippet med bevis-understøttede rettelser, inklusive en rigtig transaktionsisolerings-bug, der ville have mistet data ved parallelle uploads. +1.776 / −218 på tværs af 27 filer — en stor funktion, der stadig fandt 218 linjer at fjerne ved at tilslutte sig eksisterende slices i stedet for at opfinde nye.

Resultattavlen

Resultattavle over fem Tier-3-PR'er med tilføjede og fjernede linjer pr. PR, plus det instinkt der formede hver enkelt: træk fra, tilpas eller bevis

Fem Tier-3-PR’er: hvad hver tilføjede, hvad den fjernede, og instinktet bag.

Fem feature- og rettelses-PR’er på agentkernen fjernede 821 linjer — ikke ved at gøre mindre, men ved at nægte at duplikere det, der allerede fandtes, og ved at holde symptomlapper væk, som en rodårsagsrettelse gjorde overflødige.

Fuld åbenhed

  • Det er færdigheder, ikke et studie. Det er ikke et kontrolleret eksperiment med en baseline-arm; det er fem rigtige PR’er, hvor disciplinen blev anvendt. Kontrafaktualiteten — hvad den samme agent ville have shippet uden færdighederne — er et kvalificeret skøn, ikke en måling. Historien om det tavse kontraktbrud er det klareste bevis, fordi vi så gennemgangen genskabe bugen før redesignet.
  • Linjetal er proksier. −821 er et rigtigt tal fra diffene, men “fjernede linjer” står for “duplikering og død fleksibilitet undgået”. En færdighed, der taler en agent fra at skrive 200 spekulative linjer, efterlader slet ingen spor i en diff — de største gevinster er usynlige her.
  • Tokenbesparelser er retningsangivende. Mindre diffs, færre berørte filer og genbrugte strukturer betyder færre tokens brugt på at generere, gennemgå og gengennemgå — men vi citerer ikke et hårdt token-delta pr. PR.
  • ponytail er ikke vores. Det er en open source-færdighed af Dietrich Gebert ; vi tilpassede den. grain og review-proof er vores, bygget i samme ånd. Alle tre kører som lokale projektfærdigheder på Claude Code — prompt-og-procedure, ikke en binær, du installerer.
FlowHunt Logo

Klar til at vokse din virksomhed?

Start din gratis prøveperiode i dag og se resultater inden for få dage.

Del 3 · HVAD NU

Hvad blev shippet. Tre komponerbare færdigheder. ponytail og grain kører mens der skrives; ponytail-review, grain-review og review-proof kører på en diff. review-proof kæder grain-review som sin sidste fase, så én enkelt bevist gennemgang også får en strukturel gennemkørsel gratis.

Hvad du kan gøre på mandag — du behøver ikke vores præcise færdigheder:

  1. Gør “genbrug” til trin to, ikke trin ti. Før en agent skriver en helper, så lad den greppe efter en, der findes. “Findes det allerede i denne kodebase?” hører over “kan jeg skrive det pænt?”
  2. Ret ved roden, bevis det med kalderlisten. Kræv, at hver bugfix navngiver hver kalder af den berørte funktion. Én guard i den delte funktion slår en guard pr. kalder — og det er en mindre diff.
  3. Giv ny kode en nærmeste søskende at kopiere. “Find det nærmeste eksisterende eksempel og spejl dets form” gør arkitektur fra et dokument, ingen læser, til en standard, agenten følger.
  4. Håndhæv laggrænser i CI, ikke på fornemmelser. En ratchet, der kun fejler på nye cross-layer-imports, lader dig holde linjen uden at koge suppe på al eksisterende gæld.
  5. Ship ikke et fund, du ikke kan genskabe. Lad agenten skrive den fejlende test først. Kan den ikke få bugen til at reproducere, er det ikke en bug — det er en mening. Drop det.
  6. Lad gennemgangen slette. Ret en review-gennemgang specifikt mod over-engineering — “hvad kan vi skære væk” — adskilt fra korrekthed. Det bedste udfald af en diff er, at den bliver kortere.

Prøv det, især hvis det fejler for dig. Kører du kodeagenter på en rigtig kodebase, sker entropien allerede — du har bare ikke målt den. Lav en af disse om til en review-gennemgang på dine næste ti agent-PR’er og tæl sletningerne. Hvis træk-fra-tilpas-bevis ikke krymper dine diffs eller fanger et tavst brud, vil vi virkelig gerne høre det. Rettelser og modeksempler er særligt velkomne.

En agent tilføjer. Opgaven er at få agenten til at fortjene hver linje.

Ofte stillede spørgsmål

Štefan er en AI- og softwareingeniør, der bygger FlowHunt. Ud over selve produktet designer han agentic software-engineering workflows for udviklere, der reducerer udviklingskostnaderne, mens kodekvaliteten forbedres.

Štefan Moravík
Štefan Moravík
AI- og softwareingeniør

Byg agent-arbejdsgange der betaler sig selv

FlowHunt hjælper ingeniørteams med at designe agentiske arbejdsgange, review-gates og MCP-integrationer, der sænker udviklingsomkostningerne og samtidig løfter kodekvaliteten.