tigusigalpa / gigachat-php
π GigaChat PHP SDK - ΠΏΠΎΠ»Π½ΠΎΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΄Π»Ρ ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΈ Ρ Sber GigaChat API. ΠΡΠΎΡΡΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ GigaChat ΠΊ PHP-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌ Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ Laravel. ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΠ΅ΠΊΡΡΠ°, ΡΠ°Ρ-Π±ΠΎΡΡ, AI-Π°ΡΡΠΈΡΡΠ΅Π½ΡΡ. ΠΠΎΠ»Π½Π°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ, ΠΏΡΠΈΠΌΠ΅ΡΡ ΠΊΠΎΠ΄Π°, OAuth Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ.
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.8.2
- illuminate/support: ^8|^9|^10|^11|^12
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0|^11.0
README
PHP SDK Π΄Π»Ρ Sber GigaChat API Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ Laravel. Streaming ΠΈ ΠΎΠ±ΡΡΠ½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ.
Π―Π·ΡΠΊ: Π ΡΡΡΠΊΠΈΠΉ | English
ΠΡΡΠ³ΠΈΠ΅ Π²Π΅ΡΡΠΈΠΈ: Golang SDK
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ
- ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ Ρ GigaChat API
- Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ OAuth-ΡΠΎΠΊΠ΅Π½Π°ΠΌΠΈ (Π°Π²ΡΠΎΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅)
- ΠΡΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ GigaChat (GigaChat, GigaChat-Pro, GigaChat-Max)
- Laravel 8-12 (Service Provider, Facades)
- ΠΠΈΠ°Π»ΠΎΠ³ΠΈ ΠΈ ΠΎΠ΄ΠΈΠ½ΠΎΡΠ½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ
- Streaming-ΠΎΡΠ²Π΅ΡΡ
- ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΠ΅ΡΠ΅Π· text2image
- Π‘ΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ
- Π‘ΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΡ ΡΠ΅ΡΠ΅Π· ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ ΠΏΡΠΎΠΌΠΏΡΡ
- Helper-ΠΌΠ΅ΡΠΎΠ΄Ρ
- Rate limiting middleware
- Artisan-ΠΊΠΎΠΌΠ°Π½Π΄Ρ
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ°
ΠΠ· Packagist
Π§Π΅ΡΠ΅Π· Composer:
composer require tigusigalpa/gigachat-php
Laravel
ΠΠ°ΠΊΠ΅Ρ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ. ΠΠΏΡΠ±Π»ΠΈΠΊΡΠΉΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³:
php artisan vendor:publish --tag=gigachat-config
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ°
1. ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»ΡΡΠ΅ΠΉ
- ΠΠ°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠΉΡΠ΅ΡΡ Π² Sber AI
- Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ, ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ Client ID ΠΈ Client Secret
- Π‘Π³Π΅Π½Π΅ΡΠΈΡΡΠΉΡΠ΅ Authorization Key (Base64 ΠΎΡ "Client ID:Client Secret")
Π‘ΠΌ.: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»ΡΡΠ΅ΠΉ
2. ΠΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅
ΠΠΎΠ±Π°Π²ΡΡΠ΅ Π² .env:
# ΠΠ°ΡΠΈΠ°Π½Ρ 1: ΠΠΎΡΠΎΠ²ΡΠΉ Authorization Key GIGACHAT_AUTH_KEY=your_base64_encoded_auth_key # ΠΠ°ΡΠΈΠ°Π½Ρ 2: Client ID + Secret (auth_key Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ) GIGACHAT_CLIENT_ID=your_client_id GIGACHAT_CLIENT_SECRET=your_client_secret # ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ GIGACHAT_SCOPE=GIGACHAT_API_PERS GIGACHAT_DEFAULT_MODEL=GigaChat GIGACHAT_TEMPERATURE=0.7 GIGACHAT_MAX_TOKENS=1000 # ΠΡΠΊΠ»ΡΡΠΈΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ SSL (ΠΏΡΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°Ρ Ρ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΠ°ΠΌΠΈ) GIGACHAT_CERT_PATH=false
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅
ΠΠ΅Π· Laravel
<?php use Tigusigalpa\GigaChat\Auth\TokenManager; use Tigusigalpa\GigaChat\GigaChatClient; // Π’ΠΎΠΊΠ΅Π½-ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ $authKey = base64_encode('your_client_id:your_client_secret'); $tokenManager = new TokenManager($authKey); // ΠΠ»ΠΈΠ΅Π½Ρ $client = new GigaChatClient($tokenManager); // ΠΠΎΡΡΡΠΏΠ½ΡΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ $models = $client->models(); print_r($models); // ΠΡΠΏΡΠ°Π²ΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ $messages = [ ['role' => 'user', 'content' => 'ΠΡΠΈΠ²Π΅Ρ! ΠΠ°ΠΊ Π΄Π΅Π»Π°?'] ]; $response = $client->chat($messages); echo $response['choices'][0]['message']['content'];
Π‘ Laravel
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Facade:
<?php use Tigusigalpa\GigaChat\Laravel\GigaChat; use Tigusigalpa\GigaChat\Models\GigaChatModels; // ΠΠΎΠΏΡΠΎΡ-ΠΎΡΠ²Π΅Ρ $answer = GigaChat::ask('Π Π°ΡΡΠΊΠ°ΠΆΠΈ Π°Π½Π΅ΠΊΠ΄ΠΎΡ'); echo $answer; // Π‘ΠΏΠΈΡΠΎΠΊ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ $models = GigaChat::models(); // Π‘ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ $response = GigaChat::chat([ ['role' => 'user', 'content' => 'ΠΠ±ΡΡΡΠ½ΠΈ ΠΊΠ²Π°Π½ΡΠΎΠ²ΡΡ ΡΠΈΠ·ΠΈΠΊΡ'] ], [ 'temperature' => 0.7, 'max_tokens' => 1000, 'model' => GigaChatModels::GIGACHAT_2_PRO ]); echo $response['choices'][0]['message']['content'];
ΠΠΈΠ°Π»ΠΎΠ³ΠΈ
<?php use Tigusigalpa\GigaChat\Laravel\GigaChat; use Tigusigalpa\GigaChat\Laravel\GigaChatHelper; // Π‘ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠΌ ΠΏΡΠΎΠΌΠΏΡΠΎΠΌ $conversation = GigaChatHelper::conversation( 'Π’Ρ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠ°', 'ΠΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ REST API Π² Laravel?' ); $response = GigaChat::chat($conversation); echo GigaChatHelper::extractContent($response); // ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΈΠ°Π»ΠΎΠ³Π° $conversation = GigaChat::continueChat($conversation, 'Π ΠΊΠ°ΠΊ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ?');
Streaming
<?php use Tigusigalpa\GigaChat\Laravel\GigaChat; $messages = [ ['role' => 'user', 'content' => 'ΠΠ°ΠΏΠΈΡΠΈ Π΄Π»ΠΈΠ½Π½ΡΡ ΠΈΡΡΠΎΡΠΈΡ ΠΎ ΠΊΠΎΡΠΌΠΎΡΠ΅'] ]; // Callback GigaChat::chatStream($messages, [], function($event, $error) { if ($error) { echo "ΠΡΠΈΠ±ΠΊΠ°: " . $error; return; } if ($event === '[DONE]') { echo "\nβ ΠΠΎΡΠΎΠ²ΠΎ!"; return; } if (isset($event['choices'][0]['delta']['content'])) { echo $event['choices'][0]['delta']['content']; } }); // ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ $stream = GigaChat::chatStream($messages); foreach ($stream as $event) { if (isset($event['choices'][0]['delta']['content'])) { echo $event['choices'][0]['delta']['content']; } }
Eloquent Trait
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Tigusigalpa\GigaChat\Laravel\Traits\HasGigaChat; class Article extends Model { use HasGigaChat; protected $fillable = ['title', 'content', 'category']; public function generateSummary(): string { return $this->summarize('content'); } // ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΠ΅Π³ΠΎΠ² public function generateTags(): array { return $this->generateTags('content', 5); } // ΠΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅Π½Ρ public function generateRelatedContent(): string { return $this->generateContent( 'Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΏΠΎΡ ΠΎΠΆΡΡ ΡΡΠ°ΡΡΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΡΡΠΎΠΉ', ['title', 'category'] ); } }
ΠΠΎΠ΄Π΅Π»ΠΈ
ΠΠΊΡΡΠ°Π»ΡΠ½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ: ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½Π°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ
ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΠ΅ΠΊΡΡΠ°
| ΠΠΎΠ΄Π΅Π»Ρ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ |
|---|---|---|
| GigaChat-2 | ΠΠ°Π·ΠΎΠ²Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΏΠΎΠΊΠΎΠ»Π΅Π½ΠΈΡ | ΠΠ±ΡΠΈΠ΅ Π·Π°Π΄Π°ΡΠΈ, Π΄ΠΈΠ°Π»ΠΎΠ³ΠΈ |
| GigaChat-2-Pro | ΠΡΠΎΠ΄Π²ΠΈΠ½ΡΡΠ°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Ρ ΡΠ»ΡΡΡΠ΅Π½Π½ΡΠΌΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠΌΠΈ | Π‘Π»ΠΎΠΆΠ½ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ, ΠΊΡΠ΅Π°ΡΠΈΠ²Π½ΠΎΠ΅ ΠΏΠΈΡΡΠΌΠΎ |
| GigaChat-2-Max | ΠΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ ΡΠ°ΠΌΡΡ ΡΠ»ΠΎΠΆΠ½ΡΡ Π·Π°Π΄Π°Ρ | ΠΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ, Π°Π½Π°Π»ΠΈΠ· |
ΠΠΌΠ±Π΅Π΄Π΄ΠΈΠ½Π³ΠΈ
| ΠΠΎΠ΄Π΅Π»Ρ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ |
|---|---|---|
| Embeddings | ΠΠ°Π·ΠΎΠ²Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ Π²Π΅ΠΊΡΠΎΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ | ΠΠΎΠΈΡΠΊ ΠΏΠΎ ΡΠΌΡΡΠ»Ρ, ΠΊΠ»Π°ΡΡΠ΅ΡΠΈΠ·Π°ΡΠΈΡ |
| EmbeddingsGigaR | Π£Π»ΡΡΡΠ΅Π½Π½Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΌΠ±Π΅Π΄Π΄ΠΈΠ½Π³ΠΎΠ² | Π’ΠΎΡΠ½ΡΠΉ ΠΏΠΎΠΈΡΠΊ, ΡΠ΅ΠΌΠ°Π½ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ· |
ΠΠΎΠ½ΡΡΠ°Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ
use Tigusigalpa\GigaChat\Models\GigaChatModels; use Tigusigalpa\GigaChat\Laravel\GigaChat; $response = GigaChat::chat($messages, [ 'model' => GigaChatModels::GIGACHAT_2_PRO ]); $generationModels = GigaChatModels::getGenerationModels(); $embeddingModels = GigaChatModels::getEmbeddingModels(); if (GigaChatModels::isValidGenerationModel('GigaChat-2')) { // Π²Π°Π»ΠΈΠ΄Π½Π° }
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ
use Tigusigalpa\GigaChat\Models\GigaChatModels; $options = [ 'model' => GigaChatModels::GIGACHAT_2_PRO, // ΠΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ 'temperature' => 0.7, // ΠΡΠ΅Π°ΡΠΈΠ²Π½ΠΎΡΡΡ (0.0 - 2.0) 'top_p' => 0.9, // Nucleus sampling (0.0 - 1.0) 'max_tokens' => 1000, // ΠΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΎΠΊΠ΅Π½ΠΎΠ² 'repetition_penalty' => 1.1, // Π¨ΡΡΠ°Ρ Π·Π° ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΡ (0.0 - 2.0) 'update_interval' => 0 // ΠΠ½ΡΠ΅ΡΠ²Π°Π» ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π΄Π»Ρ streaming ]; $response = GigaChat::chat($messages, $options); ## ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΡΡΡΠΎΠ΅Π½Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ text2image. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ "Π½Π°ΡΠΈΡΡΠΉ" Π² ΠΏΡΠΎΠΌΠΏΡΠ΅ Ρ `function_call: auto`. ### ΠΠ°Π·ΠΎΠ²ΠΎΠ΅ ```php <?php use Tigusigalpa\GigaChat\Auth\TokenManager; use Tigusigalpa\GigaChat\GigaChatClient; $tokenManager = new TokenManager($authKey); $client = new GigaChatClient($tokenManager); $response = $client->generateImage("ΠΠ°ΡΠΈΡΡΠΉ ΠΊΡΠ°ΡΠΈΠ²ΡΠΉ Π·Π°ΠΊΠ°Ρ Π½Π°Π΄ ΠΌΠΎΡΠ΅ΠΌ"); // ΠΠ·Π²Π»Π΅ΡΡ ID ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ $content = $response['choices'][0]['message']['content']; if (preg_match('/<img[^>]+src=["']([^"']+)["'][^>]*>/i', $content, $matches)) { $fileId = $matches[1]; $imageData = $client->downloadImage($fileId); file_put_contents('sunset.jpg', base64_decode($imageData)); } ### Π‘ΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΡ ```php $response = $client->generateImage("ΠΠ°ΡΠΈΡΡΠΉ ΡΠΎΠ·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΡΠ°", [ 'system_message' => 'Π’Ρ β ΠΠ°ΡΠΈΠ»ΠΈΠΉ ΠΠ°Π½Π΄ΠΈΠ½ΡΠΊΠΈΠΉ' ]); $response = $client->generateImage("ΠΠ°ΡΠΈΡΡΠΉ ΠΊΠΎΡΠΌΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΊΠΎΡΠ°Π±Π»Ρ", [ 'system_message' => 'Π’Ρ β Ρ ΡΠ΄ΠΎΠΆΠ½ΠΈΠΊ-ΠΊΠΎΠ½ΡΠ΅ΠΏΡΡΠ°Π»ΠΈΡΡ Π½Π°ΡΡΠ½ΠΎΠΉ ΡΠ°Π½ΡΠ°ΡΡΠΈΠΊΠΈ', 'temperature' => 0.8 ]); ### createImage ΠΠ΅Π½Π΅ΡΠΈΡΡΠ΅Ρ ΠΈ ΡΠΊΠ°ΡΠΈΠ²Π°Π΅Ρ Π² ΠΎΠ΄Π½ΠΎΠΌ Π²ΡΠ·ΠΎΠ²Π΅: ```php $result = $client->createImage("ΠΠ°ΡΠΈΡΡΠΉ ΡΡΡΡΡΠΈΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π³ΠΎΡΠΎΠ΄", [ 'system_message' => 'Π’Ρ β Π°ΡΡ ΠΈΡΠ΅ΠΊΡΠΎΡ Π±ΡΠ΄ΡΡΠ΅Π³ΠΎ' ]); // $result: content (base64), file_id, response file_put_contents('city.jpg', base64_decode($result['content'])); ### Laravel ```php use Tigusigalpa\GigaChat\Laravel\GigaChat; // drawImage Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ "ΠΠ°ΡΠΈΡΡΠΉ" Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ $result = GigaChat::drawImage("ΠΊΡΠ°ΡΠΈΠ²ΡΠΉ ΠΏΠ΅ΠΉΠ·Π°ΠΆ"); // Π‘ΠΎ ΡΡΠΈΠ»Π΅ΠΌ Ρ ΡΠ΄ΠΎΠΆΠ½ΠΈΠΊΠ° $result = GigaChat::drawImageInStyle("ΠΏΠΎΡΡΡΠ΅Ρ ΠΊΠΎΡΠ°", "ΠΠ΅ΠΎΠ½Π°ΡΠ΄ΠΎ Π΄Π° ΠΠΈΠ½ΡΠΈ"); // ΠΠ·Π²Π»Π΅ΡΡ ID ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ $response = GigaChat::generateImage("ΠΠ°ΡΠΈΡΡΠΉ Π΄ΡΠ°ΠΊΠΎΠ½Π°"); $imageId = GigaChat::extractImageId($response['choices'][0]['message']['content']); if ($imageId) { $imageData = GigaChat::downloadImage($imageId); file_put_contents("dragon.jpg", base64_decode($imageData)); }
ΠΠ΅ΡΠΎΠ΄Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ
| ΠΠ΅ΡΠΎΠ΄ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ |
|---|---|---|
generateImage($prompt, $options) |
ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ, ΠΎΡΠ²Π΅Ρ API | array |
downloadImage($fileId) |
Π‘ΠΊΠ°ΡΠ°ΡΡ ΠΏΠΎ ID | string (base64) |
createImage($prompt, $options) |
ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ + ΡΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ | array |
drawImage($description, $options) |
Laravel: Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ "ΠΠ°ΡΠΈΡΡΠΉ" | array |
drawImageInStyle($description, $style, $options) |
Laravel: ΡΠΎ ΡΡΠΈΠ»Π΅ΠΌ Ρ ΡΠ΄ΠΎΠΆΠ½ΠΈΠΊΠ° | array |
extractImageId($content) |
ΠΠ·Π²Π»Π΅ΡΡ ID ΠΈΠ· HTML | string|null |
ΠΡΠΈΠ±ΠΊΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ
use Tigusigalpa\GigaChat\Exceptions\GigaChatException; use Tigusigalpa\GigaChat\Exceptions\ValidationException; try { $result = $client->createImage("ΠΠ°ΡΠΈΡΡΠΉ Π΄ΡΠ°ΠΊΠΎΠ½Π°"); } catch (ValidationException $e) { echo "ΠΡΠΈΠ±ΠΊΠ° Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ: " . $e->getMessage(); } catch (GigaChatException $e) { echo "ΠΡΠΈΠ±ΠΊΠ° Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ: " . $e->getMessage(); }
ΠΠ°ΠΆΠ½ΠΎ: ΠΡΠΎΠΌΠΏΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ "Π½Π°ΡΠΈΡΡΠΉ". API Π²ΡΠ·ΡΠ²Π°Π΅Ρ text2image ΠΏΡΠΈ function_call: auto.
ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠΈΠ±ΠΎΠΊ
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ:
<?php use Tigusigalpa\GigaChat\Exceptions\GigaChatException; use Tigusigalpa\GigaChat\Exceptions\AuthenticationException; use Tigusigalpa\GigaChat\Exceptions\ValidationException; try { $response = GigaChat::chat($messages); } catch (AuthenticationException $e) { // ΠΡΠΈΠ±ΠΊΠΈ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ (Π½Π΅Π²Π΅ΡΠ½ΡΠ΅ ΠΊΠ»ΡΡΠΈ, ΠΈΡΡΠ΅ΠΊΡΠΈΠΉ ΡΠΎΠΊΠ΅Π½) echo "ΠΡΠΈΠ±ΠΊΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ: " . $e->getMessage(); } catch (ValidationException $e) { // ΠΡΠΈΠ±ΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ (Π½Π΅Π²Π΅ΡΠ½ΡΠΉ ΡΠΎΡΠΌΠ°Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ) echo "ΠΡΠΈΠ±ΠΊΠ° Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ: " . $e->getMessage(); } catch (GigaChatException $e) { // ΠΠ±ΡΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ GigaChat API echo "ΠΡΠΈΠ±ΠΊΠ° GigaChat: " . $e->getMessage(); }
ΠΠΎΠ΄Ρ ΠΎΡΠΈΠ±ΠΎΠΊ
ΠΠ²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ (400-401)
| ΠΠΎΠ΄ | HTTP | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|---|---|
| 1 | 400 | scope data format invalid |
ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ ΡΠΎΡΠΌΠ°Ρ ΠΏΠΎΠ»Ρ scope |
| 4 | 401 | Can't decode 'Authorization' header |
ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ ΠΊΠ»ΡΡΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ |
| 5 | 400 | scope is empty |
Π£ΠΊΠ°ΠΆΠΈΡΠ΅ scope: GIGACHAT_API_PERS, GIGACHAT_API_B2B ΠΈΠ»ΠΈ GIGACHAT_API_CORP |
| 6 | 401 | credentials doesn't match db data |
ΠΠ΅ΡΠ΅Π²ΡΠΏΡΡΡΠΈΡΠ΅ ΠΊΠ»ΡΡ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ Π² Π»ΠΈΡΠ½ΠΎΠΌ ΠΊΠ°Π±ΠΈΠ½Π΅ΡΠ΅ |
| 7 | 401 | scope from db not fully includes consumed scope |
Π£ΠΊΠ°ΠΆΠΈΡΠ΅ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΡ Π²Π΅ΡΡΠΈΡ API Π² scope |
// ΠΡΠΈΠΌΠ΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ try { $client = new GigaChatClient($tokenManager); $response = $client->chat($messages); } catch (AuthenticationException $e) { $message = $e->getMessage(); if (str_contains($message, 'scope is empty')) { echo "ΠΠ΅ ΡΠΊΠ°Π·Π°Π½ scope. ΠΠΎΠ±Π°Π²ΡΡΠ΅ GIGACHAT_API_PERS Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ."; } elseif (str_contains($message, 'Authorization')) { echo "ΠΠ΅Π²Π΅ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ. ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ CLIENT_ID ΠΈ CLIENT_SECRET."; } elseif (str_contains($message, 'credentials doesn\'t match')) { echo "ΠΠ»ΡΡ Π½Π΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ Π²Π΅ΡΡΠΈΠΈ API. ΠΠ΅ΡΠ΅Π²ΡΠΏΡΡΡΠΈΡΠ΅ ΠΊΠ»ΡΡ."; } }
ΠΠΈΠΌΠΈΡΡ (402-403)
| HTTP | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΈΡΠΈΠ½Π° | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|---|---|
| 402 | Payment Required |
ΠΠ°ΠΊΠΎΠ½ΡΠΈΠ»ΠΈΡΡ ΡΠΎΠΊΠ΅Π½Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ | ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ Π»ΠΈΠΌΠΈΡ ΡΠΎΠΊΠ΅Π½ΠΎΠ² Π² Π»ΠΈΡΠ½ΠΎΠΌ ΠΊΠ°Π±ΠΈΠ½Π΅ΡΠ΅ |
| 403 | Permission denied |
ΠΠ΅Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΌΠ΅ΡΠΎΠ΄Ρ | ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ ΡΠ°ΡΠΈΡΠ½ΡΠΉ ΠΏΠ»Π°Π½ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, GET /balance Π½Π΅Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π΄Π»Ρ pay-as-you-go) |
try { $response = $client->chat($messages); } catch (GigaChatException $e) { $code = $e->getCode(); switch ($code) { case 402: echo "ΠΠ°ΠΊΠΎΠ½ΡΠΈΠ»ΠΈΡΡ ΡΠΎΠΊΠ΅Π½Ρ. ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅ Π±Π°Π»Π°Π½Ρ ΠΈΠ»ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΠ΅ Π»ΠΈΠΌΠΈΡΡ."; break; case 403: echo "ΠΠ΅Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΡΡΠΎΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Ρ. ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ ΡΠ°ΡΠΈΡΠ½ΡΠΉ ΠΏΠ»Π°Π½."; break; } }
Π Π°Π·ΠΌΠ΅Ρ Π΄Π°Π½Π½ΡΡ (413)
| HTTP | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΈΡΠΈΠ½Π° | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|---|---|
| 413 | Payload too large |
ΠΡΠ΅Π²ΡΡΠ΅Π½ ΡΠ°Π·ΠΌΠ΅Ρ Π²Ρ ΠΎΠ΄Π½ΡΡ Π΄Π°Π½Π½ΡΡ | Π£ΠΌΠ΅Π½ΡΡΠΈΡΠ΅ ΡΠ°Π·ΠΌΠ΅Ρ ΠΏΡΠΎΠΌΠΏΡΠ° ΠΈΠ»ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ² |
try { $response = $client->generateImage($longPrompt); } catch (GigaChatException $e) { if ($e->getCode() === 413) { echo "ΠΡΠΎΠΌΠΏΡ ΡΠ»ΠΈΡΠΊΠΎΠΌ Π΄Π»ΠΈΠ½Π½ΡΠΉ. Π‘ΠΎΠΊΡΠ°ΡΠΈΡΠ΅ ΡΠ΅ΠΊΡΡ."; // ΠΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ POST /tokens/count Π΄Π»Ρ ΠΏΠΎΠ΄ΡΡΠ΅ΡΠ° ΡΠΎΠΊΠ΅Π½ΠΎΠ² } }
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ (422)
| HTTP | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΈΡΠΈΠ½Π° | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|---|---|
| 422 | Requested model does not support functions |
ΠΠΎΠ΄Π΅Π»Ρ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΠΈ | ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Π΄ΡΡΠ³ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈΠ»ΠΈ ΠΎΡΠΊΠ»ΡΡΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ |
| 422 | system message must be the first message |
ΠΠ΅Π²Π΅ΡΠ½ΡΠΉ ΠΏΠΎΡΡΠ΄ΠΎΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ | Π‘ΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΠΏΠ΅ΡΠ²ΡΠΌ |
| 422 | Unprocessable Entity |
Π€Π°ΠΉΠ» ΠΏΡΠ΅Π²ΡΡΠ°Π΅Ρ ΡΠ°Π·ΠΌΠ΅Ρ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° | Π Π°Π·Π΄Π΅Π»ΠΈΡΠ΅ ΠΈΠ»ΠΈ ΡΠΎΠΊΡΠ°ΡΠΈΡΠ΅ ΡΠ°ΠΉΠ» |
try { $messages = [ ['role' => 'user', 'content' => 'ΠΡΠΈΠ²Π΅Ρ'], ['role' => 'system', 'content' => 'Π’Ρ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ'], // ΠΠ΅Π²Π΅ΡΠ½ΠΎ! ]; $response = $client->chat($messages); } catch (GigaChatException $e) { if (str_contains($e->getMessage(), 'system message must be the first')) { echo "Π‘ΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΠΏΠ΅ΡΠ²ΡΠΌ Π² ΡΠΏΠΈΡΠΊΠ΅."; // ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΠΏΠΎΡΡΠ΄ΠΎΠΊ $fixedMessages = [ ['role' => 'system', 'content' => 'Π’Ρ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ'], ['role' => 'user', 'content' => 'ΠΡΠΈΠ²Π΅Ρ'], ]; } }
Rate Limit (429)
| HTTP | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΈΡΠΈΠ½Π° | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|---|---|
| 429 | Too Many Requests |
ΠΡΠ΅Π²ΡΡΠ΅Π½ Π»ΠΈΠΌΠΈΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² | Π£ΠΌΠ΅Π½ΡΡΠΈΡΠ΅ ΡΠ°ΡΡΠΎΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ², Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ |
try { $response = $client->chat($messages); } catch (GigaChatException $e) { if ($e->getCode() === 429) { echo "Π‘Π»ΠΈΡΠΊΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠΎΠ². ΠΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡΠ΅ ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠΈΡΠ΅."; // ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π·Π°Π΄Π΅ΡΠΆΠΊΡ ΠΈ ΠΏΠΎΠ²ΡΠΎΡΡΠ΅ΠΌ sleep(2); $response = $client->chat($messages); } }
Π‘Π΅ΡΠ²Π΅Ρ (500)
| HTTP | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ | ΠΡΠΈΡΠΈΠ½Π° | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|---|---|
| 500 | Internal Server Error |
ΠΡΠΈΠ±ΠΊΠ° ΡΠ΅ΡΠ²ΠΈΡΠ° GigaChat | ΠΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ Π² ΡΠ»ΡΠΆΠ±Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ |
try { $response = $client->chat($messages); } catch (GigaChatException $e) { if ($e->getCode() === 500) { echo "ΠΡΠΈΠ±ΠΊΠ° ΡΠ΅ΡΠ²Π΅ΡΠ° GigaChat. ΠΠΎΠΏΡΠΎΠ±ΡΠΉΡΠ΅ ΠΏΠΎΠ·ΠΆΠ΅ ΠΈΠ»ΠΈ ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ Π² ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ."; // ΠΠΎΠ³ΠΈΡΡΠ΅ΠΌ Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π° error_log("GigaChat 500 error: " . $e->getMessage()); } }
Retry-ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ
<?php use Tigusigalpa\GigaChat\Laravel\GigaChat; use Tigusigalpa\GigaChat\Exceptions\GigaChatException; use Tigusigalpa\GigaChat\Exceptions\AuthenticationException; use Tigusigalpa\GigaChat\Exceptions\ValidationException; function handleGigaChatRequest(callable $request): array { $maxRetries = 3; $retryDelay = 1; // ΡΠ΅ΠΊΡΠ½Π΄Ρ for ($attempt = 1; $attempt <= $maxRetries; $attempt++) { try { return $request(); } catch (ValidationException $e) { // ΠΡΠΈΠ±ΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ Π½Π΅ ΠΏΠΎΠ²ΡΠΎΡΡΠ΅ΠΌ throw $e; } catch (AuthenticationException $e) { if ($attempt === $maxRetries) { throw $e; } // ΠΡΡΠ°Π΅ΠΌΡΡ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΡΠΎΠΊΠ΅Π½ sleep($retryDelay); } catch (GigaChatException $e) { $code = $e->getCode(); // ΠΠΎΠ²ΡΠΎΡΡΠ΅ΠΌ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ ΠΎΡΠΈΠ±ΠΎΠΊ if (in_array($code, [429, 500]) && $attempt < $maxRetries) { sleep($retryDelay * $attempt); // ΠΠΊΡΠΏΠΎΠ½Π΅Π½ΡΠΈΠ°Π»ΡΠ½Π°Ρ Π·Π°Π΄Π΅ΡΠΆΠΊΠ° continue; } throw $e; } } } // ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ try { $result = handleGigaChatRequest(function() { return GigaChat::createImage("ΠΠ°ΡΠΈΡΡΠΉ ΠΊΠΎΡΠ°"); }); echo "ΠΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΎ: " . $result['file_id']; } catch (Exception $e) { echo "ΠΠ΅ ΡΠ΄Π°Π»ΠΎΡΡ ΡΠΎΠ·Π΄Π°ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅: " . $e->getMessage(); }
ΠΡΠ»Π°Π΄ΠΊΠ°
try { $response = $client->chat($messages); } catch (GigaChatException $e) { error_log('GigaChat Error: ' . json_encode([ 'message' => $e->getMessage(), 'code' => $e->getCode(), ], JSON_UNESCAPED_UNICODE)); }
Π‘ΠΌ.: ΠΡΠΈΠ±ΠΊΠΈ GigaChat API
Artisan-ΠΊΠΎΠΌΠ°Π½Π΄Ρ
# Π’Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊ API php artisan gigachat:test # ΠΡΠΏΡΠ°Π²ΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ php artisan gigachat:chat "ΠΡΠΈΠ²Π΅Ρ, ΠΊΠ°ΠΊ Π΄Π΅Π»Π°?" # ΠΡΠΏΡΠ°Π²ΠΊΠ° Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ php artisan gigachat:chat "Π Π°ΡΡΠΊΠ°ΠΆΠΈ ΠΈΡΡΠΎΡΠΈΡ" --model=GigaChat-Pro --temperature=0.8 --max-tokens=500 # Streaming ΡΠ΅ΠΆΠΈΠΌ php artisan gigachat:chat "ΠΠ°ΠΏΠΈΡΠΈ Π΄Π»ΠΈΠ½Π½ΡΠΉ ΡΠ°ΡΡΠΊΠ°Π·" --stream
Rate Limiting
// Π routes/api.php Route::middleware(['gigachat.rate_limit:30,1'])->group(function () { Route::post('/chat', [ChatController::class, 'chat']); }); // ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π² config/gigachat.php 'rate_limit' => [ 'enabled' => true, 'max_attempts' => 60, // ΠΠ°ΠΊΡΠΈΠΌΡΠΌ Π·Π°ΠΏΡΠΎΡΠΎΠ² 'decay_minutes' => 1, // ΠΠ° ΠΏΠ΅ΡΠΈΠΎΠ΄ Π² ΠΌΠΈΠ½ΡΡΠ°Ρ ],
Π’Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
ΠΠ°ΠΏΡΡΠΊ
# Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ composer install --dev # ΠΠ°ΠΏΡΡΠΊ Π²ΡΠ΅Ρ ΡΠ΅ΡΡΠΎΠ² composer test # ΠΈΠ»ΠΈ php run-tests.php # ΠΠ°ΠΏΡΡΠΊ ΡΠΎΠ»ΡΠΊΠΎ unit ΡΠ΅ΡΡΠΎΠ² php run-tests.php --unit # ΠΠ°ΠΏΡΡΠΊ Ρ ΠΏΠΎΠΊΡΡΡΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π° composer test-coverage # ΠΈΠ»ΠΈ php run-tests.php --coverage
ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΡΡ
ΠΠ»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΎΠ½Π½ΡΡ ΡΠ΅ΡΡΠΎΠ² Ρ ΡΠ΅Π°Π»ΡΠ½ΡΠΌ API:
# Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ export GIGACHAT_CLIENT_ID=your_client_id export GIGACHAT_CLIENT_SECRET=your_client_secret export GIGACHAT_INTEGRATION_TEST=true # ΠΠ°ΠΏΡΡΡΠΈΡΠ΅ ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΡΡ php run-tests.php --integration
ΠΠΎΠΊΡΡΡΠΈΠ΅
- ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΠ΅ΠΊΡΡΠ° (chat, streaming)
- ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ
- ΠΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ (ΡΠΎΠΊΠ΅Π½Ρ, ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅, ΠΊΠ΅Ρ)
- Laravel (ΡΠ°ΡΠ°Π΄Ρ, helpers, service provider)
- ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ
- ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΡΡ
Π‘ΠΌ. tests/README.md
ΠΡΠΈΠΌΠ΅ΡΡ
Π§Π°Ρ-Π±ΠΎΡ
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Tigusigalpa\GigaChat\Laravel\GigaChat; class ChatController extends Controller { public function chat(Request $request) { $request->validate([ 'message' => 'required|string|max:2000' ]); try { $response = GigaChat::askWithContext( 'Π’Ρ Π΄ΡΡΠΆΠ΅Π»ΡΠ±Π½ΡΠΉ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ', $request->input('message'), ['temperature' => 0.7] ); return response()->json([ 'success' => true, 'reply' => $response ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage() ], 500); } } }
ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΊΠΎΠ½ΡΠ΅Π½ΡΠ°
<?php use Tigusigalpa\GigaChat\Laravel\GigaChat; class ContentGenerator { public function generateArticle(string $topic, string $style = 'ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΎΠ½Π½ΡΠΉ'): string { return GigaChat::askWithContext( "Π’Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠΏΠΈΡΠ°ΠΉΡΠ΅Ρ. ΠΠΈΡΠΈ Π² {$style} ΡΡΠΈΠ»Π΅.", "ΠΠ°ΠΏΠΈΡΠΈ ΡΡΠ°ΡΡΡ Π½Π° ΡΠ΅ΠΌΡ: {$topic}", ['temperature' => 0.8, 'max_tokens' => 1500] ); } public function translateText(string $text, string $targetLang = 'Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΈΠΉ'): string { return GigaChat::ask( "ΠΠ΅ΡΠ΅Π²Π΅Π΄ΠΈ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ΅ΠΊΡΡ Π½Π° {$targetLang} ΡΠ·ΡΠΊ:\n\n{$text}", ['temperature' => 0.2] ); } public function summarizeText(string $text, int $maxWords = 100): string { return GigaChat::ask( "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΡΠ°ΡΠΊΠΎΠ΅ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (Π½Π΅ Π±ΠΎΠ»Π΅Π΅ {$maxWords} ΡΠ»ΠΎΠ²):\n\n{$text}", ['temperature' => 0.3, 'max_tokens' => $maxWords * 2] ); } }
Streaming
<?php // Π ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ΅ public function streamChat(Request $request) { $messages = [['role' => 'user', 'content' => $request->input('message')]]; return response()->stream(function () use ($messages) { echo "data: " . json_encode(['type' => 'start']) . "\n\n"; GigaChat::chatStream($messages, [], function($event, $error) { if ($error) { echo "data: " . json_encode(['type' => 'error', 'error' => $error]) . "\n\n"; return; } if ($event === '[DONE]') { echo "data: " . json_encode(['type' => 'done']) . "\n\n"; return; } if (isset($event['choices'][0]['delta']['content'])) { echo "data: " . json_encode([ 'type' => 'content', 'content' => $event['choices'][0]['delta']['content'] ]) . "\n\n"; } flush(); }); }, 200, [ 'Content-Type' => 'text/event-stream', 'Cache-Control' => 'no-cache', ]); }
Laravel-ΡΠ΅ΡΡΡ
<?php namespace Tests\Feature; use Tests\TestCase; use Tigusigalpa\GigaChat\Laravel\GigaChat; class GigaChatTest extends TestCase { public function test_gigachat_basic_functionality() { $response = GigaChat::ask('ΠΡΠΈΠ²Π΅Ρ!'); $this->assertNotEmpty($response); $this->assertIsString($response); } public function test_gigachat_with_context() { $response = GigaChat::askWithContext( 'Π’Ρ ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΠΊ', 'Π‘ΠΊΠΎΠ»ΡΠΊΠΎ Π±ΡΠ΄Π΅Ρ 2+2?' ); $this->assertStringContainsString('4', $response); } }
FAQ
ΠΠ°ΠΊ ΠΏΠΎΠ»ΡΡΠΈΡΡ Client ID ΠΈ Client Secret?
ΠΠ°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠΉΡΠ΅ΡΡ Π² Sber AI ΠΈ ΡΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ.
ΠΡΠΈΠ±ΠΊΠ° "Invalid token response"?
ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ Client ID/Secret ΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΠΎΡΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ.
SSL-ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΡ?
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ GIGACHAT_CERT_PATH Π² ΠΏΡΡΡ ΠΊ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΡ ΠΈΠ»ΠΈ false.
Production?
ΠΠ°. ΠΠ°ΡΡΡΠΎΠΉΡΠ΅ SSL ΠΈ rate limiting.
Π’Π°ΡΠΈΡΡ?
ΠΡΠΈΡΠΈΠ°Π»ΡΠ½Π°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ
SSL-ΠΎΡΠΈΠ±ΠΊΠΈ
cURL error 60: SSL certificate problem
# Π Π°Π·ΡΠ°Π±ΠΎΡΠΊΠ° GIGACHAT_CERT_PATH=false # Production GIGACHAT_CERT_PATH=/path/to/certificate.pem
ΠΡΠΈΡΡΠΈΡΠ΅ ΠΊΡΡ ΠΏΠΎΡΠ»Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ:
php artisan config:clear php artisan config:cache
ΠΠΎΠ»Π½Π°Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ
config/gigachat.php:
<?php return [ // Authorization key (Base64(Client ID:Client Secret)) 'auth_key' => env('GIGACHAT_AUTH_KEY', null), // ΠΠ»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΠΎ, ΡΠΊΠ°ΠΆΠΈΡΠ΅ Client ID ΠΈ Client Secret 'client_id' => env('GIGACHAT_CLIENT_ID', null), 'client_secret' => env('GIGACHAT_CLIENT_SECRET', null), // ΠΠ±Π»Π°ΡΡΡ Π΄ΠΎΡΡΡΠΏΠ° API: GIGACHAT_API_PERS | GIGACHAT_API_B2B | GIGACHAT_API_CORP 'scope' => env('GIGACHAT_SCOPE', 'GIGACHAT_API_PERS'), // ΠΡΠΎΠ²Π΅ΡΠΊΠ° TLS ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΠΎΠ² 'verify' => env('GIGACHAT_CERT_PATH', true), // ΠΠ°Π·ΠΎΠ²ΡΠ΅ URI 'base_uri' => env('GIGACHAT_BASE_URI', 'https://gigachat.devices.sberbank.ru'), 'oauth_uri' => env('GIGACHAT_OAUTH_URI', 'https://ngw.devices.sberbank.ru:9443'), // ΠΠΎΠ΄Π΅Π»Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ 'default_model' => env('GIGACHAT_DEFAULT_MODEL', 'GigaChat'), // ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ 'default_options' => [ 'temperature' => (float) env('GIGACHAT_TEMPERATURE', 0.7), 'max_tokens' => (int) env('GIGACHAT_MAX_TOKENS', 1000), 'top_p' => (float) env('GIGACHAT_TOP_P', 0.9), 'repetition_penalty' => (float) env('GIGACHAT_REPETITION_PENALTY', 1.1), ], // Rate limiting Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ 'rate_limit' => [ 'enabled' => env('GIGACHAT_RATE_LIMIT_ENABLED', true), 'max_attempts' => (int) env('GIGACHAT_RATE_LIMIT_MAX_ATTEMPTS', 60), 'decay_minutes' => (int) env('GIGACHAT_RATE_LIMIT_DECAY_MINUTES', 1), ], // ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ 'logging' => [ 'enabled' => env('GIGACHAT_LOGGING_ENABLED', false), 'channel' => env('GIGACHAT_LOG_CHANNEL', 'default'), 'level' => env('GIGACHAT_LOG_LEVEL', 'info'), ], ];
Π’ΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ
- PHP 8.2+
- Laravel 8+ (Π²ΠΊΠ»ΡΡΠ°Ρ 11, 12)
- Guzzle HTTP 7.8.2+
- Π£ΡΠ΅ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ GigaChat API
ΠΠΈΡΠ΅Π½Π·ΠΈΡ
MIT. Π‘ΠΌ. LICENSE.
Π‘ΡΡΠ»ΠΊΠΈ
- Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠ°
- ΠΡΡΡΡΡΠΉ ΡΡΠ°ΡΡ
- Π‘ΠΏΡΠ°Π²ΠΎΡΠ½ΠΈΠΊ API
- ΠΠΎΠ΄Π΅Π»ΠΈ
- Π’Π°ΡΠΈΡΡ
ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ°
Π£ΡΠ°ΡΡΠΈΠ΅
- Π€ΠΎΡΠΊΠ½ΠΈΡΠ΅ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ
- Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ Π²Π΅ΡΠΊΡ (
git checkout -b feature/name) - ΠΠ°ΡΠΈΠΊΡΠΈΡΡΠΉΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ (
git commit -m 'Add feature') - ΠΡΠΏΡΠ°Π²ΡΡΠ΅ (
git push origin feature/name) - ΠΡΠΊΡΠΎΠΉΡΠ΅ Pull Request
Π‘Π»Π΅Π΄ΡΠΉΡΠ΅ PSR-12, Π΄ΠΎΠ±Π°Π²Π»ΡΠΉΡΠ΅ ΡΠ΅ΡΡΡ, ΠΎΠ±Π½ΠΎΠ²Π»ΡΠΉΡΠ΅ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ.
ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ
Π£ΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΠΉΡΠ΅ Π½Π° sovletig@gmail.com (Π½Π΅ Π² ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠ΅ issues).
Laravel 12
ΠΠΎΠ»Π½Π°Ρ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΡ:
- Service Provider Π°Π²ΡΠΎΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ
GigaChatFacade- Artisan-ΠΊΠΎΠΌΠ°Π½Π΄Ρ
- Rate limit middleware
HasGigaChattrait
Roadmap
- ΠΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
- ΠΠ΅ΡΡΠΈΠΊΠΈ
- WebSocket
- ΠΡΡΠ³ΠΈΠ΅ PHP-ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠΈ