Загрузка...

Разбираем OpenCode: архитектура, режимы Plan и Build, LSP и запуск открытого AI-агента

Разбираем OpenCode: архитектура, режимы Plan и Build, LSP и запуск открытого AI-агента

Терминальные AI-ассистенты первого поколения — Claude Code, Cursor или закрытые вендорные CLI-утилиты — доказали свою пользу, но быстро уперлись в фундаментальные ограничения: жесткая привязка к одному провайдеру, непрозрачная маршрутизация запросов, невозможность подключить собственные self-hosted модели (Ollama, vLLM) для закрытого контура компании и отсутствие контроля над набором токенов. Если провайдер меняет тарифную политику или блокирует запросы из региона, рабочий процесс встает.

Проект OpenCode (развиваемый сообществом и создателями SST из команды Anomaly, репозиторий anomalyco/opencode) предлагает открытую альтернативу: чистая клиент-серверная архитектура (демон на базе OpenAPI 3.1), разнообразие клиентов (TUI, WebUI, Desktop, ACP), модульная система навыков (Skills), изоляция задач через сабагентов и поддержка любых OpenAI-совместимых провайдеров (BYOK).

Терминальный интерфейс OpenCode TUI

1. Клиентская экосистема: варианты использования

В отличие от решений, запертых исключительно в эмуляторе терминала, OpenCode разделен на серверную часть и несколько независимых клиентских интерфейсов под разные сценарии:

  1. Полноценный интерактивный TUI (Terminal UI): основной консольный интерфейс. Поддерживает управление мышью, переключение агентов по Tab, визуальный сплит-экран, быстрый выбор моделей по /models и всплывающие подтверждения прав.
  2. Пакетный CLI (opencode run): сокращенный неинтерактивный терминальный режим. Принимает промпт в аргументах командной строки, выполняет задачу и возвращает итоговый ответ (или сырой JSON-поток событий) прямо в stdout. Идеален для шелл-скриптов, git-хуков и CI/CD.
  3. Нативный Desktop App: десктопное приложение с графическим интерфейсом (на базе Tauri/Electron) для macOS, Windows и Linux. Включает наглядный side-by-side диффер файлов, управление сессиями и глобальные горячие клавиши.
  4. Веб-интерфейс (opencode web): локальный браузерный SPA-клиент. Позволяет работать с кодовой базой через браузер без необходимости держать открытый эмулятор терминала.
  5. Удаленный терминальный клиент (opencode attach): уникальный режим, позволяющий подключить локальный терминал к уже запущенному удаленному серверу OpenCode (например, на мощном VPS или домашнем сервере).
  6. ACP-клиент (Agent Client Protocol): поддержка открытого протокола редакторов (Zed и др.), запускающая агент как дочерний процесс через stdio.

2. Как OpenCode устроен изнутри: демон, WebUI и параметры запуска

Архитектурно OpenCode устроен по модели «фоновый демон + тонкие клиенты»:

┌────────────────────────────────────────────────────────┐
│             Клиентские интерфейсы                      │
│   TUI │ Desktop App │ WebUI (Браузер) │ ACP │ attach   │
└──────────────────────────┬─────────────────────────────┘
                           │ HTTP REST (OpenAPI 3.1) + SSE
┌──────────────────────────▼─────────────────────────────┐
│                 OpenCode Core Daemon                   │
│   Сессии ── Провайдеры ── Права доступа ── Subagents   │
└────────────┬─────────────┬─────────────┬───────────────┘
             │             │             │
        ┌────▼────┐   ┌────▼────┐   ┌────▼────┐
        │  Tools  │   │   LSP   │   │ Skills  │
        └─────────┘   └─────────┘   └─────────┘

Ядром системы является HTTP-сервер со спецификацией OpenAPI 3.1. Все события модели, ход рассуждений и вызовы инструментов транслируются клиентам в реальном времени через поток Server-Sent Events (SSE). Когда вы вводите opencode в терминале, рантайм сначала поднимает этот локальный сервер, а затем подключает к нему TUI-клиент.

Запуск WebUI и удаленного сервера

# Локальный запуск WebUI (автоматически откроет браузер)
opencode web

# Запуск чистого безголового сервера API
opencode serve --port 4096 --hostname 127.0.0.1

Сценарий удаленного подключения (VPS / Remote Server)

Если кодовая база и окружение развернуты на удаленном сервере, вам не нужно настраивать проброс X11 или мучиться с терминалом через SSH с мобильного устройства:

# 1. На удаленном сервере запускаем защищенный WebUI
OPENCODE_SERVER_PASSWORD="StrongMasterKey_2026" OPENCODE_SERVER_USERNAME="developer" opencode web --hostname 0.0.0.0 --port 4096

