Загрузка...

популярность в разделе «Другие редакторы»

Вайб-кодинг в Neovim: настройка CodeCompanion.nvim через RouterAI (Claude, Qwen, DeepSeek)

CodeCompanion.nvim — AI-плагин для Neovim (Apache-2.0, около 6,9 тыс. звёзд на GitHub): чат прямо в буфере, inline-правки с diff, командный режим и агент с инструментами (tools) для чтения и правки файлов. В этой статье мы подключим его к RouterAI через адаптер openai_compatible: один ключ для Claude, Qwen, DeepSeek и GLM, работа из России без VPN и оплата в рублях.

Статья написана для версии плагина v20.0.1 (октябрь 2026) и Neovim 0.12.6.

Требования

  • Neovim 0.12 или новее (так сказано в документации установки);
  • curl в системе;
  • плагины plenary.nvim и nvim-treesitter (последний нужен для yaml-парсера — разбора markdown-промптов и skills);
  • менеджер плагинов, в примерах — lazy.nvim;
  • ключ RouterAI: зарегистрируйтесь на routerai.ru, пополните баланс и создайте ключ в разделе «Ключи API». Ключ показывают один раз, скопируйте его сразу.

Установка

Добавьте плагин в конфигурацию lazy.nvim. Документация рекомендует закрепить версию, чтобы обновления не ломали конфиг:

{
  "olimorris/codecompanion.nvim",
  version = "^20.0.0",
  opts = {},
  dependencies = {
    "nvim-lua/plenary.nvim",
    "nvim-treesitter/nvim-treesitter",
  },
},

Перезапустите Neovim, выполните :Lazy sync и проверьте зависимости командой :checkhealth codecompanion.

Результат :checkhealth codecompanion: версия Neovim 0.12.6, plenary.nvim и curl найдены, предупреждения по необязательным yaml parser, markitdown и sqlite3

Предупреждения (WARNING) о yaml parser, markitdown и sqlite3 относятся к необязательным зависимостям: они нужны для markdown-промптов, загрузки веб-страниц и токенов Copilot и на работу с RouterAI не влияют.

Подключение к RouterAI

В CodeCompanion HTTP-адаптеры лежат в adapters.http. Для любого OpenAI-совместимого сервиса расширяют openai_compatible под собственным именем.

Шаг 1. Ключ в переменной окружения

Не храните ключ в конфиге: адаптер читает его из переменной окружения при каждом запросе.

export ROUTERAI_API_KEY="sk-xxxxxxxxxxxxxxxx"

Добавьте строку в ~/.bashrc или ~/.zshrc и запускайте Neovim из этого же окружения.

Шаг 2. Адаптер routerai

Создайте файл ~/.config/nvim/lua/plugins/codecompanion.lua:

return {
  "olimorris/codecompanion.nvim",
  version = "^20.0.0",
  dependencies = {
    "nvim-lua/plenary.nvim",
    "nvim-treesitter/nvim-treesitter",
  },
  opts = {
    adapters = {
      http = {
        routerai = function()
          return require("codecompanion.adapters").extend("openai_compatible", {
            formatted_name = "RouterAI",
            env = {
              url = "https://routerai.ru/api",
              api_key = "ROUTERAI_API_KEY",
            },
            schema = {
              model = {
                default = "anthropic/claude-sonnet-5.5",
              },
            },
          })
        end,
      },
    },
    interactions = {
      chat = { adapter = "routerai" },
      inline = { adapter = "routerai" },
      cmd = { adapter = "routerai" },
    },
  },
}

Конфиг адаптера routerai для CodeCompanion в Neovim: url, api_key как имя переменной окружения и модель по умолчанию

Что здесь важно:

Поле Значение Пояснение
formatted_name RouterAI Название в заголовке чата и в списке адаптеров
env.url https://routerai.ru/api Без /v1 — см. ниже
env.api_key ROUTERAI_API_KEY Имя переменной окружения, а не сам ключ
schema.model.default anthropic/claude-sonnet-5.5 Модель по умолчанию, id из каталога
interactions.*.adapter routerai Чат, inline и cmd используют этот адаптер

Почему url без /v1. Адаптер собирает адрес как url + chat_url, а chat_url по умолчанию равен /v1/chat/completions. Мы проверили: с url = "https://routerai.ru/api" запросы уходят на https://routerai.ru/api/v1/chat/completions и https://routerai.ru/api/v1/models. Если указать https://routerai.ru/api/v1, получится /api/v1/v1/chat/completions и ответ 404. В других инструментах Base URL RouterAI — https://routerai.ru/api/v1, но здесь /v1 добавляет сам адаптер.

Если не задать api_key, адаптер отправит значение OPENAI_API_KEY — ваш ключ OpenAI уйдёт не туда. Всегда задавайте api_key явно.

Команды и режимы

Ни одна команда по умолчанию не привязана к клавишам; список — в справочнике команд.

Команда Что делает
:CodeCompanionChat Открывает чат-буфер
:CodeCompanionChat Toggle Показывает или скрывает последний чат
:CodeCompanionChat adapter=routerai model=qwen/qwen3-coder Чат с конкретным адаптером и моделью
:CodeCompanion <запрос> Inline-правка текущего буфера или выделения
:CodeCompanionCmd <запрос> Генерирует команду для командной строки Neovim
:CodeCompanionActions Палитра действий и библиотека промптов

Режимы (interactions) настраиваются отдельно: chat, inline и cmd. Так можно отдать чат мощной модели, а cmd — быстрой:

interactions = {
  chat = { adapter = { name = "routerai", model = "anthropic/claude-sonnet-5.5" } },
  inline = { adapter = { name = "routerai", model = "qwen/qwen3-coder" } },
  cmd = { adapter = { name = "routerai", model = "z-ai/glm-5.3-flash" } },
},

Чат

Откройте файл и выполните :CodeCompanionChat. Сообщение отправляется по <C-s> в режиме вставки или <CR> в нормальном режиме. Чтобы модель увидела код, добавьте контекст #{buffer} — без него модель отвечает только по тексту сообщения (в нашей проверке на вопрос «какие функции экспортирует этот файл?» без #{buffer} модель попросила прислать код):

Какие функции экспортирует #{buffer:invoices.js}? Ответь коротко, списком.

Окно чата CodeCompanion с адаптером RouterAI: слева вопрос с #{buffer:invoices.js} и один ответ модели со списком функций allInvoices и totalAmount, справа файл invoices.js

Inline

Выделите код и выполните:

:'<,'>CodeCompanion Добавь JSDoc к totalAmount

Модель правит выделение, а изменения показываются как diff по блокам (hunk): ga принимает блок, gr отклоняет, g2 принимает все оставшиеся, g3 отклоняет все оставшиеся. Список клавиш открывается по ? в diff. Для inline модель обязана поддерживать tool calling — именно через него она правит буфер.

Inline-правка CodeCompanion в invoices.js: выделена функция totalAmount, модель добавила JSDoc, изменение показано зелёным блоком diff с пометкой Hunk 1/1

Агентный режим и подтверждения

Чтобы модель могла читать и менять файлы, добавьте в сообщение инструменты: @{files} даёт чтение, создание и правку файлов, @{agent} — полный набор, включая запуск команд:

@{files} Добавь docstring к каждой функции в #{buffer}

По умолчанию каждый чат стартует в режиме Ask (описано в руководстве по подтверждениям):

Инструмент До выполнения После выполнения
read_file, grep_search Спрашивает —
run_command Спрашивает для каждой команды —
delete_file Спрашивает для каждого файла —
create_file, edit_file Выполняется Просит подтвердить изменение (diff)

Ответы на запрос: g1 — всегда разрешать в этом чате, g2 — разрешить один раз, g3 — отклонить с причиной, g4 — отменить всё. Режим чата меняется клавишей gty: Ask, Auto (всё, кроме run_command и защищённых инструментов вроде delete_file) и YOLO (всё без вопросов). Режим Auto пишет правки сразу на диск, поэтому проверяйте результат командой :CodeCompanionCodeReview и держите проект под git.

Режим по умолчанию меняется так:

interactions = {
  chat = {
    tools = { opts = { approval_mode = "ask" } }, -- "ask", "auto" или "yolo"
  },
},

Выбор модели

Идентификаторы сверены с каталогом RouterAI; все пять моделей отвечают через /api/v1/chat/completions и объявляют поддержку tools. Цены смотрите в каталоге — они зависят от модели и объёма контекста.

Модель Для чего
anthropic/claude-sonnet-5.5 Рефакторинг и сложные многофайловые правки, основной вариант
anthropic/claude-haiku-5.5 Быстрые ответы и мелкие правки
qwen/qwen3-coder Генерация и правка кода, inline-запросы
deepseek/deepseek-v4.1-flash-1017 Дешёвые массовые задачи: тесты, комментарии, мелкие правки
z-ai/glm-5.3-flash Недорогие быстрые запросы, например для cmd

Модель в чате переключается клавишей ga (адаптер и модель), а при пустом default адаптер возьмёт первую модель из /v1/models. Чтобы список был коротким и не зависел от каталога, задайте его вручную:

schema = {
  model = {
    default = "anthropic/claude-sonnet-5.5",
    choices = {
      "anthropic/claude-sonnet-5.5",
      "qwen/qwen3-coder",
      "deepseek/deepseek-v4.1-flash-1017",
      "z-ai/glm-5.3-flash",
    },
  },
},

Проверка подключения

  1. Запустите nvim в каталоге проекта из того же терминала, где задан ROUTERAI_API_KEY.
  2. Выполните :CodeCompanionChat — в заголовке ответа должно быть CodeCompanion (RouterAI).
  3. Отправьте Привет! Какая ты модель? #{buffer} по <C-s>.
  4. Через несколько секунд придёт ответ. Если его нет, откройте :checkhealth codecompanion и лог (stdpath("log"), файл codecompanion.log).

Решение проблем

  • 404 на запросе. В env.url стоит https://routerai.ru/api/v1. Уберите /v1: адаптер добавляет его сам.
  • Ответ не приходит. Возможно, Neovim не видит переменную ROUTERAI_API_KEY (например, запущен из GUI-ярлыка). Проверьте :lua print(vim.env.ROUTERAI_API_KEY ~= nil) (должно вывести true; сам ключ не печатается) и запускайте Neovim из терминала с экспортированной переменной.
  • Модель «не видит» файл. Добавьте #{buffer} или #{buffer:имя_файла}; для правок — @{files}.
  • Inline не вносит правки. Модель должна поддерживать tool calling. Выберите одну из моделей из таблицы выше.
  • В списке моделей не те варианты или адаптер ждёт /v1/models слишком долго. Задайте schema.model.choices вручную. Если определены два адаптера на openai_compatible, у каждого задайте default и choices: кэш моделей у них общий.
  • Нужен подробный лог. Включите opts = { log_level = "DEBUG" } в setup(), повторите запрос и посмотрите codecompanion.log; после отладки верните ERROR.

Чем отличается от Avante

CodeCompanion шире по режимам: чат, inline, cmd, агент с инструментами и подтверждениями, библиотека промптов и подключение ACP-агентов. Цена — ручная конфигурация на Lua: адаптер, модели и подтверждения вы задаёте сами. Если нужен другой подход к AI в Neovim, посмотрите гайд по Avante.

Что дальше