Главная / Статьи

Безголовой двухагентный цикл программирования с OpenCode и Ollama

Как разделить планирование и анализ между двумя агентами в OpenCode с использованием Ollama, включая настройку прав доступа, навыков, правил цензуры, скриншотов и коммитов, доступных только для людей.

Издатель: REACTAPP.TOP11 мин чтения2623 слов

Источники: Ollama on Steroids with OpenCode: A Headless Multi Agent Coding Workflow

Большинство демонстраций работы ИИ в области программирования впечатляют до того момента, пока кто-то не задаст банальный инженерный вопрос: что именно произошло, кто это проверял, какие тесты выполнялись и можно ли воспроизвести весь процесс завтра?

Приведённый ниже рабочий процесс пытается на это ответить. Вместо чат-окна, который время от времени генерирует хороший исправление, здесь программирование с использованием ИИ рассматривается как небольшой инженерный цикл:

  • один агент планирует и реализует код
  • второй агент проверяет результат и утверждает его
  • каждому запросу выделяется собственная папка локальной сессии
  • при каждой работе остаётся след в виде логов и доказательств выполнения тестов
  • человек, а не агент, решает, когда код будет сохранён или отправлен
  • частные запросы и результаты сессий остаются конфиденциальными

Разделение труда: MiniMax разрабатывает планы и пишет код, GLM проверяет и утверждает их, OpenCode управляет рабочим процессом, а Ollama направляет запросы к моделям. Результатом не является какая-то волшебная автономность — это повторяющийся цикл, в ходе которого создаются планы, производятся проверки, тесты, снимаются скриншоты, выполняются проверки безопасности, после чего человек принимает решение о сохранении результатов.

Что касается инструментов, OpenCode предоставляет неинтерактивный режим запуска opencode run, возможность создания агентов, выбора моделей, использования флага --dir, а также возможность привязки запуска к безголовому экземпляру opencode serve. Сессии можно экспортировать с помощью параметра --sanitize. Ollama описывает интеграцию с OpenCode с помощью команды ollama launch opencode, а OpenCode читает конфигурацию проекта, информацию об агентах, разрешениях, навыках и серверах MCP.

В примере конфигурации модели Ollama Cloud называются minimax-m3:cloud и glm-5.1:cloud; MiniMax предназначен для программирования и выполнения задач агентами, а GLM описывается как флагманский инструмент для инженерии агентов. Сама схема не зависит от этих конкретных моделей. Рассматривайте имена моделей как примеры и проверяйте актуальный каталог Ollama перед их копированием. Здесь не предоставляются исходные запросы, результаты сессий, локальные пути, ключи и скриншоты из оригинального проекта — только метод.

Перестаньте рассматривать программирование с помощью ИИ как один чат

Одинокий агент для программирования имеет одну слабость, схожую с слабостью одинокого разработчика под давлением: он может убедить себя, что работа завершена. Повторное использование той же модели эту проблему не решает. Решение заключается в процессе:

Prompt -> Plan -> Review -> Implement -> Test -> Review -> Fix -> Signoff -> Human commit

Вот как выглядит макет:

control-workspace/
  AGENTS.md
  opencode.json
  .opencode/
    agents/
      minimax-builder.md
      glm-reviewer.md
    skills/
      opencode-ollama-agent-guardrails/
        SKILL.md
  agent-sessions/
    project-slug/
      promptNN/
        PROMPTNN_CODER.md
        PROMPTNN_REVIEWER.md
        PROMPTNN_PLAN.md
        PROMPTNN_PLAN_REVIEW.md
        PROMPTNN_IMPLEMENTATION.md
        PROMPTNN_TEST_RESULTS.md
        PROMPTNN_IMPLEMENTATION_REVIEW.md
        PROMPTNN_SIGNOFF.md
        redacted logs
        screenshot references
  product-repo/

Почему начинать с рабочего пространства родительского контроля? Только в репозитории продукта агент может не иметь доступа к файлам запросов, файлам сессий, общим правилам или более широкой структуре рабочего процесса. Абсолютные пути, в свою очередь, могут включать в логи информацию, специфичную для конкретной машины. Поэтому существует правило: запускайте OpenCode из родительского элемента, используйте относительные пути, храните изменения в продукте в его репозитории, а результаты работы сессии — вне него. Это звучит скучно, но именно поэтому такой подход работает.