Теперь вы можете:

  • Открыть браузер на ноутбуке или планшете по адресу https://vps-ip:4096 и полноценно работать в веб-клиенте.
  • Либо подключить локальный терминал к удаленному бэкенду одной командой:
    opencode attach http://vps-ip:4096 -u developer -p StrongMasterKey_2026

Интеграция OpenCode с редакторами кода через протокол ACP

3. Полный справочник консольных команд и флагов OpenCode

CLI OpenCode предоставляет исчерпывающий набор флагов для автоматизации и тонкой настройки рантайма.

Флаги основного запуска TUI (opencode [project])

Флаг Короткий Описание
--continue -c Продолжить последнюю сессию в текущем каталоге.
--session <id> -s Подключиться к конкретной сессии по ее UUID.
--fork Ответвить (склонировать) сессию при продолжении, оставив оригинал без изменений.
--prompt <text> Передать начальный промпт при запуске интерфейса.
--model <provider/model> -m Задать модель в формате провайдер/модель.
--agent <name> Выбрать первичного агента на старте (build или plan).
--auto Автоматически одобрять все действия, не запрещенные явно в правах.
--port <num> Порт внутреннего HTTP-демона (по умолчанию 4096).
--hostname <host> Интерфейс привязки сервера (по умолчанию 127.0.0.1).
--mdns Включить анонс в локальной сети по mDNS (ZeroConf).
--mdns-domain <name> Доменное имя mDNS (по умолчанию opencode.local).
--cors <origin> Разрешенные CORS-источники для веб-клиента.

Флаги пакетного режима (opencode run [message])

Команда opencode run выполняет задачу без открытия графического TUI:

Флаг Короткий Описание
--file <path> -f Прикрепить один или несколько файлов к контексту сообщения.
--format <type> Формат вывода: default (человекочитаемый форматированный текст) или json (поток NDJSON-событий).
--attach <url> Выполнить команду на уже запущенном сервере (например, http://localhost:4096), избегая холодного старта.
--variant <name> Уровень усилий модели (reasoning effort: high, low).
--thinking Отображать блоки скрытых рассуждений модели (thinking blocks) в терминале.

Утилитарные команды CLI

  • opencode models [provider] [--refresh] — вывод списка всех распознанных моделей с проверкой актуальности на models.dev.
  • opencode auth login / logout / list — управление сохраненными ключами API (файл ~/.local/share/opencode/auth.json).
  • opencode session list [-n count] / delete <id> — просмотр и очистка локальной базы сессий.
  • opencode stats [--days N] [--models] — подробная статистика расхода токенов и затрат по дням и моделям.
  • opencode export <id> [--sanitize] / import <file> — экспорт/импорт сессий с возможностью обезличивания секретов.
  • opencode debug skill — вывод полного списка обнаруженных навыков с путями к файлам.
  • opencode debug config — просмотр итогового собранного JSON-конфига со всеми переопределениями.

4. Как добавить своего провайдера и модель (и почему это не получалось)

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

Почему добавление кастомного провайдера не срабатывает «в лоб»?

OpenCode построен на базе библиотеки Vercel AI SDK и реестра Models.dev. В отличие от простых скриптов, OpenCode требует строгой декларации провайдера в конфигурационном файле opencode.json (или ~/.config/opencode/opencode.json). Распространенные ошибки:

  1. Не указан пакет драйвера (npm): если вы просто пишете имя и URL, OpenCode не знает, какой протокол использовать. Для любых совместимых с OpenAI сервисов обязательно нужно прописать: "npm": "@ai-sdk/openai-compatible".
  2. Модель не зарегистрирована в словаре models: OpenCode валидирует доступные модели. Если модель не прописана в блоке models: { "имя": { ... } }, она никогда не появится в меню /models.
  3. Отсутствует суффикс /v1 в URL: драйвер ожидает базовый роут спецификации OpenAI. Для Ollama правильный путь — http://localhost:11434/v1, для LM Studio — http://localhost:1234/v1. Без /v1 сервер будет возвращать 404.
  4. Не заданы лимиты контекста (limit): для встроенных моделей OpenCode берет размер контекста из облачной базы. Для кастомных моделей лимиты необходимо указать явно, иначе механизм сжатия контекста (compaction) завершится ошибкой.

Эталонная конфигурация собственного провайдера

Создайте или отредактируйте файл ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "my-gateway": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Корпоративный AI Gateway",
      "options": {
        "baseURL": "https://ai-proxy.company.internal/v1",
        "apiKey": "{env:MY_GATEWAY_API_KEY}"
      },
      "models": {
        "qwen2.5-coder-32b": {
          "name": "Qwen 2.5 Coder 32B (Local)",
          "limit": {
            "context": 131072,
            "output": 8192
          }
        },
        "deepseek-coder-v2": {
          "name": "DeepSeek Coder V2.5",
          "limit": {
            "context": 65536,
            "output": 4096
          }
        }
      }
    }
  },
  "model": "my-gateway/qwen2.5-coder-32b"
}

