Легковесный AI-агент для администрирования сервера: openLight на Go и Ollama | AiManual
AiManual Logo Ai / Manual.
09 Май 2026 Гайд

Как построить легковесного AI-агента для администрирования сервера: опыт двух месяцев с openLight

Практическая ретроспектива создания локального AI-агента openLight на Go, SQLite и Ollama. Реальные уроки, архитектура, безопасность и результаты двух месяцев а

Представь: ты сидишь в 2 часа ночи, продакшн падает, а Ansible-плейбук не дописан. Или ты junior, который боится ssh'нуться на сервер и выполнить rm -rf не туда. Я был в обеих ситуациях. И тогда я решил: хватит. Нужен админ, который понимает русский (или английский) язык, не спит и не просит зарплату. Так за два месяца родился openLight — легковесный AI-агент для администрирования сервера, написанный на Go, с памятью на SQLite и мозгом на Ollama.

Кому читать: DevOps-инженерам, которые устали от копипаста рутинных команд, и разработчикам, которые хотят автоматизировать сервер без джуниора. openLight — это не очередной LangChain-монстр, а реальная рабочая лошадка на Raspberry Pi.

Почему не Ansible, а AI-агент? (Спойлер: скорость)

Ansible — круто. Я сам его обожаю за декларативность. Но когда тебе нужно быстро проверить лог, перезапустить nginx или узнать, почему диск забит на 95%, писать плейбук — это как ехать на велосипеде в Ferrari. AI-агент делает это за секунды. Просто скажи: «Проверь, какие докер-контейнеры жрут больше всего памяти» — и он выполнит команды, которые ты бы вбивал руками. Но главное — он не забудет их выполнить и запишет результат в историю.

Я потратил два месяца, чтобы openLight научился не галлюцинировать команды, не удалять базы данных и работать полностью локально. Без облаков, без API-ключей, без VPN. Только Go-бинарник, SQLite-файл и модель Qwen2.5 7B, запущенная через Ollama. Всё это влезает на Raspberry Pi 4 с 4 ГБ ОЗУ.

💡
Кстати, архитектура openLight использует паттерн planner/executor, о котором я писал в гайде по проектированию AI-агентов. Если хочешь понять, как устроен этот оркестр — загляни в статью «Как спроектировать современного AI-агента: от planner/executor до stateful memory».

Архитектура openLight: Go + SQLite + Ollama

Ключевое слово — легковесность. openLight не тянет за собой Python-окружение, не грузит transformers и не просит 16 ГБ VRAM. Весь стек:

  • Go 1.22 — компилируется в один бинарник, статическая линковка, минимальное потребление памяти (около 15 МБ в простое).
  • SQLite через github.com/mattn/go-sqlite3 — храним историю команд, сессии, контекст. Никакого Redis или PostgreSQL.
  • Ollama как бэкенд LLM — дёргаем модель через HTTP API. Используем Qwen2.5 7B (самую новую на май 2026), которая выдаёт адекватные bash-команды без лишних рассуждений.
  • Telegram Bot API — интерфейс для общения с агентом. Можно добавить WebUI, но телеграм — это идеальный пульт.

1 Прокси-слой безопасности (самая важная часть)

Первое, что я понял на первой же неделе: давать LLM прямой доступ к bash — самоубийство. openLight ничего не выполняет напрямую. Вместо этого он генерирует команду, а специальный executor проверяет её по белому списку. Если команда не в списке разрешённых (например, apt install или docker ps) — агент спрашивает подтверждение в Telegram. И даже после подтверждения команда логируется в SQLite с полным стэком.

Как НЕ надо делать:

// Плохо: выполняем что сказала нейронка
cmd := llmResponse.Command
exec.Command("bash", "-c", cmd).Run()

А надо так:

// Хорошо: проверяем и логируем
func executeSafe(command string, userID int64) (string, error) {
    if !whitelist.Check(command) {
        return "", fmt.Errorf("команда не в белом списке: %s", command)
    }
    logEntry := Log{User: userID, Command: command, Time: time.Now()}
    db.Save(&logEntry)                // SQLite
    out, err := exec.Command("bash", "-c", command).CombinedOutput()
    return string(out), err
}

Грабли: Qwen2.5 иногда вставляет лишние пробелы или переносы строк, ломая синтаксис bash. Пришлось добавить нормализатор команды — тримминг, удаление лишних \n, проверка на rm -rf / (да, такое было в тестах).

2 Память агента: почему SQLite, а не in-memory

Первая версия openLight ничего не помнила между сессиями. Ты спрашиваешь «что с диском?», агент отвечает, а через минуту забудет. Это бесило. Добавил SQLite-память: каждая команда, её результат и контекст (текущая директория, нагрузка CPU, последние ошибки) сохраняются. При следующем запросе агент получает последние 5 записей как контекст. Теперь он помнит, что ты уже перезапускал nginx 10 минут назад.

💡
Этот подход называется stateful memory. Подробнее про память AI-агентов — в статье «Как спроектировать современного AI-агента». Там же разбирается, почему хранить историю в JSON-файле — плохая идея.

Полевые испытания: что реально может openLight

За два месяца я нагружал агента всем, чем только можно. Вот сценарии, которые он закрывает на 95%:

  • Мониторинг ресурсов — «покажи топ-5 процессов по CPU», «сколько свободной памяти?».
  • Работа с Docker — «перезапусти контейнер postgres», «лог последних 10 строк контейнера api».
  • Управление Nginx — «перечитай конфиг», «проверь синтаксис nginx -t».
  • Бэкапы — «сделай дамп базы и залей в S3» (команда одна, но сложная).
  • Чтение логов — «найди ошибки за последний час в /var/log/syslog».