Два агента с разными задачами

Ключевым элементом проектирования является не сама модель, а разделение задач.

Создатель

minimax-builder может планировать, редактировать код, запускать команды и записывать примечания к реализации. Его обязанности включают чтение запроса и файла AGENTS.md, составление плана, учет замечаний рецензента, реализацию только утвержденного объема работы, выполнение проверок, фиксацию изменений и сбоев, а также ожидание одобрения человека перед любым коммитом. Запрещено: делать коммиты, пушить изменения, использовать rebasing, force-pushing, переходить к следующему запросу, смягчать тесты и редактировать файлы, предназначенные для рецензента.

Рецензент

glm-reviewer по своей конструкции является строгим. Его список проверок: соответствует ли план запросу, осталась ли реализация в рамках утвержденного объема, имеют ли тесты смысл, изменялись ли сгенерированные файлы намеренно, подтверждают ли скриншоты браузера сделанные утверждения, разумно ли обрабатываются секретные данные, и не преувеличивает ли minimax-builder результаты своей работы?

Словарь решений этого инструмента минимален:

APPROVED
CHANGES_REQUESTED
SIGNED_OFF
NOT_SIGNED_OFF

Узкий словарный запас оставляет мало возможностей для маневра. Фраза «В целом выглядит хорошо» не является окончательным одобрением.

Конфигурация OpenCode

Вот как выглядит эта конфигурация:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "ollama/minimax-m3:cloud",
  "default_agent": "minimax-builder",
  "share": "disabled",
  "instructions": ["AGENTS.md"],
  "enabled_providers": ["ollama"],
  "permission": {
    "read": {
      "*": "allow",
      "*.env": "deny",
      "*.env.*": "deny",
      "*.env.example": "allow"
    },
    "glob": "allow",
    "grep": "allow",
    "webfetch": "ask",
    "websearch": "ask",
    "external_directory": "deny",
    "skill": {
      "*": "allow"
    }
  },
  "agent": {
    "minimax-builder": {
      "description": "Main planning and implementation agent.",
      "mode": "primary",
      "model": "ollama/minimax-m3:cloud",
      "temperature": 0.2,
      "permission": {
        "edit": {
          "*": "deny",
          "product-repo/**": "allow",
          "agent-sessions/project-slug/**": "allow"
        },
        "bash": {
          "*": "ask",
          "cd product-repo && *": "ask",
          "git status *": "allow",
          "git diff *": "allow",
          "git log *": "allow",
          "git commit *": "deny",
          "git push *": "deny",
          "git rebase *": "deny",
          "rm *": "deny"
        }
      }
    },
    "glm-reviewer": {
      "description": "Strict reviewer. Must not edit product code.",
      "mode": "primary",
      "model": "ollama/glm-5.1:cloud",
      "temperature": 0.1,
      "permission": {
        "edit": {
          "*": "deny",
          "agent-sessions/project-slug/**": "allow"
        },
        "bash": {
          "*": "ask",
          "git status *": "allow",
          "git diff *": "allow",
          "git log *": "allow",
          "grep *": "allow",
          "rg *": "allow",
          "git commit *": "deny",
          "git push *": "deny",
          "git rebase *": "deny",
          "rm *": "deny"
        },
        "task": "deny"
      }
    }
  }
}

Два момента заслуживают внимания. Разделение данных по умолчанию отключено, и поскольку в OpenCode существует опция share, установка её в значение "disabled" блокирует один из путей, предотвращая случайную утечку информации. У рецензента также отсутствуют широкие права на редактирование: он может записывать файлы с рецензией и подтверждением в папку сессии, но не должен изменять код, используемый в производстве. OpenCode предусматривает детальные правила разрешений для операций edit, bash, read, grep, glob, skill и других, поэтому сама конфигурация должна обеспечивать соблюдение рабочего процесса.

Пристосуйте пути к вашему собственному репозиторию. Принцип остается неизменным:

