/
v.bolshakov
/
AIEcosystem-Testing
Обзор
Документация
Войти
/
v.bolshakov
/
AIEcosystem-Testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
dev
common/forms/ai/BaseRequestModelForm.php
606 строк
20 KB
Developer
Initial commit
03 авг 2026, 17:43
03 авг 2026, 17:43
7433917
Код
Авторство
О чём код?
<?php namespace common\forms\ai; use common\components\AnthropicComponent; use common\components\DeepseekComponent; use common\components\GoogleAlComponent; use common\components\JanusAIComponent; use common\components\OpenAIComponent; use common\components\OpenRouteComponent; use common\helpers\AiHelper; use common\helpers\AppHelper; use common\helpers\ArrayHelper; use common\helpers\Utf8Helper; use common\models\BatchLogMongo; use common\models\ModelAI; use common\models\ProjectApi; use common\models\Provider; use common\models\UserApi; use DeepSeek\DeepSeekClient; use fholbrook\Openrouter\DTO\Chat; use fholbrook\Openrouter\DTO\ChatRequest; use fholbrook\Openrouter\DTO\Message; use fholbrook\Openrouter\OpenRouter; use Gemini\Data\Content; use OpenAI\Client; use Yii; use yii\helpers\Json; use yii\helpers\VarDumper; /** * Запрос к модели * * @author Dmitry E. Semenov <sde.tomsk@gmail.com> * @copyright Self (c) 2024 */ abstract class BaseRequestModelForm extends BaseRequestForm { /** * Идентификатор модели * @var string */ public $modelUid = null; /** * Promt * @var string */ public $promt = null; /** * Формат запроса * @var null */ public $promt_format_id = null; /** * Temperature * @var float */ public $temperature = null; /** * TopP * @var float */ public $top_p = null; /** * Проект * @var null */ public $project_id = null; /** * @inheritdoc */ public function rules() { return ArrayHelper::merge(parent::rules(), [ [['temperature', 'top_p', 'modelUid', 'promt_format_id'], 'required'], [ [ 'promt_format_id', 'temperature', 'top_p', 'project_id' ], 'number' ], [['promt', 'modelUid'], 'string'] ]); } /** * @inheritdoc */ protected function doAiRequest() { /** @var ModelAI $modelAI */ $modelAI = ModelAI::findOne([ 'guid' => $this->modelUid ]); $provider_id = $modelAI->getProviderId(); $result_all = []; $token = []; if ($provider_id == Provider::GPT) { $api_key = null; if ($this->user_id) { $api_key = UserApi::find() ->select('api_key') ->andWhere([ 'user_id' => $this->user_id ]) ->published() ->scalar(); } if (!$api_key and $this->project_id) { $api_key = ProjectApi::find() ->select('api_key') ->andWhere([ 'project_id' => $this->project_id ]) ->scalar(); } $openAI = Yii::createObject([ 'class' => OpenAIComponent::class, 'api_key' => $api_key ]); /** @var Client $client */ $client = $openAI->getClient(); foreach ($this->request as $index => $request) { $start_at = microtime(true); if (is_array($request)) { $request = implode('', $request); } $the_response = []; $messages = []; $error = null; try { if ($this->promt) { $messages[] = [ 'role' => 'system', 'content' => $this->promt ]; } $messages[] = [ 'role' => 'user', 'content' => $request ]; Yii::debug(VarDumper::dumpAsString([ 'messages' => $messages ])); $parameters = [ 'model' => $modelAI->title, 'messages' => $messages, 'temperature' => $this->temperature, 'top_p' => $this->top_p ]; if ($modelAI->isGpt5()) { $parameters['text']['verbosity'] = 'low'; $parameters['reasoning']['effort'] = 'minimal'; } if ($this->is_debug) { BatchLogMongo::createRequest($index, $parameters); } $response = $client->chat()->create($parameters); if ($this->is_debug) { BatchLogMongo::createResponse($index, $response); } AiHelper::log([ 'input' => $response->usage->promptTokens, 'output' => $response->usage->completionTokens, 'total' => $response->usage->totalTokens, 'request_batch_id' => $index ]); foreach ($response->choices as $result) { $the_response[] = Utf8Helper::trim($result->message->content); } } catch (\Exception $e) { $error = $e->getMessage(); AppHelper::log('error (GPT): ' . $error); Yii::debug(VarDumper::dumpAsString([ 'error' => $error ])); } $done = microtime(true) - $start_at; $this->proccessBatch($index, $done, $this->attempt, $error); $result_all[] = implode('', $the_response); } } elseif ($provider_id == Provider::OPEN_ROUTER) { $openAI = new OpenRouteComponent(); /** @var OpenRouter $client */ $client = $openAI->getClient(); foreach ($this->request as $index => $request) { $start_at = microtime(true); if (is_array($request)) { $request = implode('', $request); } $the_response = []; $messages = []; $error = null; try { if ($this->promt) { $messages[] = new Message( content: $this->promt, role: 'system' ); } $messages[] = new Message( content: $request, role: 'user' ); Yii::debug(VarDumper::dumpAsString([ 'messages' => $messages ])); $chatData = new ChatRequest( chat: new Chat( messages: $messages, ), model: $modelAI->model_id, temperature: $this->temperature, topP: $this->top_p ); if ($this->is_debug) { BatchLogMongo::createRequest($index, $chatData->toArray(true)); } $response = $client->chat->chat($chatData); $chat = $response->getChat(); AiHelper::log([ 'input' => $response->getResponse()->usage->promptTokens, 'output' => $response->getResponse()->usage->completionTokens, 'total' => $response->getResponse()->usage->totalTokens, 'request_batch_id' => $index ]); $json = $chat->toArray(includeMetadata: true); if ($this->is_debug) { BatchLogMongo::createResponse($index, $json); } $messages = ArrayHelper::getValue($json, 'messages'); foreach ($messages as $message) { if ($message['role'] == 'assistant') { $the_response[] = Utf8Helper::trim($message['content']); } } } catch (\Exception $e) { $error = $e->getMessage(); AppHelper::log('error (Open Route): ' . $error); Yii::debug(VarDumper::dumpAsString([ 'error' => $error ])); } $done = microtime(true) - $start_at; $this->proccessBatch($index, $done, $this->attempt, $error); $result_all[] = implode('', $the_response); } } elseif ($provider_id == Provider::ANTHROPIC) { $api = new AnthropicComponent(); $client = $api->getClient(); foreach ($this->request as $index => $request) { $start_at = microtime(true); $the_response = []; $messages = []; $error = null; if (is_array($request)) { $request = implode('', $request); } $messages[] = [ 'role' => 'user', 'content' => $request ]; try { $parameters = [ 'model' => $modelAI->model_id, 'max_tokens' => $modelAI->token_limit, 'system' => $this->promt, 'messages' => $messages, ]; if ($this->is_debug) { BatchLogMongo::createRequest($index, $parameters); } $result = $client->messages()->create($parameters); if ($this->is_debug) { BatchLogMongo::createResponse($index, $result); } $input = (int)ArrayHelper::getValue($result, 'usage.inputTokens'); $output = (int)ArrayHelper::getValue($result, 'usage.outputTokens'); AiHelper::log([ 'input' => $input, 'output' => $output, 'total' => ($input + $output), 'request_batch_id' => $index ]); $the_response[] = Utf8Helper::trim(ArrayHelper::getValue($result, 'content.0.text')); } catch (\Exception $e) { $error = $e->getMessage(); AppHelper::log('error (Anthropic): ' . $error); Yii::debug(VarDumper::dumpAsString([ 'error' => $error ])); } $done = microtime(true) - $start_at; $this->proccessBatch($index, $done, $this->attempt, $error); $result_all[] = implode('', $the_response); } } elseif ($provider_id == Provider::GOOGLE_AI) { $api = new GoogleAlComponent(); /** @var \Gemini\Client $client */ $client = $api->getClient(); foreach ($this->request as $index => $request) { $start_at = microtime(true); $the_response = []; $error = null; if (is_array($request)) { $request = implode('', $request); } try { $contents = Content::parse($request); $systemInstruction = Content::parse($this->promt); if ($this->is_debug) { BatchLogMongo::createRequest($index, [ 'model' => $modelAI->model_id, 'systemInstruction' => $systemInstruction->toArray(), 'contents' => $contents->toArray() ]); } $result = $client ->generativeModel(model: $modelAI->model_id) ->withSystemInstruction($systemInstruction) ->generateContent($contents); if ($this->is_debug) { BatchLogMongo::createResponse($index, $result->toArray()); } AiHelper::log([ 'input' => $result->usageMetadata->promptTokenCount, 'output' => $result->usageMetadata->candidatesTokenCount, 'total' => $result->usageMetadata->totalTokenCount, 'request_batch_id' => $index ]); $response = $result->text(); Yii::debug(VarDumper::dumpAsString([ 'result' => $result, 'response' => $response ])); $the_response[] = Utf8Helper::trim($response); } catch (\Exception $e) { $error = $e->getMessage(); AppHelper::log('error (Google AI): ' . $error); Yii::debug(VarDumper::dumpAsString([ 'error' => $error ])); } $done = microtime(true) - $start_at; $this->proccessBatch($index, $done, $this->attempt, $error); $result_all[] = implode('', $the_response); } } elseif ($provider_id == Provider::JANUS_AI) { $api = new JanusAIComponent(); foreach ($this->request as $index => $request) { $start_at = microtime(true); $the_response = []; $error = null; $total_duration = 0; if (is_array($request)) { $request = implode('', $request); } try { $the_request = [ 'model' => $modelAI->model_id, 'system' => $request, 'prompt' => $this->promt, 'temperature' => $this->temperature, 'top_p' => $this->top_p, ]; if ($this->is_debug) { BatchLogMongo::createRequest($index, $the_request); } $response = $api->request($the_request); if ($this->is_debug) { BatchLogMongo::createResponse($index, $response); } $total_duration = $response['total_duration']; AiHelper::log([ 'input' => $response['prompt_eval_count'], 'output' => $response['eval_count'], 'total' => $response['prompt_eval_count'] + $response['eval_count'], 'request_batch_id' => $index ]); $the_response[] = $response['response']; } catch (\Exception $e) { $error = $e->getMessage(); AppHelper::log('error (JanusAI): ' . $error); Yii::debug(VarDumper::dumpAsString([ 'error' => $error ])); } $done = microtime(true) - $start_at; $this->proccessBatch($index, $total_duration, $this->attempt, $error); $result_all[] = implode('', $the_response); } } elseif ($provider_id == Provider::DEEPSEEK) { $api = new DeepseekComponent(); /** @var DeepSeekClient $client */ $client = $api->getClient(); foreach ($this->request as $index => $request) { $start_at = microtime(true); $the_response = []; $error = null; if (is_array($request)) { $request = implode('', $request); } try { if ($this->is_debug) { BatchLogMongo::createRequest($index, [ 'messages' => [ [ 'role' => 'user', 'content' => $request ], [ 'role' => 'system', 'content' => $this->promt ] ], 'model' => $modelAI->model_id, 'stream' => true, 'temperature' => $this->temperature, 'max_tokens' => $modelAI->token_limit, 'response_format' => 'text' ]); } $response = $client ->withModel($modelAI->model_id) ->withStream() ->setTemperature($this->temperature) ->setMaxTokens($modelAI->token_limit) ->setResponseFormat('text') ->query($request) ->query($this->promt, 'system') ->run(); Yii::debug(VarDumper::dumpAsString([ 'response' => $response ])); $array = explode('data: ', $response); $prompt_tokens = 0; $completion_tokens = 0; $total_tokens = 0; $the_result = []; $log = []; foreach ($array as $row) { try { $data = Json::decode($row); if (is_array($data)) { $log[] = $data; $the_result[] = ArrayHelper::getValue($data, 'choices.0.delta.content'); if ('stop' == ArrayHelper::getValue($data, 'choices.0.finish_reason')) { $prompt_tokens = (int)ArrayHelper::getValue($data, 'usage.prompt_tokens'); $completion_tokens = (int)ArrayHelper::getValue($data, 'usage.completion_tokens'); $total_tokens = (int)ArrayHelper::getValue($data, 'usage.total_tokens'); } } } catch (\Exception $exception) { Yii::debug(VarDumper::dumpAsString([ 'row' => $row, 'exception' => $exception->getMessage() ])); } } if ($this->is_debug) { BatchLogMongo::createResponse($index, $log); } AiHelper::log([ 'input' => $prompt_tokens, 'output' => $completion_tokens, 'total' => $total_tokens, 'request_batch_id' => $index ]); $the_response[] = implode('', $the_result); } catch (\Exception $e) { $error = $e->getMessage(); AppHelper::log('error (DeepSeek): ' . $error); Yii::debug(VarDumper::dumpAsString([ 'error' => $error ])); } $done = microtime(true) - $start_at; $this->proccessBatch($index, $done, $this->attempt, $error); $result_all[] = implode('', $the_response); } } $this->model = [ 'text' => implode('', $result_all), 'items' => $result_all ]; Yii::debug(VarDumper::dumpAsString($this->model)); return true; } }