Проверяем Yandex Code Assistant на сервисе для передачи секретов
Всем привет! Я Станислав Денисов, ML-инженер в «Инфосистемы Джет».
Вайбкодинг уже успел несколько раз поссорить интернеты и, похоже, еще не раз это сделает. Тема никуда не уходит: ИИ-инструменты стали частью разработки, нравится нам это или нет.
Уходить в крайности здесь бесполезно. Писать критичный код без понимания предметной области опасно. Но и тратить недели на ручную сборку MVP или небольшой внутренней утилиты, когда рядом есть агент, тоже странно.
Сценарий, где разработчик формулирует задачу, а ИИ проектирует, пишет, проверяет и доводит код до деплоя, уже не выглядит фантастикой. Claude Code, например, дает 4% публичных коммитов на GitHub, а Google говорит о 50% AI-generated кода внутри компании. Очевидно, что дальше эти цифры будут расти, но сама по себе эта динамика не показательна.
Вопрос в другом: кто управляет инструментом, как проверяет результат и где проводит границу доверия.
В этой статье разберу кодового ассистента Яндекса. Посмотрим не только на то, умеет ли он генерировать файлы, но и на то, как ведет задачу, замечает ли инженерные нюансы и где человеку все равно приходится брать управление на себя.
Короткая версия: местами очень похоже на Cursor.
Зачем проверять именно Yandex Code Assistant
Внутри команды разработки мы регулярно используем Cursor, GitHub Copilot и Claude Code. Ими мы уже пользуемся, поэтому сравнивать было с чем.
Yandex SourceCraft Code Assistant за последний год заметно вырос: это уже не просто чат для автодополнения, а агент, встроенный в процесс разработки. Логичный следующий шаг — прогнать его через задачу, где обычного «сгенерируй CRUD» недостаточно.
Для теста я взял MVP сервиса одноразовой передачи секретов. По смыслу — что-то вроде Privnote или Yopass. Пользователь создает секрет, получает ссылку, получатель открывает ее один раз, после чего данные больше недоступны.
На бумаге задача выглядит простой: создать запись, выдать токен, отдать секрет, удалить после чтения. На практике все упирается в безопасность. Если агент ограничится типовым CRUD-приложением, мы получим сервис, которому нельзя доверять. Поэтому было интересно проверить, дойдет ли он сам до threat model, правильного хранения токенов, TTL и одноразового доступа.
Как выглядит агент: режимы, роли и ход работы
Стартовали с пустого проекта. Первым делом ассистент предложил выбрать режим, в котором он будет работать.
В Code Assistant есть несколько режимов:
• Architect: проектирование и дизайн до реализации.
• Code: написание и рефакторинг кода.
• Ask: ответы на вопросы и объяснения.
• Debug: поиск и исправление багов.
• Orchestrator: автоматический координатор задач.
Больше всего здесь интересен Orchestrator. Это тот же подход, к которому быстро привыкаешь в Claude Code и Cursor: не нужно вручную дергать режимы и объяснять агенту, что сейчас пора думать об архитектуре, а не сразу писать файлы. Он сам переключает фокус по ходу задачи.
На первый промпт про MVP сервиса, архитектуру и threat model ассистент ответил не одним абзацем, а сразу набором из 8 markdown-файлов:
В них были этапы разработки, архитектурные схемы и описание основных частей системы.
Дальше после каждого запроса агент обновлял внутренний To-Do и двигался по нему достаточно последовательно:
Еще одна полезная деталь — показ изменений. Встроенный diff не просто подсвечивает правки, а помогает понять, зачем агент трогает конкретный файл и что именно в нем меняет.
Одними стандартными режимами ассистент не ограничивается. Внутри есть скиллы, знакомые по Cursor: например, create-mcp-server для подключения инструментов через Model Context Protocol и create-mode для собственных ролей. В этом тесте они не понадобились, но сама возможность важна.
Что получилось хорошо и где пришлось включаться человеку
Для проверки я собрал цепочку из 10 промптов: от архитектуры и бэкенда до тестов и фронтенда. Идея была в том, чтобы вести агента итерациями, но не зажимать его настолько, чтобы он просто исполнял пошаговую инструкцию.
Ниже несколько ключевых запросов. Формулировки немного адаптированы для статьи, смысл сохранен:
Проектирование: «Помоги спроектировать MVP сервиса для безопасной одноразовой передачи паролей и секретов. Пользователь создает секрет, получает ссылку, секрет можно открыть только один раз или до истечения TTL. Опиши архитектуру, threat model и минимальные меры безопасности».
Бэкенд: «Сгенерируй backend на FastAPI для сервиса one-time secret share. Нужны эндпоинты: создать секрет, получить секрет по токену, пометить как прочитанный и удалить просроченные записи. Используй SQLAlchemy и SQLite/PostgreSQL».
Безопасность: «Покажи безопасный подход к хранению секретов: чем шифровать секрет, как генерировать токен, нужно ли хранить хэш токена вместо самого токена, как реализовать TTL и одноразовый доступ. Перепиши текущий код в безопасном виде и объясни изменения».
QA: «Напиши pytest-тесты для этого сервиса: проверь одноразовое чтение, истекший TTL, неверный токен, попытку повторного доступа и физическое удаление после просмотра».
Нормальная основа без ручной рутины
С типовым кодом ассистент справился уверенно. На такой части задачи он действительно экономит часы: модели, схемы, эндпоинты, базовые проверки, инфраструктурные файлы.
Например, он сразу добавил Pydantic-валидацию и ограничения на размер секрета. Это важно: без лимитов сервис можно случайно или намеренно нагрузить слишком большим payload:
Также агент не забыл про уборку просроченных записей. Для MVP он не стал сразу тащить отдельный cron или воркер, а использовал BackgroundTasks из FastAPI:
Про перебор токенов ассистент тоже подумал: добавил In-Memory Rate Limiter и подключил его как middleware:
На первый взгляд, после такого уже хочется завернуть проект в Docker (его агент тоже подготовил) и отправить в прод. Но именно здесь начинается самое интересное.
Где без человека пока никак
Серверное шифрование
Ассистент выбрал шифрование на сервере через cryptography.fernet. Ключ при этом выводится из мастер-ключа сервера и ID секрета.
Формально данные в базе зашифрованы. Практически сервер все равно знает слишком много: администратор с доступом к базе и переменным окружения сможет восстановить секреты.
Для zero-knowledge-сценария нужен другой подход: шифровать на клиенте через Web Crypto API, а ключ передавать во фрагменте URL после #KEY. Такой фрагмент браузер не отправляет на сервер, поэтому бэкенд хранит только ciphertext и не получает материал для расшифровки.
Race Condition (TOCTOU)
В эндпоинте чтения секрета агент сделал типичный сценарий: сначала SELECT, затем проверка if db\_secret.accessed: raise, потом выдача секрета и UPDATE accessed = True.
Это классический TOCTOU — Time-of-Check to Time-of-Use. Два параллельных запроса могут одновременно увидеть accessed = False и оба получить секрет. В этот момент одноразовый доступ перестает быть одноразовым.
Исправлять такое лучше на уровне БД: через транзакционные блокировки (SELECT ... FOR UPDATE) или атомарный UPDATE ... RETURNING, где проверка и изменение состояния происходят одной операцией.
Удаление данных
После чтения ассистент помечает запись как удаленную: secret.deleted = True. Для обычной бизнес-сущности этого иногда достаточно. Для сервиса секретов — нет
Зашифрованный текст при soft delete продолжает лежать в базе. Для такого класса данных нужен физический DELETE, а в более строгом варианте — крипто-шреддинг: перед удалением перезаписать колонку мусором, чтобы снизить шанс восстановления по следам в WAL и резервных копиях.
Промежуточный итог
ИИ хорошо берет на себя рутину: каркас приложения, типовые эндпоинты, схемы, тестовую инфраструктуру, Docker и связку файлов вокруг проекта. Это уже не игрушечная автоподстановка, а рабочий способ быстро получить первую версию.
Но контроль остается на стороне разработчика. Особенно там, где важны бизнес-правила, безопасность и гарантии поведения под нагрузкой. Можно не писать каждую строчку руками, но нужно понимать, какие свойства система обязана сохранять.
Что запомнилось
Сильные стороны:
• Orchestrator работает ожидаемо и удобно. Агент сам понимает, когда нужно проектировать, а когда переходить к коду.
• Контекст держится неплохо. Если попросить добавить ограничение на число просмотров, ассистент меняет схему и связанную логику, а не переписывает все вокруг.
• Diff с пояснениями помогает ревьюить результат. Для кода, который сгенерировал ИИ, это особенно важно.
• Инфраструктурную часть агент собрал без особых проблем: docker-compose.yml, Dockerfile для фронтенда и бэкенда, конфиг Nginx.
Что насторожило:
• Языки местами смешались: промпты и документация были на русском, а интерфейс фронтенда получился на английском.
Выводы
Паниковать рано: разработчиков ИИ пока не заменяет. Код, который получился в тесте, нельзя было бы отдавать в прод без внимательного технического ревью. Впрочем, это справедливо почти для любого ИИ-ассистента на рынке.
При этом результат мне понравился. Задачу, на которую раньше легко ушел бы день, агент довел до рабочей версии примерно за час. Роль разработчика в таком процессе смещается: меньше ручного набора типового кода, больше архитектуры, ревью, проверки инвариантов и безопасности. Если держать это в голове, инструмент получается действительно полезным.