Дайте любому текстовому агенту OpenCode способность видеть картинки — без перехода на vision-модель.
Ваш агент работает на DeepSeek, GLM, Qwen или другой модели, которая не умеет работать с изображениями? Этот мост добавляет зрение в два приёма: входящие картинки автоматически описываются текстом (плагин), а когда нужно точное прочтение — агент сам вызывает vision-модель через MCP-сервер. Сама модель остаётся текстовой, зрение приходит снаружи.
Для агента: выполните шаги 1–7 по порядку. Каждая команда исполняема буквально.
Плагин автоматически заменяет входящие изображения на текстовое описание. Инструкция по установке — в репозитории плагина: https://github.com/nicholasgriffintn/opencode-eyesight
Linux / macOS:
mkdir -p ~/.config/opencode/bin
cp bin/vision-mcp.py ~/.config/opencode/bin/
cp bin/run-mcp-with-secrets.sh ~/.config/opencode/bin/
cp PROMPT.md ~/.config/opencode/vision-describe-prompt.md
chmod +x ~/.config/opencode/bin/run-mcp-with-secrets.shWindows (PowerShell):
mkdir "$HOME\.config\opencode\bin" -Force
Copy-Item bin\vision-mcp.py "$HOME\.config\opencode\bin\"
Copy-Item bin\run-mcp-with-secrets.ps1 "$HOME\.config\opencode\bin\"
Copy-Item PROMPT.md "$HOME\.config\opencode\vision-describe-prompt.md"| OpenRouter + Alibaba | neuraldeep | |
|---|---|---|
| Цена | платно, дешевле всех из 6 провайдеров | бесплатно |
| Доступ из России | возможны блокировки (см. ниже) | работает без ограничений |
| Модель | qwen3-vl-30b-a3b-instruct |
qwen3.6-35b-a3b |
В октябре 2025 года Евросоюз принял 19-й пакет санкций, который запретил предоставление ИИ-услуг (включая доступ к языковым моделям через API) лицам и компаниям из России. С мая–июня 2026 года OpenRouter начал рассылать российским пользователям уведомления о невозможности пополнить счёт и грядущей блокировке аккаунтов — сначала перестали проходить платежи, затем последовали технические ограничения.
Если вы в России — рекомендуем neuraldeep: бесплатный тариф включает vision-модель, регистрации ничего не стоит, блокировок нет.
Linux / macOS:
cat > ~/.config/opencode/.env.secrets << 'EOF'
# ── ВАРИАНТ A: OpenRouter ──
OPENROUTER_API_KEY=sk-or-v1-ваш-ключ
# ── ВАРИАНТ B: neuraldeep (раскомментируйте и подставьте свой ключ) ──
# VISION_API_KEY=ваш-neuraldeep-ключ
# VISION_MODEL=qwen3.6-35b-a3b
# VISION_BASE_URL=https://api.neuraldeep.ru/v1/chat/completions
# VISION_PROVIDER_ORDER=
EOF
chmod 600 ~/.config/opencode/.env.secretsWindows (PowerShell) — путь к секретам тот же: $HOME\.config\opencode\.env.secrets.
Создайте файл любым редактором (Notepad/VS Code) с содержимым выше.
Для OpenRouter достаточно указать OPENROUTER_API_KEY — MCP подхватит его автоматически.
Для neuraldeep — раскомментируйте четыре строки VISION_* и впишите свой ключ.
Получить бесплатный ключ neuraldeep можно по ссылке: зарегистрироваться на neuraldeep →
Возьмите один файл из config/ и добавьте его содержимое в ваш ~/.config/opencode/opencode.json:
- OpenRouter →
config/opencode.openrouter.json - neuraldeep →
config/opencode.neuraldeep.json
Замените {{HOME}} на путь к вашему домашнему каталогу (например /Users/anton, C:\\Users\\Ivan — в JSON обратные слеши Windows удваиваются).
Если в opencode.json уже есть ключи "plugin" или "mcp" — добавьте записи внутрь существующих, не заменяйте их целиком.
Windows: в блоке mcp.vision замените command на вариант с run-mcp-with-secrets.ps1 — готовый фрагмент лежит в поле _windows конфиг-файла (ключ _windows в итоговый opencode.json не копируйте).
Откройте файл из папки injections/, соответствующий вашей модели, и скопируйте блок в системный промпт:
| Модель | Файл | Куда вставить |
|---|---|---|
| Любая текстовая (Claude, GPT, Qwen, Llama…) | injections/generic.md |
В любое стабильное место |
| GLM 5.x | injections/glm.md |
Основной блок — в начало, якорь — в конец |
| DeepSeek V4 Pro | injections/deepseek-pro.md |
Краткий блок — в начало, якорь — в конец |
| DeepSeek V4 Flash | injections/deepseek-flash.md |
Только якорь — в самый конец |
Блок самодостаточен — структура вашего агента не имеет значения, просто вставьте текст в системный промпт.
# MCP компилируется?
python3 -m py_compile ~/.config/opencode/bin/vision-mcp.py && echo "OK"
# Windows: python -m py_compile "$HOME\.config\opencode\bin\vision-mcp.py"
# Проверьте describe_image на любой картинке:
uv run --no-project --with mcp --with httpx python3 -c "
import asyncio, importlib.util, os
spec = importlib.util.spec_from_file_location('vmp', os.path.expanduser('~/.config/opencode/bin/vision-mcp.py'))
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
r = asyncio.run(m.describe_image('/путь/к/картинке.png', 'опиши кратко'))
print(r)
"Автоматические тесты без реального ключа (подменённый API):
pip install mcp httpx pytest
python -m pytest tests/ -vЕсли вернулся осмысленный текст — всё работает. Дополнительные сценарии проверки — в smoke-test/PROTOCOL.md.
Мост состоит из двух слоёв, которые дополняют друг друга:
┌─────────────────────────────────┐
Картинка → контекст ──→ │ СЛОЙ 1: АВТО (плагин) │ → "[Image: текстовое описание]"
│ opencode-eyesight │ общий обзор, низкая достоверность
└─────────────────────────────────┘
│
┌─────────────────────────────────┐ │
Агент: "точный текст?" →│ СЛОЙ 2: РУЧНОЙ (MCP) │ ←──────────┘
│ describe_image(path, prompt) │ → точный ответ, высокая достоверность
└─────────────────────────────────┘
Плагин (слой 1) даёт общее описание на входе — этого часто достаточно, чтобы понять суть картинки. Но текстовая модель не может задать изображению уточняющий вопрос: «прочитай текст дословно», «какая кнопка сейчас активна», «сравни первый и третий кадр». Для таких задач нужен слой 2 — MCP-сервер describe_image. Агент вызывает его сам, когда автоописания не хватило, и получает точный ответ на конкретный вопрос.
Без второго слоя агент слепо доверяет общему описанию и додумывает детали, которых там не было.
Правило простое — всегда указывайте источник информации:
- Автоматическое описание (от плагина) — это общий обзор. Низкая достоверность: годится для понимания «что на картинке», но не для точных деталей.
describe_image(вызов агентом) — точный ответ на конкретный вопрос. Высокая достоверность.- Формулируйте ссылки на источник так: «по данным describe_image: …» или «по автоописанию: …». Не пишите «я вижу…» — модель не видит изображения, она работает с текстом.
- Сначала используйте автоматическое описание. Обращайтесь к
describe_imageтолько тогда, когда нужна точность — каждый вызов расходует токены и время.
vision-bridge-opencode/
├── README.md # этот файл
├── LICENSE # MIT
├── PROMPT.md # шаблон для автоматического описания (слой 1)
├── pyproject.toml # закреплённые зависимости (mcp, httpx)
├── bin/
│ ├── vision-mcp.py # MCP-сервер describe_image (слой 2)
│ ├── run-mcp-with-secrets.sh # обёртка секретов: Linux/macOS
│ └── run-mcp-with-secrets.ps1 # обёртка секретов: Windows (PowerShell)
├── config/
│ ├── opencode.openrouter.json # настройки: OpenRouter + Alibaba
│ └── opencode.neuraldeep.json # настройки: neuraldeep (бесплатно, РФ)
├── injections/ # блоки для системного промпта агента
│ ├── generic.md # любая текстовая модель
│ ├── glm.md # GLM 5.x (разреженное внимание — раннее позиционирование)
│ ├── deepseek-pro.md # DeepSeek V4 Pro (эффект недавности)
│ └── deepseek-flash.md # DeepSeek V4 Flash (только якорь)
├── tests/
│ └── test_vision_mcp.py # pytest, API подменяется — ключ не нужен
├── .github/workflows/test.yml # CI: pytest на Linux/Windows
└── smoke-test/
└── PROTOCOL.md # сценарии проверки
Задаются в ~/.config/opencode/.env.secrets:
| Переменная | Дефолт | Назначение |
|---|---|---|
VISION_API_KEY |
— | Ключ провайдера (или OPENROUTER_API_KEY для OpenRouter) |
VISION_BASE_URL |
https://openrouter.ai/api/v1/chat/completions |
Endpoint OpenAI-совместимого API |
VISION_MODEL |
qwen/qwen3-vl-30b-a3b-instruct |
Имя vision-модели |
VISION_PROVIDER_ORDER |
alibaba |
Маршрутизация провайдера (только OpenRouter); пусто — не задавать |
VISION_ALLOW_FALLBACKS |
false |
Разрешить fallback-провайдеров (1/true/yes) |
VISION_MAX_TOKENS |
4096 |
Лимит токенов ответа. У reasoning-моделей часть бюджета идёт на внутреннее рассуждение — не опускайте ниже 2048 |
VISION_TIMEOUT |
60 |
Таймаут HTTP-запроса, сек |
VISION_MAX_FILE_MB |
20 |
Лимит размера файла до кодирования в base64 (base64 добавляет ~33%) |
VISION_MAX_SIDE |
0 (выкл.) |
Даунскейл до N px по длинной стороне перед отправкой; требует pip install Pillow |
| Симптом | Причина | Решение |
|---|---|---|
describe_image ERROR: API key not set |
ключ не задан | проверьте ~/.config/opencode/.env.secrets (шаг 4) |
describe_image ERROR 401: ... |
неверный ключ | перепроверьте ключ провайдера |
| MCP не появляется в списке инструментов | неверный формат конфигурации | ключ "mcp" (НЕ mcpServers), тип "local" (НЕ stdio), command — массив |
| Плагин не описывает картинки | модель не подключена | проверьте "model" в plugin: openrouter/qwen/... или neuraldeep/qwen3.6-... |
describe_image ERROR 404: ... |
неверная модель или адрес | сверьте VISION_MODEL и VISION_BASE_URL с провайдером |
| Запросы идут через дорогой провайдер | маршрутизация не применена | убедитесь, что provider.openrouter.models...options.provider.order задан (шаг 5) |
describe_image ERROR EMPTY: ... finish_reason=length |
у reasoning-модели не хватило max_tokens |
поднимите VISION_MAX_TOKENS (дефолт уже 4096) |
describe_image ERROR 413/504 |
изображение слишком большое для лимита API | задайте VISION_MAX_SIDE=1568 (нужен Pillow) или уменьшите файл вручную |
describe_image ERROR BAD_FORMAT |
файл не изображение или неподдерживаемый формат | поддерживаются png/jpeg/gif/webp/bmp; формат определяется по содержимому, не расширению |
describe_image ERROR TOO_LARGE |
файл больше VISION_MAX_FILE_MB |
уменьшите файл или поднимите лимит |
uv run падает с конфликтом зависимостей в каталоге с pyproject.toml |
uv подхватывает чужой проект | в command уже стоит uv run --no-project — обновите конфиг из репозитория |
Windows: run-mcp-with-secrets.sh не запускается |
bash-скрипт на Windows | используйте run-mcp-with-secrets.ps1 (шаг 5) |
Шесть провайдеров обслуживают модель qwen3-vl-30b-a3b-instruct; Alibaba — самый дешёвый ($0.13/$0.52 за миллион токенов) и быстрый. Настройка order: ["alibaba"], allow_fallbacks: false жёстко закрепляет провайдер — цена всегда предсказуема. Если нужна отказоустойчивость (переключение на другой провайдер при сбое Alibaba) — поставьте allow_fallbacks: true.
Бесплатный тариф включает модель qwen3.6-35b-a3b с поддержкой изображений. Один провайдер — маршрутизация не нужна. Регистрация: создать аккаунт neuraldeep →. Ограничение: одна картинка на запрос.
bin/vision-mcp.py, обёртки,injections/, конфигурации, тесты — MIT (файлLICENSE).- Плагин opencode-eyesight — сторонний проект со своей лицензией (см. репозиторий плагина).
- Это не форк плагина, а рецепт интеграции поверх него.