Теперь достаточно экспортировать ключ в терминале: export MY_GATEWAY_API_KEY="sk-..." и запустить opencode. Модель my-gateway/qwen2.5-coder-32b будет сразу активна по умолчанию.

5. Откуда OpenCode берет навыки (Skills): папки, коллизии и приоритеты

Система навыков (Skills) в OpenCode стандартизирована под спецификацию SKILL.md. Агент не читает все инструкции разом: он видит краткие описания (name + description) и загружает полный текст через встроенный инструмент skill только при необходимости.

Где OpenCode ищет навыки:

OpenCode сканирует строго определенный список каталогов (с поддержкой кросс-совместимости с форматами Claude Code и Cursor):

Область Путь к каталогу навыка Стандарт
Проектная .opencode/skills/<name>/SKILL.md Нативный OpenCode
Проектная (совместимость) .claude/skills/<name>/SKILL.md Claude Code
Проектная (совместимость) .agents/skills/<name>/SKILL.md Cursor / Agent Skills
Глобальная ~/.config/opencode/skills/<name>/SKILL.md Нативный OpenCode
Глобальная (совместимость) ~/.claude/skills/<name>/SKILL.md Claude Code
Глобальная (совместимость) ~/.agents/skills/<name>/SKILL.md Cursor / Agent Skills

Какие папки OpenCode НЕ подхватывает:

  • Папки верхнего уровня вроде .skills/, skills/, docs/skills/ — они игнорируются, если не вложены в одну из служебных директорий (.opencode/skills, .claude/skills или .agents/skills).
  • Одиночные файлы .md, лежащие прямо в корне папки навыков (например, .opencode/skills/deploy.md). Навык обязан находиться в отдельной подпапке с именем файла SKILL.md.
  • Каталоги с именами, нарушающими спецификацию: имя должно быть в нижнем регистре, содержать только латиницу, цифры и одиночные дефисы (1–64 символа) и строго совпадать с полем name в YAML-шапке.

Алгоритм разрешения коллизий: кто побеждает?

При старте OpenCode выполняет подъем по дереву каталогов от текущей рабочей директории вверх до корня Git-репозитория:

  1. Сначала в реестр загружаются глобальные пользовательские навыки из домашней папки (~/.config/...).
  2. Затем загружаются проектные навыки из корня репозитория.
  3. Наконец, загружаются проектные навыки текущего подкаталога (актуально для монорепозиториев).

Правило разрешения конфликтов: реестр хранится в структуре Map<SkillName, SkillInfo>. Если в разных местах обнаружен навык с одинаковым именем (например, deploy), проектный локальный навык перезаписывает глобальный. Ближайший по дереву каталогов файл всегда имеет наивысший приоритет. Никаких сбоев или дублирования вызовов не происходит — в контекст попадет только самая специфичная для проекта версия.

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

opencode debug skill

6. Режимы работы: Primary Agents и Subagents

OpenCode разделяет агентов на первичных и вспомогательных сабагентов:

  • build (Primary, по умолчанию): основной рабочий режим разработчика. Разрешены операции edit, write, bash. Используется для реализации фич и прогона тестов.
  • plan (Primary, переключение по Tab): режим архитектурного планирования. Любые прямые правки файлов проекта и деструктивные шелл-команды заблокированы. Агент исследует проект, задает вопросы через question и сохраняет готовый план в директорию .opencode/plans/.
  • explore (Subagent): быстрый read-only сабагент для исследования кодовой базы. Его промежуточные вызовы не раздувают историю диалога.
  • general (Subagent): автономный агент для сложных изолированных подзадач, запускаемый через вызов @general <задача>.

7. LSP в PHP: друг или враг LLM?

В OpenCode встроен сервер Intelephense для PHP, однако по умолчанию LSP выключен (lsp: false). Это осознанное архитектурное решение.

Проблема «преждевременной диагностики»

Когда LLM выполняет многоэтапный рефакторинг, она часто сначала пишет вызов нового метода $service->process() в контроллере, а сам метод планирует создать следующим шагом. Если LSP выдает мгновенную ошибку Undefined method, модель впадает в панику (diagnostic thrashing), сбивается с плана и тратит токены на бесконечные попытки «починить» не завершенный код.