Проблема была только с командами, требующими sudo. openLight не хранит рутовый пароль, поэтому для таких операций я добавил интеграцию с systemd-run и временное повышение привилегий через Telegram-подтверждение со второго фактора. Да, это костыль, но безопасность важнее удобства. Если хочешь, чтобы агент работал с sudo без пароля — смотри в сторону настройки sudoers для конкретных команд.

Ошибки, которые я совершил (и ты тоже совершишь)

Перечислю три главных грабля, на которые наступил:

  1. Модель не понимала контекст директории. Когда я писал «открой файл config.yaml», она пыталась открыть его в корне. Решение — в каждом запросе передавать агентту текущую рабочую директорию из SQLite (мы её запоминаем после последней команды).
  2. Галлюцинации с флагами команд. LLM может придумать несуществующий флаг, например docker ps --sort-by memory. Вместо этого я захардкодил проверки через man или предложил модель использовать только известные утилиты. На практике Qwen2.5 7B хорошо знает популярные команды, но с редкими флагами бывают ошибки.
  3. Забывал про escape-последовательности. В SQLite хранился вывод команд, и если в выводе были спецсимволы (ansi-цвета), они ломали отображение. Пришлось на стороне Go чистить вывод через stripAnsi.

Что дальше: суб-агенты и CI/CD

После двух месяцев я пришёл к выводу: один агент — хорошо, а сеть агентов — лучше. Сейчас openLight умеет вызывать суб-агентов для узких задач: один занимается Docker, другой — сетью, третий — логами. Это снижает нагрузку на LLM и ускоряет ответ. Тот же паттерн описан в статье «Как правильно использовать суб-агентов в AI-разработке: 3 реальных сценария» — настоятельно рекомендую.

Ещё одна идея, которую я только начал внедрять — интеграция openLight в CI/CD. Вместо того чтобы ругаться с GitLab Runner'ом, можно попросить агента задеплоить новую версию на staging. И да, я знаю, что GPT-4 в CI/CD — это боль, поэтому мы заменили его на локальную SLM. Как — читай в статье «GPT-4 в CI/CD - это боль. Заменяем на локальную SLM и обретаем покой».

Развёртывание: от идеи до продакшена за 30 минут

Если хочешь попробовать openLight на своём сервере — вот минимальный план. Предполагаю, что у тебя уже есть Linux-сервер (Ubuntu 22.04+) и телеграм-бот.

1 Устанавливаем Ollama и качаем модель

curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:7b
# Проверяем, что работает
ollama run qwen2.5:7b "Hello"

2 Скачиваем бинарник openLight

wget https://github.com/yournick/openlight/releases/latest/download/openlight_linux_amd64.tar.gz
tar -xzf openlight_linux_amd64.tar.gz
mv openlight /usr/local/bin/

3 Настраиваем через YAML

# /etc/openlight/config.yaml
ollama:
  endpoint: "http://localhost:11434/api/generate"
  model: "qwen2.5:7b"
telegram:
  token: "YOUR_BOT_TOKEN"
  allowed_users: [123456789]   # только ваши ID
sqlite:
  path: "/var/lib/openlight/history.db"
whitelist:
  allowed_commands:
    - "^docker\s.*"
    - "^nginx\s.*"
    - "^df\s.*"
    - "^free\s.*"
    - "^systemctl\s.*"
  denied_commands:
    - "rm\s+-rf\s+/"
    - ":(){ :|:& };:"

4 Запускаем systemd-сервис

cat <<EOF > /etc/systemd/system/openlight.service
[Unit]
Description=OpenLight AI Agent
After=network-online.target

[Service]
ExecStart=/usr/local/bin/openlight --config /etc/openlight/config.yaml
Restart=always
User=root

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now openlight

Готово. Теперь пиши своему боту /start и пробуй команды. Первый запрос может быть медленным (модель грузится в память), но потом Qwen2.5 отвечает за 1-2 секунды даже на Raspberry Pi.

Стоимость и производительность

Компонент Потребление Примечание
openLight (Go) ~15 MB RAM статический бинарник
Ollama + Qwen2.5 7B ~4.5 GB RAM загружена в память постоянно
SQLite ~50 MB (за 2 месяца) вся история команд
Цена в месяц $0 всё локально, без API

Сравни с GPT-4-turbo, который за два месяца обошёлся бы в ~$200 при активном использовании. openLight окупает себя за первый день, если считать время админа. Кстати, похожий кейс миграции с OpenAI на локальную Llama 3 разобран в статье «Как перевести корпоративный RAG-агент с OpenAI на локальную Llama 3 и сэкономить за 5 месяцев» — там те же грабли, что и у меня.

Неочевидный совет напоследок

Два месяца эксплуатации показали: не пытайся сделать агента умнее себя. Не заставляй его писать сложные bash-скрипты с циклами и условиями — для этого есть Ansible. Пусть openLight будет твоими быстрыми руками: проверить статус, перезапустить, показать логи. А когда нужно что-то сложное — пусть сгенерирует плейбук, а ты его проверишь. И да, обязательно настрой Telegram-уведомления об опасных командах — однажды я чуть не удалил базу через «очисти кэш», потому что модель решила, что кэш — это весь /var.

Проектируя openLight, я прошёл путь от «дай нейронке рут-доступ» до «каждую команду через три фильтра». Если хочешь собрать такого же агента с нуля — читай мой гайд по созданию AI-агента на Bun за 30 минут (ссылка). Там тот же принцип, но на Bun, легче для старта.

Подписаться на канал