Представь: ты сидишь в 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: 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 минут назад.
Полевые испытания: что реально может openLight
За два месяца я нагружал агента всем, чем только можно. Вот сценарии, которые он закрывает на 95%:
- Мониторинг ресурсов — «покажи топ-5 процессов по CPU», «сколько свободной памяти?».
- Работа с Docker — «перезапусти контейнер postgres», «лог последних 10 строк контейнера api».
- Управление Nginx — «перечитай конфиг», «проверь синтаксис nginx -t».
- Бэкапы — «сделай дамп базы и залей в S3» (команда одна, но сложная).
- Чтение логов — «найди ошибки за последний час в /var/log/syslog».
Проблема была только с командами, требующими sudo. openLight не хранит рутовый пароль, поэтому для таких операций я добавил интеграцию с systemd-run и временное повышение привилегий через Telegram-подтверждение со второго фактора. Да, это костыль, но безопасность важнее удобства. Если хочешь, чтобы агент работал с sudo без пароля — смотри в сторону настройки sudoers для конкретных команд.
Ошибки, которые я совершил (и ты тоже совершишь)
Перечислю три главных грабля, на которые наступил:
- Модель не понимала контекст директории. Когда я писал «открой файл config.yaml», она пыталась открыть его в корне. Решение — в каждом запросе передавать агентту текущую рабочую директорию из SQLite (мы её запоминаем после последней команды).
- Галлюцинации с флагами команд. LLM может придумать несуществующий флаг, например
docker ps --sort-by memory. Вместо этого я захардкодил проверки черезmanили предложил модель использовать только известные утилиты. На практике Qwen2.5 7B хорошо знает популярные команды, но с редкими флагами бывают ошибки. - Забывал про 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, легче для старта.