Ботинок (сущ.) — консольный ИИ-агент. Будучи надетым на привычные костыли уставшей линукс-системы, делает их почти неотличимыми от настоящих ног.

Хабр, привет!

Эта статья — не туториал и не обзор. Это история о том, как я искал инструмент для своих задач, не нашёл, расстроился, а потом успокоился и написал свой. Речь пойдёт о Ботинке — консольном AI-агенте для работы по SSH. Но сначала немного контекста.

Я работаю с Linux-серверами уже лет пятнадцать. За это время видел разные эпохи: когда всё настраивали руками, когда появился Ansible, когда все бросились в Kubernetes, когда устали от Kubernetes и вернулись к простым docker-compose. Скрипты-костыли множились, документация устаревала, а сервера как требовали внимания, так и требуют.

И вот теперь добавился ещё один слой — LLM. Можно спросить у модели, как настроить nginx, и получить рабочий конфиг. Можно попросить проанализировать логи. Но каждый раз копировать-вставлять между терминалом и чатом — это отдельный вид боли. Хочется, чтобы модель жила прямо в консоли, понимала контекст сервера и могла сама выполнить рутину.

Статья будет полезна тем, кто:

  • Работает с серверами по SSH и устал от рутины

  • Интересуется AI-агентами, но хочет что-то лёгкое и локальное

  • Имеет ограниченные ресурсы (не у всех есть 24GB VRAM)

  • Хочет понять, как строится архитектура агента с инструментами

Зачем ещё один AI-агент?

Ситуация знакомая?: есть задачи, которые хочется поручить AI — проанализировать логи, написать код, найти информацию в интернете. Но мне нужен был именно консольный агент — работаю в терминале, хожу по серверам по SSH, не хочу отвлекаться на GUI.

На волне хайпа попробовал OpenClaw — хайповый проект 2025-2026 года, self-hosted AI-агент для автоматизации жизненных задач. Идея в целом норм: агент работает 24/7, отвечает в Telegram/WhatsApp, умеет чистить почту, управлять календарём, чекиниться на рейсы. Четырёхслойная архитектура, куча интеграций, активное сообщество.

Но на практике для моих задач оказалось слишком тяжело:

  • Оверсложнённая архитектура — Gateway, Integration, Execution, Intelligence — это отлично для энтерпрайза, но перебор для «зайти на сервер и поправить конфиг»

  • Ориентация на lifestyle-автоматизацию — почта, календарь, бронирования. А мне нужно: логи, systemd, docker, nginx

  • Постоянно висящий сервис — 24/7 демон, который кушает ресурсы. А я хочу: запустил — поработал — закрыл

  • Мессенджер как интерфейс — удобно для личного ассистента, но для админской работы нужен терминал и SSH

OpenClaw крут для своей ниши — персональный ассистент в Telegram. Но моя задача другая: консольный агент для системного администрирования. Зайти по SSH, диагностировать проблему, поправить, уйти. Без демонов, без мессенджеров, без оверхеда.

Так родился Ботинок.

Ключевая идея: не сервис, а инструмент

Здесь важно остановиться на главном. Ботинок — это не фоновый сервис и не постоянно висящая служба. Это обычное приложение: запустил, поработал, закрыл. Никаких веб-серверов, демонов, системных служб.

Идея пришла из наблюдения за тем, как работают разработчики с Cursor, Windsurf и подобными IDE. Там ты открываешь проект, AI помогает писать код, настраивать окружение, исправлять баги — и всё это в контексте конкретной задачи. Когда закончил — закрыл IDE и забыл.

Ботинок переносит этот подход в консоль:

# Сценарий: заходим на сервер настроить среду
ssh admin@192.168.1.100
botinok "Настрой docker, nginx и деплой для моего Flask-приложения"
# ... работаем с агентом ...
# Готово — закрываем терминал и идём дальше

Ollama может быть где угодно — на локальной машине, на соседнем сервере в локалке, на мощной рабочей станции. Ботинок просто подключается к нему по HTTP.

Настройка подключения — через интерактивный мастер:

botinok --wizard

Мастер проверит доступность Ollama, покажет список моделей и сохранит настройки в конфиг. После этого просто запускаете:

botinok "Проанализируй логи nginx"

Это делает Ботинок идеальным для:

  • Администраторов — зашёл по SSH, дал задачу, получил результат

  • DevOps-инженеров — настроить CI/CD, разобраться с конфигами

  • Разработчиков — быстро накатить окружение на новой машине

  • Энтузиастов с ограниченным железом — мощный Ollama на одной машине, лёгкий клиент на другой

Что умеет

Инструменты (Function Calling)

Ботинок использует полноценный function calling через Ollama API:

🌐 Сеть и поиск:
- web_search — поиск через DuckDuckGo (lynx)
- open_url — извлечение контента со страниц

🛠 Системные инструменты:
- file_system — навигация, grep, чтение файлов
- shell_exec — выполнение bash-команд (требует --dangerous)
- journal — анализ journalctl

💻 Разработка:
- code_editor — чтение, запись, замена фрагментов кода
- github — clone, log, status, diff

📚 Навыки и опыт:
- skills — загрузка промптов-инструкций из репозитория ClawHub
- experience — база позитивного/негативного опыта

Веб-поиск и открытие страниц: почему lynx

Отдельно стоит рассказать про реализацию сетевых инструментов. Было выбрано решение работать через lynx — консольный текстовый браузер. Это может показаться спорным решением, но мне оно понравилось больше всего по нескольким причинам:

Почему не Python-библиотеки?

Можно было использовать requests + BeautifulSoup, Selenium, Playwright или специализированные API. Но каждый вариант имеет недостатки:

  • requests/BeautifulSoup — не обрабатывает JavaScript, нужен дополнительный парсинг

  • Selenium/Playwright — тяжёлые, требуют браузер, не работают по SSH без X11

  • Google/Bing API — требуют ключи, лимиты, платные

Почему lynx?

# Веб-поиск — просто вызов subprocess
result = subprocess.run([
    "lynx", "-dump", "-number_links",
    "-display_charset=utf-8",
    f"-useragent={user_agent}",
    f"https://html.duckduckgo.com/html/?q={encoded_query}"
], capture_output=True, text=True, timeout=15)
  • Легковесный — установлен в большинстве Linux-дистрибутивов

  • Быстрый — не грузит JS, CSS, картинки, шрифты

  • Чистый текст-dump выдаёт структурированный контент без HTML-тегов

  • Нет зависимостей — не нужны Python-пакеты для работы с вебом

  • Работает по SSH — идеально для серверного сценария

Как работает web_search:

  1. Формирует URL DuckDuckGo HTML-версии (не JS-версию!)

  2. Вызывает lynx с таймаутами из конфига

  3. Парсит результат, обрезает до лимита (5000 символов по умолчанию)

  4. Сохраняет полный дамп в файл сессии

