
Всем привет!
Меня зовут Дмитрий Бутенко, я эксперт-разработчик банка Уралсиб.
Всё началось с рабочего созвона в первой половине февраля, на котором упомянули возможность применять модели ИИ прямо внутри инфраструктуры банка. Поначалу речь шла о работе через JetBrains AI Assistant — точечные запросы, ревью, вопросы по проекту. Вопросов, кстати, было много. Но довольно скоро случился переход на OpenCode, и это открыло принципиально другой уровень: не отдельные запросы к модели, а полноценные агенты, которые сами читают файлы, вносят изменения, итерируются по результату.
О том, какими были эти вопросы и задачи, и о том, что из этого вышло — речь пойдёт ниже.
Два важных уточнения:
Этот текст — о пользовательском опыте применения конкретных инструментов для конкретных задач. Вопрос о целесообразности выбора именно этих инструментов остаётся за рамками;
Инструменты преднастроены — системные промпты, команды, субагенты. Это влияет на результат, но насколько сильно — отдельная тема, в тексте не рассматривается.
Стек
OpenCode версии 1.2.19 на момент написания
Модели: gpt-oss:120b и qwen3.5-27b-claude-4.6-Opus
MCP-интеграции: Confluence, GitLab, Jira, TestIT
Языки программирования на проектах и фреймворки: Scala/Java/Play framework, PHP/Laravel, PHP/Symfony
Инициализация проекта
Первое, с чем пришлось столкнуться — инициализация проекта командой /init-project. Кастомная команда инициализации, аналог «стандартной» /init, которая создает md-файл в корне проекта с его описанием и освновными деталями. На scala-проекте поведение оказалось неожиданным: при первом запуске модель полностью игнорировала весь scala/java-код, если на это явно не указать вторым сообщением. Со временем и после нескольких обновлений проблема была устранена. PHP-проекты инициализировались без серьёзных затруднений, хотя здесь обнаружился другой нюанс: после анализа проекта модель иногда предлагала создать markdown-файл и зафиксировать изменения, но не показывала, какие именно. Содержимое приходилось запрашивать отдельно.

CRUD на Scala: две модели, разное поведение
На задаче создания нового маршрута со связанными контроллером и middleware обе модели справились, но по-разному.
Примеры промтов:
Добавь новый маршрут в файл conf/routes: /v1/packet/:packet_code/options, название метода и контроллер OptionsController.getOptionsByPacketCode, параметры (packet_code: String, promo_code: String). Добавь класс контроллера в src\app\smart\controllers, класс опиши по аналогии с контроллерами рядом;
В методе getOptionsByPacketCode контроллера app\smart\controllers\OptionsController добавь следующее: описание бизнес-логики действия.
qwen3.5-27b-claude-4.6-Opus следовал структуре, которая уже была в проекте, и при реализации похожих паттернов требовал меньше уточнений — прослеживалось понимание сложившейся архитектуры.
gpt-oss:120b с задачей тоже справился, но потребовал больше направляющих уточнений. На некоторых задачах с постановкой вида «реализуй новый роут с определенными параметрами» модель рисковала надолго уйти в раздумья — если явно не указать, где находится файл настроек роутов, какой контроллер создать и какие middleware подключить.
Отдельно выделяется задача, которая не поддалась ни одной из моделей: генерация класса на основе java.net.http.HttpClient для отправки формы с multipart/form-data. Несмотря на корректную последовательность вызовов, модели не справились с корректным расчётом размера тела запроса и корректное добавление boundary — код не работал, и никакие итерации его не спасли. В итоге этот фрагмент пришлось переписывать вручную.
Исправление ошибок
Для простых ошибок вроде NPE с полным стек-трейсом или четким упоминанием класса как правило проблем не возникает.
Пример: объясни, с чем может быть связана ошибка и напиши, как можно исправить [вставлен стек-трейс]

