Files
openspec-lab/openspec/changes/local-extractor/design.md
T

2.9 KiB

Design: local-extractor

Approach

Расширить существующий /opt/hermes/.hermes/scripts/tavily_extract_proxy.py:

  • В local-режиме (нет --socks) сервер НЕ проксирует в Tavily, а сам извлекает: для каждого URL делает HTTP-запрос (httpx, при --local-socks через SOCKS5-туннель) и конвертирует HTML → Markdown через trafilatura (включён в venv).
  • Формат ответа в точности повторяет Tavily /extract: {"results":[{url,title,raw_content,metadata}], "failed_results":[{url,error}], "failed_urls":[...]} — Hermes-провайдер (plugins/web/tavily/provider.py:_normalize_tavily_documents) обрабатывает его без изменений.
  • Режимы взаимозаменяемы через аргументы CLI:
    • --socks 127.0.0.1:1080 — forward в Tavily (как сейчас в systemd)
    • --local или ничего — локальная экстракция
    • --local-socks 127.0.0.1:1080 — локальная, но страницы через туннель
  • systemd-юнит указать на tavily_extract_proxy.py (уже сделано, forward-режим).

Files

  • /opt/hermes/.hermes/scripts/tavily_extract_proxy.py — добавлены _fetch_page, _extract_local, _extract_local_batch, --local-socks
  • /opt/hermes/.hermes/hermes-agent/venv/ — установлен trafilatura 2.2.0
  • /etc/systemd/system/tavily-proxy.service — ExecStart → tavily_extract_proxy.py (forward), --socks 127.0.0.1:1080

Commands

# Локальный режим (тест)
python3 /opt/hermes/.hermes/scripts/tavily_extract_proxy.py --port 8972 --local
curl -s -X POST http://127.0.0.1:8972/extract -H 'Content-Type: application/json' \
  -d '{"urls":["https://example.com"]}'   # → {"results":[...]}

# Переключение systemd на local (когда решено отказаться от облака)
# в /etc/systemd/system/tavily-proxy.service: ExecStart → ... --port 8971 --local
# sudo systemctl daemon-reload && sudo systemctl restart tavily-proxy

Rollback

# Вернуть forward-режим:
# ExecStart → ... --socks 127.0.0.1:1080 --upstream https://api.tavily.com
sudo systemctl daemon-reload && sudo systemctl restart tavily-proxy

Risks

  • trafilatura хуже Tavily на JS-heavy страницах (нет headless-браузера) — приемлемо для типовых статей/доков.
  • Локальная экстракция не обходит блокировки РФ сама по себе — нужен --local-socks через туннель для таких сайтов.
  • Fetch без туннеля из РФ на github может висеть — ограничение сети, не кода.