Вдобавок в Laravel динамические свойства моделей и фасады без сгенерированных метаданных вызывают массу ложных предупреждений. Поэтому включать LSP ("lsp": true) рекомендуется только для проектов со строгой типизацией (PHP 8.2+, declare(strict_types=1)) и после предварительной генерации хелперов:

php artisan ide-helper:generate
php artisan ide-helper:meta

8. Интеграция с GitHub: как подключить бота, какая модель работает и кто платит

Автоматически созданный Pull Request ботом opencode-agent в GitHub

Для OpenCode не нужно держать запущенный терминал на своем компьютере: агент умеет работать как автономный разработчик прямо внутри репозитория GitHub. Однако «из коробки» в случайном проекте команда /oc работать не будет — требуется предварительное подключение.

1. Что нужно добавить в репозиторий, чтобы команды заработали

Интеграция настраивается один раз на репозиторий (или организацию):

  1. Установить приложение GitHub App: перейдите на страницу github.com/apps/opencode-agent и нажмите Install, выбрав нужный репозиторий. Бот получает права комментировать тикеты, создавать изолированные ветки и открывать Pull Request от имени opencode-agent.

    (Альтернатива без установки стороннего бота: использовать стандартный токен GITHUB_TOKEN с флагом use_github_token: true — тогда коммиты будут идти от имени стандартного github-actions[bot]).
  2. Добавить файл воркфлоу: положите в проект файл .github/workflows/opencode.yml. Именно он перехватывает комментарии к задачам и запускает виртуальную машину.
  3. Добавить секреты API: в настройках репозитория (Settings → Secrets and variables → Actions) добавьте ключ вашей языковой модели (например, ANTHROPIC_API_KEY).

Все три шага можно выполнить автоматически одной консольной командой из локального терминала проекта:

opencode github install

2. Какая модель запускается и как устроен биллинг: платно или бесплатно?

Здесь действует модель полной прозрачности и отсутствия скрытых комиссий:

  • Сам OpenCode — на 100% бесплатный open-source софт: за использование рантайма или экшена никакой платы нет.
  • Оплата за серверные мощности (GitHub Actions): вызовы выполняются на стандартных раннерах GitHub (ubuntu-latest). Для публичных (open-source) репозиториев минуты GitHub Actions полностью бесплатны. Для приватных репозиториев расходуются стандартные бесплатные лимиты аккаунта GitHub (2000 минут в месяц для бесплатного плана Free).
  • Оплата за токены LLM: модель выбираете вы сами в строке model файла воркфлоу (например, anthropic/claude-sonnet-5-5, openai/gpt-4o или opencode/gpt-6.1-sol). Запросы оплачиваются напрямую вашему провайдеру по обычному API-тарифу через API-ключ, сохраненный в Secrets вашего репозитория.

3. Можно ли подключить свою модель или свой шлюз?

Да. Если в корне вашего репозитория уже лежит настроенный файл opencode.json с кастомным провайдером (например, локальный vLLM / Ollama или корпоративный proxy через @ai-sdk/openai-compatible), GitHub Action автоматически подхватит его конфигурацию. Достаточно передать URL шлюза и токен через переменные окружения раннера.

4. Как выглядит файл сценария .github/workflows/opencode.yml

name: opencode

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

jobs:
  opencode:
    # Запускаем только если комментарий содержит /oc или /opencode
    if: |
      contains(github.event.comment.body, '/oc') ||
      contains(github.event.comment.body, '/opencode')
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v6
      - uses: anomalyco/opencode/github@latest
        env:
          # Ваш собственный API-ключ провайдера
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        with:
          # Модель, которую вы хотите использовать
          model: anthropic/claude-sonnet-5-5

5. Повседневный сценарий использования

После однократной настройки разработчик работает прямо через сайт GitHub:

  1. Открывает тикет (Issue) с задачей и пишет комментарий:
    /oc Реализуй экспорт заказов в CSV и напиши юнит-тесты
  2. GitHub Actions запускает контейнер, OpenCode клонирует код, изучает проект, создает ветку opencode/issue123-..., пишет код и прогоняет тесты.
  3. Бот сам публикует готовый Pull Request с меткой Closes #123 и подробным списком изменений. Вы смотрите дифф и нажимаете Merge.

Открытый исходный код, независимость от провайдеров, предсказуемая работа со скиллами и возможность подключать локальные LLM делают OpenCode одним из самых зрелых инструментов для команд, ценящих автономность и безопасность своих данных.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *