Агенты opencode: как настроить роли, модели и инструменты

Свой агент в opencode — это роль, модель и список разрешений. Показываем конфиг и пример, где рутину делает дешёвая модель, а код правит сильная.

5 мин · · агенты · экономия

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

Параметры сверены с разделом Agents документации opencode.ai/docs на 18 октября 2026. В проекте есть заметка про вторую версию, поэтому если ваша версия ведёт себя иначе, откройте документацию именно под неё.

Какие агенты есть в opencode

Агенты делятся на два типа.

Основные (primary) — те, с кем вы разговариваете. Переключаются клавишей Tab. Встроенных два: Build (все инструменты включены) и Plan (ограниченный: правки и bash по умолчанию требуют подтверждения, он нужен для анализа и планов).

Субагенты (subagent) — помощники, которых вызывает основной агент для отдельной задачи или которых вы зовёте упоминанием @имя. Встроенные: General (универсальный, может править файлы), Explore (быстрый, только чтение) и Scout (только чтение, для внешней документации и исходников зависимостей).

Есть ещё скрытые служебные агенты: один сжимает длинный контекст, другой придумывает названия сессий, третий делает сводки. Выбрать их в интерфейсе нельзя, но они тоже обращаются к модели. Об этом будет ниже, в разделе про расходы.

Два способа описать агента

Первый способ — блок agent в opencode.json. Ключ — имя агента:

bash
{
  "$schema": "https://opencode.ai/config.json",
  "agent": {
    "reviewer": {
      "description": "Ревью кода без правок",
      "mode": "subagent",
      "model": "anthropic/claude-opus-5-5",
      "prompt": "Ты ревьюер. Смотри на безопасность, производительность и читаемость.",
      "permission": { "edit": "deny" }
    }
  }
}

Второй способ — markdown-файл. Положите его в ~/.config/opencode/agents/ (для всех проектов) или в .opencode/agents/ (для текущего). Имя файла становится именем агента: review.md создаёт агента review. Настройки идут в front matter, а текст после него — системный промпт.

Поле description обязательно. Без описания основной агент не поймёт, когда этого субагента вызывать.

Быстро создать заготовку можно командой opencode agent create: она спросит, где сохранить, зачем нужен агент, и предложит выбрать разрешения, а всё невыбранное запретит.

Что можно задать

  • model в формате провайдер/модель. Если не указать, основной агент берёт глобальную модель, а субагент — модель вызвавшего его основного агента.
  • permission — что агенту можно: read, edit, bash, task, webfetch и другие. Значения allow, ask, deny; для edit и bash можно задавать объект с шаблонами.
  • mode — primary, subagent или all (по умолчанию).
  • steps — потолок числа шагов агента. Дойдя до него, агент должен подвести итог текстом. Это простой предохранитель от дорогих зацикливаний.
  • temperature, top_p — степень случайности. Если не задана, берутся значения по умолчанию для модели.
  • prompt — текст или файл через {file:./prompts/review.txt}, путь считается от места конфига.
  • hidden — спрятать субагента из подсказок @ (только для субагентов).

Поле tools в документации помечено как устаревшее: для новых конфигов советуют permission.

Пример: дешёвая модель для рутины

Допустим, основную работу делает claude-sonnet-5, планы строит claude-opus-5-5, а описания коммитов и правки документации отдаём недорогой модели. Для Claude берём встроенный провайдер anthropic (так шлюз видит кэш), для дешёвых моделей добавляем OpenAI-совместимый провайдер. Адрес в обоих случаях https://api.zukko.pro/v1, подробности есть в документации по opencode.

