Почему ваш AI-агент до сих пор просит денег?
Сначала честно: вы используете Perplexity, GPT с веб-серфингом или прикручиваете SerpAPI к LangChain. Это работает, пока в один прекрасный день приходит счёт на $500. Или пока OpenAI решает поменять тарифы. Или пока ваш агент в офлайн-режиме просто разводит руками: «нет доступа к данным».
Меня это бесило. В 2024-м я написал свою первую Agentic RAG систему, которая тянула данные из внешнего API. К 2025-му стало ясно: зависимость от облака — это раковая опухоль для любого продакшн-агента. Задержки, цензура, простои. И главное — вы не контролируете кэш. Каждый запрос бьётся в один и тот же сервер.
В середине 2026 года я наконец-то нашёл комбинацию, которая реально работает. Без облачных ключей. Без ежемесячной подписки. Без молитв на аптайм. Только ваш сервер (или даже Raspberry Pi 5) и четыре компонента.
Disclaimer: В статье много кода и команд. Если вы ищете «просто включил и поехало» — это не сюда. Это гайд для тех, кто хочет понять, как работает каждый винтик.
Анатомия агента: четыре кита
Локальный веб-исследовательский агент — это не монолит, а пайплайн из четырёх блоков, каждый из которых решает свою проблему:
- Поисковик — куда агент шлёт запросы. Мы берём SearXNG, потому что он агрегирует десятки поисковых систем, а не одну.
- Кэш — чтобы не долбить поисковик одинаковыми запросами. Тут нужен Hister — лёгкий HTTP-кэш на Rust, который в 2026-м стал стандартом для self-hosted агентов.
- Сборщик контента — парсинг страниц. Используем Scrapling (библиотека Python) или Playwright для JS-heavy сайтов.
- Мозг — локальная LLM. Мы не тащим облачные модели. Берём Llama 3.3-70B от Meta или Qwen 2.5-72B, запущенные через llama.cpp или vLLM.
Соединяет их оркестратор — простой Python-скрипт с инструментами (Tools) или готовый фреймворк Strands Agents SDK, который мы уже разбирали. Только вместо Exa ставим SearXNG.
Шаг 1. Ставим SearXNG — метапоиск на свои рельсы
SearXNG — это как Google, но без рекламы, без слежки и с возможностью расширять. Вы поднимаете его в Docker за пять минут.
# docker-compose.yml (версия 2026 года, включает Hister в соседнем контейнере)
services:
searxng:
image: searxng/searxng:2025.12.31
ports:
- "4000:8080"
environment:
- SEARXNG_BASE_URL=https://search.yourdomain.com
- SEARXNG_CACHE_TYPE=redis
- SEARXNG_REDIS_URL=redis://redis:6379/0
volumes:
- ./searxng-config:/etc/searxng
restart: always
redis:
image: redis:7-alpine
restart: alwaysГлавное — отключить все внешние провайдеры, которые требуют ключи (например, Google Custom Search). В конфиге /etc/searxng/settings.yml оставьте только engines, которые работают без API: DuckDuckGo, Qwant, Brave Search (через HTML).
Ошибка №1: Не ставьте SEARXNG_SECRET_KEY в открытую. Используйте .env. Иначе любой может дёргать ваш searxng снаружи.
Проверить: curl http://localhost:4000/search?q=latest+ai+papers — должен вернуть JSON с результатами.
Шаг 2. Hister — кэш, который режет латентность на 80%
Проблема SearXNG: каждый запрос выполняется 1-3 секунды. Если ваш агент делает 20 запросов для одного ответа, пользователь уснёт. Hister решает это, кэшируя ответы на лету.
Hister (версия 0.6.0, релиз июня 2026) — это обратный прокси-кэш, написанный на Rust. Он понимает HTTP-заголовки, поддерживает TTL по-урлам и умеет работать с Redis.
# Установка через бинарник (амд64)
wget https://github.com/hister-proxy/hister/releases/download/v0.6.0/hister-linux-amd64
chmod +x hister-linux-amd64
./hister-linux-amd64 --port 8081 --upstream http://localhost:4000 --redis redis://localhost:6379Теперь всё, что шло на SearXNG, идёт через Hister. Первый запрос — медленный, второй — из кэша. Пример конфига:
# hister.yaml
server:
listen: :8081
upstream: http://localhost:4000
cache:
redis:
addr: localhost:6379
ttl: 3600 # час для одинаковых запросов
rules:
- path: /search
ttl: 7200 # для поиска — 2 часаПосле запуска агент будет обращаться к http://localhost:8081/search. Время ответа для кэшированных запросов падает с 1500 мс до 5 мс. Мы писали об этом в материале про сжатие латентности — только тогда мы использовали Redis напрямую, Hister даёт тот же эффект, но проще.
Шаг 3. Сборщик контента: Scrapling + Playwright
SearXNG возвращает ссылки и сниппеты, но агент хочет читать полный текст. Для этого нужен парсер. Scrapling (библиотека 2025-2026) отлично вытаскивает чистый текст из HTML, а если сайт использует JavaScript — Playwright.
# Пример функции извлечения контента
import asyncio
from scrapling import Fetcher
from playwright.async_api import async_playwright
async def extract(url: str) -> str:
fetcher = Fetcher()
resp = await fetcher.get(url)
if resp.status == 200 and not "text/html" in resp.headers.get("content-type", ""):
# Если не HTML — используем Playwright
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url, wait_until="domcontentloaded")
content = await page.content()
await browser.close()
return content
else:
return resp.textВажный момент: Scrapling по умолчанию использует aiodns и быстрее requests. Но если сайт блокирует — добавляйте User-Agent и задержки. В 2026-м большинство сайтов уже не любят ботов. Используйте ротацию User-Agent (список из 10-15 строк).
Подробнее про выбор скрапера — в нашем гайде по SearXNG + Scrapling.
Шаг 4. Мозг: локальная LLM с функциями
Теперь самое интересное. Локальные модели 2026 года уже не уступают GPT-4o в задачах с инструментами. Llama 3.3-70B (июнь 2026) и Qwen 2.5-72B дают отличные результаты при квантовании Q4_K_M. Ставим vLLM или llama.cpp.
# Запуск vLLM с моделью (требуется GPU, минимум 24GB VRAM)
docker run --gpus all -p 8000:8000 \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.3-70B-Instruct-GGUF \
--served-model-name agent-llm \
--api-key localkeyДаём агенту инструменты: search (поиск через Hister->SearXNG), visit (извлечение текста), think (анализ). LLM генерирует вызовы в специальном формате (напр., JSON).
# Оркестратор на Python (упрощённо)
import requests
def search(query: str) -> list:
resp = requests.get(f"http://localhost:8081/search?q={query}&format=json")
return resp.json()["results"]
def visit(url: str) -> str:
# вызов async extract
return asyncio.run(extract(url))
def answer(prompt: str) -> str:
payload = {
"model": "agent-llm",
"messages": [{"role": "user", "content": prompt}],
"tools": [search, visit]
}
# vLLM поддерживает инструменты через OpenAI-compatible API
resp = requests.post("http://localhost:8000/v1/chat/completions", json=payload, headers={"Authorization": "Bearer localkey"})
return resp.json()["choices"][0]["message"]["content"]Полный цикл: пользователь задаёт вопрос -> LLM решает, что нужно искать -> агент вызывает search() -> получает результаты -> может вызвать visit() для каждого -> LLM анализирует и даёт ответ. Всё это без единого внешнего API.
Нюансы, которые сломают ваш пайплайн
После трёх лет с local-first агентами вот что бесит:
- Сайты с Cloudflare. SearXNG через DuckDuckGo часто получает капчу. Решение: купить пул резидентных прокси (всё равно дешевле платного API поиска) или использовать Browser-use агента в WASM — он эмулирует браузер, но жрёт память.
- Размер контекста. Собранные тексты могут быть огромными. Придётся резать или использовать RAG. Рекомендую подход, описанный в руководстве по Agentic RAG.
- Скорость. Даже с Hister, извлечение контента с 3-5 страниц может занять 10-20 секунд. Асинхронность — must have. Я использую asyncio.gather.
- Хранение кэша. Hister в Redis — хорошо, но если Redis упадёт, кэш потеряется. Для продакшена поднимите Redis Cluster или используйте файловый кэш (Hister поддерживает и такой).
Что дальше? 2027 год — без компромиссов
Уже сейчас локальный стек догоняет облачный по качеству. Model-as-a-Service умирает — все крупные вендоры выпускают открытые модели, а сообщество делает ещё более эффективные рантаймы (llama.cpp, TensorRT-LLM). Hister в 2026-м обрастает плагинами для кэширования эмбеддингов.
Моя рекомендация: не ждите, пока Perplexity подорожает. Соберите своего агента сегодня. Лишним не будет — вы хотя бы перестанете платить за каждый запрос. А когда облачные API снова упадут (а они упадут), ваш локальный робот продолжит молотить.
P.S. Если хотите углубиться в тему — посмотрите, как Яндекс построил DeepResearch — там похожие принципы, но с гигантским кэшем. Или почитайте про Agent Browser Workspace — готовую альтернативу Perplexity для self-hosted сценариев.