Přeskočit na obsah

Lekce 02.2: Nedeterminismus (Non-Determinism)

⏱️ 3 min čtení Lekce 02.2

🧠 Mentální model & teoretický rozbor

Jazykový model není databáze ani kalkulačka. Je to obří pravděpodobnostní rozdělení nad tokeny:

$$P(w_t \mid w_1, w_2, \dots, w_{t-1})$$

Při každém kroku generování model vybírá další token z pravděpodobnostního koše. I při teplotě nastavené blízko nuly (temperature = 0) může dojít k drobným rozdílům v závislosti na zaokrouhlování plovoucí řádové čárky (GPU non-determinism) a verzích systémových vah.

STEJNÝ PROMPT: "Vytvoř funkci pro parsování data"
┌──> POKUS 1: Použije nativní `new Date()` a regex
├──> POKUS 2: Nainstaluje balíček `date-fns`
└──> POKUS 3: Použije novou specifikaci `Temporal`

V tradičním inženýrství vyžadujeme deterministické chování (stejný kód + stejný vstup = stejný výstup). Jak zkrotit nedeterministického agenta v deterministickém softwarovém projektu?


🏢 Realistický scénář z praxe

Tým vyvíjí platební bránu.

  • Vývojář A zadá agentovi: „Implementuj validaci IBANu.“ Agent použije regex validaci.
  • Vývojář B o týden později zadá stejnému agentovi: „Přidej podporu IBANu pro Slovensko.“ Agent regex smaže a importuje externí knihovnu ibantools, čímž nečekaně zvětší klientský bundle o 150 kB a rozbije existující unit testy.
  • Kde byla chyba? V zadání chyběla specifikace technologie a deterministický test.

💻 Konkrétní ukázky kódu & promptů

Jak zkrotit nedeterminismus pomocí přísných typů a testů:

1. Striktní kontrakt rozhraní (src/types/iban.ts):

export interface IbanValidationResult {
readonly isValid: boolean;
readonly countryCode?: string;
readonly errorCode?: 'INVALID_LENGTH' | 'INVALID_CHECKSUM' | 'UNSUPPORTED_COUNTRY';
}
export type IbanValidatorFn = (iban: string) => IbanValidationResult;

2. Deterministický prompt, který neponechává prostor pro náhodu:

Úkol: Implementuj funkci validateIban v src/utils/iban.ts.
Striktní požadavky (Deterministické mantinely):
1. Funkce MUSÍ splňovat typ IbanValidatorFn z src/types/iban.ts.
2. ZÁKAZ instalace externích balíčků (žádné úpravy package.json).
3. Validace algoritmem MOD-97 (ISO 7064).
4. Všechny testy v src/utils/__tests__/iban.test.ts musí projít:
`npx vitest run src/utils/__tests__/iban.test.ts`.

⚠️ Analýza selhání & Anti-patterns

Chyba: Spoléhání na to, že “minule to fungovalo”

Pokud agent včera vyřešil úkol jedním způsobem, nečekejte, že dnes při stejném vágním promptu zopakuje stejný postup.

  • Anti-pattern: Psát prompty bez specifikace vstupních/výstupních formátů a bez automatických testů.
  • Důsledek: Kód se stane chaotickým patchworkem různých stylů a knihoven.

🛠️ Inženýrský postup krok za krokem (Playbook)

  1. Definujte typové mantinely jako první: Než necháte model psát implementaci, nechte ho (nebo sami) definovat TypeScript typy/rozhraní.
  2. Připravte sadu testovacích případů (Golden Data): Připravte pole 10 konkrétních vstupů a očekávaných výstupů.
  3. Spusťte linter: Automatický formátovač (Biome) okamžitě zarovná nedeterministický styl kódu do standardizované podoby.

🧪 Praktické cvičení (Hands-on Lab)

Úkol:

Otestujte nedeterminismus v praxi a následně ho zkroťte.

Kroky:

  1. Otevřete nové sezení a zadejte: „Napiš TypeScript funkci pro výpočet faktoriálu.“ Poznamenejte si, zda použil rekurzi, cyklus for, nebo reduce.
  2. Zadejte /clear.
  3. Zadejte stejný dotaz znovu. Sledujte odlišnosti v kódu.
  4. Nyní napište mantinel: „Napiš funkci factorial(n: number): bigint. MUSÍ být iterativní s cyklem while a ošetřením pro záporná čísla.“
  5. Zopakujte to dvakrát za sebou – kód bude v obou případech strukturálně identický!