# 9. Эксплуатация

🔵 Запуск, тестирование, бенчмарки, деплой и мониторинг — используя только
скомпилированные бинарники.

---

## 9.1 Бинарники

| Бинарник | Назначение |
|---|---|
| `agent_web_bot` | HTTP-сервер (главный процесс) |
| `agent_bench` | E2E-бенчмарк агентов |
| `site_tool` | тест YAML-инструмента локально (без сервера и LLM) |
| `hook_tool` | тест YAML-хука локально |
| `workflow_tool` | локальный запуск воркфлоу |
| `scraper` | краулер сайта в архив; анализ архива |
| `route_tool` | тест HTTP-маршрутов локально (`http_route` / `static_route`) |
| `office_tool` | тест офисного инструмента локально (скачивает OfficeCLI при первом запуске) |
| `officecli_pdf_exporter` | PDF-экспортер-плагин OfficeCLI (headless Chromium) |

---

## 9.2 Запуск сервера

```bash
./agent_web_bot
AGENT_OS_BIND=0.0.0.0:8080 ./agent_web_bot        # сменить адрес привязки
```

Загружает `.env`, `config/server.yaml`, `config/agents/**`,
`config/budgets.yaml`, `config/web/**`. См. `03-server-configuration`.

---

## 9.3 Тестирование инструментов

```bash
site_tool config/agents/ngu/tools/ngu_search.yaml '{"query":"поступление"}'
site_tool config/agents/drom/tools/drom_find_brands.yaml '{"query":"газ"}'
```

Печатает переданные аргументы, `call_template`, вывод для LLM и
`result_template`. Ненулевой код выхода при ошибке.

---

## 9.4 Тестирование хуков

```bash
hook_tool config/agents/ngu/hooks/faq_cache.yaml user "Как поступить на фит?"
hook_tool config/agents/ngu/hooks/faq_cache.yaml turn "вопрос" "ответ" --db /tmp/faq.db
hook_tool config/scripts/hooks/moderation.yaml user "Привет" --live   # реальный LLM-судья
```

Команды: `info`, `user "<msg>"`, `turn "<q>" "<a>"`, `loop "<reason>"`. Флаги:
`--db`, `--live`, `--agent`, `--template`, `--user`, `--session`.

---

## 9.5 Бенчмарки

`agent_bench` прогоняет сценарии из `config/agents/<agent>/bench/scenarios.yaml`.

```bash
# против работающего сервера
agent_bench --url=https://HOST --agent=drom --max=5

# поднять собственный локальный сервер (нужен DEEPSEEK_API_KEY в .env)
agent_bench --port=3001 --max=3

# фильтр по имени сценария (подстрока / regex)
agent_bench --url=https://HOST --name="Camry|BMW" --max=10

# параллельность + таймаут
agent_bench --url=https://HOST --agent=drom --parallel=3 --timeout=90
```

Флаги:

| Флаг | По умолчанию | Описание |
|---|---|---|
| `--url=` | (спавн локального) | подключиться к работающему серверу (пропускает спавн) |
| `--port=` | `3001` | порт локального сервера (игнорируется при `--url`) |
| `--agent=` | (все) | только этот шаблон |
| `--name=` | (все) | только сценарии с этой подстрокой в имени |
| `--max=` | все | максимум N сценариев |
| `--parallel=` | `4` | параллельных сценариев |
| `--timeout=` | `90` | таймаут хода (сек) |

Результаты пишутся в `bench_report_<timestamp>.json` в рабочей папке, со
счётчиками `passed`/`failed` и per-turn `failures`.

### Формат сценария

```yaml
name: "Drom Agent"
model: "drom-agent"

scenarios:
  - name: "Поиск Camry"
    turns:
      - user: "Найди Toyota Camry"
        assert:
          contains: [camry]
          min_links: 2
          valid_urls: true
```

Проверки: `contains` (подстроки), `min_links` / `min_urls` (число
markdown-ссылок), `valid_urls` (все ссылки http/https).

---

## 9.6 Краулинг сайта в архив

```bash
scraper https://nsu.ru -w 8 -d 3 -n 500          # обход
scraper --analyze nsu_full.archive               # анализ повторяющихся блоков
```

