PHP SDK: AI: анализ и обработка данных
$ctx->ai() помогает разобраться в содержимом страницы, преобразовать запись, найти элемент и подготовить исправление алгоритма. Вызовы выполняются в ядре платформы: ключ сервиса и внутренний выбор модели недоступны сценарию.
Используются самые передовые модели на текущий момент времени. Вы выбираете уровень small, medium или large, а платформа сама подбирает подходящую модель. Уровень можно менять без переписывания алгоритма.
Попадание extract() в проверенный кэш не обращается к модели и не расходует AI-токены.
Перед первым вызовом
- Обращение к модели расходует AI-бюджет того пространства, которому принадлежит сайт. Расход входных и выходных токенов отражается в лимитах и журнале операций. Кроме AI-бюджета учитывается обычное время работы сценария.
- За один прогон можно сделать не более восьми AI-вызовов. На один вызов можно передать до 48 КБ данных. Для больших страниц сначала выберите нужный фрагмент обычными методами SDK.
- Не передавайте пароли, токены и персональные данные в содержимом запроса. Известные платформе ключи сайта блокируются перед отправкой.
- При работе агента автономно и при воспроизведении прогона AI-вызовы недоступны. Для надёжного регулярного сбора закрепляйте проверенную логику в PHP-коде.
Уровень и усилие
| Параметр | Значения | Когда выбирать |
|---|---|---|
$tier |
small, medium, large |
small для коротких страниц и простых записей; medium для неоднозначной структуры; large для сложного исправления кода. |
$effort |
low, medium, high, extra_high |
Чем выше усилие, тем больше времени и токенов может потребоваться для ответа. Начните с medium; extra_high используйте для особенно сложных случаев. |
Значения по умолчанию: small и medium, кроме repair(): у него large и high. Стоимость зависит от фактического расхода токенов. Перед запросом бюджет резервируется, после ответа неиспользованная часть освобождается. Если бюджета недостаточно, сценарий получает понятную ошибку и запрос не отправляется.
analyze
analyze(string $content, string $question, string $tier = 'small', string $effort = 'medium'): string
Задайте вопрос о уже полученном фрагменте страницы или данных. Метод возвращает текст ответа.
$html = $ctx->http()->get($ctx->param('catalog_url'))->body;
$answer = $ctx->ai()->analyze($html, 'Где на странице расположена цена товара?');
$ctx->log($answer);
Ответ может быть неточным. Перед записью товаров проверяйте фактические значения.
transform
transform(array $data, array $shape, string $instruction = '', string $tier = 'small', string $effort = 'medium'): array
Передайте исходную запись, образец нужной структуры и уточнение. Метод возвращает массив в поле data; отсутствующие факты не должны придумываться.
$raw = ['title' => 'Ремень', 'cost' => '1 250 ₽'];
$shape = ['name' => '', 'price_rub' => 0];
$item = $ctx->ai()->transform($raw, $shape, 'Сохрани цену числом в рублях');
$ctx->emit($item, 'ремень-1');
Если структура стабильная, обычное преобразование PHP быстрее и дешевле. AI полезен, когда входные записи заметно различаются.
find
find(string $html, string $description, string $tier = 'small', string $effort = 'medium'): array
Предлагает CSS-селектор элемента на переданном HTML. Результат содержит selector и reason. Если элемент не найден, selector пустой.
$html = $ctx->http()->get($ctx->param('product_url'))->body;
$match = $ctx->ai()->find($html, 'Кнопка перехода на следующую страницу', 'medium', 'high');
if ($match['selector'] !== '') {
$node = $ctx->dom($html)->q($match['selector']);
$nextUrl = $node?->abs();
}
Проверьте предложенный селектор на текущей странице и на других страницах списка. Результат не заменяет проверку пагинации.
repair
repair(string $source, string $error, string $goal, string $tier = 'large', string $effort = 'high'): string
Возвращает предложенный исправленный PHP-код. Метод ничего не сохраняет и не меняет активную версию сценария. Проверьте код, выполните пробный прогон и затем опубликуйте новую версию через редактор.
$source = (string) $ctx->param('algorithm_source', '');
$error = (string) $ctx->param('last_error', '');
if ($source !== '' && $error !== '') {
$suggestion = $ctx->ai()->repair(
$source,
$error,
'Обойти все страницы каталога и собрать товары',
'large',
'extra_high'
);
$ctx->log($suggestion);
}
Обычно repair() удобнее запускать при отладке: исходный код и текст ошибки должны быть доступны сценарию из его параметров или других разрешённых источников. Не передавайте в AI результат credential().
Ошибки и оплата
При недоступности сервиса или неверном ответе SDK выдаёт исключение. Отклонённый сервисом запрос не оплачивается. Если ответ не удалось подтвердить после сетевого сбоя, резерв остаётся до сверки, чтобы избежать неверного списания или повторной оплаты. При полученном ответе оплачивается фактический расход токенов, даже если предложенный селектор или код нужно доработать.
Общий справочник SDK · Лимиты и баланс
documentRows
documentRows(Document $document, int|string $sheet = 0): array
Помогает разобрать плоскую таблицу, не раскрывая содержимое внешней модели. Бесплатный Mistral получает только коды типов ячеек, размеры и признак объединений. Заголовки и значения превращаются в records локально. Возвращает status=ready, records, header_row, confidence либо needs_range с пустыми records. Для неполного документа возвращает incomplete, при ошибках формул needs_range. При объединениях, неоднозначной структуре, недоступной модели или квоте автоматический разбор не выполняется: используйте явный sheet()->records(). Внешнего платного fallback нет. На автономном агенте внешняя модель не вызывается. Лимиты: 50 планов на пространство в сутки, 200 общих, план расходует один из восьми документных вызовов прогона. Это определение структуры, а не семантический анализ приватного PDF или счёта. Никогда не передавайте текст писем и файлов в общие analyze/transform.
$document = $ctx->documents()->fromBytes("Артикул;Остаток\nTEST-001;17", 'report.csv');
$result = $ctx->ai()->documentRows($document);
if ($result['status'] === 'ready') {
foreach ($result['records'] as $row) $ctx->emit(['sku' => $row['Артикул'], 'stock' => (int) $row['Остаток']]);
}
extract
extract(array|string|Document $input, array $schema, array $options = []): array
Извлекает записи из одной HTML-таблицы, JSON-массива, массива строк или одного листа документа. CSV сначала прочитайте через documents()->fromBytes() или sources()->document(). PDF без таблицы и произвольные карточки страницы нужно предварительно преобразовать в строки.
$result = $ctx->ai()->extract([
['Артикул', 'Цена', 'Валюта'],
['001', '1 250,50', 'RUB'],
], [
'sku' => ['type' => 'string', 'unique' => true],
'price' => ['type' => 'decimal', 'min' => 0],
'currency' => 'string',
], ['key' => 'supplier-prices', 'expected_rows' => 1]);
foreach ($result['records'] as $record) {
$ctx->emit($record, $record['sku']);
}
records всегда содержит свежие значения. cache_hit означает повторное использование проверенного правила, ai_used показывает обращение к модели. Это кэш алгоритма, а не кэш вчерашних цен.
Типы полей: string, decimal, integer, boolean. Доступны required (по умолчанию true), unique, min, max. Поле role указывает назначение: sku, name, price, stock, currency, url. Известные русские и английские заголовки распознаются по закрытому словарю. Произвольные названия полей можно связать с одной из этих ролей.
Если заголовки неоднозначны, укажите column в каждом поле и header_row в options. Оба номера начинаются с нуля. Полностью явное сопоставление не вызывает модель даже в первый раз. Вручную выбранные колонки нужно проверять владельцу сценария.
При создании и восстановлении правила модель получает только коды назначения колонок и типы ячеек. Текст писем, имена, цены, адреса, названия колонок и другие исходные значения ей не передаются. Модель возвращает ограниченный план с числовыми индексами; произвольный сгенерированный код не исполняется. Непроверенное правило не сохраняется. Не больше двух предложений модели на восстановление; не больше восьми AI-обращений в одном прогоне.
Повторное извлечение проверяет все строки: обязательность, типы, диапазоны, уникальность и ширину таблицы. Если формат сменился, проверяется новое сопоставление. Если записей стало меньше 70% прежнего проверенного количества, требуется проверка полноты и явный expected_rows. Это сигнал возможной проблемы, а не доказательство потери данных. Без контрольного количества из самого источника система не может доказать, что сайт прислал весь каталог.
Кэш изолирован по пространству, сайту, ключу, структуре и версии механизма проверки. Он хранится 180 дней после последнего успешного применения. Каждое успешное применение продлевает срок; ошибка не продлевает. Срок истёк: правило создаётся заново. Прежние проверенные варианты разметки могут использоваться повторно.
При попадании в кэш AI-токены и новый AI-резерв не создаются. Генерация и восстановление используют обычный AI-бюджет по фактическому расходу; время выполнения и другие ресурсы оплачиваются как обычно. Дополнительная модель на каждом попадании в кэш не вызывается.
Лимит одного вызова: 2 МБ входа, до 5000 строк, 100 колонок и 30 полей. Большие источники обрабатывайте частями с явной проверкой числа записей каждой части. Числа с неоднозначными разделителями тысяч, валютными суффиксами или более чем двумя знаками дробной части нужно предварительно нормализовать. Неполный документ, несколько листов, объединённые ячейки или ошибки формул требуют явного выбора проверенных строк.