Как я снизил стоимость обработки данных с помощью AI в 12 раз

от автора

Мне понадобилось обрабатывать десятки тысяч рекламных объявлений с помощью 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
agent mode + context

~ 2 копейки

~ 25 секунд

Qwen 3.6-plus OpenCode Go
agent mode. No context

~ 1.7 копеек

~ 21 секунда

Цена указана для одинакового входного промпта и среднего размера ответа с учётом сниженной цены на токены. Фактическая стоимость зависит от количества входных и выходных токенов.

Сравнение показывает чёткую картину — использование OpenCode API позволяет снизить цену запроса в 12 раз, потеряв пару секунд в скорости ответа, что для асинхронной обработки данных сильной роли не играет.

Исходный код

Исходный код с инструкцией по поднятию доступен на Гитхабе.

P. S. Если данная статья была полезна — буду рад вопросам и предложениям.

ссылка на оригинал статьи https://habr.com/ru/articles/1060576/