Флаги: `-w/--workers`, `-d/--max-depth`, `-n/--max-pages`, `-r/--rate-limit`
(мс), `-o/--output` (путь архива), `-m/--navmap`, `--timeout` (сек),
`--no-same-domain`.

Архив (каталог с `meta.json`, `docs.bin`, `terms.bin`) — это то, что ищет
[`archive_tool`](05-tools-data.md#55-archive_tool).

---

## 9.7 Мониторинг и логи

| Источник | Где | Что показывает |
|---|---|---|
| stdout сервера | запуск на переднем плане / редирект в файл | старт, ошибки, список шаблонов |
| JSONL-трейсы | `logs/process-<pid>.jsonl` | события процесса (спавн, tool-вызовы, ошибки) |
| Событийное хранилище | `logs/events.db` (DuckDB) | запрашиваемая история событий |
| Message store | `logs/messages.db` (DuckDB) | транскрипты + FAQ-кэш |
| Access-лог | `logs/access.jsonl`, `logs/access.db` | только HTTP-запросы |
| Cron store | `logs/cron.db` (DuckDB) | задания + per-run статус/токены/стоимость |
| Health | `curl .../health` | жив ли сервис |

### Использование `trace-agent`

Шаблон `trace-agent` (`config/agents/trace/agent.yaml`) — диагностический
ассистент поверх `logs/events.db`. Спроси его (в чате) «В каких сессиях были
ошибки?», «Сколько потратил агент X?», «Какие поиски вернули ноль результатов?».
Его инструменты `trace_*` (sessions, events, transcript, search, process)
описаны в [trace_tool](05-tools-observe.md#59-trace_tool).

### Дашборд

Страница `/dashboard` (и её API `GET /v1/dashboard`) даёт сводку по серверу:

- **Система** — CPU, память, uptime, версия сборки;
- **Провайдер** — текущая модель и base URL, лимит конкурентности;
- **Состояние** — число активных/всего сессий, активных процессов, шаблонов,
  бюджетных групп, потраченные токены;
- **Auth** — включён ли админ-auth, число токенов/пользователей;
- **Серии** — временные ряды активности/токенов из событийного хранилища.

---

## 9.8 Деплой изменений конфига

Конфиг-only изменения (агенты, инструменты, хуки, бюджеты, веб-контент) не
требуют пересборки — скопируй изменённые `config/` и `data/` на сервер и
перезапусти (или положись на live reload для `config/agents/**` /
`config/web/**`):

```bash
# загрузить
scp -r config/ data/ user@host:/path/to/agent_os/

# перезапустить
ssh user@host "kill \$(pgrep agent_web_bot); cd /path/to/agent_os && \
  set -a && source .env && set +a && nohup ./agent_web_bot > agent_os.log 2>&1 &"

# проверить
curl -sk https://HOST/health
```

Если добавлен новый движок инструмента/хука (новый `kind:`, потребовавший
Rust-кода), бинарник надо пересобрать — но добавление агентов/инструментов/хуков
на существующих движках не требует этого никогда.

### Деплой конфига из git-репозитория

Вместо копирования файлов укажи серверу конфиг-репозиторий — он склонирует и
зафиксирует при старте (или будет опрашивать):

```bash
# зафиксировать тег при старте
AGENT_OS_CONFIG_REPO=https://github.com/org/agent-config \
AGENT_OS_CONFIG_REF=v1.2.0 \
./agent_web_bot

# или опрашивать репозиторий и hot-reload при изменении
AGENT_OS_CONFIG_REPO=https://github.com/org/agent-config \
AGENT_OS_CONFIG_POLL=60 \
./agent_web_bot
```

Разрешённый коммит логируется при старте и виден на `/health` в поле `config`
(`source`, `url`, `ref`, `commit`, `poll_secs`). Чтобы выкатить изменение —
закоммить/тегни в конфиг-репозитории и перезапусти (pin-режим) или дождись
следующего тика опроса. См. §3.1.

---

## 9.9 TLS

Задай PEM-сертификат/ключ через `AGENT_OS_TLS_CERT` / `AGENT_OS_TLS_KEY`;
иначе — обычный HTTP (например за reverse-прокси).
