Содержание
После сохранения формы сервер отвечает кодом 500. В чат уходит одно предложение. Дальше происходит не «модель написала PHP». Программа открывает проект, ищет контроллер, читает связанный код, правит файл, запускает проверку и, если проверка красная, возвращает ошибку в следующий запрос.
Языковая модель в этой мастерской заполняет наряд. Верстак трогает другой код: файлы, терминал, git, языковой сервер. Пока наряд не исполнен и результат не вернулся в диалог, модель о репозитории не знает ничего сверх того, что программа уже положила в запрос.
Ниже разбор этой обвязки. Открытый чертёж взят из репозитория OpenCode (ветка dev, начало ноября 2026) и документации. Cursor, Claude Code и Codex видны только по публичному контракту: их внутренние каталоги наружу не выложены. Как IDE вообще собирает контекст, уже разобрано в материале про работу среды с кодом. Здесь вопрос уже другой: из каких программных частей состоит агент, который сам доходит до патча.
Ключевые выводы
Модель не открывает файл. Она возвращает структурированный запрос. Читает диск, запускает команду и пишет патч программа. У Anthropic это прямо названо контрактом: приложение описывает инструменты, модель выбирает вызов, код приложения исполняет его и возвращает результат.
Один ответ почти никогда не чинит форму. Агент крутит цикл: собрать контекст, спросить модель, исполнить инструмент, вернуть результат, повторить. Остановка наступает, когда модель завершает ход, кончился лимит шагов или человек прервал сессию.
Контекст собирает программа, не веса. Поиск по тексту, чтение файла, индекс, векторный поиск и языковой сервер отвечают на разные вопросы. Для правки функции полезно знать вызывающий код и тесты, а не только тело функции.
Три замка не заменяют друг друга. Инструкция модели, таблица разрешений приложения и изоляция процесса на уровне операционной системы ломаются по разным причинам. Запрет в тексте промпта не останавливает команду, если приложение её всё же запустило.
Несколько агентов делят задачу и портят одни файлы. Исследователь, разработчик и проверяющий ускоряют работу, только если не пишут в одно и то же место. Иначе время уходит на согласование, а не на патч.
Свой агент собирают слоями. Сначала клиент модели и два инструмента чтения. Потом цикл. Потом запись и терминал. Песочница и подагенты имеют смысл после того, как один агент уже умеет остановиться по зелёной проверке, а не по фразе «готово».
Модель пишет наряд, верстак его исполняет
Автодополнение дописывает текущую строку. Чат объясняет выделенный кусок. Кодовый агент берёт формулировку задачи и сам ходит по репозиторию, пока не появится изменение и проверка. Разница не в «более умной модели». Разница в том, что вокруг модели стоит программа с состоянием, инструментами и правом сказать «нет».
В ремонтной мастерской клиент говорит: после сохранения формы падает 500. Диспетчер не хватает горелку. Он выписывает наряд: посмотреть контроллер, прочитать преобразование данных, прогнать тест. Модель в агенте занимает место диспетчера. Верстак, шкаф с инструментами и журнал смены принадлежат приложению.
Устойчивые части такой системы одни и те же у терминального агента, у агента в редакторе и у агента в облачной среде. Меняется оболочка, не набор обязанностей.
| Часть | Что делает в мастерской | Что делает в агенте |
|---|---|---|
| Интерфейс | Окно приёмки | Терминал, редактор, настольная программа, веб |
| Диспетчер | Ведёт смену и наряд | Цикл задачи, состояние, отмена |
| Модель | Решает, какой наряд выписать | Запрос к API поставщика |
| Сборка контекста | Чертежи на столе | Файлы, поиск, история, правила проекта |
| Инструменты | Шкаф с оснасткой | Чтение, правка, поиск, терминал, внешние сервисы |
| Разрешения | Кто имеет право на горелку | Разрешить, спросить, запретить |
| Верстак | Деталь, станок, склад | Файлы, терминал, git, диагностика |
| Журнал | Смена и откат | Сессия, история, снимки, уплотнение |
Это роли, не дерево каталогов. В OpenCode часть ролей живёт в packages/core, интерфейс разнесён по packages/tui, packages/app и packages/desktop, а поставщики моделей подключаются через пакеты в packages/ai. В закрытом продукте те же роли могут сидеть в одном процессе.
Модель здесь один узел. Поведение, которое снаружи выглядит как «агент понял проект», чаще собрано обычным кодом: что положить в запрос, какой инструмент разрешён, когда остановиться, что сохранить между шагами. Разница между явной программой и обученной моделью разобрана отдельно в статье про программу и модель.
Цикл крутится, пока форма не перестанет падать
Упрощённый цикл выглядит так. Это учебный набросок, не код OpenCode.
async function runAgent(task: string) {
const messages = await prepareContext(task);
while (true) {
const response = await llm.generate({
messages,
tools: toolRegistry.definitions(),
});
if (response.stopReason === "end_turn") {
return response.content;
}
if (response.stopReason === "tool_use") {
for (const call of response.toolCalls) {
const result = await executeTool(call.name, call.arguments);
messages.push(response, result);
}
}
}
}
На задаче «после сохранения формы HTTP 500» хороший ход почти никогда не начинается с патча. Сначала поиск контроллера и маршрута. Потом чтение преобразования входных данных. Потом гипотеза: падает приведение типа, а не сама запись в базу. Потом правка. Потом тест. Если тест красный, в цикл возвращается текст ошибки, и гипотеза меняется. Линейный план из восьми пунктов на слайде здесь врёт. Агент возвращается к поиску, выкидывает первую догадку и иногда пишет тест, которого не было в исходной формулировке.
Реальный цикл толще учебника. Потоковая генерация, несколько вызовов за один ход, отмена, повтор при ошибке поставщика, предел итераций и уплотнение истории. В документации Anthropic цикл для клиентских инструментов завязан на stop_reason: пока причина остановки tool_use, приложение исполняет вызовы и шлёт tool_result. Выход из цикла бывает и по end_turn, и по лимиту токенов, и по отказу.
В ветке dev репозитория anomalyco/opencode этот ход собран в packages/core/src/session/runner/llm.ts. Функция прогона шагает циклом: подготовить границу шага, выполнить шаг, увеличить счётчик. Перед запросом оценивается размер контекста. Если он не влезает, срабатывает уплотнение. Если у агента задан предел шагов и счётчик его достиг, в запрос добавляется текст о пределе, а выбор инструмента отключается (toolChoice: "none"). Модель на этом ходе уже не вызывает инструменты, а обязана свернуть работу. Отдельный путь повторяет запрос, если поставщик ответил сбоем.
Ошибка команды здесь полезнее гладкого «готово». Упавший тест возвращает факт. Модель может прочитать его и сменить гипотезу. Может и зациклиться: тот же поиск, та же правка, та же красная проверка. В разрешениях OpenCode для этого есть отдельный предохранитель doom_loop: три одинаковых вызова с тем же входом по умолчанию спрашивают человека.
Поставщиков имеет смысл прятать за одним интерфейсом. OpenCode на dev помечает пакеты поставщиков префиксом aisdk: и подгружает их как модули. Снаружи остаются разные окна контекста, разные форматы вызова инструментов и разная цена. Дешёвую модель разумно ставить на классификацию и короткие служебные ходы, сильную на проектирование правки, локальную на кусок, который нельзя отправлять наружу. Счёт за такие круги считается не по одному запросу, а по доведённой задаче. Это разобрано в токеномике программирования с моделью.
Репозиторий в запрос не попадает сам
Веса модели не содержат вашего репозитория. Если программа не положила файл в запрос, для этого хода файла нет. Поэтому «агент изучил проект» всегда означает, что какой-то код заранее выбрал, что показать.
Для поиска функции хватает текста. OpenCode гоняет grep и glob через ripgrep и по умолчанию уважает .gitignore. Это дёшево и точно, когда известно имя, строка или путь.
Для вопроса «кто ещё сломается, если поменять это приведение типа» текста мало. Нужны вызывающие места, интерфейс, зависимости и тесты. Языковой сервер отвечает на часть такого вопроса: определение, ссылки, иерархия вызовов. В документации OpenCode инструмент lsp помечен как экспериментальный и включается отдельным флагом. В нём есть переход к определению, поиск ссылок, символ документа и входящие и исходящие вызовы. Это уже не поиск по строке.
Векторный поиск полезен, когда человек описал поведение словами, а имя функции в голове не всплыло. Он плохо заменяет точное совпадение идентификатора и легко притаскивает соседний модуль, который «про то же самое». Индекс всего репозитория окупается на большом дереве и на повторяющихся вопросах. На маленьком сервисе агент чаще доходит до нужного файла двумя вызовами glob и grep, без отдельной базы векторов. Как устроен поиск по документам в прикладной системе, рядом лежит разбор производственного RAG.
Отдельно в запрос попадают правила проекта. Команда /init в OpenCode создаёт AGENTS.md: как собирать, как проверять, какие соглашения не видны из имён файлов. Глобальный файл в ~/.config/opencode/AGENTS.md добавляет личные правила. Если своего файла нет, читается CLAUDE.md. Это не память о прошлых сессиях. Это инструкция, которую программа подмешивает в контекст каждой новой смены.
| Вопрос агента | Чем отвечать |
|---|---|
| Где лежит контроллер? | Поиск по пути и тексту |
| Что внутри функции? | Чтение файла, лучше диапазоном строк |
| Кто её вызывает? | Языковой сервер или аккуратный поиск по символу |
| Где похожее поведение без точного имени? | Векторный поиск, затем проверка чтением |
| Как в этом репозитории принято проверять? | AGENTS.md и соседние инструкции |
Инструмент вызывает программа, не модель
Модель не умеет открыть диск. Она умеет вернуть имя инструмента и аргументы по схеме, которую приложение положило в запрос. Дальше шесть шагов, и все они в программе: описать схему, отдать её модели, принять выбор, проверить разрешение, исполнить, вернуть результат.
В публичной документации OpenCode встроенные инструменты называются так: read, write, edit, apply_patch, grep, glob, bash, lsp, todowrite, webfetch, websearch, question, skill. Правка файлов сидит под одним разрешением edit. На ветке dev к началу ноября 2026 модули называются чуть иначе: shell.ts вместо bash, patch.ts вместо apply_patch, subagent.ts вместо отдельного имени task из более ранних страниц. Имена сверяйте с той версией, которую запускаете. Роли те же.
edit меняет файл точной заменой строки. write создаёт файл или перезаписывает его. patch несёт несколько операций в одном тексте: добавить, обновить, перенести, удалить. question останавливается и спрашивает человека. skill подгружает текст навыка, а не исполняет произвольный код само по себе.
Есть и исключение из формулы «модель ничего не запускает». У Anthropic часть инструментов исполняется на стороне поставщика: поиск в сети, загрузка страницы, исполнение кода в их среде. Приложение тогда не собирает tool_result само. Для файлов вашего репозитория это исключение не работает. Их по-прежнему трогает ваш процесс.
Свои инструменты в OpenCode описываются схемой и функцией execute. Плагин с тем же именем, что у встроенного инструмента, заменяет встроенный. Внешние сервисы подключаются отдельно, через MCP, и появляются рядом со встроенными вызовами. Протокол общий. Исполнение всё равно проходит через тот же цикл и те же разрешения.
Три замка: инструкция, разрешение, изоляция
Представьте команду, которая стирает корень диска, или чтение файла с секретом и отправку его наружу. Текст «будь осторожен» в системной инструкции это не останавливает. Инструкция влияет на то, что модель склонна запросить. Если запрос всё же пришёл, решает приложение. Если приложение разрешило запуск, процесс ещё можно запереть так, чтобы вред не вышел за каталог и сеть.
У Explore в исходниках dev это видно на одном агенте. Системный текст запрещает создавать и менять файлы и требует, чтобы команды оболочки были только на чтение. Рядом таблица разрешений: сначала запрет всего, потом точечный допуск read, grep, glob, shell, webfetch и websearch. Чтение *.env спрашивает человека, *.env.example разрешено. Запрет в тексте и запрет в таблице совпадают по намерению. Совпадение не делает их одним механизмом. Текст модель может проигнорировать. Таблица отклоняет вызов до запуска.
Разрешения в документации сводятся к трём исходам: allow, ask, deny. Последнее совпавшее правило побеждает, поэтому общий шаблон * ставят первым, а частные исключения после него. Так можно разрешить git status и спрашивать на git push, запретить rm *, пускать правки только в каталог документации. Каталоги вне корня проекта закрывает external_directory: по умолчанию вопрос человеку. Три одинаковых вызова подряд ловит doom_loop.
ask в интерфейсе даёт три ответа: один раз, всегда для этого шаблона до конца сессии, отказ. Режим --auto сам подтверждает то, что иначе спросило бы. Явный deny он не снимает.
Третий замок стоит ниже. Каталог на диске, отдельный пользователь, контейнер, сеть без выхода наружу, журнал команд. OpenCode из коробки не является такой песочницей: он исполняет команды в среде проекта и опирается на разрешения. Изоляцию процесса добавляют отдельно, тем же Docker или другой границей операционной системы. Снимок файлов, который умеет packages/core/src/snapshot.ts (capture, diff, restore), откатывает правки агента. Он не отменяет команду, которая уже ушла в сеть.
У Cursor публично описаны свои контрольные точки: снимок изменённых файлов перед крупной правкой, хранится локально и отдельно от git. Откат точки возвращает файлы и не стирает сообщения диалога. Это четвёртый, продуктовый контур отката. Он тоже не заменяет ни разрешения, ни изоляцию.
Состязательные проверки самого приложения вокруг модели собраны в плейбуке атакующих проверок. Для кодового агента практический минимум короче: секрет не читается без вопроса, разрушительная команда запрещена шаблоном, каталог проекта не равен всему диску, а откат файлов проверен до того, как агенту дали сеть.
Сессия помнит дольше, чем окно
Смена на несколько часов не обязана помещаться в один запрос. Программа хранит реплики человека, ответы модели, вызовы инструментов, результаты, список дел, diff файлов и короткие сводки. Окно модели хранит только то, что влезло в очередной запрос.
В OpenCode сессия умеет уплотняться. На ветке dev в packages/core/src/session/compaction.ts запас по умолчанию такой: оставлять свободными около 15% окна и не меньше 16 тысяч токенов. Рядом со сводкой сохраняется хвост недавней переписки дословно. Сводку можно считать заранее, в фоне, чтобы в момент переполнения не ждать её с нуля. Повод бывает автоматический, ручной (/compact) и аварийный: поставщик отклонил контекст как слишком длинный. Скрытый агент Compaction для этого существует отдельно от Build. Плагин может дописать в промпт уплотнения свои факты через хук experimental.session.compacting.
Сжатие теряет детали. Поэтому в хвосте держат последние решения, а в сводке оставляют, какие файлы трогали и что ещё не сделано. Если после уплотнения агент снова ищет тот же файл, сводка оказалась слишком бедной. Это чинится содержимым сводки, а не более длинным окном.
Рядом живут служебные агенты, которых нельзя выбрать в интерфейсе. Title называет сессию короткой фразой. Summary пишет два-три предложения в духе описания к запросу на слияние. Оба в исходниках лишены инструментов. Они не чинят код. Они упаковывают журнал, чтобы человек нашёл смену потом.
Снимок файлов и журнал сообщений расходятся. Откат снимка возвращает дерево файлов. История диалога при этом может остаться. В документации OpenCode команда /undo возвращает и правки, и исходное сообщение, чтобы формулировку можно было поправить и запустить снова. Перед работой полезно знать, какой из двух откатов вы нажимаете.
Второй агент делит работу и файлы
Одного диспетчера хватает, пока наряд один. Когда поиск по дереву, правка и прогон тестов мешают друг другу в одном окне, работу отдают второму агенту. Выигрыш появляется, если у второго свой стол. Если оба пишут в один файл, время уходит на стыковку.
В OpenCode основные агенты видны человеку и переключаются клавишей Tab. Подагента вызывает основной, либо человек упоминает его через @. Дочерняя сессия открывается отдельно, в неё можно зайти и вернуться к родителю.
На ветке dev роли такие.
Build работает по умолчанию и исполняет инструменты в рамках разрешений. Plan тоже основной, но правки запрещены везде, кроме каталога ~/.opencode/plan. В контекст подмешивается напоминание: реализацию не делать, пока человек не переключит агента. Если правка всё же упрётся в запрет, сообщение об ошибке говорит, что файл вне этого каталога. Публичная документация описывает близкое правило для файлов плана в .opencode/plans/. Сверяйте путь с версией: намерение одно, каталог в коде и в документации может называться по-разному.
Explore ищет по дереву и не должен ничего менять. Ему ещё и запрещено звать подагентов. В описании для модели прямо задают глубину: быстрый проход, средний или подробный обход. General берёт многошаговую работу и может менять файлы, но сам не задаёт вопросы человеку и не порождает следующих подагентов. Иначе цепочка агентов растёт без присмотра.
Параллельный запуск имеет смысл на независимых кусках: один ищет вызовы, другой читает тесты, третий смотрит конфигурацию. Общий файл, общая миграция, один и тот же модуль авторизации так не делятся. Для изоляции правок в git есть отдельные рабочие деревья. В packages/core/src/worktree.ts это отдельная служба, а не «просто ещё один чат». Конфликт двух патчей на одной строке всё равно остаётся конфликтом.
Координатор, который только раздаёт задачи, тоже стоит денег. Каждый подагент тащит свой контекст. Сводка наверх должна быть короче, чем исходный поиск, иначе родительское окно забивается чужими журналами. В документации Cursor для крупной работы описан похожий приём снаружи: проектный агент планирует и раздаёт куски другим агентам. Как устроен обмен внутри, страница не показывает.
Расширения не заменяют цикл
Встроенных инструментов хватает, пока задача внутри репозитория. База, трекер, документация библиотеки и мониторинг живут снаружи. Их подключают так, чтобы цикл не пришлось переписывать.
MCP добавляет чужие инструменты по общему протоколу. В OpenCode сервер бывает локальным (команда, свой каталог, переменные окружения) и удалённым (адрес, заголовки, OAuth). Имена инструментов получают префикс сервера, и на них действуют те же разрешения, включая шаблон mymcp_*. Каждый сервер раздувает описание инструментов в запросе. Документация прямо предупреждает: сервер GitHub легко съедает окно. Включают тот сервер, который нужен этой задаче, и выключают остальные.
Навык устроен иначе. Это файл SKILL.md с именем и коротким описанием. Модель видит список описаний и загружает полный текст инструментом skill, когда он понадобился. Так в контекст не попадают все инструкции сразу. Навыки ищутся в .opencode/skills/, в совместимых каталогах .claude/skills/ и .agents/skills/, плюс глобально в домашнем каталоге. Разрешение skill может спрятать внутренние навыки шаблоном internal-*.
Плагин меняет само приложение. Хук tool.execute.before видит аргументы до запуска. Им закрывают чтение .env или экранируют команду. Хук tool.execute.after видит результат. События сессии, разрешений и диагностики языкового сервера тоже доступны. Свой инструмент регистрируется рядом со встроенными. Это не MCP: плагин живёт внутри процесса агента, а MCP приносит чужой сервер.
Языковой сервер дополняет картину структуры. Он не заменяет grep и не даёт права на запись. Он отвечает, где символ объявлен и кто его вызывает, если сервер для этого языка поднят.
Чертёж открытого агента на ветке разработки
Имя OpenCode встречается в двух несовместимых историях. Репозиторий opencode-ai/opencode архивирован 18 сентября 2025 года. В README написано, что проект продолжен как Crush, вместе с командой Charm. Современный агент с этим именем живёт в anomalyco/opencode, лицензия MIT, интерфейсы: терминал, настольная программа, расширение редактора. Читать исходники старого архива, чтобы понять текущий цикл, бессмысленно.
Ветка dev на начало ноября 2026 раскладывается так. Это карта для чтения, не обещание, что путь не переедет в следующем месяце.
| Что искать | Куда смотреть |
|---|---|
| Цикл шага | packages/core/src/session/runner/llm.ts |
| Предел шагов | packages/core/src/session/runner/max-steps.ts |
| Уплотнение | packages/core/src/session/compaction.ts |
| Встроенные агенты | packages/core/src/plugin/agent.ts, plan.ts |
| Инструменты | packages/core/src/tool/plugin/ |
| Разрешения | packages/core/src/permission.ts |
| MCP | packages/core/src/mcp/ |
| Навыки | packages/core/src/skill/ |
| Поставщики | packages/core/src/provider.ts |
| Снимки файлов | packages/core/src/snapshot.ts |
| Рабочие деревья git | packages/core/src/worktree.ts |
| Контракт плагина | packages/plugin |
Полезный порядок чтения короткий. Сначала agent.ts и plan.ts, чтобы увидеть, чем Build отличается от Plan и Explore не лозунгом, а списком разрешений. Потом один инструмент, например read.ts или shell.ts, от схемы до исполнения. Потом цикл в llm.ts: где оценивается контекст, где вызывается уплотнение, где обрываются инструменты по лимиту шагов. Плагины и MCP после этого читаются как добавка к уже понятному шкафу, а не как отдельный продукт.
Документация на opencode.ai описывает поведение, которое видит человек: Tab между агентами, /init, /undo, конфиг opencode.json. Исходники dev описывают, как это собрано. Когда имена расходятся (bash и shell, каталог планов), верить стоит той версии, которую вы запускаете, и рядом держать оба названия.
Закрытые агенты видны только снаружи
Внутренние каталоги этих трёх продуктов публично не разобраны так, как packages/core. Сравнивать можно контракт, который описан в документации, и не приписывать им файлы, которых снаружи нет.
Cursor в обзоре агента называет три части: инструкции, инструменты и модель. Инструкции включают системный текст и правила. Инструменты ищут по дереву, читают и правят файлы, запускают терминал, ходят в браузер, задают вопросы. Отдельного потолка на число вызовов за задачу документация не ставит. Контрольные точки снимают изменённые файлы и откатываются отдельно от git. Для большой работы описан координатор, который планирует и раздаёт куски. Сообщение можно поставить в очередь до конца текущего хода или отправить сразу, чтобы оно попало на ближайшую границу инструмента. Это тот же цикл «модель, инструмент, снова модель», упакованный в редактор. Как устроен индекс репозитория, эта страница не раскрывает. Его место в конвейере среды показано в статье про IDE и код.
Claude Code снаружи узнаётся по тому же контракту Anthropic. Модель возвращает tool_use, процесс на машине разработчика исполняет чтение, правку и команду, результат возвращается в диалог. Схемы вроде оболочки и текстового редактора у Claude натренированы заранее, поэтому свои имена для тех же действий часто вызываются хуже, чем знакомые. Права, предел контекста и сводка истории остаются обязанностью приложения вокруг модели. OpenCode даже читает CLAUDE.md и каталог навыков .claude/skills/, если своих файлов нет. Совместимость файлов не означает общий исходный код.
Codex в публичном описании OpenAI берёт задачу по репозиторию и может исполнять её в изолированной среде, отдельно от вашего ноутбука. Наружу видны поручение, граница исполнения и возврат изменений. Не видно, как именно устроены очередь, снимок и выбор модели внутри. Для архитектуры важен сам приём: верстак можно вынести из локального процесса, а журнал и ревью оставить у человека.
Общий рисунок такой. OpenCode показывает швы. Cursor показывает, как те же швы сидят в редакторе с контрольными точками и координатором. Claude Code показывает сильный контракт вызова инструментов на локальной машине. Codex показывает вынесенную среду исполнения. Выбор продукта под задачу, а не под логотип, лежит в обзоре альтернатив Cursor.
Свой агент собирают слоями
Повторять OpenCode целиком не нужно. Учебный агент на TypeScript полезен тем, что каждый слой можно включить отдельно и увидеть, где ломается поведение. Стек спокойный: Node.js, клиент API или AI SDK, Zod для схем инструментов, SQLite для журнала сессии. Языковой сервер и tree-sitter подключают на слое структуры кода. Контейнер подключают на слое изоляции, не в первый день.
- Клиент модели. Один запрос, один ответ, потоковый вывод. Без инструментов. Если этот слой врёт, цикл только размножит ошибку.
- Три инструмента чтения: список файлов, чтение диапазона, поиск по тексту. Схемы короткие, пути только внутри корня проекта.
- Цикл. Модель сама выбирает инструмент. Результат возвращается в историю. Есть предел шагов и причина остановки.
- Запись. Сначала точная замена фрагмента, потом создание файла. Каждая правка оставляет
diff, который человек может прочитать. - Терминал. Одна команда проверки, которую вы сами считаете безопасной: тест или сборка. Вывод обрезается, код возврата попадает в следующий запрос.
- Сборка контекста. Правила проекта отдельным файлом, история сессии в SQLite, уплотнение, когда оценка токенов перешагнула порог.
- Разрешения. Запрет путей вне корня, вопрос на разрушительные команды, журнал вызовов. Контейнер вокруг терминала, когда команда больше не ограничивается одним тестовым сценарием.
- Второй агент. Один ищет, второй правит. У исследователя нет записи. Общий файл они не трогают параллельно.
Каталог может выглядеть так, когда слои уже есть. На первом этапе из него живы только llm и cli.
mini-coding-agent/
├── src/
│ ├── agent/
│ │ ├── loop.ts
│ │ └── subagent.ts
│ ├── llm/
│ │ └── provider.ts
│ ├── context/
│ │ ├── builder.ts
│ │ └── compaction.ts
│ ├── tools/
│ │ ├── registry.ts
│ │ ├── filesystem.ts
│ │ └── terminal.ts
│ ├── security/
│ │ └── permissions.ts
│ ├── sessions/
│ │ └── storage.ts
│ └── cli/
│ └── index.ts
└── package.json
Критерий готовности задайте снаружи модели. Сборка проходит. Назначенный тест зелёный. diff не трогает файлы вне задачи. Фраза модели «я исправил» без этого критерия не закрывает наряд.
Стоимость держится теми же ручками, что и в большом агенте. Предел шагов. Короткий хвост вместо всей истории. Дешёвая модель на поиске, сильная на правке. Кэш неизменного префикса, если поставщик его даёт. Подагент только когда его сводка короче, чем самостоятельный поиск родителя.
Полностью локальная смена собирается из тех же слоёв: локальная модель, локальный поиск, локальный журнал, терминал без сети. Компромисс в качестве модели и в том, что индекс и языковой сервер надо поднять самим. Карта тем для работы без внешнего API лежит в дорожной карте офлайн-инженера.
Частые вопросы
Чем кодовый агент отличается от автодополнения?
Автодополнение предлагает продолжение строки в открытом файле. Агент сам ищет файлы, вызывает инструменты и повторяет ход, пока задача не закроется или не упрётся в предел. Модель может быть той же. Обвязка другая.
Модель может выполнить команду сама?
На вашем диске нет. Она возвращает структурированный вызов, а процесс агента решает, запускать ли его. У части поставщиков поиск в сети и исполнение кода в их среде происходят на сервере поставщика. К файлам проекта это не относится.
Нужно ли заранее индексировать весь репозиторий?
Не всегда. Точное имя и путь закрывают поиск по тексту. Индекс и векторы окупаются, когда вопросов много, дерево большое, а формулировка не содержит идентификатора. Языковой сервер нужен для связей между символами, и он не заменяет grep.
Как понять, что задача выполнена?
Задайте проверку до цикла: команда сборки, тест, ограничение на список файлов. Ответ модели «готово» фиксирует только то, что модель решила остановиться. Красный тест возвращает цикл к гипотезе.
Почему агент зацикливается?
Один и тот же вызов с тем же входом, неверная гипотеза, потеря решения при уплотнении, нет условия остановки. Лечится пределом шагов, запретом повторного идентичного вызова и внешней проверкой, которая даёт новый факт, а не ту же ошибку.
Можно ли держать кодового агента локально?
Да, если локально подняты модель, инструменты, журнал и граница исполнения. Качество правки будет зависеть от локальной модели. Секреты при этом не уходят поставщику вместе с контекстом.
Архив и текущий репозиторий — один проект?
Нет. Архив opencode-ai/opencode с 18 сентября 2025 года указывает на Crush. Текущий OpenCode развивается в anomalyco/opencode. Общие корни в названии не делают общими текущие исходники.
Параллельные агенты ускоряют разработку?
Только на независимых кусках. Два агента в одном файле тратят ход на конфликты. Подагент без запрета плодить следующих подагентов раздувает контекст быстрее, чем растёт патч.
Что почитать на сайте
Смежные разборы на сайте, от общего устройства среды к цене и к локальному запуску:
- Как IDE работают с кодом: индекс, режимы подсказки, чата и агента.
- Программа и модель: что в агенте задано кодом, а что весами.
- Токеномика программирования с моделью: сколько стоит доведённый цикл, а не один запрос.
- Cursor и альтернативы: какой класс инструмента брать под задачу.
- Производственный RAG: когда векторный поиск помогает и когда врёт.
- Атакующие проверки LLM-приложений: как проверять обвязку, а не только ответ модели.
- Офлайн-дорожная карта: что поднимать, если внешнего API нет.
Внешние первоисточники, на которых держится фактическая часть: исходники открытого агента, документация открытого агента, агенты и разрешения, как устроен вызов инструментов у Anthropic, обзор агента Cursor, протокол контекста для моделей.
Заключение
Кодовый агент похож на диспетчерскую, а не на оракула в строке редактора. Наряд пишет модель. Файлы, команды и откат делает программа. Качество смены зависит от того, что попало в запрос, какие инструменты разрешены и какая проверка имеет право сказать «ещё нет».
Практический следующий шаг короткий. Возьмите небольшой репозиторий, запустите OpenCode в режиме Plan и попросите только найти причину одной известной ошибки, без правок. Посмотрите, какие вызовы ушли в журнал. Потом переключитесь на Build и сравните, что изменилось в разрешениях, а не в красноречии ответа. После этого учебный цикл с чтением файла и одним тестом уже есть с чем сверять.



Комментарии