# Результат поиска выглядит так:
1.  Python asyncio tutorial — Real Python
    https://realpython.com/async-io-python/
    
    Async IO in Python: A Complete Walkthrough. This tutorial...
    
2.  asyncio — Asynchronous I/O — Python Documentation
    https://docs.python.org/3/library/asyncio.html
    ...

Как работает open_url:

  1. Нормализует URL (добавляет https:// если нужно)

  2. Открывает через lynx, получает текстовый дамп

  3. Обрезает до лимита (8000 символов)

  4. Сохраняет полный дамп в сессию

Ограничения lynx:

Честно признаю — решение не идеально:

Проблема

Пример

Решение

Нет JavaScript

SPA-сайты (React, Vue) могут быть пустыми

Агент видит это по пустому контенту и сообщает

Капчи

DDG иногда блокирует

Fallback на другой URL, ретрай с таймаутом

Нет авторизации

Закрытые страницы недоступны

Это ограничение по дизайну — только публичный контент

Потеря визуального контекста

Таблицы, диаграммы превращаются в текст

Агент адаптируется к текстовому формату

Размер контента

Обрезка до N символов

Полный дамп сохраняется в сессию, агент может его прочитать

Когда lynx работает отлично:

  • Документация (docs.python.org, MDN, StackOverflow)

  • Статьи и блоги

  • GitHub README

  • Википедия

  • Новости

Когда lynx может подвести:

  • Современные SPA-приложения

  • Сайты с тяжёлой защитой от ботов

  • Сайты с авторизацией

Это компромисс, который мне подошёл — простота и скорость в обмен на ограничения. Для сценария «быстро глянуть документацию или статью по SSH» — идеально.

file_system: глаза и руки агента на сервере

Центральный инструмент для навигации по файловой системе. В концепции «зашёл по SSH — настроил сервер» это основной способ агента понять, что происходит на машине.

Основные действия:

Action

Что делает

Пример

list

Список файлов с размером и датой

list /etc/nginx

search

Поиск файлов по маске

search /var/log "*.log"

grep

Поиск текста в файлах

grep /etc "server_name" "*.conf"

read

Чтение файла с пагинацией

read /var/log/syslog offset=0 limit=500

info

Метаданные файла

info /etc/passwd

Inspect-команды — мощный комбо:

Отдельный набор действий через action="inspect", который объединяет аналитические команды:

inspect command="fs.tree" path="/var/www" depth=3       # дерево директорий
inspect command="du.top_files" path="/var/log"          # самые большие файлы
inspect command="du.dir_total" path="/home/user"        # размер папки
inspect command="sys.meminfo"                           # память из /proc/meminfo
inspect command="sys.disk_free" path="/"                # место на диске
inspect command="proc.list"                             # список процессов
inspect command="proc.info" pid=1234                    # детали процесса
inspect command="svc.status" unit="nginx"               # статус systemd-сервиса
inspect command="env.os_release"                        # версия ОС

Безопасность по дизайну:

  • Все действия — read-only. Никакой записи, удаления, изменения.

  • Пагинация для больших файлов: offset, limit, max_bytes

  • Обрезка контента с маркером [TRUNCATED], чтобы не раздувать контекст

  • Бинарные файлы игнорируются при поиске

Зачем это в нашей концепции:

# Типичный сценарий диагностики
botinok "Разберись почему nginx отдаёт 502"

# Агент:
# 1. inspect command="svc.status" unit="nginx"        # статус сервиса
# 2. journal action="unit_tail" unit="nginx"          # логи nginx
# 3. read /etc/nginx/sites-enabled/default            # конфиг
# 4. grep /var/log/nginx "error" "*.log"              # поиск ошибок
# 5. inspect command="proc.list" | grep "php-fpm"     # запущен ли backend

Агент сам выбирает нужные инструменты, пользователь просто ставит задачу.

journal: системная диагностика без выхода из терминала

Отдельный инструмент для работы с systemd journal. Почему не просто grep по /var/log? Потому что современные дистрибутивы используют journald, и journalctl даёт структурированный доступ к логам с фильтрацией по времени, приоритету и юниту.

Действия:

Action

Что делает

Пример

tail

Последние N строк

tail lines=100

unit_tail

Логи конкретного юнита

unit_tail unit="docker" lines=200

since

Логи с определённого времени

since since="2 hours ago"

query

Комбинация фильтров

query unit="nginx" grep="error" since="today"

stats

Статистика по уровням

stats unit="ssh" since="1 day ago"

Пример статистики:

{
  "action": "stats",
  "unit": "nginx",
  "since": "1 hour ago",
  "levels": {
    "emerg": 0, "alert": 0, "crit": 0,
    "err": 12,
    "warning": 45,
    "notice": 120,
    "info": 340,
    "debug": 0
  }
}

Это позволяет агенту быстро оценить ситуацию — много ли ошибок, есть ли критические.

Фильтрация:

# Агент может комбинировать параметры
journal action="query"
  unit="docker"
  since="2025-03-25 10:00:00"
  until="2025-03-25 12:00:00"
  priority="err"
  grep="connection refused"

Зачем отдельный инструмент:

В file_system есть inspect command="journal.*", но полноценный анализ логов заслуживает собственного инструмента с:

  • Понятным API для агента

  • Фильтрацией по приоритету (emerg, err, warning…)

  • Поддержкой временных диапазонов

  • Грубой статистикой по уровням

github: быстро глянуть репозиторий без браузера

Инструмент для работы с GitHub API. Без авторизации, только публичные репозитории. В концепции «настройка среды» это полезно для:

  • Поиска библиотек и их версий

  • Чтения README перед установкой

  • Проверки доступных тегов/релизов

  • Анализа конфигурационных файлов из репозиториев

Действия:

Action

Что делает

Пример

search_repos

Поиск репозиториев

search_repos query="fastapi cors middleware"

get_repo

Информация о репозитории

get_repo repo="tiangolo/fastapi"

get_readme

README файла

get_readme repo="tiangolo/fastapi"

get_file

Содержимое файла

get_file repo="tiangolo/fastapi" path="pyproject.toml"

get_tags

Список тегов/версий

get_tags repo="tiangolo/fastapi"

get_branches

Список веток

get_branches repo="tiangolo/fastapi"

Пример поиска:

🔍 Найдено 42 репозитория:

  ⭐ 78,234 | tiangolo/fastapi
     FastAPI framework, high performance, easy to learn...
     🏷️ Python | 🍴 6,543

  ⭐ 12,456 | encode/starlette
     The little ASGI framework that shines...
     🏷️ Python | 🍴 1,234

Пример получения тегов:

🏷️ Теги репозитория tiangolo/fastapi:
  • 0.115.0 (a1b2c3d)
  • 0.114.0 (e4f5g6h)
  • 0.113.0 (i7j8k9l)

Зачем это в нашей концепции:

# Сценарий: выбрать версию библиотеки
botinok "Какая последняя стабильная версия fastapi? Покажи что нового в последнем релизе"

# Агент:
# 1. github action="get_tags" repo="tiangolo/fastapi"
# 2. github action="get_readme" repo="tiangolo/fastapi"
# 3. Выводит версию и краткое описание изменений

Ограничения:

  • Нет авторизации — только публичные репозитории

  • Rate limit GitHub API (60 запросов/час без токена)

  • Контент обрезается до 5000 символов

Для полноценной работы с git-репозиториями есть shell_exec с git clone, но для быстрого «гуглинга» библиотек — github инструмент удобнее.

Опасные инструменты: двойная защита

Все инструменты выше — read-only. Они читают, ищут, анализируют, но ничего не меняют. Для реальной работы — редактирования кода, выполнения команд — нужны инструменты с доступом на запись. Но они требуют двойной защиты.

Уровень 1: Ключ запуска --dangerous

Опасные инструменты по умолчанию отключены. Агент их просто не видит в списке доступных. Чтобы активировать:

botinok --dangerous "Исправь баг в коде"

Флаг --dangerous:

  • Добавляет в системный промпт: «Dangerous-mode: ON»

  • Загружает определения инструментов code_editor и shell_exec

  • Показывает в заголовке UI: DANGEROUS MODE: ON

Без этого флага агент физически не может вызвать опасные инструменты — их нет в его контексте.

Уровень 2: Ручная валидация каждого действия

Даже с --dangerous, каждое действие требует подтверждения пользователя. Но перед этим Ботинок подробно показывает, что именно будет сделано:

════════════════════════════════════════════════════════════════════════════════
┌─────────────────────────── ВНИМАНИЕ: ОПАСНОЕ ДЕЙСТВИЕ ───────────────────────┐
│                                                                             │
│  ### Запрос на использование инструмента: `shell_exec`                      │
│                                                                             │
│  **Аргументы:**                                                             │
│  ```json                                                                    │
│  {                                                                          │
│    "command": "docker restart nginx",                                       │
│    "cwd": "/var/www/project"                                                │
│  }                                                                          │
│  ```                                                                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Разрешить выполнение? (y/n): _

Пользователь видит:

  • Какой инструмент вызывается

  • Полные аргументы (команда, путь, содержимое)

  • Предупреждения если путь вне папки сессии

Если отказать — агент просит указать причину и учитывает это в дальнейшей работе:

Укажите причину отказа для бота: Это продакшн сервер, нельзя перезапускать

# Агент получит:
# ОТКАЗАНО ПОЛЬЗОВАТЕЛЕМ. Причина: Это продакшн сервер, нельзя перезапускать

code_editor: редактирование файлов

Инструмент для создания и изменения файлов. Поддерживает несколько действий:

Action

Что делает

Пример

read

Чтение файла

Безопасно, не требует --dangerous

write

Полная перезапись файла

write path="main.py" content="..."

replace

Замена фрагмента

replace path="main.py" old_text="..." new_text="..."

Защита по пути:

code_editor привязан к папке сессии. Есть три уровня доступа:

Путь

Требует подтверждения?

session_path/project/*

Нет — безопасная песочница

session_path/* (вне project)

Да — предупреждение

Абсолютный путь вне сессии

Да — красное предупреждение

Свободная работа внутри песочницы:

Если агент пишет файлы в session_path/project/ — подтверждение не требуется. Это сознательное решение: папка проекта изолирована, агент может свободно экспериментировать с кодом без постоянных диалогов.

sessions/20250325_143052_my-task/
└── project/           # ← Агент может свободно писать сюда
    ├── main.py
    ├── config.yaml
    └── tests/

Если агент попытается написать в /etc/nginx/nginx.conf — увидит красное предупреждение и пользователь должен явно разрешить.

SHA256-проверка:

Для защиты от гонок (race conditions) code_editor поддерживает expected_sha256:

code_editor(
    action="replace",
    path="main.py",
    old_text="version = '1.0'",
    new_text="version = '1.1'",
    expected_sha256="abc123..."  # SHA256 файла до изменений
)

Если файл изменился с момента чтения — операция отклонится. Агент должен перечитать файл и получить новый хеш.

shell_exec: выполнение команд

Самый мощный и опасный инструмент — прямой доступ к shell. Всегда требует подтверждения, даже для простых команд.

shell_exec(
    command="docker-compose up -d",
    cwd="/var/www/project",
    interactive=True,    # Интерактивный режим (ввод паролей и т.д.)
    timeout_sec=120
)

Интерактивный режим:

Если interactive=True (по умолчанию), команда запускается в «честном» терминале:

  • Пользователь видит живой вывод

  • Можно вводить пароли, подтверждения

  • После завершения — можно оставить комментарий для агента

--- Запуск интерактивной команды (CWD: /var/www/project) ---
[вывод команды в реальном времени]
...

Команда завершена.
Нажмите Enter для возврата или введите комментарий для модели: _

Ограничения:

  • Таймаут по умолчанию 120 секунд (настраивается)

  • Вывод обрезается до 256KB

  • Команда выполняется от имени пользователя, запустившего Ботинка

Когда нужны опасные инструменты

Сценарий

Инструменты

Анализ логов, поиск файлов

file_system, journal — безопасные

Поиск в интернете, чтение статей

web_search, open_url — безопасные

Написание нового кода

code_editor внутри песочницы — безопасно

Правка конфигов системы

code_editor + подтверждение

Установка пакетов, docker

shell_exec + подтверждение

Перезапуск сервисов

shell_exec + подтверждение

Философия безопасности:

  1. Default deny — по умолчанию агент ничего не может менять

  2. Explicit enable — пользователь явно включает опасный режим

  3. Per-action confirm — каждое действие подтверждается

  4. Isolated workspace — есть безопасная песочница для экспериментов

  5. Transparent logging — все действия логируются в сессию

Skills: направляем интеллект, а не расширяем его

После опасных инструментов логично рассказать про skills — систему, которая меня особенно вдохновила. Это не очередной инструмент в классическом смысле, а способ дать агенту «целевую установку» на решение конкретного класса задач.

Что такое skill по сути

В отличие от инструментов, skill ничего не делает сам по себе. Это просто файл с промптом — инструкцией, которая говорит агенту: «Вот как нужно подходить к задачам такого типа». Skill не добавляет новых возможностей, он помогает использовать существующие инструменты целенаправленно.

Представьте: у агента есть shell_exec, file_system, journal. Он может делать что угодно. Но если вы просите «настроить nginx», агент может пойти разными путями — проверить конфиг, посмотреть логи, перезапустить сервис… А может сразу начать править конфиг без диагностики.

Skill «nginx-troubleshooting» скажет агенту: «Сначала проверь статус сервиса, потом логи, только потом лезь в конфиг». Это не новая команда — это упорядочивание мышления.

Структура skill

Простейший skill — это markdown-файл с определённой структурой:

---
name: nginx-troubleshooting
description: Пошаговая диагностика проблем nginx
tags: [nginx, web, troubleshooting, logs]
author: user
version: 1.0
---

# Nginx Troubleshooting Guide

При диагностике проблем nginx следуй этому алгоритму:

1. **Проверь статус сервиса**
   - `systemctl status nginx`
   - Если не активен — проверь конфиг: `nginx -t`

2. **Анализ логов**
   - Сначала errors: `journalctl -u nginx -p err`
   - Потом access логи если нужно

3. **Проверь upstream**
   - Если 502/503 — проверь backend
   - Проверь что порт открыт: `ss -tlnp | grep <port>`

4. **Конфигурация**
   - Только после диагностики правь конфиг
   - Всегда делай `nginx -t` перед reload

ВАЖНО: Не перезапускай nginx без понимания причины проблемы!

Когда агент загружает этот skill, промпт добавляется в системный контекст. Теперь при задаче «почини nginx» агент будет следовать этому алгоритму.

Идея skills в индустрии

Концепция Agent Skills сейчас активно развивается. Anthropic представила skills как способ дать Claude доменно-специфичные знания. Есть официальный репозиторий anthropics/skills с примерами. Появляются агрегаторы типа ClaudeSkills.org и Agent-Skills.cc.

Репозиторий навыков ClawHub

Я подключил Ботинка к ClawHub — открытому репозиторию skills. Главная фишка: агент может сам найти, изучить и установить нужный skill.

botinok "Мне нужно настроить CI/CD пайплайн для Python-проекта"

# Агент:
# 1. Ищет в ClawHub: skill search "ci cd python"
# 2. Находит: python-ci-cd-guide v2.1
# 3. Читает описание, решает что подходит
# 4. Скачивает и распаковывает в ~/.botinok/skills/
# 5. Загружает промпт в контекст
# 6. Приступает к задаче по алгоритму из skill

Это создаёт эффект «самообучения» — агент не просто выполняет задачу, но и подтягивает экспертизу из сообщества.

Как это работает в Ботинке

Действия skills инструмента:

Action

Что делает

Пример

list

Список установленных skills

list

search

Поиск в ClawHub

search query="docker nginx"

install

Скачать и установить

install skill_id="nginx-hardening"

load

Загрузить в контекст

load name="nginx-troubleshooting"

info

Информация о skill

info name="nginx-troubleshooting"

Структура папки skills:

~/.botinok/skills/
├── nginx-troubleshooting/
│   ├── skill.md           # главный промпт
│   ├── metadata.json      # метаданные
│   └── examples/          # примеры использования
├── docker-diagnosis/
│   └── skill.md
└── python-testing/
    └── skill.md

Сверхидея: коллективный опыт

Skills — это шаг к коллективному интеллекту AI-агентов. Представьте:

  1. Вы создали skill для диагностики специфической проблемы в вашем стеке

  2. Опубликовали в ClawHub

  3. Другой пользователь в другой компании скачал

  4. Его агент работает по вашему алгоритму

  5. Пользователь улучшил skill, запушил обновление

  6. Ваш агент обновился и стал умнее

Это не магия обучения модели — это обмен промптами. Но эффект похож: знания распространяются между агентами, накапливаются, улучшаются.

Чем это круто:

  • Локальные агенты получают «доступ к знаниям сообщества»

  • Не нужно переобучать модель — достаточно обновить skill

  • Можно создать skill под конкретный стек/компанию

  • Открытый формат — любой может создать и опубликовать

Ограничения:

  • Skill работает только пока загружен в контекст

  • Качество зависит от автора skill

  • Нужен механизм валидации и рейтинга

Практический пример

botinok "Настрой firewall для веб-сервера, открой только 80 и 443"

# Без skill агент может:
# - Сразу начать писать iptables rules
# - Не проверить текущие правила
# - Забыть про SSH и потерять доступ

# С skill "firewall-safe-setup":
botinok "Установи skill firewall-safe-setup и настрой firewall"

# Агент:
# 1. skills action="search" query="firewall"
# 2. skills action="install" skill_id="firewall-safe-setup"
# 3. skills action="load" name="firewall-safe-setup"
# 4. Следует алгоритму из skill:
#    - Проверяет текущие правила
#    - Убеждается что SSH разрешён
#    - Добавляет правила по одному
#    - Проверяет связность после каждого

Когда skills полезны

Сценарий

Как помогает skill

Новая технология

Даёт пошаговый алгоритм

Типовые задачи

Стандартизирует подход

Командная работа

Все агенты следуют одним best practices

Обучение новичка

Skill как «шпаргалка» для агента

Специфический стек

Можно создать свой skill

Skills vs Experience: в чём разница

Skills и experience перекликаются, но это разные концепции:

Аспект

Skills

Experience

Фокус

Как делать правильно

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

Источник

Создаются вручную или агентом

Автоматически из ошибок

Формат

Пошаговый алгоритм

Запись о проблеме и решении

Обновление

Явное, через файл

Автоматическое в процессе работы

Обмен

ClawHub, сообщество

Локальный, личный опыт

Experience — это «шрамы» от ошибок. Агент запомнил, что бинарные файлы нельзя читать как текст, и больше так не делает. Это негативный опыт, который копится автоматически.

Skills — это «рецепты» успеха. Проверенный алгоритм, который работает. Его нужно явно создать и загрузить, но зато можно поделиться с другими.

Создание skill: руками или агентом

Создать skill просто — это обычный markdown-файл. Можно написать вручную:

# Создаём skill для своего проекта
mkdir -p ~/.botinok/skills/my-project-deploy
cat > ~/.botinok/skills/my-project-deploy/skill.md << 'EOF'
---
name: my-project-deploy
description: Деплой нашего Flask-проекта
tags: [flask, deploy, docker]
---

# Деплой MyProject

1. Проверь тесты: pytest tests/
2. Обнови версию в __init__.py
3. Собери docker image: docker build -t myproject:latest .
4. Останови старый контейнер
5. Запусти новый с правильными env vars
6. Проверь health endpoint
EOF

Но есть и более интересный способ — попросить агента создать skill по результатам успешной работы:

botinok "Мы только что успешно настроили мониторинг. Создай skill на основе этого опыта, чтобы в следующий раз алгоритм был готов"

# Агент:
# 1. Анализирует что было сделано (из history сессии)
# 2. Выделяет ключевые шаги
# 3. Формирует структурированный промпт
# 4. Сохраняет в ~/.botinok/skills/monitoring-setup/skill.md

Это превращает разовый успех в повторяемый алгоритм. Агент сам структурирует свой опыт и делает его доступным для будущих задач.

Сессии как контейнеры работы

Сессия — это не просто лог, а контейнер для работы. Каждая сессия изолирована, но при этом не закрыта — агент может смотреть в другие сессии, искать информацию, переносить идеи.

Интерактивный выбор при старте

При запуске в интерактивном режиме Ботинок предлагает выбрать стратегию:

╭─ Старт BOTINOK: выбрать сессию ─────────────────────────╮
│                                                         │
│  ❯ Продолжить последнюю: 20250325_143052_nginx-debug   │
│    Выбрать другую сессию                                │
│    Начать новую сессию                                  │
│                                                         │
╰─────────────────────────────────────────────────────────╯

Продолжить последнюю — мгновенно загружает последнюю сессию с хвостом последнего ответа агента. Контекст восстанавливается, можно продолжить с того же места.

Выбрать другую сессию — список всех сессий с превью:

╭─ Выберите сессию для продолжения ─────────────────────────────────────────╮
│                                                                          │
│  20250325_143052_nginx-debug   │ 2025-03-25 14:30 │ Разберись почему...  │
│  20250324_091523_docker-setup  │ 2025-03-24 09:15 │ Настрой docker...    │
│  20250323_185012_log-analysis  │ 2025-03-23 18:50 │ Проанализируй...     │
│  20250322_120000_api-dev       │ 2025-03-22 12:00 │ Напиши REST API...   │
│                                                                          │
╰──────────────────────────────────────────────────────────────────────────╯

Видно имя сессии, время последней активности и первый запрос пользователя.

Новая сессия — чистый лист, новая папка, пустая история.

Сценарий: Исследование → Исправление

Один из ключевых паттернов работы:

# Шаг 1: Исследование в безопасном режиме
botinok "Проанализируй почему падает сервис авторизации"

# Агент изучает логи, конфиги, код...
# Выявляет проблему: неправильный формат JWT токена
# Сохраняет анализ в сессию 20250325_143052_auth-debug

# Шаг 2: Переключение в опасный режим для исправления
botinok --dangerous
# Выбираем: "Продолжить последнюю: 20250325_143052_auth-debug"

# Агент видит предыдущий анализ, понимает контекст
# Предлагает исправление кода
# Пользователь подтверждает

Почему это важно:

  • Исследование безопасно — агент ничего не меняет

  • Контекст сохранён — не нужно заново объяснять проблему

  • Исправление осознанно — пользователь явно включает опасный режим

Сценарий: Многодневный проект

sessions/
├── 20250320_api-design/       # День 1: Проектирование API
├── 20250321_api-impl/         # День 2: Реализация
├── 20250322_api-tests/        # День 3: Тесты
└── 20250323_api-deploy/       # День 4: Деплой

Каждая сессия — отдельный этап. Но агент может обращаться к предыдущим:

botinok "Продолжи работу над API. Посмотри что было сделано в прошлых сессиях"

# Агент:
# 1. Читает sessions/20250320_api-design/response.md
# 2. Читает sessions/20250321_api-impl/project/main.py
# 3. Понимает контекст проекта
# 4. Продолжает работу

Сессия как песочница

session_path/project/ — изолированная папка для кода:

sessions/20250325_143052_my-feature/
├── project/              # ← Песочница
│   ├── main.py           # Код, созданный агентом
│   ├── config.yaml
│   └── tests/
│       └── test_main.py
├── context.json          # Структурированная история (JSON)
├── response.md           # ← Весь диалог сессии (Markdown)
├── thinking.md           # ← Размышления модели (Markdown)
└── artifacts/            # Большие файлы

Два главных файла для анализа

response.md и thinking.md — это ключевые файлы для быстрого анализа работы сессии.

response.md — полная хронология диалога:

---
type: BOTINOK_SESSION_METADATA
status: START
timestamp: 2025-03-25T14:30:52
model: qwen3.5:4b
context_limit: 8192
prompt: |
  Проанализируй почему nginx отдаёт 502
---

## Ассистент

Проанализирую конфигурацию nginx и логи...

### Вызов инструмента: file_system

**Action:** read
**Path:** /etc/nginx/sites-enabled/default

### Результат

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

---

## Пользователь

А что с php-fpm?

## Ассистент

Проверю статус сервиса...

thinking.md — поток размышлений модели (chain-of-thought):

---
type: BOTINOK_SESSION_METADATA
status: START
---

Анализирую конфигурацию nginx...
Нужно проверить:
1. Работает ли backend на порту 8000
2. Нет ли ошибок в логах
3. Корректна ли конфигурация proxy_pass

Пользователь спрашивает про php-fpm, но в конфиге вижу proxy_pass на порт 8000 — это FastAPI или подобный backend, не PHP. Нужно уточнить архитектуру...

Почему Markdown:

Преимущество

Описание

Человекочитаемость

Любой текстовый редактор, cat, less, nano

MD-рендеринг

GitHub, VS Code, Obsidian, Typora — красивое отображение

Поиск

grep, ripgrep — текстовый поиск по всем сессиям

Бот-доступ

Агент читает через file_system read без парсинга JSON

Diff-friendly

Git-совместимо, можно версионировать

Быстрый анализ человеком:

# Просмотр диалога
less sessions/20250325_143052/response.md

# Поиск по всем сессиям
grep -r "CORS" sessions/*/response.md

# Последние ответы
tail -100 sessions/20250325_143052/response.md

# В VS Code с предпросмотром
code sessions/20250325_143052/

Быстрый анализ ботом:

botinok "Посмотри что мы делали в прошлой сессии с nginx"

# Агент:
# 1. file_system action="read" path="sessions/20250324.../response.md"
# 2. Видит всю историю в удобном формате
# 3. Резюмирует: "Вы настраивали proxy_pass для FastAPI backend..."

Отличие от context.json:

Файл

Формат

Назначение

context.json

JSON

Структурированные данные для API, восстановление состояния

response.md

Markdown

Человекочитаемая хронология диалога

thinking.md

Markdown

Поток размышлений для анализа логики агента

JSON нужен для технического восстановления контекста. Markdown — для понимания «что произошло» человеком или ботом через обычный текстовый просмотр.

Преимущества песочницы:

  • Агент может свободно писать код без подтверждений

  • Эксперименты не ломают основной проект

  • Можно удалить всю сессию — и код исчезнет

  • Можно скопировать project/ в рабочую директорию

Но нет полной изоляции:

Агент может:

  • Читать файлы из других сессий

  • Искать по всем сессиям через file_system grep

  • Обращаться к любым путям в системе (с подтверждением)

Это мягкая изоляция — сессия как рабочая область, а не как песочница в security-смысле.

Сценарий: Поиск в истории сессий

botinok "Найди где мы обсуждали проблему с CORS, было это на прошлой неделе"

# Агент:
# 1. file_system action="grep" path="sessions" pattern="*.md" content_query="CORS"
# 2. Находит: sessions/20250318_091234_frontend/response.md
# 3. Читает контекст, резюмирует обсуждение

История сессий — это база знаний. Все разговоры, весь код, все артефакты доступны для поиска.

Сценарий: Режим корректора в отдельной сессии

При использовании --proofread, корректор работает в подпапке сессии:

sessions/20250325_143052_api-code/
├── project/              # Код исполнителя
│   └── main.py
├── proofreader/          # Контекст критика
│   └── context.json      # Отдельная история
├── context.json          # История исполнителя
└── ...

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

Практические советы

Когда создавать новую сессию:

  • Новая задача, не связанная с предыдущими

  • Эксперимент, который может не сработать

  • Разный контекст (разные серверы, проекты)

Когда продолжать старую:

  • Продолжение работы над той же задачей

  • Нужно вернуться к анализу через несколько дней

  • Переключение между безопасным и опасным режимом

Именование сессий:

Сессия автоматически именуется по времени создания: 20250325_143052. Но можно добавить суффикс через имя папки при ручном создании:

# Сессии именуются автоматически: sessions/20250325_143052/
# При продолжении сессии видно превью первого запроса
# Это помогает найти нужную работу в списке

Имя помогает найти нужную сессию в списке — превью первого запроса показывается при выборе.

Архивация:

Сессии не удаляются автоматически. Можно:

# Архивировать старые сессии
tar -czf sessions_archive_$(date +%Y%m).tar.gz sessions/202503*

# Очистить папку
rm -rf sessions/202503*

Или просто оставить — дисковое место дешёвое, а история бесценна.

Продвинутый консольный UI

На базе библиотеки Rich — с цветами, панелями, живой статистикой:

┌─────────────────────────────────────────────────────────────────┐
│ BOTINOK AGENT | Model: qwen3.5:4b | Context: 8192 | 4.2GB VRAM │
├─────────────────────────────────────┬───────────────────────────┤
│                                     │ Performance               │
│  Thinking...                        │ Status: Generating... ⠋   │
│  - Анализирую структуру проекта     │ TTFT: 2.34s               │
│  - Нужно проверить зависимости      │ Thinking: 156 tokens      │
│                                     │ Response: 89 tokens       │
│  Response:                          │ TPS: 28.5                 │
│  Проект использует FastAPI...       │                           │
│                                     │ SessionCtx: 2341/8192     │
│                                     │ ████████░░░░ 28.6%        │
├─────────────────────────────────────┴───────────────────────────┤
│ Prompt: Проанализируй структуру проекта                           │
└─────────────────────────────────────────────────────────────────┘

Отслеживаем:

  • TTFT (Time To First Token) — время до первого токена

  • TPS (Tokens Per Second) — скорость генерации

  • VRAM usage — потребление видеопамяти

  • Context fill — заполнение контекстного окна

Умное управление контекстом

Это главная фишка для работы с малым VRAM.

Когда контекст переполняется, Ботинок:

  1. Сохраняет полную историю в артефакт

  2. Просит модель сгенерировать SESSION_PROTOCOL — краткий протокол сессии

  3. Очищает контекст, оставляя только протокол

  4. Продолжает работу

SESSION_PROTOCOL
reason: context_overflow
key_facts:
- Проект использует FastAPI + SQLAlchemy
- Найдены 3 критические ошибки в auth.py
- Исправлена проблема с CORS
next_steps:
- Добавить тесты для auth module
- Проверить migration scripts

Система навыков (Skills)

Навыки — это расширения функционала. Каждый навык — папка с файлом SKILL.md:

~/.botinok/skills/          # личные навыки
./skills/                   # навыки проекта
  └── excel/
      └── SKILL.md          # описание возможностей

Навыки автоматически обнаруживаются и подключаются. Есть интеграция с ClawHub.ai — базой навыков сообщества.

Безопасность

По умолчанию опасные инструменты отключены:

# Безопасный режим (только чтение)
botinok "Проанализируй логи"

# Опасный режим (запись, shell)
botinok --dangerous "Исправь баги в коде"

При shell_exec агент всегда спрашивает подтверждение перед выполнением команды.

Установка и запуск

Быстрый старт

# 1. Установить Ollama
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen3.5:4b

# 2. Установить Ботинок
curl -sSL https://raw.githubusercontent.com/siv237/botinok/main/install.sh | sudo bash

# 3. Запустить
botinok

Режимы работы

# Интерактивный режим
botinok

# Одиночный запрос
botinok "Найди ошибки в /var/log/syslog"

# Режим для скриптов (без UI)
botinok --stealth "Сколько свободной памяти?"

# Pipe mode
tail -100 /var/log/nginx/error.log | botinok "Проанализируй ошибки"

# Выбор модели и контекста
botinok -m qwen3.5:9b -c 16384 --dangerous

# Режим «Разработчик + Критик» (цикл Исполнитель -> Корректор)
botinok --proofread "Напиши REST API для блога на FastAPI"

Режим «Разработчик + Критик» (–proofread)

Отдельно стоит рассказать про режим корректора. Это экспериментальная фича, которая запускает двух агентов подряд:

  1. Исполнитель (Developer) — решает задачу, пишет код, вызывает инструменты

  2. Критик (Proofreader) — читает результат в read-only режиме, проверяет качество, указывает на ошибки

┌─────────────────────────────────────────────────────────────────┐
│ PROOFREADER AGENT | Model: qwen3.5:4b | Context: 8192 | ...     │
├─────────────────────────────────────────────────────────────────┤
│ Критик анализирует ответ исполнителя...                          │
│ - Проверяет логику кода                                         │
│ - Ищет потенциальные баги                                       │
│ - Предлагает улучшения                                          │
└─────────────────────────────────────────────────────────────────┘

Критик работает в read-only режиме — может читать файлы, но не может их менять или выполнять shell-команды. Это безопасный способ получить «второе мнение» по задаче.

Как это работает под капотом

Архитектура

botinok.py                 # главный модуль, UI, основной цикл
├── core/
│   ├── session_manager.py # управление сессиями, артефакты
│   ├── tool_manager.py    # загрузка и выполнение инструментов
│   └── config_wizard.py   # настройка Ollama URL, модели
└── tools/
    ├── file_system.py     # работа с файлами
    ├── code_editor.py     # редактирование кода
    ├── web_search.py      # поиск в интернете
    ├── github.py          # работа с репозиториями
    ├── experience.py      # база опыта
    └── skills.py          # система навыков

Структура сессии и полная хронология

Каждый запуск создаёт директорию с исчерпывающей историей работы. Агент всегда может полагаться на файлы сессии — они хранят всю хронологию, включая служебные события, и доступны для анализа в любой момент.

sessions/20250325_143052_my-task/
├── context.json        # полная история диалога в структурированном виде
├── thinking.md         # поток размышлений модели (chain-of-thought)
├── response.md         # финальные ответы ассистента
├── tools.log           # каждый вызов инструмента: args, result, size, status
├── session_raw.log     # сырые чанки стрима с timestamp и delta_sec
├── performance.log     # метрики: TPS, VRAM, context fill по шагам
├── steps/              # JSON-снимки каждого шага (request/response)
│   ├── step_001.json
│   └── step_002.json
├── artifacts/          # большие ответы инструментов
│   ├── web_search_xxx.json
│   ├── file_read_yyy.txt
│   └── context_overflow_full_zzz.json
├── project/            # файлы проекта по умолчанию
│   └── main.py
└── proofreader/        # история режима корректора
    └── context.json

context.json — полная история

Главный файл сессии. Хранит каждое сообщение с временными метками:

{
  "session_id": "20250325_143052_my-task",
  "created_at": "20250325_143052",
  "history": [
    {
      "timestamp": "2025-03-25T14:30:52.123456",
      "role": "user",
      "content": "Проанализируй логи nginx"
    },
    {
      "timestamp": "2025-03-25T14:30:54.234567",
      "role": "assistant",
      "content": "...",
      "thinking": "Нужно проверить файл логов...",
      "tool_calls": [
        {"name": "file_system", "arguments": {"action": "read", "path": "/var/log/nginx/error.log"}}
      ]
    },
    {
      "timestamp": "2025-03-25T14:30:55.345678",
      "role": "tool",
      "content": "TOOL_RESULT_SUMMARY\ntool: file_system\nsize_kb: 234.5\n..."
    },
    {
      "timestamp": "2025-03-25T14:31:02.456789",
      "role": "system",
      "content": "Контекст был автоматически сокращён... Старые сообщения сохранены в артефакт: artifacts/context_overflow_full_..."
    }
  ]
}

Обратите внимание: служебные события тоже попадают в историю. Очистка контекста, ошибки HTTP, протоколы сессии — всё сохраняется с role: "system".

session_raw.log — посекундная хронология

Каждый чанк стрима логируется с точным временем и дельтой от предыдущего:

{"timestamp": "2025-03-25T14:30:53.123456", "delta_sec": 0.0, "type": "thinking", "content": "Анализирую..."}
{"timestamp": "2025-03-25T14:30:53.156789", "delta_sec": 0.033, "type": "thinking", "content": " запрос"}
{"timestamp": "2025-03-25T14:30:53.190123", "delta_sec": 0.033, "type": "response", "content": "Нужно"}
{"timestamp": "2025-03-25T14:30:54.456789", "delta_sec": 1.266, "type": "metrics", "metrics": {"tps": 28.5, "vram_gb": 4.2}}

Это позволяет восстановить точную картину работы: где были задержки, сколько времени заняло мышление, когда пришли метрики.

tools.log — прозрачность инструментов

Каждый вызов инструмента фиксируется полностью:

{
  "timestamp": "2025-03-25T14:30:55.123456",
  "tool": "file_system",
  "arguments": {"action": "read", "path": "/var/log/nginx/error.log"},
  "status": "success",
  "size_kb": 234.56,
  "full_result": "2025/03/25 14:30:01 [error] ......"
}

Размер результата — важная метрика. Если ответ инструмента больше 100KB, он автоматически обрезается в контексте, но полный текст сохраняется в artifacts/.

Агент всегда может вернуться к истории

В системном промпте агенту сообщается расположение всех файлов сессии:

SESSION_FILES_AND_LAYOUT
- context_json: sessions/.../context.json
- response_md: sessions/.../response.md
- thinking_md: sessions/.../thinking.md
- tools_log: sessions/.../tools.log
- artifacts_dir: sessions/.../artifacts/

Это значит агент может:

  • Перечитать свои предыдущие ответы из response.md

  • Найти детали вызова инструмента в tools.log

  • Загрузить обрезанный контекст из artifacts/

  • Проанализировать свои размышления в thinking.md

Прозрачность для пользователя — в любой момент можно открыть папку сессии и увидеть полную картину. Не нужно включать «режим отладки» или искать логи в системе — всё лежит в одном месте.

Поток обработки

# Упрощённая схема основного цикла
while True:
    # 1. Отправляем запрос в Ollama с tool definitions
    response = ollama_chat(
        model=model,
        messages=messages,
        tools=tool_definitions,
        stream=True
    )

    # 2. Стримим ответ, собираем thinking и tool_calls
    for chunk in response:
        handle_thinking(chunk.thinking)
        handle_content(chunk.content)
        collect_tool_calls(chunk.tool_calls)

    # 3. Если есть tool_calls — выполняем инструменты
    if tool_calls:
        for call in tool_calls:
            result = execute_tool(call.name, call.args)
            messages.append(tool_result_message(result))
        continue  # следующий раунд

    # 4. Иначе — финальный ответ
    break

Работа с VRAM

Для моделей типа qwen3.5:9b на 8GB VRAM есть трюк:

# Принудительная выгрузка моделей перед загрузкой большой
if "qwen3.5:9b" in model:
    unload_all_models()
    time.sleep(1)  # даём Ollama время освободить память

Плюс мониторинг через /api/ps — если загружено несколько моделей, выгружаем лишние.

База опыта: обучаем агента на своих ошибках

Одна из идей, которая меня увлекла — а что если агент будет учиться на своём опыте? Не просто помнить контекст текущей сессии, а накапливать знания между сессиями, между задачами.

Идея

Когда я работаю над задачей, я часто наступаю на одни и те же грабли. Забываю, что бинарные файлы нельзя читать как текст. Пытаюсь использовать grep по огромным логам без фильтрации. Не проверяю статус сервиса перед тем как смотреть логи.

А что если агент будет запоминать:

  • Позитивный опыт — что сработало хорошо

  • Негативный опыт — на чём споткнулся

И при следующей похожей задаче — подсказывать себе: «Эй, в прошлый раз тут была проблема, делай иначе».

Как это работает

Опыт хранится глобально, вне сессий:

~/.botinok/experience/
├── positive/                    # Успешные решения
│   ├── 20250325_143052_docker-logs-filter.json
│   └── 20250324_091523_journal-priority.json
├── negative/                    # Ошибки и грабли
│   ├── 20250320_185012_binary-read-error.json
│   └── 20250318_120000_grep-huge-log.json
└── index.json                   # Индекс для быстрого поиска

Запись позитивного опыта:

experience(
    action="add_positive",
    title="Фильтрация docker logs по времени",
    description="При анализе логов контейнеров лучше сначала ограничить по времени",
    tags=["docker", "logs", "filter"],
    solution="docker logs --since='1 hour ago' container_name"
)

Запись негативного опыта:

experience(
    action="add_negative",
    title="Чтение бинарных файлов как текст",
    description="Попытка прочитать .db файл через file_system read ломает вывод",
    tags=["file", "binary", "error"],
    error_context="file_system read на /var/data/database.db вернул мусор и сломал контекст"
)

Автоматическое использование

Агент может проверить опыт перед началом работы:

botinok "Проанализируй логи docker контейнера"

# Агент внутри:
# 1. experience action="check" title="docker logs"
# 2. Находит: positive/docker-logs-filter.json
# 3. Видит решение: использовать --since
# 4. Применяет: docker logs --since='1 hour ago' ...

Это не магия — агент сам решает проверить опыт, если в системном промпте есть рекомендация. Но это создаёт эффект «обучения».

Пример записи опыта

{
  "type": "positive",
  "title": "journalctl priority filter",
  "description": "При поиске ошибок в systemd логах эффективнее сразу фильтровать по priority",
  "tags": ["journal", "systemd", "logs", "filter"],
  "solution": "journalctl -p err -u service_name",
  "timestamp": "2025-03-24T09:15:23"
}

Когда это полезно

Сценарий

Как помогает опыт

Анализ логов

Напоминает про фильтры по времени/уровню

Работа с файлами

Предупреждает про бинарные файлы

Docker

Подсказывает типовые команды диагностики

Git

Напоминает про git log --oneline -n 20

Ошибки API

Запоминает типовые паттерны ошибок

Ограничения

Это не replacement для полноценного обучения модели. Опыт:

  • Хранится локально, не переносится на другие машины

  • Требует явного вызова инструмента

  • Не влияет на веса модели — только на контекст

Но для личного использования — это способ сделать агента «умнее» именно в ваших типовых задачах. Он начинает помнить, как вы привыкли работать, какие инструменты предпочитаете, на чём обычно спотыкается.

Почему Ollama

Отдельно стоит рассказать про выбор Ollama как бэкенда для моделей. Это не единственный вариант, но для моего сценария оказался оптимальным.

Что такое Ollama

Ollama — это локальный сервер для запуска LLM с простым HTTP API. По сути, это «Docker для моделей»: одна команда установки, одна команда для скачивания модели, и всё работает.

Сила Ollama в простоте:

# Установка (Linux)
curl -fsSL https://ollama.com/install.sh | sh

# Скачивание модели
ollama pull qwen3.5:4b

# Готово — модель работает
ollama run qwen3.5:4b

Никакой возни с Python-окружением, CUDA, зависимостями. Ollama сам подтягивает всё нужное и предоставляет унифицированный API. Модели упакованы в оптимизированные квантованные версии (GGUF), что позволяет запускать их на потребительском железе.

Репозиторий моделей

Ollama hosts собственный репозиторий моделей — тысячи вариантов, от крошечных 1B до полноценных 70B. Есть модели для кода, для русского языка, для инструментов (function calling).

# Популярные модели для агентов
ollama pull qwen3.5:4b      # 2.6GB — минимальный вариант
ollama pull qwen3.5:14b     # 9GB — золотая середина
ollama pull llama3.3:70b    # 40GB — для мощных машин
ollama pull gemma3:12b      # для задач с визуальным контекстом

Облачные модели — приятная возможность

Помимо локальных моделей, Ollama поддерживает и облачные. Начиная с конца 2025 года, интегрированы API популярных облачных провайдеров. Можно переключаться между локальными и облачными моделями, не меняя ни строчки кода.

# Локальная модель (бесплатно, на своём железе)
ollama run qwen3.5:4b

# Облачная модель (бесплатно с лимитами)
ollama run qwen3.5:cloud
ollama run GLM-5:cloud
ollama run minimax-m2.7:cloud

Для Ботинка это означает: тот же скрипт работает и с локальными моделями на слабом железе, и с мощными облачными LLM. Достаточно поменять модель в конфиге — и агент становится «мегаумным».

Почему это круто:

  • GLM-5:cloud — отличная модель от китайского Zhipu AI, хорошо работает с кодом и русским языком

  • minimax-m2.7:cloud — мощная модель от MiniMax, большой контекст, сильная логика

  • qwen3.5:cloud — облачная версия Qwen, превосходит локальные квантованные версии

Бесплатные лимиты: Ollama предоставляет щедрые бесплатные лимиты для облачных моделей — миллионы токенов в месяц. Лимиты обновляются ежедневно и еженедельно. Для личного использования хватит с запасом.

Как это работало на практике

Часть кода Ботинка была написана им самим через эти облачные модели. Я описывал задачу, агент генерировал код через code_editor, я проверял и уточнял. Это не «AI написал весь проект», а интерактивная разработка: я задаю направление, модель пишет boilerplate, я правлю логику.

Особенно это помогло с инструментами — file_system, journal, github. Агент сам разбирался в структуре проекта, предлагал улучшения, ловил баги. С облачными моделями это работает на удивление хорошо.

Мой сетап

У меня Ollama крутится на домашнем сервере с видеокартой P104-100 — это урезанная P104-100 майнинг-карта с 8GB VRAM. Стоит копейки на вторичке, для инференса LLM — отличное решение.

Основные тесты делал на qwen3.5:4b — самая лёгкая модель с нормальной поддержкой function calling. И знаете что? Из неё можно извлекать пользу. Медленно, с ошибками, иногда путается — но работает. Для простых задач «прочитай логи и найди ошибки» или «покажи конфиг nginx» вполне достаточно.

Но надеяться на результаты как с облачными моделями не приходится. qwen3.5:4b — это «велосипед», а облачные модели — «спортивный мотоцикл». Оба едут, но скорость и комфорт разные.

Итог по Ollama

Аспект

Локальные модели

Облачные модели

Стоимость

Бесплатно, своё железо

Бесплатно с лимитами

Приватность

Полная, данные не уходят

Данные через API провайдера

Качество

Зависит от модели и железа

Топовое, latest & greatest

Скорость

Зависит от GPU

Зависит от сети

Доступность

Всегда

Нужен интернет

Ollama даёт оба варианта в едином интерфейсе. Для Ботинка это идеальное решение: на слабом сервере работает qwen3.5:4b, когда нужна мощь — переключаюсь на облачные модели.

Куда развивается концепция

Текущий Ботинок — это «толстый клиент». Вся логика упакована в один CLI-скрипт, что удобно для одиночного использования, но плохо масштабируется. Логичный следующий шаг — разделение на сервер и легковесных агентов.

Идея простая: центральный сервер держит Ollama, хранит все сессии, копит experience, управляет skills. На целевые машины ставится только крошечный агент, который получает команды и возвращает результаты. Один «мозг» — много «рук».

Технологии, которые считаю перспективными для развития:

  • RAG и векторные базы — индексация всех сессий, семантический поиск похожих случаев, подгрузка релевантного опыта вместо раздувания контекста

  • WebSocket-протокол — двусторонняя связь между сервером и агентами в реальном времени

  • Централизованный experience — опыт, накопленный на одном сервере, автоматически доступен агентам на других машинах

  • Skill-синхронизация — сервер как точка распространения навыков для всех агентов

Это не ближайшие планы, а общее направление. Концепция «запустил — поработал — закрыл» останется, но для тех, кто управляет множеством серверов, серверная архитектура даст единый центр знаний.

Технические требования

  • Python 3.8+

  • Ollama (локально или удалённо)

  • Модель с Function Calling: qwen3.5, llama3.3, gemma3

  • Опционально: lynx (для web_search), git

Минимально работает на qwen3.5:4b с контекстом 8192 на 8GB VRAM.

Ссылки


Вопрос к сообществу: какие инструменты/фичи добавили бы в консольного AI-агента? Что вам не хватает в существующих решениях?