Однако, поиск ошибок мог не приводить к результату, если ошибки были связаны с внешними компонентами, а обращения к этим компонентам встречаются в нескольких местах в проекте. Например, ошибки при запросах в БД. Нужно было дополнительно добавлять возможные обстоятельства, из-за чего могла произойти ошибка. Или уточнять у модели, можно ли что-то логировать дополнительно, что позволит локализовать проблему.


Изменение поведения API на Laravel: модель делает больше, чем нужно
Задача была такая: упростить алгоритм, который добавляет в архив файлы документов и их подписанные копии, полученные из внешнего сервиса. Оригиналы и подписанные файлы располагались в разных каталогах, при этом пути подписанных документов зависели от путей оригиналов. Суть упрощения: перестать учитывать эту зависимость и просто класть подписанные файлы в свой каталог как есть. Итог — три метода, два цикла, никаких архитектурных изменений.
Представить задачу можно следующим псевдокодом (строки, которые необходимо изменить, отделены // от остального кода)
zip = new Zip("/path/file.zip"); for (doc: documents) { zip->add(getFilePathByDocument(doc), doc->getData()) } for (i = 0; i < signedDocuments.lenght; i++) { signedDoc = signedDocuments[i] // doc = documents[i] zip->add(getFilePathBySignedDocument(doc, signedDoc), signedDoc->getData()) // } zip->save()
Модель, как бы ни формулировали промпт, неизменно трогала что-то за пределами обозначенных рамок. Повторные уточнения только усугубляли ситуацию: одни изменения откатывались, но появлялись другие. В какой-то момент модель изменила поведение приватного метода в сервисе и самостоятельно пошла искать по проекту, где ещё он вызывается — чтобы убрать «ненужный» вызов. Всё это раз за разом либо ломало тесты, либо проявлялось во время работы приложения.

Добавление вызовов API на Symfony: аккуратно, но с оговорками
На symfony-проекте обе модели в целом справлялись с задачами по добавлению новых вызовов — вероятно, во многом благодаря более чёткой структуре проекта: разделение на слои, соответствие определенному поведению у классов в одном пространстве имен, строгие соглашения по именованию. Возможно, при повторяющейся структуре модели проще генерировать код, соответствующий уже неоднократно реализованному шаблону. Тем не менее в деталях ошибки случались: например, в аннотациях к модели, описывающих ограничения на свойства (допустимые типы, тип в БД, правила валидации). Как правило, это исправлялось дополнительным промптом, но не снимало необходимости более тщательно просматривать все внесённые изменения.
Dockerfile и Docker Compose: каркас есть, на этом все
Оба инструмента генерировали файлы, похожие на правду. Но в корпоративной среде с настройками проксирования и собственными зеркалами репозиториев результат оказывался непригоден к прямому использованию. Реальная ценность здесь — каркас, от которого можно оттолкнуться, понимая, что доработка вручную всё равно потребуется. Однако, если есть несколько проектов с похожим стеком технологий, то проще взять за основу файлы из соседнего проекта.
Отдельно стоит отметить: при уточняющих вопросах о конкретном образе для одного из stage модель могла неверно интерпретировать запрос. Помогал более детальный вопрос с самого начала.
Исправление падающего теста на Laravel: модель меняет тест вместо кода
Для нетривиального теста — получение всех документов клиента в одном архиве — модель нашла часть проблем, связанных с изменившимися сигнатурами методов. Тест действительно нетривиальный: из-за связности существующих классов пришлось много мокать и создавать тестовые реализации интерфейсов.

Несмотря на это, до конца модель задачу не решила. Примечательно другое: тесты проверяли ожидаемое количество файлов в архиве, и модель решила изменить сам тест, а не тестируемую функциональность — и продолжала это делать до тех пор, пока в промпте явно не запретили трогать файлы тестов.
Помощник
Очень хорошо модели показали себя в режиме "планирования": модель работает в режиме только на чтение, как правило анализируя проект и отвечая на вопросы по нему, или на какие-то более общие вещи. Например, объяснение синтаксических конструкций, scala в моем случае, вывод связей классов в приложении, примеры использования архитектурных паттернов с привязкой к фреймворку и т.д. Разработчику, который не знаком с какими-то особенностями проекта это существенно снизит время на онбординг в проект.

Недостатки самого инструмента
Несколько слов об использовании OpenCode в Windows. При запуске в PowerShell или CMD недоступна вставка из буфера обмена. В MSYS2 OpenCode не запускается вовсе, поэтому единственным рабочим вариантом остаётся терминал внутри IDE — который приходится откреплять в отдельное окно. Вставка медиаконтента в промпт не работает, распознавание изображений тоже недоступно. И иногда появляются артефакты, похожие на те, что на изображении ниже.

Итоги
Модели уверенно справляются с рутинными задачами: создание новых эндпоинтов, генерация миграций, описание моделей по бизнес-требованиям. По мере усложнения задачи растёт и необходимое описание желаемого результата — и вот здесь начинаются проблемы. Модель может уйти в ложном направлении или изменить больше кода, чем нужно. В итоге время тратится не на решение, а на исправление результата уточняющими промптами или откатами с повтором. Буквально приходится подводить модель к решению: сначала обозначить рамки, потом требования, потом общий алгоритм. Иногда проще решить задачу самостоятельно, чем всё это расписывать.
Зато роль помощника модель отыгрывает хорошо. В тех ситуациях, когда решение частично понятно и нужно уточнить какие-то детали или описать гипотезы в общих чертах модель сильно экономят время.
Собрав собственные кейсы, стало интересно, каким возможным опытом делились коллеги из других компаний. И буквально здесь же нашлась пара похожих примеров: один и два. Из чего-то более масштабного с более формализованной методологией есть исследование IBM Research на 669 сотрудниках: наиболее стабильный прирост от AI-ассистента дают задачи на понимание чужого кода.
Наблюдается один и тот же паттерн: локальные модели берут рутину, помогают разобраться в незнакомом коде и служат удобным собеседником для проектирования. Сложные многошаговые задачи с размытыми границами — если для «сервисных» моделей обычная задача, то для локальных пока зона риска, которую можно с разной степенью эффективности закрывать сменой модели, системных промптов, дополнительным обогащением, через, например, RAG.
Комментарии (10)

SlavaVSLK
29.06.2026 15:28Маюсь немного схожей фигней, сразу скажу один rag вам тут не поможет. Я делаю целый цикл на локальных моделях. RAG там присутствует, но только как маленький, незначительный слой предварительной помощи в навигации. Пайплайн строит сырую карту отсеивая мусорные пути, потом наиболее вероятнее кандидаты отправляются узкому спициалисту llm на проверку approve / reject, маленькими скоупами и пока я добился качества карты не выше 0.8, а нужно хотя-бы 0.95, потому что от качества карты маршрутов сильно зависят дальнейшие шаги. И это проектоориентированный пайплайн, я боюсь представить, что было бы на универсализации)) маленькие локальные модели, помещающиеся в 16 гб vram, очень тупенькие.

