🤖 AI-агенты для бизнеса

3. Конфигурация сервера

🔵 Платформу настраивают два файла: config/server.yaml (ядро, провайдер, логирование, auth, виджет) и config/budgets.yaml (бюджетные группы и привязка шаблонов). Расписания — в config/cron.yaml, слежение за изменениями — в config/monitors.yaml, воркфлоу — в config/workflows/. Секреты — только в .env.


3.1 Источник конфига — локальная папка или git-репозиторий

Всё дерево конфига (server.yaml, agents/, web/, workflows/, budgets.yaml, cron.yaml, monitors.yaml) грузится из одного корня. По умолчанию это локальная ./config; вместо неё можно клонировать git-репозиторий, чтобы конфиг версионировался и ревьюировался отдельно от бинарника.

Приоритет: CLI-флаг → переменная окружения → локальный ./config.

CLI-флаг Переменная Значение по умолчанию Что делает
--config-repo <url> AGENT_OS_CONFIG_REPO клонировать конфиг из git (иначе — локальная папка)
--config-ref <ref> AGENT_OS_CONFIG_REF main ветка / тег / коммит, на который фиксируется конфиг
--config-dir <path> AGENT_OS_CONFIG_DIR ./config локальная папка конфига (игнорируется в git-режиме)
--config-poll <secs> AGENT_OS_CONFIG_POLL off периодически git pull + hot-reload конфига
AGENT_OS_CONFIG_REPO=https://github.com/org/agent-config \
AGENT_OS_CONFIG_REF=v1.2.0 \
./agent_web_bot

Репозиторий клонируется (shallow) в ~/.agent-os/configs/<repo>-<ref> и фиксируется на разрешённом коммите; SHA коммита пишется в лог при старте и виден на /health в поле config. Секреты в конфиг-репозитории не хранятся — только ссылки на имена переменных из .env.


3.2 config/server.yaml

provider — LLM

provider:
  base_url: "https://api.deepseek.com"   # любой OpenAI-совместимый endpoint
  model: "deepseek-v4-flash"
  api_key: ""                            # опционально; предпочтительно .env
  pricing:                               # оценка стоимости инференса
    prompt_per_million: 0.14
    cached_per_million: 0.014
    completion_per_million: 0.28
Поле По умолчанию Описание
base_url https://api.deepseek.com базовый URL OpenAI-совместимого провайдера
model deepseek-v4-flash имя модели
api_key пусто ключ; пустое значение → берётся из env
pricing.prompt_per_million 0.14 $ за 1M prompt-токенов
pricing.cached_per_million 0.014 $ за 1M кэшированных prompt-токенов
pricing.completion_per_million 0.28 $ за 1M completion-токенов

Порядок выбора ключа: provider.api_keyAGENT_OS_API_KEYDEEPSEEK_API_KEY. Пусто везде → агенты отвечают симулированными ответами.

models — именованные модели

Дополнительные конфиги моделей: каждый становится отдельным провайдером со своим base_url / api_key / model / pricing. Шаблон агента выбирает нужную полем model: в своём agent.yaml. provider: выше — это дефолт (он же регистрируется как "default").

models:
  cheap:
    base_url: "https://api.deepseek.com"
    model: "deepseek-chat"
  strong:
    base_url: "https://api.openai.com/v1"
    model: "gpt-4o"
    api_key: ""

kernel — планировщик и сессии

kernel:
  scheduler: round_robin
  concurrency_limit: 3
  live_reload: true
  session_ttl_secs: 300
  session_cleanup_interval_secs: 60
