AI Access: jedno PHP rozhraní pro OpenAI, Claude, Gemini, DeepSeek a Grok

AI Access je PHP knihovna, která sjednocuje práci s jazykovými modely. Místo pěti různých API a pěti různých formátů odpovědí píšeš jeden kód, který mluví s ChatGPT od OpenAI, s Claude od Anthropicu, s Gemini od Googlu, s DeepSeekem i s Grokem od xAI. Přepnutí mezi nimi je změna jediného řádku.

Zvládá celý pracovní postup: konverzaci, streamování odpovědí, volání nástrojů (function calling), strukturovaný výstup podle JSON schématu, obrázky a dokumenty na vstupu, generování obrázků, embeddingy pro vyhledávání i dávkové zpracování za poloviční cenu.

Nemá žádné závislosti. Jen čisté PHP 8.3 a curl, žádné SDK od výrobce a žádné konflikty verzí ve tvém projektu.

K čemu je jazykový model v aplikaci dobrý

Jestli jsi žádné AI API zatím nevolal, princip je jednodušší, než se zvenčí zdá. Pošleš text a model pošle text zpátky. Všechno ostatní jsou nadstavby nad tímhle jedním pohybem.

V praxi z toho vyroste překvapivě široká škála úloh a stojí za to je znát dřív, než se pustíš do kódu, protože podle toho poznáš, kterou část dokumentace vlastně potřebuješ:

  • Psaní a přepisování textu. Shrnutí článku, návrh odpovědi na e-mail, překlad, korektura. Nejběžnější a nejjednodušší případ, stačí ti obyčejná konverzace.
  • Klasifikace a rozhodování. Je tahle registrace spam? Do které kategorie patří tenhle dotaz? Model odpoví jedním slovem a ty se podle toho zachováš.
  • Vytahování dat z nestrukturovaného textu. Z faktury, životopisu nebo e-mailu potřebuješ pole, která umíš uložit do databáze. Na to je strukturovaný výstup, kde modelu předepíšeš JSON schéma a on ho dodrží.
  • Odpovídání nad vlastními daty. Model o tvé dokumentaci nic neví, ale když mu k dotazu přiložíš relevantní úryvky, odpoví přesně. Najít ty správné úryvky je práce pro embeddingy, což je právě to vyhledávání podle významu, kterému se říká RAG.
  • Práce s obrázky a dokumenty. Popiš, co je na fotce, přečti údaje z účtenky, shrň přiložené PDF. Viz obrázky a dokumenty na vstupu.
  • Akce, ne jen text. Model může požádat o zavolání tvojí funkce, dostat výsledek a pokračovat. Tak vzniká asistent, který se opravdu podívá do tvé databáze, místo aby si odpověď vymyslel. Viz volání nástrojů.
  • Hromadné zpracování. Když nepotřebuješ odpověď hned, dávkové zpracování ti dá tytéž modely za polovinu ceny.

Co AI Access naopak není: není to agentní framework, nesnaží se za tebe vymýšlet prompty ani si nedrží konverzace v databázi. Je to vrstva, která mluví s API providerů, a končí přesně tam, kde začínají rozhodnutí tvojí aplikace.

Instalace

composer require ai-access/ai-access

Vyžaduje PHP 8.3 nebo novější a rozšíření curl, json a fileinfo, která bývají všude.

První zpráva

Potřebuješ klíč od providera, kterého chceš použít. Vydávají je ve svých konzolích OpenAI, Anthropic, Google, DeepSeek a xAI.

$client = new AIAccess\Provider\OpenAI\Client($apiKey);

$response = $client->createChat('gpt-5.6-luna')
	->sendMessage('Napiš haiku o PHP.');

echo $response->getText();

To je celé. createChat() otevře konverzaci nad zvoleným modelem, sendMessage() pošle zprávu a vrátí odpověď.

Jméno modelu je obyčejný řetězec, ne konstanta ani výčtový typ. Zní to jako maličkost, ale znamená to, že nový model funguje v den, kdy ho provider vydá, a nemusíš čekat na aktualizaci knihovny. Ověřit, že model pořád existuje, umí seznam modelů.

Přepnutí providera je jeden řádek

Tohle je hlavní slib knihovny, tak ať je vidět hned. Změní se konstruktor a jméno modelu, nic jiného:

$client = new AIAccess\Provider\Claude\Client($apiKey);
$chat = $client->createChat('claude-sonnet-5');

$client = new AIAccess\Provider\Gemini\Client($apiKey);
$chat = $client->createChat('gemini-3.5-flash-lite');