d3d11
29.06.2026 15:28А можно, подробнее, что за карта каких маршрутов?

SlavaVSLK
29.06.2026 15:28Мои наблюдения: если вы даёте локальной llm задачупо типу "где-то там, найди что-то там и сделай вот так вот" условно, то она с большой долей вероятности не найдёт то что нужно, или найдёт не то что нужно, но так как поставленную задачу нужно выполнить, она найдёт что-то и выдаст какой-то результат. В большинстве случаев она делает дичь, если это не точечная и очень чёткая задача. Но мы же не за этим к ним приходим. Так вот, в большинстве случаев многосоставной работы (анализ, поиск, анализ, продумывание, генерация и т.д.) модели уходят не в ту сторону уже на стадии поиска. А если в свежую сессию подавать конкретную карту маршрута (куда ей нужно идти и что конкретно искать именно в этом конкретном месте), то она не распыляется на эти объёмные задачи. Моя идея в том, что бы как раз таки строить точную маршрутную карту по проекту заранее отдельными инструментами и сессиями, а llm с ролью исполнителя задачи (лучше несколько атомарных задач, в зависимости от объёма) получала уже точное местоположение нужных файлов и даже номеров строк.
Но пока что это даётся с трудом. Буду рад идеям.
Железо: ryzen 9 5900x, 64gb ram, rtx 4080 16gb vram. Модель на данный момент использую qwen2.5-coder-14b-instruct, max ctx примерно 50к

