Nette Documentation Preview

syntax
Nastavení a reasoning effort
****************************

.[perex]
Nejdůležitější věc, kterou dnes u modelu nastavuješ, je kolik si toho má rozmyslet, než začne odpovídat. Ovlivňuje to kvalitu, rychlost i cenu. Ukážeme si, jak se to řídí jedním ovladačem napříč všemi providery, kde najdeš zbytek nastavení, a na konec se podíváme, co se stalo s parametrem `temperature`, o kterém možná někde čteš.


Kolik si model rozmyslí, než odpoví
===================================

Novější modely umí něco, co ty starší neuměly: než začnou psát odpověď, napíšou si stranou jakýsi koncept úvahy. Rozeberou si zadání, zkusí postup, najdou v něm chybu, opraví ji, a teprve pak odpovědí. Tomuhle konceptu se říká reasoning nebo thinking, česky prostě přemýšlení. Pokud tě zajímá, co se při něm uvnitř modelu děje, rozebírá to článek [Reasoning modely: co to je |https://www.umeligence.cz/blog/reasoning-modely-co-to-je].

Dvě věci o něm potřebuješ vědět. **Do samotné odpovědi se nedostane**, takže ho `getText()` nikdy neobsahuje; někteří provideři ho ale vracejí zvlášť, u některých jen jako shrnutí, a [přečteš si ho |chat#Co všechno je v odpovědi] přes `getReasoning()`. A hlavně **ho platíš**, protože se počítá jako výstupní tokeny, kterých bývá u složitější úlohy víc než v samotné odpovědi.

Kolik toho model má promyslet, řekneš metodou `setEffort()`:

```php
use AIAccess\Chat\Effort;

$chat = $client->createChat('gpt-5.6-luna');
$chat->setEffort(Effort::Low);

echo $chat->sendMessage('Do které kategorie patří tato reklamace?')->getText();
```

Stupňů je šest: `None`, `Low`, `Medium`, `High`, `XHigh` a `Max`. `None` znamená, že model nemá přemýšlet vůbec a má odpovědět rovnou.

Každý provider si hodnotu přeloží do svého, protože se ani v pojmenování neshodnou:

| Provider | Jak se to jmenuje u něj                                   |
|----------|-----------------------------------------------------------|
| Claude   | `output_config.effort`, `None` navíc vypne `thinking`     |
| OpenAI   | `reasoning.effort`                                        |
| Gemini   | `thinkingConfig.thinkingLevel`, `None` je nulový rozpočet |
| DeepSeek | `thinking.reasoning_effort`                               |
| Grok     | `reasoning_effort`                                        |

Někteří provideři neznají všech šest stupňů, takže se mapují na nejbližší. Gemini má jen tři úrovně, takže `High`, `XHigh` i `Max` u něj skončí stejně.

Dvě zásady stojí za vyslovení. Zaprvé, **dokud `setEffort()` nezavoláš, neposílá se nic** a platí výchozí nastavení providera. Právě proto DeepSeek přemýšlí, i když jsi o to nežádal. Zadruhé, **knihovna si nedrží tabulku schopností modelů**. Když model ovladač nemá, provider odpoví chybou, a to je správně; udržovat seznam toho, co který model zrovna umí, by znamenalo dokumentaci, která zastará dřív, než ji dopíšeš.


Který stupeň si vybrat
======================

Volba stupně není kosmetická, protože přímo určuje, jak dlouho se na odpověď čeká a kolik stojí.

- **`None`** na úlohy, kde není co promýšlet: klasifikace, vytažení údajů z textu, přeformulování věty, překlad. Odpověď přijde nejrychleji a nejlevněji.
- **`Low` a `Medium`** na běžnou práci, kde model potřebuje chvíli přemýšlet, ale ne dlouho: shrnutí delšího textu, návrh odpovědi, jednodušší rozhodování.
- **`High` a výš** na úlohy o více krocích: rozbor kódu, matematika, plánování, uvažování nad protichůdnými informacemi. Počítej s tím, že odpověď přijde později a bude výrazně dražší.

Nejlevnější optimalizace bývá zjistit, že úloha si vystačí s `None`. Rozdíl v ceně mezi vypnutým a maximálním přemýšlením bývá větší než rozdíl mezi dvěma modely.


Nastavení, která má každý provider svoje
========================================

Zbytek nastavení sjednocený není, protože sjednocený být nemůže: `store` má jen OpenAI, `safetySettings` jen Gemini, `seed` jen Grok. Proto jsou to **pojmenované argumenty metody `setOptions()`** na konkrétní třídě providera, ne klíče ve sdíleném poli.

```php
// Claude
$chat->setOptions(maxOutputTokens: 1024, stopSequences: ['KONEC']);

// OpenAI
$chat->setOptions(maxOutputTokens: 1024, store: false, parallelToolCalls: true);
```

Rozdíl proti poli poznáš hned při psaní. IDE ti nabídne přesně to, co daný provider zná, a překlep zachytí PHP samo. Sdílené pole by klíč, který nikam nepatří, tiše spolklo a ty by ses to dozvěděl leda tak, že by se nic nedělo.

Nejužitečnější z nich je `maxOutputTokens`, tedy strop na délku odpovědi. Jmenuje se stejně u všech providerů, protože ho potřebuje každý; na drátě se přitom pokaždé jmenuje jinak, jednou `max_tokens`, jindy `max_completion_tokens`, ale to už je věc knihovny.

Kompletní seznam pro každého providera najdeš v signatuře `setOptions()` v `src/Provider/*/Chat.php`, případně ti ho ukáže IDE. A pokud používáš [generického klienta |providers] pro cizí endpoint, má navíc argument `custom`, kterým protlačíš cokoli, co ten endpoint zná a knihovna ne.


Co se stalo s temperature
=========================

Když někde čteš o nastavování modelů, skoro jistě narazíš na parametr `temperature`. Stojí za to vědět, co dělal a proč ho tahle dokumentace nedoporučuje.

Model nevybírá jedno jediné správné pokračování věty. V každém okamžiku má seznam slov, která by mohla přijít, a ke každému pravděpodobnost; z nich pak jedno vylosuje. Právě proto dostaneš na tutéž otázku pokaždé trochu jinou odpověď. `temperature` určovala, jak riskantní to losování bude: hodnota kolem nuly znamenala střízlivého a předvídatelného pisatele, který skoro vždy sáhne po nejpravděpodobnějším slově, vyšší hodnoty nápaditější text, ale i víc nepřesností. Podobnou věc dělaly jinak parametry `top_p` a `top_k`.

Uvažovací modely tenhle způsob řízení opustily. Když jim `temperature` přesto pošleš, jedni odpoví chybou HTTP 400, což dělá Claude na nejnovějších modelech a OpenAI od GPT-5.1, a druzí ji **tiše ignorují**, což dělá Gemini a DeepSeek pokaždé, když přemýšlí.

Nebezpečné je to druhé. Chyba tě aspoň upozorní; tiše ignorovaný parametr znamená, že aplikace vypadá funkčně, ty ladíš hodnoty a nemá to vůbec žádný účinek.

Knihovna ti `temperature` nezakazuje a na starších modelech ji klidně použij přes `setOptions()`. Jen s ní nestav nic, co má vydržet: na modelech, které vyjdou příští rok, s velkou pravděpodobností nebude fungovat vůbec.


Kam dál
=======

- [Streamování |streaming] - odpověď čti, zatímco ji model teprve píše
- [Volání nástrojů |tools] - když má model sáhnout do tvé aplikace
- [Strukturovaný výstup |structured-output] - když potřebuješ data, ne prózu
- [Provideři |providers] - co který umí a čím se liší

Nastavení a reasoning effort

Nejdůležitější věc, kterou dnes u modelu nastavuješ, je kolik si toho má rozmyslet, než začne odpovídat. Ovlivňuje to kvalitu, rychlost i cenu. Ukážeme si, jak se to řídí jedním ovladačem napříč všemi providery, kde najdeš zbytek nastavení, a na konec se podíváme, co se stalo s parametrem temperature, o kterém možná někde čteš.

Kolik si model rozmyslí, než odpoví

Novější modely umí něco, co ty starší neuměly: než začnou psát odpověď, napíšou si stranou jakýsi koncept úvahy. Rozeberou si zadání, zkusí postup, najdou v něm chybu, opraví ji, a teprve pak odpovědí. Tomuhle konceptu se říká reasoning nebo thinking, česky prostě přemýšlení. Pokud tě zajímá, co se při něm uvnitř modelu děje, rozebírá to článek Reasoning modely: co to je.

Dvě věci o něm potřebuješ vědět. Do samotné odpovědi se nedostane, takže ho getText() nikdy neobsahuje; někteří provideři ho ale vracejí zvlášť, u některých jen jako shrnutí, a přečteš si ho přes getReasoning(). A hlavně ho platíš, protože se počítá jako výstupní tokeny, kterých bývá u složitější úlohy víc než v samotné odpovědi.

Kolik toho model má promyslet, řekneš metodou setEffort():

use AIAccess\Chat\Effort;

$chat = $client->createChat('gpt-5.6-luna');
$chat->setEffort(Effort::Low);

echo $chat->sendMessage('Do které kategorie patří tato reklamace?')->getText();

Stupňů je šest: None, Low, Medium, High, XHigh a Max. None znamená, že model nemá přemýšlet vůbec a má odpovědět rovnou.

Každý provider si hodnotu přeloží do svého, protože se ani v pojmenování neshodnou:

Provider Jak se to jmenuje u něj
Claude output_config.effort, None navíc vypne thinking
OpenAI reasoning.effort
Gemini thinkingConfig.thinkingLevel, None je nulový rozpočet
DeepSeek thinking.reasoning_effort
Grok reasoning_effort

Někteří provideři neznají všech šest stupňů, takže se mapují na nejbližší. Gemini má jen tři úrovně, takže High, XHigh i Max u něj skončí stejně.

Dvě zásady stojí za vyslovení. Zaprvé, dokud setEffort() nezavoláš, neposílá se nic a platí výchozí nastavení providera. Právě proto DeepSeek přemýšlí, i když jsi o to nežádal. Zadruhé, knihovna si nedrží tabulku schopností modelů. Když model ovladač nemá, provider odpoví chybou, a to je správně; udržovat seznam toho, co který model zrovna umí, by znamenalo dokumentaci, která zastará dřív, než ji dopíšeš.

Který stupeň si vybrat

Volba stupně není kosmetická, protože přímo určuje, jak dlouho se na odpověď čeká a kolik stojí.

  • None na úlohy, kde není co promýšlet: klasifikace, vytažení údajů z textu, přeformulování věty, překlad. Odpověď přijde nejrychleji a nejlevněji.
  • Low a Medium na běžnou práci, kde model potřebuje chvíli přemýšlet, ale ne dlouho: shrnutí delšího textu, návrh odpovědi, jednodušší rozhodování.
  • High a výš na úlohy o více krocích: rozbor kódu, matematika, plánování, uvažování nad protichůdnými informacemi. Počítej s tím, že odpověď přijde později a bude výrazně dražší.

Nejlevnější optimalizace bývá zjistit, že úloha si vystačí s None. Rozdíl v ceně mezi vypnutým a maximálním přemýšlením bývá větší než rozdíl mezi dvěma modely.

Nastavení, která má každý provider svoje

Zbytek nastavení sjednocený není, protože sjednocený být nemůže: store má jen OpenAI, safetySettings jen Gemini, seed jen Grok. Proto jsou to pojmenované argumenty metody setOptions() na konkrétní třídě providera, ne klíče ve sdíleném poli.

// Claude
$chat->setOptions(maxOutputTokens: 1024, stopSequences: ['KONEC']);

// OpenAI
$chat->setOptions(maxOutputTokens: 1024, store: false, parallelToolCalls: true);

Rozdíl proti poli poznáš hned při psaní. IDE ti nabídne přesně to, co daný provider zná, a překlep zachytí PHP samo. Sdílené pole by klíč, který nikam nepatří, tiše spolklo a ty by ses to dozvěděl leda tak, že by se nic nedělo.

Nejužitečnější z nich je maxOutputTokens, tedy strop na délku odpovědi. Jmenuje se stejně u všech providerů, protože ho potřebuje každý; na drátě se přitom pokaždé jmenuje jinak, jednou max_tokens, jindy max_completion_tokens, ale to už je věc knihovny.

Kompletní seznam pro každého providera najdeš v signatuře setOptions() v src/Provider/*/Chat.php, případně ti ho ukáže IDE. A pokud používáš generického klienta pro cizí endpoint, má navíc argument custom, kterým protlačíš cokoli, co ten endpoint zná a knihovna ne.

Co se stalo s temperature

Když někde čteš o nastavování modelů, skoro jistě narazíš na parametr temperature. Stojí za to vědět, co dělal a proč ho tahle dokumentace nedoporučuje.

Model nevybírá jedno jediné správné pokračování věty. V každém okamžiku má seznam slov, která by mohla přijít, a ke každému pravděpodobnost; z nich pak jedno vylosuje. Právě proto dostaneš na tutéž otázku pokaždé trochu jinou odpověď. temperature určovala, jak riskantní to losování bude: hodnota kolem nuly znamenala střízlivého a předvídatelného pisatele, který skoro vždy sáhne po nejpravděpodobnějším slově, vyšší hodnoty nápaditější text, ale i víc nepřesností. Podobnou věc dělaly jinak parametry top_p a top_k.

Uvažovací modely tenhle způsob řízení opustily. Když jim temperature přesto pošleš, jedni odpoví chybou HTTP 400, což dělá Claude na nejnovějších modelech a OpenAI od GPT-5.1, a druzí ji tiše ignorují, což dělá Gemini a DeepSeek pokaždé, když přemýšlí.

Nebezpečné je to druhé. Chyba tě aspoň upozorní; tiše ignorovaný parametr znamená, že aplikace vypadá funkčně, ty ladíš hodnoty a nemá to vůbec žádný účinek.

Knihovna ti temperature nezakazuje a na starších modelech ji klidně použij přes setOptions(). Jen s ní nestav nic, co má vydržet: na modelech, které vyjdou příští rok, s velkou pravděpodobností nebude fungovat vůbec.

Kam dál