builder can edit product code;
reviewer can write review notes;
neither agent can commit or push;
external directories are denied;
dangerous shell commands ask or deny.

Навыки как портативные ограждения

Самым многократно используемым элементом являются не только файлы конфигурации, но и сами навыки. Навыки OpenCode — это многократно используемые определения в формате SKILL.md, хранящиеся в папках проектов или глобальных навыков. Стандартное местоположение на уровне проекта —:

.opencode/skills/<skill-name>/SKILL.md

Существуют также пути развития навыков, совместимые с Claude и агентами, но в данном рабочем процессе разумно оставить всё простым. Разместите навык ограничения здесь:

.opencode/
  skills/
    opencode-ollama-agent-guardrails/
      SKILL.md

Каждый файл SKILL.md должен содержать фронтматер с минимумом поля name и description. Имя должно быть написано строчными буквами, разделенными дефисами, и совпадать с именем папки. Навык-ограничитель может задавать агентам такие правила, как:

- Do not publish raw prompts.
- Do not publish raw session logs.
- Do not use absolute local paths.
- Do not edit outside the approved product directory.
- Do not claim success without test output.
- Do not weaken tests to make validation pass.
- Do not commit, push, rebase, or force-push.
- Store review notes separately from production code.
- Treat screenshots as sensitive evidence.
- Stop for human approval after signoff.

Правила кажутся простыми, но они предотвращают реальные ошибки. Если они находятся только в файле AGENTS.md определённого репозитория, они остаются там. Если же они упакованы в виде навыка, они сопровождают вас повсюду.

Режим без графического интерфейса обеспечивает воспроизводимость

Интерактивное программирование подходит для исследований. Режим без графического интерфейса лучше подходит для повторных запусков. Фрагмент кода, отвечающий за сборку, выглядит так:

opencode run \
  --model ollama/minimax-m3:cloud \
  --agent minimax-builder \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_CODER.md)"

И результат проверки:

opencode run \
  --model ollama/glm-5.1:cloud \
  --agent glm-reviewer \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_REVIEWER.md)"

Для более сложных конфигураций с серверами MCP достаточно запустить один раз локальный сервер OpenCode, а последующие запуски подключить к нему, тем самым избегая многократных полных запусков:

opencode serve --hostname 127.0.0.1 --port 4096

opencode run \
  --attach http://localhost:4096 \
  --agent minimax-builder \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_CODER.md)"

Подключите сервер к 127.0.0.1. Те, кто делает его доступным с другого устройства, должны установить значение OPENCODE_SERVER_PASSWORD и запускать его как настоящую службу разработки, поскольку в документации к CLI описывается аутентификация по HTTP с использованием этой переменной. Модель не стала умнее; просто стало сложнее её обмануть.

Хранение вводных данных и результатов без их утечки

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

Правило: хранить всё локально и публиковать только отредактированные краткие сводки и повторно используемые шаблоны. Команда opencode export [sessionID] из OpenCode с параметром --sanitize помогает при внутреннем рассмотрении, но её следует рассматривать лишь как первый этап, а не как кнопку публикации. Всё, что предназначено для публикации, должно пройти вторую проверку на отредактирование.

Для публичного репозитория сохраните следующее:

