Мне понадобилось обрабатывать десятки тысяч рекламных объявлений с помощью LLM. На выходе нужен был строго валидный JSON с датами, тегами, временем, стоимостью и другой структурированной информацией. Главные требования были простыми:
высокая точность;
стабильный Structured Output;
минимальная стоимость обработки.
Перепробовав множество вариантов, я обнаружил, что полностью бесплатные модели вроде OpenRouter действительно позволяют решить задачу без вложений, но на практике я столкнулся с двумя проблемами:
около 40% ответов не соответствовали требуемой JSON‑схеме;
даже корректный JSON часто содержал ошибки в извлечённых данных (даты, теги, описание).
Было принято решение попробовать платные модели:
Модель |
Цена за запрос |
Частота правильных ответов |
Качество парсинга |
Qwen 3.5-Flash |
~ 8 копеек |
95% |
8/10 |
Mistral‑3.5 |
~ 7 копеек |
80–85% |
5/10 |
GPT 5-nano |
10–12 копеек |
100% |
10/10 |
Тестирование проводилось на нескольких сотнях сообщений из реального дата сета.
Лучше всего справился GPT и я даже думал оставить именно его, однако при моих нагрузках получается цена 100–120 рублей за 10 000 обработанных постов. Как по мне цена в долгосрочной перспективе кусается, а оптимизацией промптов удалось добиться лишь снижения качества ответов. Нужно было как можно быстрее найти более дешёвое решение.
Этап 1 — обнаружение решения
К моменту, как у меня возникла эта проблема я уже некоторое время пользовался Codex от OpenAI для помощи в разработке. Первое, что пришло на ум было использовать уже оплаченный Codex. Однако официального API у него нет, а автоматизация через неофициальные мосты нарушает условия использования. Поэтому этот вариант пришлось сразу отбросить.
Далее я познакомился с Opencode — инструментом для работы с AI‑агентами, полностью написанным на Typescript. Opencode Go продаёт подписку за $5/месяц, которая включает $60 кредитов на модели. При этом стоимость токенов остаётся такой же, как если бы вы платили напрямую. Фактически получается 12-кратная скидка на первые $60 использования.
Этап 2 — поиск готовых вариантов
В этот момент возникла новая проблема. Opencode Go отлично подходит для интерактивной работы, но готового API для интеграции в приложения я не нашёл. Все существующие решения были либо прокси под OpenAI API, либо CLI‑утилитами.
Поэтому пришлось написать собственный сервер.

Этап 3 — создание собственного API
Как базу для API — взял стандартный backend с модульной архитектурой на Express.js с простой авторизацией по username + password в заголовках и обработкой ошибок, базовым роутингом. Такой backend достаточно легко расширять не теряя при этом чёткой структуры.
В качестве базы данных был выбран SQLite — необходимости в чём то большем нет.
Первым делом я нашёл информацию о том, куда отправляется запрос при использовании Opencode‑go и сразу же столкнулся с первой проблемой:
В подписке доступны 13 моделей, 5 из которых (Minimax и Qwen различных версий) поддерживают только только Anthropic совместимый формат запроса(system prompt отдельным полем в body, другие обязательные параметры вроде max_tokens), а оставшиеся только OpenAI совместимый формат. Пришлось «развести» модели по разным форматам, сохраняя при этом единый формат запроса к уже моему API.
const isAnthropic = ANTHROPIC_MODELS.includes(model) if (isAnthropic) { // отдельное поле system // api ключ в заголовке x-api-key // anthropic-version } else { // system превращается в первое сообщение // api ключ в заголовке Authorization: Bearer sk-xx }
В итоге получилось создать готовый endpoint, который можно использовать программно без необходимости соблюдения формата разных провайдеров.
На этом можно было бы закончить, но я решил пойти дальше и на 100% использовать функционал самого opencode, предоставив для этого удобное api.
Этап 4 — Использование Agent API
Самой интересной особенностью Opencode оказался не обычный chat completion, а Agent API.
В отличие от классического запроса к модели, агент умеет работать с собственным системным промптом (AGENTS.md), имеет долговременную память (context.md) и может использовать весь функционал Opencode (чтение и запись файлов, websearch, webfetch, structured output)
Мне хотелось сохранить эти возможности, но сделать их доступными через обычный HTTP‑запрос.
Были созданы эндпоинты:
/agent — позволяющий читать уже готовый
AGENTS.md(освобождает от необходимости передавать system prompt, либо дополняющий его), использовать инструменты (websearch) и сохраняющий контекст вcontext.mdдля задач, требующих долгосрочной памяти./agent/md — позволяет автоматически создать
AGENTS.mdфайл. Необходимо лишь описать какого агента вы хотите использовать.
Этап 5 — Многопользовательский режим
Поскольку сервер планировалось использовать сразу в нескольких проектах, возникла необходимость разделить пользователей.
Для каждого пользователя автоматически создаётся собственное рабочее пространство:
workspaces/ alice/ AGENTS.md context.md bob/ AGENTS.md context.md
Это позволило полностью изолировать память и инструкции разных пользователей.
Итоги
В итоге получился небольшой self‑hosted сервер, который предоставляет:
REST API для OpenCode Go
Единый формат запросов независимо от модели
Agent API
Многопользовательский режим
Docker‑развёртывание
SQLite без необходимости поднимать PostgreSQL
Работа API без использования прокси или VPN
Таблица сравнения:
Вариант использования |
Цена за запрос |
Время ответа |
GPT 5-nano |
10–12 копеек |
~ 6 секунд |
Qwen 3.5-Flash API |
~ 8 копеек |
~ 12 секунд |
Qwen 3.6-plus OpenCode Go |
~ 0.6 копеек |
~ 15 секунд |
Minimax‑m2.7 |
~ 0.4 копейки |
~ 8 секунд |
Qwen 3.6-plus OpenCode Go |
~ 2 копейки |
~ 25 секунд |
Qwen 3.6-plus OpenCode Go |
~ 1.7 копеек |
~ 21 секунда |
Цена указана для одинакового входного промпта и среднего размера ответа с учётом сниженной цены на токены. Фактическая стоимость зависит от количества входных и выходных токенов.
Сравнение показывает чёткую картину — использование OpenCode API позволяет снизить цену запроса в 12 раз, потеряв пару секунд в скорости ответа, что для асинхронной обработки данных сильной роли не играет.
Исходный код
Исходный код с инструкцией по поднятию доступен на Гитхабе. -
Изменено: получилась битая ссылка на репозиторий, оставляю её ниже
https://github.com/sacist/opencode-api
P. S. Если данная статья была полезна — буду рад вопросам и предложениям.