Головна / Статті

Безголовий двоагентний цикл програмування з 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, складання плану, врахування відгуків рецензента, реалізацію лише схваленого обсягу роботи, виконання перевірок, фіксацію змін та невдач, а також зупинку процесу у разі потреби у людському схваленні будь-якого коміту. Заборонено: робити коміти, пускати код у репозиторій, змінювати базу, використовувати силове пускання, переходити до наступного запиту, послаблювати тести та редагувати файли, призначені для рецензента.

Рецензент

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, ретельно обрізати їх, перевірити перед публікацією та ніколи не фіксувати сторінки автентифікації, панелі керування в промисловому середовищі, приватні вкладки чи термінали, які відображають значення середовища. Скріншот є доказом та за замовчуванням не вважається публічним артефактом.

Дослідження випадку приватного проекту wiki

Автор застосував це до приватного вікі з 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 без додаткових зборів за кожен запит до моделі.