Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Події
Інше
Про нас
Новини 27 серпня 2026

Laravel AI: завантаження інструментів на вимогу з ToolSearch

Раніше кожен інструмент, який експонував агент, надсилався провайдеру при кожному запиті. Для агента з чотирма інструментами це прийнятно, але для агента з тридцятьма визначення перетворюються на велику фіксовану вартість кожного виклику, а модель має більше варіантів вибору, що робить її рішення менш точним.

Laravel AI v0.11.0 додає спосіб відкласти частину цього каталогу. Контрибутор @behzadsp реалізував обгортку ToolSearch у pull request #697, яка відображається на вже існуючий пошук інструментів, що пропонують OpenAI та Anthropic: провайдер отримує пошуковий запис плюс відкладені визначення і завантажує повне визначення інструменту тільки тоді, коли вирішує його використати.

Обгортання інструментів для відкладеного завантаження

ToolSearch приймає інструменти для відкладення як перший аргумент. Все, що залишається поза обгорткою, надсилається так само, як і раніше:

use Laravel\Ai\Providers\Tools\ToolSearch;

public function tools(): iterable
{
    return [
        new LookupAccount,
        new ToolSearch(tools: [
            new IssueRefund,
            new ChangePlan,
            new ResendInvoice,
            new TransferSeat,
            // ...решта каталогу back office
        ]),
    ];
}

Самі інструменти не потребують жодних змін. Немає інтерфейсу для реалізації і немає опцій провайдера для кожного інструменту окремо, тому один і той самий клас інструменту може бути відкладеним в одному агенті та надісланим одразу в іншому.

Стратегія пошуку Anthropic є другим аргументом конструктора - regex або bm25, яка валідується при створенні об'єкта:

new ToolSearch(tools: [new IssueRefund, new ChangePlan], strategy: 'bm25');

Будь-яке інше значення викидає InvalidArgumentException там, де ви його написали, а за відсутності аргументу надсилається regex. Інші поля пошукового запису провайдера, включно з cache_control, передаються через withProviderOptions() на обгортці. У Anthropic обгортка - єдине місце, де може бути точка розриву кешу, оскільки їхній API повертає 400 для будь-якого інструменту, що містить і defer_loading: true, і cache_control. Пакет розміщує опції провайдера тільки на пошуковому записі і ніколи на відкладених визначеннях, тому таку комбінацію тут створити неможливо.

Що отримує кожен провайдер

На OpenAI обгортка перетворюється на запис {"type": "tool_search"}. На Anthropic вона стає версіонованим типом tool_search_tool_regex_20251119 або еквівалентом bm25. В обох випадках відкладені інструменти йдуть слідом як звичайні визначення з defer_loading: true, що відображає те, як обидва провайдери моделюють це нативно: один пошуковий інструмент плюс відкладення для кожного інструменту.

Коли модель викликає відкладений інструмент, шлюз вирішує його за іменем зсередини обгортки точно так само, як вирішує інструмент верхнього рівня, тому виконання і результати поводяться однаково.

Обидва провайдери по-різному звітують про пошук у відповіді. Anthropic повертає блок server_tool_use, що містить патерн або запит, який шукав Claude, потім блок tool_search_tool_result зі списком tool_reference записів для знайденого, і розгортає їх у повні визначення до того, як Claude їх побачить. Цей блок не є викликом інструменту, на який ви відповідаєте: повернення tool_result для його srvtoolu_ ID призводить до відхилення запиту Anthropic. OpenAI вирішує розміщений пошук всередині того ж виклику і звітує про це як елементи tool_search_call та tool_search_output. Laravel AI відображає тільки бік запиту, тому жодна форма не парситься в щось, що експонує SDK.

Нічого не повинно залишатися поза обгорткою. ToolSearch, що містить кожен інструмент агента, відображається однаково, з пошуковим записом як єдиним визначенням, що надсилається без відкладення.

Перевірка того, що було надіслано

Створіть фейковий HTTP-виклик і інспектуйте масив tools. Відкладене визначення містить defer_loading: true, а визначення верхнього рівня - ні:

use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;

Http::fake(['*' => Http::response([
    'id' => 'resp_123',
    'status' => 'completed',
    'model' => 'gpt-5.4',
    'output' => [[
        'type' => 'message',
        'status' => 'completed',
        'content' => [['type' => 'output_text', 'text' => 'ok']],
    ]],
    'usage' => ['input_tokens' => 1, 'output_tokens' => 1],
])]);

(new SupportAgent)->prompt('Refund order 41');

Http::assertSent(function (Request $request) {
    $tools = collect(data_get($request->data(), 'tools'));
    $deferred = $tools->firstWhere('name', 'IssueRefund');
    $plain = $tools->firstWhere('name', 'LookupAccount');
    
    return $tools->contains(fn ($tool) => ($tool['type'] ?? null) === 'tool_search')
        && ($deferred['defer_loading'] ?? false) === true
        && ! isset($plain['defer_loading']);
});

Імена беруться з ToolNameResolver, який повертає basename класу інструменту, якщо клас не визначає метод name(). На Anthropic те саме твердження справджується з tool_search_tool_regex_20251119 замість tool_search, а фейкове тіло має форму відповіді Anthropic, а не OpenAI.

Агент, єдиним інструментом якого є порожня обгортка, не надсилає ключа tools взагалі, і не надсилає tool_choice.

Підтримка провайдерів та обмеження