AGENTS.md
opencode.json
.opencode/agents/*.md
.opencode/skills/*/SKILL.md
templates/*.md
scripts/*.zsh
scripts/redact_sessions.py
docs/publication-redaction-checklist.md

и игнорируйте следующие:

agent-sessions/**
screenshots/**
.env
project.local.env
*.raw.log
*.events.jsonl
opencode-session-*.json

Результатом являются отчеты, которыми можно делиться, при этом репозиторий не становится источником утечек информации.

Где помогли инструменты MCP

Модели — это лишь часть системы, а интерфейс инструментов имеет огромное значение. Полезным способом рассматривать MCP и встроенные инструменты является представление их как специализированных органов чувств и рук:

| Workflow stage   | Useful tool or MCP category                             | What it helped with                                |
| ---------------- | ------------------------------------------------------- | -------------------------------------------------- |
| Planning         | repo search, docs lookup, issue/context reader          | understand current architecture before changing it |
| Coding           | filesystem, shell, language server, package manager     | edit code, inspect symbols, run targeted commands  |
| Review           | git diff, grep, test reports, generated artifact reader | catch scope creep and weak tests                   |
| Unit tests       | test runner, coverage                                   | prove the patch did not only compile               |
| Browser tests    | Playwright/browser automation                           | validate real UI routes and flows                  |
| Security tests   | secret scan, dependency audit, SAST                     | catch obvious unsafe output before publish         |
| Docs/site checks | static-site build, route checks, smoke tests            | catch generated-output drift                       |

Лучшая настройка MCP не включает всё возможное. Она предоставляет агенту лишь необходимые инструменты и заставляет использовать рискованные функции с предварительным запросом. OpenCode определяет серверы MCP под ключом mcp в файле opencode.json и предоставляет команды CLI для их управления. Рассматривайте эти определения как зависимости, необходимые в производственной среде: фиксируйте их версии, тщательно проверяйте и удаляйте ненужные.

Почему скриншоты нашли своё место

Тесты в браузере возвращают результаты «прошло» или «не прошло». Скриншоты предоставляют визуальные доказательства. Они помогли проверяющим обнаружить то, что ускользает от тестов на единицы: сломанную структуру после успешной сборки, неверный контент на определённом маршруте, пустые генерируемые страницы, регрессии в навигации, ошибочные баннеры, на которые не было написано ни одного теста, а также подтверждение того, что маршрут статического сайта существует и корректно отображается.

Они также несут риски: имена профилей браузера, закрытые вкладки, пути localhost, названия проблем, токены URL и вывод инструментов разработчика могут попасть в кадр. Политика предусматривает съемку скриншотов только интерфейса localhost, их строгую обрезку, проверку перед публикацией, а также запрет на фиксацию страниц аутентификации, производственных панелей управления, закрытых вкладок или терминалов, отображающих значения среды. Скриншот является доказательством и по умолчанию не считается публичным материалом.

Пример из практики частного проекта вики

Автор применил это решение к частному вики на основе LLM и проекту статического сайта, опубликовав лишь отредактированный отчет. В заключительных записях о проверке указано, что пройдено 977 тестов на Python, выполнена пересборка статического сайта с обновлением, проверки типа smoke-site и верификация домена, сгенерированы документация, произведены проверки маршрутов, а также пройдено 150 тестов Playwright. Что касается завершенных функций в рамках заданного объема работ, у автора была высокая уверенность — примерно 8–9 из 10 — подкрепленная воспроизводимыми тестами, проверками сгенерированного сайта, проверками маршрутов и верификацией в браузере. Эта оценка субъективна и не должна применяться к другим проектам.

Слабым местом не был код продукта. Один скрипт безголовой автоматизации не сработал из-за неправильной настройки имен агентов; в нем использовались универсальные имена:

planner
coder
tester
reviewer

в то время как на самом деле были настроены следующие агенты:

minimax-builder
glm-reviewer

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

opencode run \
  --model ollama/minimax-m3:cloud \
  --agent minimax-builder \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_CODER.md)"

opencode run \
  --model ollama/glm-5.1:cloud \
  --agent glm-reviewer \
  --dir . \
  "$(cat agent-sessions/project-slug/promptNN/PROMPTNN_REVIEWER.md)"

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

Насколько близко к рабочему процессу Frontier?

Здесь легко преувеличивать преимущества. Настройка MiniMax в сочетании с GLM на OpenCode и Ollama не является тем же, что и прямая работа с лучшей моделью программирования Frontier. Модели Frontier по-прежнему обладают более сильными навыками первичного анализа, лучшей работой с длинными контекстами и более эффективным выполнением стандартных инструкций, поэтому сравнение модели с моделью было бы несправедливым. Важным является сравнение качества рабочего процесса: планирование, проверка, тестирование, скриншоты, проверки безопасности и утверждение человеком.

Рабочий процесс имеет огромное значение. При выполнении задач с четко определенными рамками и надежными тестами такая структура может напоминать сильные модели типа Frontier, поскольку она предусматривает разделение ролей, заранее планирование, проверку с обеих сторон реализации, обязательные этапы верификации, использование локальной памяти сессий, снимки экрана в качестве доказательств, проверки безопасности, а также контроль за коммитами со стороны человека.

Такая модель хорошо справляется с детерминированной разработкой функций, генерацией статических сайтов, обработкой данных и поиском, задачами, требующими множества тестов, проверкой генерируемого вывода, выявлением расширения объема работ и обязательной документацией сбоев. Однако модели типа Frontier по-прежнему превосходят ее в ситуациях неоднозначных архитектурных решений, глубокой переработке плохо протестированного кода, оценке стиля и качества продукта, самокоррекции на длительной перспективе, сокращении количества попыток, автоматическом следовании инструкциям и анализе сложных снимков экрана.

Модель угроз

Несколько распространённых опасностей, связанных с использованием ИИ для программирования, снижаются благодаря этому рабочему процессу: ложные утверждения о успехе, когда разработчики работают вне предусмотренного репозитория, когда рецензенты превращаются в исполнителей, когда необработанные запросы попадают в публичные репозитории, когда логи раскрывают пути или секреты, когда скриншоты показывают приватные вкладки или токены, когда происходят незаметные изменения в сгенерированных файлах, а также когда агенты сохраняют или отправляют изменения до того, как кто-либо их просмотрит.

Проверка человеком по-прежнему необходима. Целью не является полная автономия; цель — более строгий контроль, при котором каждое утверждение сопровождается доказательствами, а каждое рискованное действие имеет ограничения.

Плюсы и минусы

Плюсы

  • Воспроизводимость. Запросы сопровождаются папками, выполнение операций оставляет записи, а подтверждения можно отследить.
  • Контроль. Разработчик не может тайно пропустить тесты, если рецензент обязан заблокировать подтверждение без доказательств проверки.
  • Гибкость моделей. Вы можете менять модели по мере развития поддержки со стороны Ollama и OpenCode, причем этот процесс выдерживает более высокую скорость изменений.
  • Скорость. Как только существуют промпты и скрипты, выполнение следующей задачи происходит быстро.

Недостатки

  • Больше формальностей. Этот подход сложнее, чем просто отправка промпта в чат, и это его цена.
  • Необходимость настройки контроля. Просьба к рецензенту не изменять код в продакшене менее эффективна, чем применение разрешений и проверок в рамках CI.
  • Плохие промпты всё равно дают плохие результаты. Циклы снижают хаос, но не заменяют чёткое определение задачи.
  • Необходимо осторожно обращаться с разрешениями. Серверы MCP и доступ к оболочке обладают большой мощностью, поэтому к ним следует относиться как к доступу в продакшене.
  • Логи являются конфиденциальными. Чем более подробны ваши логи, тем тщательнее должна быть их обработка.

Обоснованное утверждение

Эта конфигурация не превратит MiniMax или GLM в модели высшего уровня. Она же делает более дешевое агентное программирование через Ollama более дисциплинированным, поддающимся аудиту и полезным для решения конкретных инженерных задач. Это единственное утверждение, которое она может честно сделать.

Связанные материалы

  • Создание мультиагентного маршрутизатора с использованием LangGraph и агента-надзирателя — Как разделить одного перегруженного агента на специалистов с помощью агента-надзирателя в LangGraph, используя готовые вспомогательные инструменты и ручно созданный StateGraph, а также особенности проектирования состояний и распространенные ошибки.
  • Создание потрясающих видео с ИИ с использованием GPT 6 Astra и Topview Canvas — Пошаговое руководство по созданию короткого фильма в Topview Canvas с помощью агента Astra: настройка, вопросы, которые задает агент, примеры сцен и другие инструменты студии.
  • Мультиагентный системный блогер без затрат на API на Mac: Gemma 4, Ollama и Google ADK — Создайте локальную систему агентов-планировщиков, авторов и верификаторов на чипах Apple Silicon с использованием Gemma 4 через Ollama, LiteLLM и Google ADK, без дополнительных платежей за использование моделей за каждый запрос.