DVamp1r3 Автор
29.06.2026 15:28В самом простом случае можно записать результат планирования в файл, а новую сессию уже использовать для чтения из этого файла и исполнения :) Но это если задача решается в 2 этапа, а это далеко не всегда так, самих таких планирований может быть несколько, да и изменений тоже. Кажется, что здесь ключевое - кто будет верифицировать план, и на основании чего. В случае, когда это все просматривает разработчик - верифицирует он. А вот если этот процесс пробовать завернуть в конвейер, то тут становится менее очевидно, как формализовать эту валидацию.
В отрыве от агентской разработки у меня есть кейс генерации кода через LLM, код валидируется сначала синтаксически, затем через тесты к сгенерированному коду. Если какой-то из этапов не пройден, то весь конвейер запускается сналала. Но это не исключает, например, ситуаций, когда корректный код совсем не про то, что в исходном промте :) Это как пример, на практике там все сложнее: код соответствует в общих чертах, но в деталях могут быть проблемы. Про ваш опыт (как я понимаю, схожий) именно в контексте агентов можно где-то ознакомиться?
А под картой вы имеете в виду context precision или что-то свое?

ToniDoni
29.06.2026 15:28А на каком железе крутилась модель и как с latency и со скоростью генерации?

SlavaVSLK
29.06.2026 15:28Железо описал выше. Скорость генерации 39-54 t/s, не отслеживаю от чего зависит, в одной и той же сессии вот такой разлет. В целом комфортно. Latency в данном контексте не понимаю о чем речь

ToniDoni
29.06.2026 15:28Latency - time to first token при контексте реально заполненном до 50К (ну или 25К хотя бы), при первом запросе, и втором (когда должен работать префикс кеш) - вот это интересно.

DVamp1r3 Автор
29.06.2026 15:28По железу информацию давать не могу (и сомневаюсь, что она мне известна в достаточной степени, чтобы с уверенностью ответить), а вот что касается остального, насчет latency, тут и правда непонятно, что имелось в виду, но ответ от сервиса в виде лога рассуждений получаю примерно сразу же :). Что касается скорости генерации, у opencode, насколько мне известно, нет отображения именно этой метрики. И не особо это интересовало, т.к. больше внимания уделяю "качеству" сгенерированного. Если все-таки дать какие-то численные метрики, то "инициализация" проекта с кодовой базов ~8Мб (~1200 файлов) занимает ~6 минут и выдает описание на 2500 символов. По текущему опыту это довольно долгая задача. Дольше был только пример из материала, когда модель не справилась с поиском причины ошибки, по-моему за 10 минут тогда перевалило. В среднем режим планирования (поиск цепочки зависимостей в проекте, объяснение, составление плана изменений и прочие задачи, которые требуют не точечного погружения в участок проекта, а переходы по файлов) это 2-3 минуты. Фикс синтаксических ошибок, предупреждений внутри файла решается за секунды.
Timmek
В Уралсибе не могут выделить ~16 млн ₽ (одна квартира) на одну ноду с 4-мя B200, дабы захостить MiniMax 2.7 / GLM 5.2 ?
Ну какой GPT OSS, ну какой 3.5-27b
ToniDoni
И сколько одновременно пользователей обслужит такая нода без деградации?