CLI-агент для поиска и ответов на естественном языке поверх SearxNG, MCP и подключаемых LLM.
Маршрутизирует запросы, вызывает веб-поиск только когда это действительно нужно, делает двухступенчатый реранк результатов и возвращает аккуратный терминальный ответ с источниками и таймингом пайплайна.
Проект состоит из трёх связанных частей:
- терминальный клиент с интерактивным CLI-интерфейсом;
- агент с роутингом
поиск / прямой ответ; - retrieval-пайплайн поверх SearxNG, FlashRank,
trafilaturaи Jina reranker.
Внутренне это MCP-приложение: терминальный клиент говорит с MCP-сервером агента, а агент, в свою очередь, вызывает внутренний MCP search tool для SearxNG. Такое разделение упрощает эксперименты с пайплайном, LLM-провайдерами и интерфейсом, не смешивая эти слои в одном модуле.
> Что такое Model Context Protocol?
╭─ Qwen 2.5 ───────────────────────────────────────────────────────────────────────────────╮
│ │
│ Model Context Protocol (MCP) — это открытый протокол прикладного уровня для │
│ взаимодействия языковых моделей с внешними инструментами, данными и │
│ удаленными или локальными системами. │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Источники ──────────────────────────────────────────────────────────────────────────────╮
│ │
│ [1] docs.anthropic.com │
│ https://docs.anthropic.com/en/docs/agents-and-tools/mcp │
│ │
│ [2] ru.wikipedia.org │
│ https://ru.wikipedia.org/wiki/Model_Context_Protocol │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────╯
> Объясни психологию Пиаже
01:50:07 · Получен запрос пользователя: 'Объясни психологию Пиаже'
01:50:08 · Второй пайплайн | Решение агента | use_search=True
01:50:11 · SearxNG HTTP | query='Объясни психологию Пиаже' | found=21 | returning=20
01:50:12 · Retrieval pipeline | query='Объясни психологию Пиаже' | stage1=20 -> top=10
01:50:14 · Retrieval pipeline | query='Объясни психологию Пиаже' | fulltext_extracted=9/10
01:50:17 · Retrieval pipeline | query='Объясни психологию Пиаже' | stage2=9 -> final=2
╭─ Тайминг запроса ────────────────────────────────────────────────────────────────────────╮
│ │
│ Этап Время │
│ ────────────────────── ────── │
│ Решение агента 0.81 с │
│ Поиск SearxNG 2.34 с │
│ Первичный реранк 0.29 с │
│ Извлечение и обработка 3.02 с │
│ Финальный реранк 1.12 с │
│ Суммаризация 1.23 с │
│ Всего 8.81 с │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────╯
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtdocker compose -f searxng-docker/docker-compose.yml up -dcp .env.example .envЕсли используется локальная модель через Ollama, убедитесь, что сервис поднят и нужная модель доступна:
ollama pull qwen2.5:3bpython src/main.py| Провайдер | Что делает | Когда использовать |
|---|---|---|
direct |
отключает LLM и оставляет только retrieval/поиск | отладка пайплайна поиска |
ollama |
использует локальную модель через Ollama API | локальные эксперименты и офлайн-сценарии |
openrouter |
использует облачную модель через OpenRouter | когда нужен внешний провайдер или более сильная модель |
Команды CLI:
| Команда | Назначение |
|---|---|
/provider |
показать текущий провайдер |
/provider <name> |
переключить провайдера |
/provider <name> <model> |
переключить провайдера и сразу задать модель |
/model <name> |
сменить модель текущего провайдера |
/status |
показать активную конфигурацию |
/help |
вывести справку |
/exit |
завершить сессию |
Используемая схема:
- Запрос уходит в SearxNG и получает начальный пул документов.
- Первый реранк выполняется через
FlashRank(ms-marco-MultiBERT-L-12). - Для top-k документов скачиваются страницы и извлекается основной текст через
trafilatura. - Второй реранк выполняется через
jinaai/jina-reranker-v2-base-multilingual. - В итог идут самые релевантные документы, которые затем суммаризирует агент.
В agent mode этот пайплайн запускается только если роутер решает, что прямого ответа без веб-поиска недостаточно.
Ключевые переменные окружения:
| Переменная | По умолчанию | Назначение |
|---|---|---|
LLM_PROVIDER |
ollama |
активный провайдер: direct, ollama, openrouter |
OLLAMA_MODEL_NAME |
qwen2.5:3b |
локальная модель Ollama |
OPENROUTER_MODEL |
openai/gpt-4o-mini |
модель OpenRouter |
SEARXNG_INSTANCES |
http://localhost:8080 |
один или несколько SearxNG URL |
SEARXNG_PARALLELISM |
3 |
размер внутреннего пула MCP-клиентов поиска |
RETRIEVAL_INITIAL_RESULTS_N |
20 |
размер первичного пула документов |
RETRIEVAL_STAGE1_TOP_K |
5 |
сколько документов оставить после FlashRank |
RETRIEVAL_STAGE2_TOP_K |
2 |
сколько документов оставить после второго реранка |
SMART_PIPELINE_STAGE1_TOP_K |
10 |
top-k для агентного retrieval-пайплайна |
SMART_PIPELINE_FINAL_TOP_K |
2 |
сколько документов суммаризировать в agent mode |
LLM_TIMEOUT |
120 |
таймаут запросов к модели |
LLM_MAX_OUTPUT_TOKENS |
2048 |
целевой лимит длины ответа |
SHOW_LOGS |
1 |
включить пошаговые логи и таблицу тайминга |
Полный пример .env
# --- LLM provider ---
LLM_PROVIDER=ollama
# --- Ollama ---
OLLAMA_MODEL_URL=http://localhost:11434
OLLAMA_MODEL_NAME=qwen2.5:3b
# --- OpenRouter ---
OPENROUTER_API_KEY=
OPENROUTER_MODEL=openai/gpt-4o-mini
OPENROUTER_BASE_URL=https://openrouter.ai/api
# --- SearxNG ---
SEARXNG_INSTANCES=http://localhost:8080
SEARXNG_DEFAULT_LANGUAGE=ru
SEARXNG_DEFAULT_CATEGORIES=general
REQUEST_TIMEOUT=10
SEARXNG_PARALLELISM=3
# --- Retrieval ---
RETRIEVAL_INITIAL_RESULTS_N=20
RETRIEVAL_STAGE1_TOP_K=5
RETRIEVAL_STAGE2_TOP_K=2
RETRIEVAL_DOC_MAX_CHARS=6000
RETRIEVAL_MIN_EXTRACTED_CHARS=300
SMART_PIPELINE_STAGE1_TOP_K=10
SMART_PIPELINE_FINAL_TOP_K=2
# --- LLM runtime ---
LLM_TIMEOUT=120
LLM_MAX_OUTPUT_TOKENS=2048
# --- Logging ---
SHOW_LOGS=1
LOG_LEVEL=INFO
LOG_CONSOLE_LEVEL=INFO
LOG_FILE=logs/results.logЕсли SHOW_LOGS=1, приложение:
- печатает шаги пайплайна в реальном времени;
- сохраняет подробный лог в
logs/results.log; - показывает после ответа таблицу с длительностью этапов.
Это в первую очередь полезно для сравнения конфигураций retrieval, оценки времени на каждом шаге и отладки поведения роутера.
config/
settings.py # конфигурация через .env
src/
agent/ # роутинг, прямой ответ, суммаризация
interfaces/ # терминальный UI и MCP-клиент
llm/ # адаптеры direct / Ollama / OpenRouter
mcp_server/ # MCP-сервер агента и внутренний search tool
searxng/ # HTTP-клиент, MCP-клиент и retrieval pipeline
utils/ # runtime и логирование
main.py # точка входа
searxng-docker/
docker-compose.yml # локальный SearxNG
- Model Context Protocol для взаимодействия между клиентом, агентом и search tool
- SearxNG как метапоисковый backend
- Ollama / OpenRouter как LLM-провайдеры
- FlashRank для первого реранка
- Sentence Transformers / Jina reranker для второго реранка
- Trafilatura для извлечения основного текста страниц
- Rich для терминального интерфейса