Тільки OpenAiProvider та AnthropicProvider реалізують маркер SupportsToolSearch. Всі інші провайдери викидають LogicException до того, як запит виходить, а не відкидають інструменти обгортки. Це стосується Azure, шлюзів chat-completions (Groq, DeepSeek, Mistral, OpenRouter), Gemini, xAI, Bedrock та Ollama. Чи підтримує конкретна модель це, перевіряється API провайдера, а не локально.

Три додаткові правила керують використанням обгортки:

  • Перевірка підтримки виконується щоразу, коли присутня обгортка, включно з порожньою, тому неправильно налаштований провайдер викидає виняток у розробці, а не тоді, коли список відкладених вперше стає непорожнім у продакшені.
  • На один запит може бути зареєстрована тільки одна обгортка. Друга ToolSearch викидає виняток.
  • На OpenAI пакет відхиляє ToolSearch у поєднанні з store=false, а не дозволяє запиту провалитися на API.

Порожня обгортка на підтримуваному провайдері нічого не генерує.

Бюджетування кроків

Коли ви не встановлюєте maxSteps самостійно, SDK виводить значення за замовчуванням з того, скільки інструментів має агент. Якби обгортка рахувалася як один інструмент, обгортання двадцяти інструментів зменшило б бюджет кроків за замовчуванням до частки того, що мав той самий агент раніше, і виконання зупинялося б до завершення роботи агента.

ToolSearch::budget() розгортає кожну обгортку в кількість її відкладених інструментів, тому бюджет кроків не змінюється залежно від того, як упаковані інструменти.

Коли використовувати

Цикл генерації рахує один крок на кожен round-trip до провайдера, і він робить інший round-trip тільки тоді, коли модель викликає інструмент, який SDK виконує локально. Провайдер завантажує відкладене визначення всередині свого власного виклику, тому пошук ніколи не додає власного кроку.

Відкладений інструмент, який викликає модель, виконується як звичайний крок, так само як він виконувався б без обгортки. Обгортання змінює те, що повідомляється провайдеру про інструмент, а не те, як він виконується.

Ви економите токени промпта і витрачаєте час всередині виклику провайдера. Зважте це проти розміру каталогу. Чотири інструменти не надсилають достатньо визначень, щоб варто було відкладати, а модель має шукати, перш ніж викликати один.

Два обмеження застосовуються незалежно від розміру каталогу. Тільки OpenAI та Anthropic підтримують обгортку, тому ланцюг failover викидає виняток, коли досягає будь-якого іншого провайдера. Розміщений пошук OpenAI також вимагає збережених відповідей, тому додаток, який встановлює store=false для збереження промптів поза серверами провайдера, не може використовувати його там.

Клієнтський пошук інструментів

Ранжування каталогу всередині бібліотеки, яке працювало б на кожному провайдері, є окремою функцією. Pull request #805 запропонував це поряд з цим pull request і був закритий без злиття, тому це не поставляється сьогодні. ToolSearch - це розміщена обгортка: провайдер виконує пошук, і тільки OpenAI та Anthropic підтримують це.

Додаткова інформація

ToolSearch вийшов у версії v0.11.0 разом з подіями життєвого циклу виконання та ширшим failover провайдерів. Той самий pull request також додав stateless відтворення виводу для OpenAI, яке захоплює повний упорядкований вивід відповіді та відтворює його при продовженні, коли зберігання відповідей вимкнено.

Для ознайомлення з пакетом дивіться анонс AI SDK та наше висвітлення схвалення інструментів human-in-the-loop. Вихідний код знаходиться в репозиторії laravel/ai на GitHub.

2

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

whereBinary()
Новини 28 серпня 2026

whereBinary(): регістрозалежні запити MySQL у Laravel

Laravel 13.27 додає новий метод whereBinary() для точного побайтового порівняння рядків у MySQL. Він вирішує проблему, коли стандартне collation utf8mb4_unicode_ci ігнорує регістр, акценти та пробіли при порівнянні токенів, slug-ів та інших критичних даних.

Laravel 13.27
Новини 27 серпня 2026

Laravel 13.27: маскування параметрів запитів, бінарні порівняння та пасимістичні блокування

У Laravel 13.27 з'явилася можливість приховувати параметри запитів вException-повідомленнях, нові методи whereBinary() для точних порівнянь, refreshForUpdate() для перезавантаження моделі під блокуванням та багато інших покращень безпеки й продуктивності.

2

Вакансії за темою

Softprom
18 днів тому

FullStack Developer (PHP Laravel + React) for Automation and AI

FullStack розробник для проектів автоматизації та AI. Розробка backend на PHP Laravel з мікросервісною архітектурою, інтеграція ERP/CRM систем (NetSuite, HubSpot), та frontend на React з AI-функціоналом (chatbots, генерація контенту). Потребує 5+ років PHP, 3+ років Laravel на рівні архітектури, досвід мікросервісів, OOP, REST API, Websockets.

Пакети за темою

Docudoodle

genericmilk/docudoodle

Генерування документації для вашого Laravel-додатку за допомогою OpenAI.

159 2.3.0 13 6

Checkbox.in.ua SDK

kolirt/checkbox.in.ua-sdk

PHP SDK для Checkbox.in.ua: робота з касами, змінами та фіскальними чеками через REST API. Альтернативна реалізація клієнта ПРРО Checkbox для проєктів без прив'язки до Laravel.

5 0.0.6 1