Поле По умолчанию Описание
scheduler round_robin политика планирования (сейчас реализован только round_robin)
concurrency_limit 3 максимум одновременно выполняющихся процессов
live_reload true hot-reload config/agents/** и config/web/**
session_ttl_secs 300 максимум простоя сессии (сек), после которого она убивается
session_cleanup_interval_secs 60 как часто (сек) запускается чистильщик сессий

logging — логи и хранилища

logging:
  filter: "agent_os=debug"
  jsonl_dir: "logs"
  duckdb_path: "logs/events.db"
  messages_db_path: "logs/messages.db"
  messages_retention_days: 30
  state_db_path: "logs/state.db"
  temp_dir: "logs/temp"
  access_db_path: "logs/access.db"
  cron_db_path: "logs/cron.db"
  user_db_path: "logs/users.db"
  monitor_db_path: "logs/monitors.db"
  workflow_db_path: "logs/workflows.db"
  bench_db_path: "logs/bench.db"
Поле По умолчанию Описание
filter agent_os=debug фильтр уровня логирования (tracing)
jsonl_dir logs папка JSONL-логов (process-*.jsonl, access.jsonl)
duckdb_path logs/events.db событийное хранилище DuckDB (пустая строка = выкл)
messages_db_path logs/messages.db общий message store: транскрипты + FAQ-кэш (пусто = выкл)
messages_retention_days 30 сколько дней хранить транскрипты до очистки
state_db_path logs/state.db scoped state store (session / user / agent); пусто = выкл
temp_dir logs/temp scratch-хранилище сессий для файлов-генераторов; file_tool читает оттуда (пусто = выкл)
access_db_path logs/access.db DuckDB-лог HTTP-запросов (пусто = выкл)
cron_db_path logs/cron.db cron: динамические задания + история запусков (пусто = динамические задания не переживают рестарт)
user_db_path logs/users.db реестр канонических пользователей: канальные id → один user id (пусто = выкл)
monitor_db_path logs/monitors.db курсоры change-мониторов (пусто = курсоры не персистятся)
workflow_db_path logs/workflows.db история запусков воркфлоу (пусто = выкл)
bench_db_path logs/bench.db история бенчмарков и снапшоты (пусто = история не пишется)

auth — админ-API и web-логин

auth:
  admin_token_env: ""              # имя env-переменной с токенами (опционально)
  admin_tokens:                    # карта имя → токен (или { token, templates })
    admin: "<token>"
    drom-op:
      token: "<token>"
      templates: [drom-agent]
  users:                           # web-логин: логин → пароль (или { password, templates })
    admin: "<password>"
    drom-viewer:
      password: "<password>"
      templates: [drom-agent]
  web_user_secret_env: ""          # env с HMAC-секретом для токенов конечных пользователей

web_user_secret_env — имя env-переменной с HMAC-секретом для подписи токенов идентичности конечных пользователей (POST /v1/user-ticket). Если пусто, сервер сам генерирует и хранит секрет в data/web_user_secret — идентичность подписывается HMAC по умолчанию. Подробности — в 08-http-api.

Админ-эндпоинты принимают либо Authorization: Bearer <токен>, либо cookie agentos_session.

widget — встраиваемый виджет

widget:
  default_model: "drom-agent"   # агент по умолчанию

Единственная серверная настройка — default_model: агент, к которому виджет обращается, когда модель не задана явно. Полный разбор виджета (встраивание, порядок выбора модели, демо, визуальные блоки) — в §19.

proxy — ограничения HTTP-прокси

proxy:
  allow_hosts: []   # пусто = любой публичный хост

/proxy и /proxy/content всегда блокируют приватные, loopback, link-local и reserved-диапазоны (включая 169.254.169.254) на каждом редиректе. allow_hosts дополнительно ограничивает по хосту (точное совпадение или поддомен).

inbound — входящий webhook

inbound:
  token_env: ""   # env с bearer-токеном для POST /v1/inbound/:template (пусто = открыто, dev)

POST /v1/inbound/:template — внешние системы запускают один ход агента синхронно. См. 08-http-api.


3.3 config/budgets.yaml

budget_groups:
  - name: my-shared
    refill_per_sec: 50
    max_bucket: 50000
    max_total: 5000000        # null/отсутствует = без лимита
    per_user:                 # опционально
      refill_per_sec: 20
      max_bucket: 20000
      max_total: 500000
    per_session:              # опционально
      refill_per_sec: 30
      max_bucket: 10000
      max_total: 200000

agents:
  - template: my-agent        # перекрывает budget_group / budget из agent.yaml
    group: my-shared
    budget:                   # опционально
      refill_per_sec: 10
      max_bucket: 200
      max_total: 1000

Поля бюджета

Поле Описание
refill_per_sec пополнение ведра, токенов/сек
max_bucket ёмкость ведра (burst)
max_total жёсткий лимит за всю жизнь (отсутствует = без лимита)

3.4 Запланированные задания (config/cron.yaml)

Cron запускает шаблон агента по расписанию. Задаются в двух местах, оба hot-reload'ятся:

jobs:
  - name: morning-digest
    template: rss
    schedule: "0 0 9 * * *"      # sec min hour dom month dow (UTC)
    prompt: "Резюмируй сегодняшние новости."
    notify: [{ type: log }]

Каждое задание задаёт ровно одно из schedule / interval_secs / oneshot_at и доставляет результат в список notify-sink'ов (log, webhook, telegram, messages_db, agent, email, workflow). История — в logs/cron.db, эндпоинт GET /v1/cron. Полный справочник — 11-cron-jobs.


3.5 Change-мониторы (config/monitors.yaml)

Монитор — это pull-триггер: следит за внешним источником и запускает ход агента только при появлении новых элементов (в отличие от cron, который стреляет по расписанию независимо). Источник изменений подключаемый (сейчас — rss).

monitors:
  - name: news-watch
    source:
      type: rss
      url: "https://lenta.ru/rss"
    template: rss-agent
    prompt: "Кратко резюмируй эти новые статьи:\n{{items}}"
    notify: [{ type: telegram, chat_id: 123456 }]
    poll_secs: 300
Поле Смысл
name уникальный id (он же ключ курсора и сессия monitor:<name>)
source.type источник изменений: rss
source.url URL ленты
template шаблон агента для запуска на новых элементах
prompt шаблон промпта; {{items}} заменяется новыми элементами
notify sink'и, куда раздаётся результат (те же типы, что у cron)
poll_secs интервал опроса (по умолчанию 300)

Монитор хранит курсор в logs/monitors.db: первый опрос только «догоняет» (сохраняет курсор, ничего не запускает), дальше запускается только на элементах новее курсора.


3.6 Переменные окружения

Переменная Назначение
DEEPSEEK_API_KEY / AGENT_OS_API_KEY ключ LLM-провайдера
AGENT_OS_BIND адрес привязки (по умолчанию 127.0.0.1:3000)
AGENT_OS_TLS_CERT / AGENT_OS_TLS_KEY пути к PEM-сертификату и ключу для HTTPS
AGENT_OS_ADMIN_TOKEN админ-токены: список через запятую, имя=токен (альтернатива auth.admin_tokens)
AGENT_OS_BENCH_MODE 1 = безлимитные бюджеты (для локального спавна бенчмарка)
AGENT_OS_CONFIG_REPO / _REF / _DIR / _POLL источник конфига (см. §3.1)
AGENT_OS_DISTRIB_DIR путь к папке дистрибутива (по умолчанию distrib)
(на агента) имя из telegram.token_env токен Telegram-бота, названный в agent.yaml
(на агента) имя из email.imap_password_env пароль IMAP для email-канала
(на агента) имя из vk.token_env group access token VK-сообщества, названный в agent.yaml

.env подхватывается автоматически при старте (dotenv). Он в .gitignore, шаблон — .env.example.


3.7 Live reload

При kernel.live_reload: true (по умолчанию) сервер следит за config/:


3.8 Логирование HTTP-запросов

Каждый HTTP-запрос (метод, путь, статус, длительность, IP клиента, user-agent, X-User-Id, имя админ-токена) пишется в logs/access.jsonl и logs/access.db (оба отключаются пустой строкой в соответствующем поле logging). Значение токена не логируется — только его имя или пометка invalid.