AI agent je tak dobrý, jak dobré jsou vaše typy

před 2 hodinami od David Grudl  

Jakmile začnete programovat s AI agentem, zjistíte, že důležitost špičkového IDE typu PhpStorm najednou klesá, zatímco důležitost špičkové typové kontroly, třeba přes PHPStan, prudce roste. Před dvěma lety by to znělo jako kacířství. Dnes je to spíš praktický návod, jak psát lepší kód.

IDE bylo pro člověka, analýza je pro stroj

IDE jsme milovali za našeptávač, za typ, který vyskočí při najetí myší, za skok na definici a za bezpečný refactoring. To všechno je ale pomoc pro lidské oko a ruku. Agent obrazovku nečte. Nepotřebuje tooltip, který se objeví po najetí kurzorem. Potřebuje informaci, kterou si přečte jako text a hlavně si ji umí ověřit sám.

A přesně to je statická analýza: ne nápověda pro člověka, ale verdikt pro stroj. PhpStorm vám decentně podtrhne místo, kde možná předáváte null. PHPStan tutéž věc napíše do konzole jako chybu, kterou agent přečte, pochopí a opraví, aniž byste u toho museli sedět.

Neznamená to, že IDE umírá, pořád je to skvělý nástroj. Jen se posunulo, kde vzniká ta užitečná hodnota. To, co dřív dodával editor jednomu člověku u klávesnice, dnes potřebujete mít v podobě, kterou spolkne i nástroj běžící bez vás.

Celé je to o smyčce

První zkušenost s agentem bývá zklamání a skoro vždycky za to může:

  • pustíte ho bez konvencí
  • pustíte ho bez prostředí

Agent není kouzelník, který uhodne, jak má váš kód vypadat. Musíte mu to popsat: konvence, styl, linter. Pro Nette jsme tohle sepsali do sady pravidel pro Claude Code, díky které agent generuje kód přesně tak, jak je v Nette zvykem.

Je to také nástroj, který je přesně tak dobrý, jak dobrá je zpětná vazba, kterou dostává. Agent něco napíše, spustí statickou analýzu a testy, přečte si výsledek, opraví chybu a zkusí to znovu. Napiš, ověř, oprav, opakuj. Tomuhle cyklu se říká agentní smyčka a je to ten okamžik, kdy se z generátoru textu stane něco, co kód opravdu doladí do funkčního stavu.

Dva zdroje zpětné vazby máte po ruce hned. Statickou analýzu a testy. Pokud testy nepíšete, je to úplně první věc, kterou si nechte od agenta vygenerovat. Bez slušného pokrytí totiž smyčku nezavřete, agent nemá jak poznat, že něco rozbil.

Náskok, který teprve teď začíná dávat smysl

Tady přichází na řadu Nette, protože celé je otypované do morku kostí. A není to věc posledního roku.

Když PHP 7.1 přineslo skalární a návratové typy, bylo Nette vůbec prvním full-stack frameworkem, který je nasadil naplno, včetně declare(strict_types=1) v každém souboru. A pak to pokračovalo: jakmile PHP 7.4 přidalo typované property, Nette je převzalo. Co uměl jazyk vyjádřit nativně, to Nette používalo, většinou dřív než ostatní.

Roky to byla hlavně otázka kvality a čistoty kódu. Hezké, ale tak trochu detail pro fajnšmekry. S nástupem agentů se z toho stala konkurenční výhoda. Čím líp je základ otypovaný, tím míň toho musí agent hádat a tím přesněji generuje právě váš kód.

Co umí typy, na které samotné PHP nestačí?

Nativní typy mají strop. PHP neumí zapsat „pole řetězců“, „neprázdný seznam“ ani „návratová hodnota závisí na argumentu“. Jenže právě tyhle věci dokáže vyjádřit PHPStan přes anotace v PHPDoc a Nette je využívá naplno.

Nejlíp je to vidět na běžném vzorci: formulář vám vrátí data rovnou jako vaši DTO třídu. Stačí říct si o ni jménem a getValues() ji vrátí přesně otypovanou:

$data = $form->getValues(RegistrationData::class);

echo $data->email;   // $data je RegistrationData, plně otypované

Funguje to díky podmíněnému návratovému typu, který říká „když ti předám jméno třídy, vrátíš mi instanci té třídy“. Žádný nativní typ tohle nezvládne:

/**
 * @template T of object
 * @param class-string<T>|T|'array'|true|null  $returnType
 * @return ($returnType is class-string<T>|T ? T : ($returnType is 'array'|true ? mixed[] : ArrayHash<mixed>))
 */
public function getValues(string|object|bool|null $returnType = null): object|array

Statická analýza tedy ví, že $data je RegistrationData, a tím pádem to ví i agent. Nemusí nic hádat, čte to rovnou z typu, a když napíšete $data->emial, dostane chybu ještě před spuštěním.

Napříč frameworkem najdete array shapes jako array{absolute: bool, path: string, signal: bool, ...}, dále class-string<T>, positive-int, non-empty-string nebo @param-out. Jsou to desítky a desítky míst, kde typ nese víc informací, než kolik by uneslo holé PHP.

Výsledkem je API, které samo o sobě popisuje, co dělá. A to je přesně to, co agent v té smyčce potřebuje.

Nově: celé Nette projde PHPStanem na level 8

A teď to hlavní. S posledními verzemi jsme typování dotáhli do konce. Všechny balíčky Nette jsou nově doplněné o vyčerpávající typové anotace a všechny do jednoho procházejí statickou analýzou na plný level 8. Ne jen části, ne s hromadou výjimek, ale celý framework.

Pro vás z toho plyne to podstatné: stavíte na základu, který je otypovaný tak důsledně, jak to jen jde. A na dobře otypovaném základu se snadno staví dobře otypovaná aplikace. Vaše vlastní typy se mají oč opřít a agent, který staví na Nette, má pod nohama pevnou půdu.

A proč „jen“ osmička, když PHPStan má jedenáct úrovní (0 až 10)? Protože všechno nad ní je už jen o striktním zacházení s typem mixed, se kterým framework legitimně pracuje (konfigurace, DI kontejner, libovolné callbacky), takže level 8 je nejvyšší stupeň, který tady ještě dává praktický smysl.

A typování nekončí na hranici frameworku. Nette dodává i rozšíření pro PHPStan, které analyzátor naučí nettí specifika: $this['menu'] rozpozná jako vaši MenuControl, odvodí typy formulářových prvků z addText() nebo addSelect(), pochopí properties s #[Inject]. Statická analýza tak vidí i do vašeho kódu, ne jen do toho frameworkového, a agent ve smyčce má z čeho číst.

Kód už nečtou jen lidé

IDE nezmizí, pořád je to skvělý nástroj pro člověka. Ale těžiště se přesunulo. Hodnotu, kterou jsme dřív čekali od editoru, dnes nesou typy a testy, protože z nich čte i stroj. Nette ji shromažďovalo roky, kdy se to ještě zdálo jako detail.

Jestli vás láká pustit se do programování s agenty pořádně, dá se to i naučit, mám k tomu kurz. A pak už jen zavřete agenta do smyčky a nechte ho pracovat.

David Grudl Zakladatel Uměligence a autor Nette Framework, populárního PHP frameworku. Od roku 2021 se naplno věnuje umělé inteligenci a učí lidi ji využívat v praxi. Spolu s kolegy z Tech Guys každý týden rozebírá tech novinky. Píše na phpFashion a La Trine. Věří, že AI není sci-fi, ale nástroj pro lepší život už dnes.