$client = new AIAccess\Provider\DeepSeek\Client($apiKey);
$chat = $client->createChat('deepseek-v4-flash');

$client = new AIAccess\Provider\Grok\Client($apiKey);
$chat = $client->createChat('grok-4.3');

V reálné aplikaci si klienta zaregistruješ do DI kontejneru a přepnutí providera je pak změna v konfiguraci, ne v kódu.

Pět API, která se neshodnou na ničem

Když si vlastní obal nad providery napíšeš sám, u prvních dvou to vypadá na pár hodin práce. Problém začne u třetího, protože každý z nich má jinou představu o tom, jak vypadá rozhovor s modelem. Tady je malý výběr toho, v čem se liší:

v čem se liší Claude OpenAI Gemini Grok a DeepSeek
endpoint v1/messages v1/responses :generateContent chat/completions
autentizace hlavička x-api-key Bearer hlavička x-goog-api-key Bearer
tvar požadavku messages[] input[] a instructions contents[].parts[] messages[]
jak se jmenuje role modelu assistant assistant model assistant
klíče spotřeby tokenů input_tokens totéž promptTokenCount prompt_tokens
kde je důvod ukončení stop_reason status, pak incomplete_details finishReason finish_reason

Poslední řádek má háček, který stojí za vyslovení nahlas: Gemini v finishReason nikdy neohlásí, že model chce zavolat nástroj. Zůstane tam STOP a samotné volání najdeš až mezi částmi odpovědi. Kdo to neví, napíše kód, který tiše ignoruje polovinu toho, co model řekl, a nedozví se o tom.

Takových drobností jsou desítky a žádná z nich není zajímavá práce. AI Access je má vyřešené a otestované proti skutečným odpovědím API, ne proti vymyšlenému JSONu.

Zároveň ale nepředstírá, že rozdíly neexistují. Sjednocuje to, co mají provideři opravdu společné, a kde se liší, dá ti to najevo typem nebo výjimkou hned při psaní kódu, ne až chybou z produkce.

Co knihovna umí

Schopnost OpenAI Claude Gemini DeepSeek Grok Generický klient
Konverzace
Reasoning effort
Volání nástrojů
Streamování
Obrázky na vstupu
Dokumenty na vstupu
Strukturovaný výstup
Generování obrázků
Dávkové zpracování
Embeddingy
Seznam modelů

Kde je minus, tam buď provider takové API nemá, nebo ho knihovna zatím nezabaluje.

Poslední sloupec je generický klient pro cokoli, co mluví dialektem chat/completions: běžící Ollamu na tvém notebooku, Mistral, OpenRouter, Together, vLLM nebo Azure. Značka u něj znamená něco jiného než u ostatních, totiž co knihovna umí poslat; jestli to opravdu funguje, rozhoduje endpoint a model, na který ho namíříš. Podrobnosti najdeš u providerů.

Navržená, ne nabalená

Nastavení specifická pro providera jsou pojmenované argumenty, ne klíče ve sdíleném poli. Rozdíl poznáš hned při psaní: IDE ti u každého providera nabídne přesně to, co daný provider umí, místo aby pole tiše spolklo klíč, který nikam nedojde. K tomu striktní typy všude a readonly hodnotové objekty.

Hierarchie výjimek je postavená na jediné otázce, která v produkci opravdu dává smysl, totiž jestli má cenu volání zopakovat:

try {
	$response = $chat->sendMessage('...');

} catch (AIAccess\ApiException $e) {
	// provider řekl ne; $e->getCode() nese HTTP status
	if ($e->getCode() === 429) {
		// překročený limit, zkus to za chvíli
	}

} catch (AIAccess\CommunicationException $e) {
	// výpadek sítě nebo nečitelná odpověď, opakování může pomoct
}

LogicException schválně stojí mimo tenhle strom, protože chyba ve tvém vlastním kódu není nic, co by měla produkce odchytávat a přecházet. Celou hierarchii rozebírá kapitola o ošetření chyb.

Opakování mimochodem nemusíš psát ručně. Knihovna má dekorátory HTTP vrstvy, které umí opakovat po limitech a výpadcích, logovat každý požadavek nebo odpovědi během vývoje cachovat, aby tě opětovné spouštění skriptu nestálo peníze.

Kam dál

A když si při psaní kódu necháváš pomáhat od AI agenta, mrkni na Nette AI. Najdeš tam plugin pro Claude Code, který agenta naučí Nette, a MCP Inspector, díky kterému se agent podívá přímo do tvojí běžící aplikace.

verze: 1.0