701 lines
28 KiB
PHP
701 lines
28 KiB
PHP
|
|
<?php
|
|||
|
|
/*********************************************************************************
|
|||
|
|
* Набор методов для работы с Yandex GPT и ChatGPT через прокладку proxyapi.ru
|
|||
|
|
* All Rights Reserved.
|
|||
|
|
* Contributor(s): Илья Руденко itsaturn@yandex.ru
|
|||
|
|
********************************************************************************/
|
|||
|
|
require_once 'include/utils/utils.php';
|
|||
|
|
|
|||
|
|
function VerbTransfer($list) {
|
|||
|
|
$body = '{
|
|||
|
|
"modelUri": "gpt://b1gvol62rds4n2e5gnm3/yandexgpt-lite",
|
|||
|
|
"completionOptions": {
|
|||
|
|
"stream": false,
|
|||
|
|
"temperature": 0.01,
|
|||
|
|
"maxTokens": 1000
|
|||
|
|
},
|
|||
|
|
"messages": [
|
|||
|
|
{
|
|||
|
|
"role": "system",
|
|||
|
|
"text": "Перепиши фразы, изменив глаголы во второе лицо множественное число, настоящее время"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"role": "user",
|
|||
|
|
"text": "'.$list.'"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}';
|
|||
|
|
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Тело запроса:'.PHP_EOL.$body.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
|
|||
|
|
$curl = curl_init();
|
|||
|
|
|
|||
|
|
curl_setopt_array($curl, array(
|
|||
|
|
CURLOPT_URL => 'https://llm.api.cloud.yandex.net/foundationModels/v1/completion',
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_ENCODING => '',
|
|||
|
|
CURLOPT_MAXREDIRS => 10,
|
|||
|
|
CURLOPT_TIMEOUT => 0,
|
|||
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|||
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|||
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|||
|
|
CURLOPT_POSTFIELDS => $body,
|
|||
|
|
CURLOPT_HTTPHEADER => array(
|
|||
|
|
'Authorization: '.$apikey,
|
|||
|
|
'x-folder-id: b1gvol62rds4n2e5gnm3',
|
|||
|
|
'Content-Type: application/json'),
|
|||
|
|
));
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
$response = str_replace('\n', '', $response);
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Ответ от нейросети:'.PHP_EOL.$response.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
|
|||
|
|
curl_close($curl);
|
|||
|
|
|
|||
|
|
$response = json_decode($response, true);
|
|||
|
|
$output = $response['result']['alternatives'][0]['message']['text'];
|
|||
|
|
|
|||
|
|
return $output;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ChangeFlithy($text) {
|
|||
|
|
$output = SendRequest('Замени в тексте матерные слова и выражения звездочками. От себя ничего не добавляний и никакой редактуры не делай - никакого креатива! Только замена мата на звездочки', $text);
|
|||
|
|
return $output;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function CheckFlithy($text) {
|
|||
|
|
$output = SendRequest('Проверь текст. Если найдешь в нем матерные слова и выражения - верни 1. Если нет - верни 0', $text);
|
|||
|
|
return $output;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function SendRequest($task, $text) {
|
|||
|
|
$text = str_replace(array("\r\n", "\n", "\r"), " ", $text);
|
|||
|
|
$body = '{"model": "gpt-3.5-turbo","messages": [{"role": "system","content": "'.$task.'"},{"role": "user","content": "'.$text.'"}],"temperature": 0.01}';
|
|||
|
|
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Тело запроса:'.PHP_EOL.$body.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
|
|||
|
|
$curl = curl_init();
|
|||
|
|
|
|||
|
|
curl_setopt_array($curl, array(
|
|||
|
|
CURLOPT_URL => 'https://api.proxyapi.ru/openai/v1/chat/completions',
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_ENCODING => '',
|
|||
|
|
CURLOPT_MAXREDIRS => 10,
|
|||
|
|
CURLOPT_TIMEOUT => 0,
|
|||
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|||
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|||
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|||
|
|
CURLOPT_POSTFIELDS => $body,
|
|||
|
|
CURLOPT_HTTPHEADER => array(
|
|||
|
|
'Content-Type: application/json',
|
|||
|
|
'Authorization: Bearer sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY'
|
|||
|
|
),
|
|||
|
|
));
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Ответ от нейросети:'.PHP_EOL.$response.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
|
|||
|
|
if ($response == 'Internal Server Error') {
|
|||
|
|
sleep(10);
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Ответ от нейросети:'.PHP_EOL.$response.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
curl_close($curl);
|
|||
|
|
|
|||
|
|
$response = json_decode($response, true);
|
|||
|
|
$output = $response['choices'][0]['message']['content'];
|
|||
|
|
|
|||
|
|
return $output;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//тестим новый код
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function AskPDF($pdfFile) {
|
|||
|
|
static $analysis = null;
|
|||
|
|
|
|||
|
|
if ($analysis === null) {
|
|||
|
|
$analysis = [
|
|||
|
|
'status' => true,
|
|||
|
|
'files' => [],
|
|||
|
|
'case_updated' => false,
|
|||
|
|
'dispute_summary' => '',
|
|||
|
|
'censorship_issues' => false,
|
|||
|
|
'verdict' => 'Прошло модерацию',
|
|||
|
|
'dispute_type' => '',
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Обрабатываем PDF: $pdfFile");
|
|||
|
|
|
|||
|
|
$text = ExtractTextFromPDF($pdfFile);
|
|||
|
|
if (strpos($text, "Ошибка:") !== false) {
|
|||
|
|
logMessage("Ошибка при обработке: $text");
|
|||
|
|
return json_encode(["error" => $text]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Текст успешно извлечен, отправляем в GPT-4-Turbo.");
|
|||
|
|
$gptAnalysis = AnalyzeTextWithGPT($text);
|
|||
|
|
|
|||
|
|
if (!$gptAnalysis) {
|
|||
|
|
logMessage("Ошибка: GPT-4-Turbo не вернул ответ.");
|
|||
|
|
return json_encode(["error" => "GPT-4-Turbo не вернул данные"]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateAnalysis($analysis, $gptAnalysis, $pdfFile);
|
|||
|
|
|
|||
|
|
// Если файлы продолжают поступать, возвращаем анализ + "waiting"
|
|||
|
|
if (ReceivingFiles()) {
|
|||
|
|
logMessage("Ожидание следующего файла...");
|
|||
|
|
return json_encode(["status" => "waiting", "current_analysis" => $analysis], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|||
|
|
} else {
|
|||
|
|
CheckFinalVerdict($analysis);
|
|||
|
|
logMessage("Все файлы обработаны, завершаем.");
|
|||
|
|
return json_encode(["status" => "complete", "final_analysis" => $analysis], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function ExtractTextFromPDF($pdfFile) {
|
|||
|
|
logMessage("Начинаем извлечение текста из PDF: $pdfFile");
|
|||
|
|
|
|||
|
|
if (!file_exists($pdfFile)) {
|
|||
|
|
logMessage("Ошибка: Файл PDF не найден ($pdfFile)");
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$text = shell_exec("pdftotext -layout $pdfFile -");
|
|||
|
|
|
|||
|
|
logMessage("Распознанных символов: " . mb_strlen($text));
|
|||
|
|
logMessage("Первые 500 символов: " . mb_substr($text, 0, 500));
|
|||
|
|
logMessage("Последние 500 символов: " . mb_substr($text, -500));
|
|||
|
|
|
|||
|
|
return trim($text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function AnalyzeTextWithGPT($text) {
|
|||
|
|
$task = "Анализируй следующий текстовый документ:
|
|||
|
|
1. Определи тип документа (например, договор, претензия, ответ на претензию, подтверждение оплаты).
|
|||
|
|
2. Проверь соответствие названия файла его содержимому.
|
|||
|
|
3. Проверь наличие ненормативной лексики.
|
|||
|
|
4. Определи ключевые моменты спора (если есть).
|
|||
|
|
5. Вынеси итоговый вердикт.";
|
|||
|
|
|
|||
|
|
$body = json_encode([
|
|||
|
|
"model" => "gpt-4-turbo",
|
|||
|
|
"messages" => [
|
|||
|
|
["role" => "system", "content" => $task],
|
|||
|
|
["role" => "user", "content" => $text]
|
|||
|
|
],
|
|||
|
|
"max_tokens" => 4000
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
logMessage("Отправка запроса в GPT-4-Turbo...");
|
|||
|
|
logMessage("Запрос: " . substr($body, 0, 1000));
|
|||
|
|
|
|||
|
|
$curl = curl_init();
|
|||
|
|
curl_setopt_array($curl, [
|
|||
|
|
CURLOPT_URL => 'https://api.proxyapi.ru/openai/v1/chat/completions',
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_POST => true,
|
|||
|
|
CURLOPT_POSTFIELDS => $body,
|
|||
|
|
CURLOPT_HTTPHEADER => [
|
|||
|
|
'Content-Type: application/json',
|
|||
|
|
'Authorization: Bearer sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY'
|
|||
|
|
]
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
curl_close($curl);
|
|||
|
|
|
|||
|
|
logMessage("Ответ от GPT-4-Turbo: " . substr($response, 0, 1000));
|
|||
|
|
|
|||
|
|
return json_decode($response, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function UpdateAnalysis(&$analysis, $gptAnalysis, $pdfFile) {
|
|||
|
|
$responseContent = $gptAnalysis['choices'][0]['message']['content'] ?? '';
|
|||
|
|
|
|||
|
|
if (empty($responseContent)) {
|
|||
|
|
logMessage("Ошибка: Нейросеть вернула пустой ответ.");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$responseContent = mb_convert_encoding($responseContent, "UTF-8", "auto");
|
|||
|
|
|
|||
|
|
if (strpos($responseContent, "{") === false) {
|
|||
|
|
logMessage("GPT-4-Turbo вернул текст, а не JSON. Пытаемся извлечь данные вручную.");
|
|||
|
|
|
|||
|
|
$fileAnalysis = [
|
|||
|
|
'name' => basename($pdfFile),
|
|||
|
|
'type' => ExtractValueFromGPTResponse($responseContent, "Тип документа"),
|
|||
|
|
'content_match' => ExtractValueFromGPTResponse($responseContent, "Соответствие названия") === "да",
|
|||
|
|
'censorship' => ExtractValueFromGPTResponse($responseContent, "Наличие ненормативной лексики") === "да",
|
|||
|
|
'requires_manual_check' => false,
|
|||
|
|
'violations' => [],
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
} else {
|
|||
|
|
$parsedData = json_decode($responseContent, true);
|
|||
|
|
|
|||
|
|
if (!$parsedData) {
|
|||
|
|
logMessage("Ошибка: JSON-ответ содержит ошибки. Декодируем вручную.");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$fileAnalysis = [
|
|||
|
|
'name' => basename($pdfFile),
|
|||
|
|
'type' => $parsedData['Тип документа'] ?? '',
|
|||
|
|
'content_match' => $parsedData['Соответствие названия'] ?? true,
|
|||
|
|
'censorship' => $parsedData['Наличие ненормативной лексики'] ?? false,
|
|||
|
|
'requires_manual_check' => false,
|
|||
|
|
'violations' => [],
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!empty($fileAnalysis['type'])) {
|
|||
|
|
$analysis['case_updated'] = true;
|
|||
|
|
$analysis['dispute_summary'] .= " | Добавлен документ: {$fileAnalysis['type']}";
|
|||
|
|
$analysis['dispute_type'] = DetermineDisputeType($fileAnalysis['type']);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($fileAnalysis['censorship']) {
|
|||
|
|
$analysis['censorship_issues'] = true;
|
|||
|
|
$analysis['verdict'] = "Не прошло модерацию (требуется участие человека)";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$analysis['files'][] = $fileAnalysis;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ExtractValueFromGPTResponse($response, $key) {
|
|||
|
|
$lines = explode("\n", $response);
|
|||
|
|
foreach ($lines as $line) {
|
|||
|
|
if (stripos($line, $key) !== false) {
|
|||
|
|
return trim(str_ireplace($key . ":", "", $line));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function CheckFinalVerdict(&$analysis) {
|
|||
|
|
if ($analysis['censorship_issues']) {
|
|||
|
|
logMessage("Обнаружены проблемы с цензурой. Обновляем вердикт.");
|
|||
|
|
$analysis['verdict'] = "Не прошло модерацию (требуется участие человека)";
|
|||
|
|
} elseif (empty($analysis['files'])) {
|
|||
|
|
logMessage("Обнаружена ошибка: файлы обработаны, но не добавлены в список.");
|
|||
|
|
$analysis['verdict'] = "Ошибка анализа (файл не записан)";
|
|||
|
|
} else {
|
|||
|
|
logMessage("Финальный вердикт: Прошло модерацию.");
|
|||
|
|
$analysis['verdict'] = "Прошло модерацию";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function DetermineDisputeType($fileType) {
|
|||
|
|
$types = [
|
|||
|
|
"договор" => "некачественная услуга",
|
|||
|
|
"претензия" => "не возвращают деньги",
|
|||
|
|
"ответ на претензию" => "товар не привезли",
|
|||
|
|
"подтверждение оплаты" => "финансовый спор"
|
|||
|
|
];
|
|||
|
|
return $types[$fileType] ?? "не определено";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ReceivingFiles() {
|
|||
|
|
$processingLock = "storage/processing.lock";
|
|||
|
|
|
|||
|
|
if (file_exists($processingLock)) {
|
|||
|
|
logMessage("Есть сигнал о поступлении новых файлов. Ожидание...");
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Файлы больше не поступают. Завершаем обработку.");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function logMessage($message) {
|
|||
|
|
$logFile = "logs/GPT.log";
|
|||
|
|
|
|||
|
|
if (!is_dir(dirname($logFile))) {
|
|||
|
|
mkdir(dirname($logFile), 0777, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
file_put_contents($logFile, date("Y-m-d H:i:s") . " - " . mb_convert_encoding($message, "UTF-8", "auto") . PHP_EOL, FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//старый код 3
|
|||
|
|
/*
|
|||
|
|
function logMessage($message) {
|
|||
|
|
$logFile = "logs/GPT.log"; // Путь к файлу логов
|
|||
|
|
$logDir = dirname($logFile);
|
|||
|
|
|
|||
|
|
// Если папка логов не существует, создаем
|
|||
|
|
if (!is_dir($logDir)) {
|
|||
|
|
mkdir($logDir, 0777, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// file_put_contents($logFile, date("Y-m-d H:i:s") . " - " . $message . "\n", FILE_APPEND);
|
|||
|
|
file_put_contents($logFile, date("Y-m-d H:i:s") . " - " . utf8_encode($message) . "\n", FILE_APPEND);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ExtractTextFromPDF($pdfFile) {
|
|||
|
|
logMessage("Начинаем извлечение текста из PDF: $pdfFile");
|
|||
|
|
|
|||
|
|
// Проверяем существование файла
|
|||
|
|
if (!file_exists($pdfFile)) {
|
|||
|
|
logMessage("Ошибка: Файл PDF не найден ($pdfFile)");
|
|||
|
|
return "Ошибка: Файл не найден.";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Извлекаем текст из PDF
|
|||
|
|
$text = shell_exec("pdftotext -layout $pdfFile -");
|
|||
|
|
|
|||
|
|
// Логируем количество символов
|
|||
|
|
logMessage("Распознанных символов: " . mb_strlen($text));
|
|||
|
|
|
|||
|
|
// Логируем начало и конец текста
|
|||
|
|
logMessage("Первые 500 символов: " . substr($text, 0, 500));
|
|||
|
|
logMessage("Последние 500 символов: " . substr($text, -500));
|
|||
|
|
|
|||
|
|
// Если текст есть, возвращаем его, иначе переходим к OCR
|
|||
|
|
if (!empty(trim($text))) {
|
|||
|
|
return trim($text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Текст не найден, запускаем OCR...");
|
|||
|
|
return OCRFromPDF($pdfFile);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function OCRFromPDF($pdfFile) {
|
|||
|
|
logMessage("Запуск OCR для PDF: $pdfFile");
|
|||
|
|
|
|||
|
|
$outputFolder = "logs/pdf_images/";
|
|||
|
|
if (!is_dir($outputFolder)) {
|
|||
|
|
mkdir($outputFolder, 0777, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
shell_exec("pdftoppm -jpeg $pdfFile $outputFolder/output");
|
|||
|
|
logMessage("PDF конвертирован в изображения.");
|
|||
|
|
|
|||
|
|
$images = glob($outputFolder . "*.jpg");
|
|||
|
|
if (empty($images)) {
|
|||
|
|
logMessage("Ошибка: Не удалось конвертировать PDF в изображения.");
|
|||
|
|
return "Ошибка: Не удалось конвертировать PDF в изображения.";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$recognizedText = "";
|
|||
|
|
foreach ($images as $image) {
|
|||
|
|
logMessage("Распознаем текст с изображения: $image");
|
|||
|
|
$text = shell_exec("tesseract $image stdout -l rus+eng");
|
|||
|
|
logMessage("Распознанный текст: " . substr($text, 0, 500));
|
|||
|
|
$recognizedText .= "\n" . trim($text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return empty(trim($recognizedText)) ? "Ошибка: Не удалось распознать текст." : trim($recognizedText);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function CheckPDF($pdfFile) {
|
|||
|
|
logMessage("Обрабатываем PDF: $pdfFile");
|
|||
|
|
|
|||
|
|
$text = ExtractTextFromPDF($pdfFile);
|
|||
|
|
if (strpos($text, "Ошибка:") !== false) {
|
|||
|
|
logMessage("Ошибка при обработке: $text");
|
|||
|
|
return ["error" => $text];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Текст успешно извлечен, отправляем в GPT-4-Turbo.");
|
|||
|
|
return AnalyzeTextWithGPT($text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function AnalyzeTextWithGPT($text) {
|
|||
|
|
logMessage("Отправка запроса в GPT-4-Turbo...");
|
|||
|
|
|
|||
|
|
$task = "Анализируй следующий текстовый документ:
|
|||
|
|
1. Определи тип документа (например, договор, претензия, ответ на претензию, подтверждение оплаты).
|
|||
|
|
2. Проверь соответствие названия файла его реальному содержимому.
|
|||
|
|
3. Проанализируй документ на наличие ненормативной лексики.
|
|||
|
|
4. Определи ключевые моменты спора, если они есть.
|
|||
|
|
5. Вынеси итоговый вердикт (Прошло модерацию / Не прошло модерацию).";
|
|||
|
|
|
|||
|
|
$body = json_encode([
|
|||
|
|
"model" => "gpt-4-turbo",
|
|||
|
|
"messages" => [
|
|||
|
|
["role" => "system", "content" => $task],
|
|||
|
|
["role" => "user", "content" => $text]
|
|||
|
|
],
|
|||
|
|
"max_tokens" => 4000
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
logMessage("Запрос к GPT-4-Turbo: " . substr($body, 0, 1000));
|
|||
|
|
|
|||
|
|
$curl = curl_init();
|
|||
|
|
curl_setopt_array($curl, [
|
|||
|
|
CURLOPT_URL => 'https://api.proxyapi.ru/openai/v1/chat/completions',
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_POST => true,
|
|||
|
|
CURLOPT_POSTFIELDS => $body,
|
|||
|
|
CURLOPT_HTTPHEADER => [
|
|||
|
|
'Content-Type: application/json',
|
|||
|
|
'Authorization: Bearer sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY'
|
|||
|
|
]
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
logMessage("Ответ от GPT-4-Turbo: " . substr($response, 0, 1000));
|
|||
|
|
|
|||
|
|
curl_close($curl);
|
|||
|
|
return json_decode($response, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//старый код 2
|
|||
|
|
|
|||
|
|
function CheckPDF($PDFFile) {
|
|||
|
|
static $analysis = [
|
|||
|
|
'status' => true,
|
|||
|
|
'files' => [],
|
|||
|
|
'case_updated' => false,
|
|||
|
|
'dispute_summary' => '',
|
|||
|
|
'censorship_issues' => false,
|
|||
|
|
'verdict' => 'Прошло модерацию',
|
|||
|
|
'dispute_type' => '',
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// Разбираем PDF на изображения
|
|||
|
|
$files = pdf2jpg($PDFFile);
|
|||
|
|
$file_analysis = [
|
|||
|
|
'name' => basename($PDFFile),
|
|||
|
|
'type' => '',
|
|||
|
|
'content_match' => true,
|
|||
|
|
'censorship' => false,
|
|||
|
|
'requires_manual_check' => false,
|
|||
|
|
'violations' => [],
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
$page = 1;
|
|||
|
|
foreach ($files as $jpg) {
|
|||
|
|
$link = 'https://crm.clientright.ru/tmp/' . basename($jpg);
|
|||
|
|
$found = AnalyzeImage('Задача: Анализируй каждый загружаемый документ, выполняя следующие шаги:
|
|||
|
|
1. Обновление списка файлов
|
|||
|
|
o Добавь новый файл в список уже загруженных документов.
|
|||
|
|
o Определи его содержимое (например, "договор", "претензия", "ответ на претензию", "подтверждение оплаты" и т. д.).
|
|||
|
|
o Проверь, соответствует ли название файла его реальному содержимому.
|
|||
|
|
o Если обнаружено несоответствие, укажи, в чем проблема.
|
|||
|
|
2. Обновление анализа спора
|
|||
|
|
o Если ранее уже загружены связанные файлы, обнови анализ спора.
|
|||
|
|
o Уточни истца (потребителя) и ответчика (компанию, на которую подана жалоба).
|
|||
|
|
o Дополни суть спора с учетом новых данных.
|
|||
|
|
o Если новый файл содержит важную информацию, измени или дополни аргументы сторон.
|
|||
|
|
3. Проверка на цензуру
|
|||
|
|
o Проанализируй новый документ на наличие ненормативной лексики и нецензурных изображений.
|
|||
|
|
o Если это изображение, укажи, требуется ли его ручная проверка.
|
|||
|
|
4. Обновление итогового вердикта
|
|||
|
|
o Если после добавления нового файла вся информация корректна, оставь "Прошло модерацию".
|
|||
|
|
o Если появились несоответствия или спорные моменты, измени статус на "Не прошло модерацию (требуется участие человека)", указав, что именно требует проверки.
|
|||
|
|
5. Характер спора
|
|||
|
|
o Если суть спора изменилась или уточнилась, обнови краткое описание (например, "некачественный товар", "товар не привезли", "не возвращают деньги", "некачественная услуга" и т. д.).
|
|||
|
|
Важно:1.Если файл связан с уже загруженными данными, обнови анализ с учетом новой информации. 2. Если файл независимый, создай новый кейс анализа.
|
|||
|
|
• Итоговый отчет должен оставаться актуальным, а не дублироваться при поступлении новых файлов.', $link);
|
|||
|
|
|
|||
|
|
if ($found) {
|
|||
|
|
$file_analysis['censorship'] = true;
|
|||
|
|
$file_analysis['violations'][] = $page;
|
|||
|
|
$analysis['censorship_issues'] = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
unlink($jpg);
|
|||
|
|
$page++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Определение типа документа (эмуляция)
|
|||
|
|
$file_analysis['type'] = IdentifyFileType($PDFFile);
|
|||
|
|
$file_analysis['content_match'] = CheckFileNameMatchesContent($PDFFile, $file_analysis['type']);
|
|||
|
|
|
|||
|
|
// Обновление данных по спору
|
|||
|
|
if ($file_analysis['type']) {
|
|||
|
|
$analysis['case_updated'] = true;
|
|||
|
|
$analysis['dispute_summary'] = UpdateDisputeSummary($file_analysis['type']);
|
|||
|
|
$analysis['dispute_type'] = DetermineDisputeType($file_analysis['type']);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Проверка на цензуру и финальный вердикт
|
|||
|
|
if ($file_analysis['censorship'] || !$file_analysis['content_match']) {
|
|||
|
|
$analysis['verdict'] = "Не прошло модерацию (требуется участие человека)";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Добавляем файл в общий список
|
|||
|
|
$analysis['files'][] = $file_analysis;
|
|||
|
|
|
|||
|
|
// Если файлы еще загружаются — возвращаем 0
|
|||
|
|
if (ReceivingFiles()) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Когда загрузка завершена, возвращаем итоговый анализ
|
|||
|
|
return $analysis;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function AnalyzeImage($task, $image) {
|
|||
|
|
$body = json_encode([
|
|||
|
|
"model" => "gpt-4-turbo",
|
|||
|
|
// "model" => "gpt-o1",
|
|||
|
|
"messages" => [
|
|||
|
|
["role" => "user", "content" => [
|
|||
|
|
["type" => "text", "text" => $task],
|
|||
|
|
["type" => "image_url", "image_url" => ["url" => $image]]
|
|||
|
|
]]
|
|||
|
|
],
|
|||
|
|
"max_tokens" => 4000
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
file_put_contents('logs/GPT.log', date('Y-m-d H:i:s') . " Тело запроса:\n" . $body . "\n", FILE_APPEND);
|
|||
|
|
|
|||
|
|
$curl = curl_init();
|
|||
|
|
curl_setopt_array($curl, [
|
|||
|
|
CURLOPT_URL => 'https://api.proxyapi.ru/openai/v1/chat/completions',
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_POST => true,
|
|||
|
|
CURLOPT_POSTFIELDS => $body,
|
|||
|
|
CURLOPT_HTTPHEADER => [
|
|||
|
|
'Content-Type: application/json',
|
|||
|
|
'Authorization: Bearer sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY'
|
|||
|
|
]
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
file_put_contents('logs/GPT.log', date('Y-m-d H:i:s') . " Ответ от нейросети:\n" . $response . "\n", FILE_APPEND);
|
|||
|
|
curl_close($curl);
|
|||
|
|
|
|||
|
|
$response = json_decode($response, true);
|
|||
|
|
return isset($response['choices'][0]['message']['content']) && $response['choices'][0]['message']['content'] == '1';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function IdentifyFileType($file) {
|
|||
|
|
// Заглушка: определение типа файла по содержимому (можно подключить AI)
|
|||
|
|
$types = ["договор", "претензия", "ответ на претензию", "подтверждение оплаты"];
|
|||
|
|
return $types[array_rand($types)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function CheckFileNameMatchesContent($file, $detectedType) {
|
|||
|
|
// Эмуляция проверки соответствия названия содержимому
|
|||
|
|
return stripos($file, $detectedType) !== false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function UpdateDisputeSummary($fileType) {
|
|||
|
|
// Заглушка обновления информации по спору
|
|||
|
|
return "Обновлен анализ спора на основе документа: $fileType";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function DetermineDisputeType($fileType) {
|
|||
|
|
// Заглушка определения характера спора
|
|||
|
|
$types = [
|
|||
|
|
"договор" => "некачественная услуга",
|
|||
|
|
"претензия" => "не возвращают деньги",
|
|||
|
|
"ответ на претензию" => "товар не привезли",
|
|||
|
|
"подтверждение оплаты" => "финансовый спор"
|
|||
|
|
];
|
|||
|
|
return $types[$fileType] ?? "не определено";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ReceivingFiles() {
|
|||
|
|
// Заглушка, возвращает true, если файлы продолжают поступать
|
|||
|
|
return rand(0, 1) == 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
//старый код 2
|
|||
|
|
|
|||
|
|
|
|||
|
|
function CheckPDF($PDFFile) {
|
|||
|
|
$files = pdf2jpg($PDFFile); // Разобрали PDF на набор JPG-ов
|
|||
|
|
$result = [];
|
|||
|
|
$result['status'] = true;
|
|||
|
|
$page = 1;
|
|||
|
|
foreach ($files as $jpg) {
|
|||
|
|
//echo $jpg.'<br>';
|
|||
|
|
$link = 'https://crm.clientright.ru/tmp/'.basename($jpg);
|
|||
|
|
$found = AnalyzeImage('Проанализируй содержимое и определи - есть в нем матерные слова и выражения в любых склонениях? Ответ представь одной цифрой без дополнительных комментариев - при наличии матерных слов верни 1, при отсутствии верни 0', $link);
|
|||
|
|
if ($found) {
|
|||
|
|
if ($result['status'] == true) { // нашли первое нарушение в файле
|
|||
|
|
$result['pages'] = []; // создадим массив со списком страниц с нарушениями
|
|||
|
|
$result['status'] = false;
|
|||
|
|
}
|
|||
|
|
$result['pages'][] = $page;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
unlink($jpg); // Удаляем файл, он нам больше не нужен
|
|||
|
|
$page++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function AnalyzeImage($task, $image) {
|
|||
|
|
$body = '{"model": "gpt-4-turbo","messages": [{"role": "user","content": [{"type": "text","text": "'.$task.'"},{"type": "image_url","image_url": {"url": "'.$image.'"}}]}],"max_tokens": 300}';
|
|||
|
|
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Тело запроса:'.PHP_EOL.$body.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
|
|||
|
|
$curl = curl_init();
|
|||
|
|
|
|||
|
|
curl_setopt_array($curl, array(
|
|||
|
|
CURLOPT_URL => 'https://api.proxyapi.ru/openai/v1/chat/completions',
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_ENCODING => '',
|
|||
|
|
CURLOPT_MAXREDIRS => 10,
|
|||
|
|
CURLOPT_TIMEOUT => 0,
|
|||
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|||
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|||
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|||
|
|
CURLOPT_POSTFIELDS => $body,
|
|||
|
|
CURLOPT_HTTPHEADER => array(
|
|||
|
|
'Content-Type: application/json',
|
|||
|
|
'Authorization: Bearer sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY'
|
|||
|
|
),
|
|||
|
|
));
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Ответ от нейросети:'.PHP_EOL.$response.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
|
|||
|
|
if ($response == 'Internal Server Error') {
|
|||
|
|
sleep(10);
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
$logstring = date('Y-m-d H:i:s').' Ответ от нейросети:'.PHP_EOL.$response.PHP_EOL;
|
|||
|
|
file_put_contents('logs/GPT.log', $logstring, FILE_APPEND);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
curl_close($curl);
|
|||
|
|
|
|||
|
|
$response = json_decode($response, true);
|
|||
|
|
$result = $response['choices'][0]['message']['content'];
|
|||
|
|
if ($result == '0') {
|
|||
|
|
$output = false;
|
|||
|
|
} else {
|
|||
|
|
$output = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $output;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
?>
|