AI agent je tak dobrý, jak dobré jsou vaše typy
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.
Chcete-li odeslat komentář, přihlaste se