Як надати вашому Laravel AI agent доступ до актуальних знань із вебу в реальному часі

Перекладено ШІ 0 JustSteveKing 05 серпня, 2026

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

Одна з головних переваг Laravel AI SDK — відсутність прив’язки до конкретного провайдера. Ви можете легко замінити OpenAI на Anthropic або додати Gemini як резервний варіант (failover), майже не змінюючи код агента. Це головна ідея інструменту, і вона загалом працює.

Поки вашому агенту не знадобиться доступ до вебу.

Обіцянка незалежності має вразливе місце

SDK пропонує два інструменти для роботи з мережею: WebSearch та WebFetch. Вони зручні: кілька рядків коду — і агент шукає інформацію або завантажує сторінку. Проте вони не є частиною уніфікованого шару SDK. Їх реалізують самі AI-провайдери, тому доступність цих інструментів повністю залежить від обраної моделі.

WebSearch працює з Anthropic, OpenAI, Gemini та OpenRouter. WebFetch підтримують лише Anthropic та Gemini. Якщо у вашому ланцюжку відмовостійкості є Groq, DeepSeek, Mistral або xAI, і один із них стане активним, агент «тихо» втратить можливість переглядати веб. Без помилок чи попереджень — він просто перестане цитувати джерела або помічати зміни на сторінках.

Виявити таке в продакшені неприємно. Ви налаштовували failover саме для того, щоб уникнути збоїв через ліміти запитів або вимкнення сервісів, а виявилося, що один із резервних провайдерів просто не має потрібної функції.

Навіть коли це працює, результат досить поверхневий

Забудьте на мить про проблеми з провайдерами. Навіть там, де WebSearch та WebFetch доступні, ви отримуєте «сирі» дані: результати пошуку або контент сторінки, які модель має проаналізувати самостійно. Тут немає чіткої схеми чи гарантованого відстеження цитат. Якщо вам потрібна структурована відповідь із посиланнями на джерела, цей аналіз відбувається всередині інференсу моделі, а не на рівні, який ви можете контролювати чи протестувати.

Для багатьох завдань цього достатньо. Але для досліджень, конкурентного аналізу або будь-яких випадків, де користувач може запитати «звідки ця інформація?», — цього замало.

Створіть власний інструмент, незалежний від провайдера

Вихід — відмовитися від нативних інструментів провайдера на користь кастомного рішення. Використовуйте зовнішній API замість функцій моделі. Саме для цього в Laravel AI SDK існує Tool class.

Пакет juststeveking/tabstack надає клієнт для такої реалізації. Метод agent()->research() приймає запитання, шукає інформацію в різних джерелах, синтезує відповідь і повертає звіт із цитатами за один виклик.

Оскільки пакет не має вбудованої інтеграції з Laravel, спершу зареєструйте його в service provider:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use JustSteveKing\Tabstack\Tabstack;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(Tabstack::class, fn () => Tabstack::make(
            apiKey: config('services.tabstack.key'),
        ));
    }
}

Додайте ключ у config/services.php:

'tabstack' => [
    'key' => env('TABSTACK_API_KEY'),
],

Тепер створимо сам інструмент. Він обгортає agent()->research() і повертає агенту звіт зі списком джерел:

<?php

namespace App\Ai\Tools;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use JustSteveKing\Tabstack\Requests\AgentResearch;
use JustSteveKing\Tabstack\Requests\ResearchMode;
use JustSteveKing\Tabstack\Tabstack;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;
use Stringable;

class WebResearch implements Tool
{
    public function __construct(
        private readonly Tabstack $tabstack,
    ) {}

    public function description(): Stringable|string
    {
        return 'Answers a question by researching multiple sources on the web and returns a synthesized, cited report. Use this when you need current information not in your training data.';
    }

    public function handle(Request $request): Stringable|string
    {
        $result = $this->tabstack->agent()->research(
            params: new AgentResearch(
                query: $request['query'],
                mode: ResearchMode::Fast,
            ),
        )->result();

        $sources = collect($result->metadata->get('citedPages', []))
            ->map(fn ($page) => "- {$page['title']}: {$page['url']}")
            ->implode("\n");

        return "{$result->report}\n\nSources:\n{$sources}";
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'query' => $schema->string()
                ->required()
                ->description('The question to research'),
        ];
    }
}

Виклик ->result() очікує завершення стріму і повертає типізований ResearchResult. Це спрощує метод handle. Якщо ви хочете транслювати прогрес агенту в реальному часі, клієнт підтримує ->each(), але для виклику інструменту зазвичай краще дочекатися повного результату.

Підключіть його до будь-якого агента через метод tools:

<?php

namespace App\Ai\Agents;

use App\Ai\Tools\WebResearch;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;

class MarketAnalyst implements Agent, HasTools
{
    use Promptable;

    public function instructions(): string
    {
        return 'You help analyze markets and competitors. Use the research tool whenever you need current information. Always mention your sources.';
    }

    public function tools(): iterable
    {
        return [
            app(WebResearch::class),
        ];
    }
}

Тепер змінюйте провайдерів як завгодно:

$response = (new MarketAnalyst)->prompt(
    'What are the current pricing trends for cloud browser automation APIs?',
    provider: [Lab::OpenAI, Lab::Anthropic, Lab::Groq],
);

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

Чому це краще за звичайний fetch?

Схоже рішення можна було б створити на базі WebFetch, вказавши конкретний URL. Але це працює лише тоді, коли ви знаєте, на якій сторінці шукати відповідь. Метод /research створений для випадків, коли джерело невідоме: він сам обирає потрібні сайти, аналізує їх та узагальнює дані. Це складніший процес, який вбудовані інструменти SDK навіть не намагаються охопити.

Підсумки

Незалежність від провайдерів у Laravel AI SDK — це чудово, поки ви не стикаєтеся з інструментами, які цю незалежність порушують. Доступ до вебу не має зникати залежно від того, яка модель обробляє запит. Створення власного Tool class на базі API гарантує стабільну роботу вашого агента.

Якщо ви розробляєте застосунки на Laravel AI SDK і хочете мати такий інструмент під рукою, раджу почати з juststeveking/tabstack на Packagist.

Популярні

Інше, що варто прочитати

15 Оновлено 26 червня, 2026

Claude Agent тепер інтегрований в AI Assistant для PhpStorm

Ви коли-небудь задумувалися, як полегшити свою роботу в Laravel? У нашій статті ми розглядаємо, як інтеграція Claude Code в PhpStorm може підвищити вашу продуктивність, спростивши процес написання коду та навчання нових розробників. Читайте далі, щоб дізнатися більше про переваги та функціональність цього потужного поєднання

17 Оновлено 26 червня, 2026

Обробка геопросторових даних за допомогою Laravel Magellan

Ви готові відкрити нові горизонти у роботі з геопросторовими даними в Laravel? Дізнайтеся, як за допомогою PostGIS та пакету Laravel-Magellan можна легко зберігати, запитувати та маніпулювати інформацією про розташування, перетворюючи ваші проекти на вражаючі рішення у сфері картографії та геолокації!

10 Оновлено 26 червня, 2026

Усе, що ми знаємо про Laravel 12

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