bash
{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-sonnet-5",
  "small_model": "zukko/glm-5.3-flash",
  "provider": {
    "anthropic": {
      "options": { "baseURL": "https://api.zukko.pro/v1", "apiKey": "{env:ZUKKO_API_KEY}" },
      "models": { "claude-sonnet-5": {}, "claude-opus-5-5": {} }
    },
    "zukko": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Zukko",
      "options": { "baseURL": "https://api.zukko.pro/v1", "apiKey": "{env:ZUKKO_API_KEY}" },
      "models": {

Поле small_model в документации описано как отдельная модель для лёгких задач вроде заголовков сессий. Если его не задать, opencode сам постарается найти что-то подешевле у вашего провайдера, иначе возьмёт основную. Лучше задать явно, чтобы не гадать, куда уходят эти запросы.

Теперь файл .opencode/agents/changelog.md:

bash
---
description: Пишет сообщения коммитов и записи в CHANGELOG по git diff
mode: subagent
model: zukko/deepseek-v4.1-flash
temperature: 0.2
steps: 8
permission:
  edit:
    "*": deny
    "CHANGELOG.md": allow
  bash:
    "*": deny
    "git diff*": allow
    "git log*": allow
    "git status*": allow
---
Ты ведёшь историю изменений. Читай diff, группируй изменения по смыслу
и пиши коротко, в прошедшем времени. Не придумывай то, чего нет в diff.
Правь только CHANGELOG.md.

В правилах permission последнее подходящее правило побеждает, поэтому сначала идёт общий запрет "*": deny, а исключения за ним. Если перепутать порядок, запрет перекроет разрешения.

Использовать агента просто: в сообщении напишите @changelog подготовь запись по последним трём коммитам. Основной агент тоже может вызвать его сам, ориентируясь на description.

Как ограничить, кого агент может звать

У оркестратора есть право task. С его помощью можно перечислить, каких субагентов он вправе вызывать:

bash
{
  "agent": {
    "orchestrator": {
      "mode": "primary",
      "permission": {
        "task": { "*": "deny", "changelog": "allow", "reviewer": "ask" }
      }
    }
  }
}

Запрещённый субагент исчезает из описания инструмента, и модель даже не пытается его вызвать. Вручную через @ вы по-прежнему можете позвать любого.

Сколько это экономит

Цены Zukko на 18 октября 2026, $ за 1M токенов, кэш не учитываем. Условный запуск рутинного агента: 50 000 токенов входа и 5 000 выхода.

  • deepseek-v4.1-flash (0.013 вход / 0.038 выход): 0.05 × 0.013 + 0.005 × 0.038 = 0.00065 + 0.00019 = $0.00084.
  • claude-sonnet-5 (0.4 / 2): 0.05 × 0.4 + 0.005 × 2 = 0.02 + 0.01 = $0.03.

За сто запусков это около $0.08 против $3.00. Разница заметна, когда рутина идёт каждый день. Но не стоит делегировать дешёвой модели всё подряд: для коммитов и документации её хватает не всегда, это надо проверять на своих задачах. Актуальные цены и список моделей смотрите в GET https://api.zukko.pro/v1/models.

Проверка

  1. Запустите opencode и выполните /models: в списке должны быть модели обоих провайдеров.
  2. Вызовите @changelog и убедитесь, что он не может править ничего, кроме CHANGELOG.md.
  3. Загляните в раздел «Использование» в кабинете Zukko: запросы должны идти на ту модель, которую вы назначили агенту.

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

Частые вопросы

Чем агент отличается от субагента?

Основным агентом вы пользуетесь напрямую, переключая его через Tab. Субагента вызывает основной агент или вы через @, он выполняет отдельную задачу в своей сессии.

Как подключить MCP только одному агенту?

Серверы описываются в блоке mcp, а доступ к их инструментам ограничивается правами или шаблонами вида имя_сервера_*. Подробности и примеры есть в разделе MCP servers документации opencode.

Чем это похоже на агентов в Cline?

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

Агент не видит модель из конфига. Что делать?

Проверьте, что имя модели в agent.<имя>.model совпадает с ключом в блоке models провайдера и что провайдер указан правильно: zukko/deepseek-v4.1-flash, а не просто deepseek-v4.1-flash.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.