Оценка кода без агента: используем Gemini Notebook
Обычный вечер понедельника. Я уже собирался уходить домой после работы, как вдруг зацепился за разговор коллег о неком Gemini Notebook. Стало интересно, что это, как люди им пользуются, а главное — надо ли оно мне. Глянул пару обзорных видео, послушал про его плюсы, чудеса и все такое прочее, но больше всего зацепил меня тезис о том, что окно контекста у этой штуки — миллион токенов. Вечер перестал быть томным.
Недавно я стал одним из ответственных за поддержку terraform-provider со стороны выделенных серверов, при том что ранее работал вообще в другом направлении. Я старался быстро влиться в проект, и будто бы ИИ-RAG-инструмент, способный обрабатывать и анализировать структуры огромных монолитов, появился очень кстати.
В общем, мы с Gemini Notebook встретились в странный период моей жизни. А что из этого вышло — читайте в этой статье.
Небольшой дисклеймер перед стартом:
ИИ-инструменты могут помочь сэкономить время при погружении в незнакомый проект и избавить ваших коллег от десятков банальных вопросов. Однако важно помнить: нейросеть — это только ассистент, но никак не полная замена опыту и мышлению инженера. Для ускорения рутины и первичной навигации использовать LLM вполне можно, но очень важно критически оценивать ее ответы на основе собственных знаний.
История чуть не закончилась, не успев начаться
Как уже можно было понять, начитался я исключительно позитивных отзывов. Что инструмент позволяет обрабатывать колоссальное количество информации, анализировать видео, аудио и текст, а зарубежные разработчики и эксперты по Data Science вовсю используют Gemini Notebook для прототипирования и изучения структуры больших проектов.
Заходил на сайт я на самой доброй ноте. И первое, с чем столкнулся — это проблема, о которой ничего за время своего ресерча не видел. Огромная черная кнопка дружелюбно предлагала опробовать этот чудо-инструмент, однако после нажатия на нее меня раз за разом перебрасывало на страницу с другим содержанием, но все той же заветной кнопкой. Стало понятно, что здесь что-то не так.

И тут я замечаю, что в URL красуется надпись «location=unsupported». Ну что же, хорошо там, где нас нет. «В наше время есть много способов оказаться за тысячи километров от дома», — подумал я. Однако даже в виртуальной командировке, и даже приезжая инкогнито, попасть в интерфейс модели никак не мог.
Начал, в общем, я бродить по интернету и изучать гайды о том, как получить доступ к Gemini Notebook, пока не наткнулся на видео, в котором говорилось, что куда проще сделать это со смартфона.
Я решил дать модели последний шанс. Чемодан, вокзал, новая личность и вот наконец-то я могу попасть в Gemini Notebook на телефоне. Кажется, самая сложная часть позади, и можно приступать к реализации своего плана.
Важное предупреждение о конфиденциальности
На главной странице Gemini Notebook расположена плашка: «Мы заботимся о конфиденциальности данных вашей организации и никогда не используем их для обучения Gemini Notebook». Я внимательно изучил оферту и правила использования, чтобы проверить это утверждение на практике.
Как выяснилось, политика обработки зависит от типа вашей учетной записи:
- Бесплатная версия для личных аккаунтов: ваши промпты, загруженные файлы и ответы модели отправляются на анализ асессорам и могут использоваться для обучения только в том случае, если вы явно оставляете фидбек на ответ (ставите лайк или дизлайк).
- Google Workspace / Workspace for Education: для корпоративных и учебных аккаунтов Google заявляет полный отказ от использования пользовательских данных для обучения моделей.
- Enterprise-версии: самый защищенный сценарий, при котором инстанс размещается в изолированном облаке компании.
Главный вывод: если вы планируете использовать бесплатный тариф с личного аккаунта, ни в коем случае не загружайте туда проприетарный или продакшн-код. Это может привести к утечке интеллектуальной собственности компании или персональных данных, за что легко получить штраф или дисциплинарное взыскание.
Интерфейс Gemini Notebook
Заходим на сайт, и нам сразу предлагают приступить к работе. Навигация, как по мне, вполне интуитивно понятная.

Создаем notebook и видим панель, куда можно загружать файлы, отправлять ссылки на аудио, видео и в целом интернет-ресурсы, находящиеся в открытом доступе.

Для нашей цели нужно собрать код в один PDF-документ, указать его в качестве источника, после чего можно будет переходить к постановке задач.
Собираем PDF из кода
Как многие, я пользуюсь VSCode. В нем есть расширение CodePDF Exporter, с помощью которого можно перенести в PDF как весь репозиторий, так и выборочно только конкретные файлы.

Переносим весь проект в PDF, результат выглядит примерно следующим образом: мы получаем структурированный документ с соблюдением отступов и нумерацией строк.

Анализ кода
Напомню, что я преследую цель разобраться в нашем Terraform-провайдере. Сохраненный код добавляю в качестве источника в созданный notebook.

Анализ PDF-документа объемом в 1 472 страницы занял от силы минуту, после чего я смог спокойно задавать интересующие меня вопросы.
Первый запрос: описание проекта
Для начала я решил составить достаточно простой промпт, в общих чертах описав ситуацию, чтобы не перегружать запрос лишними деталями и дать модели некоторую свободу в построении ответа:
Мне передали проект на поддержку. Опиши основную логику приложения, предоставь подробную информацию по каждому пакету. Укажи потенциальные проблемы и места, на которые стоит обратить внимание.
Ответ модели
Начало было многообещающим: модель дала емкое описание проекта, определила язык, на котором он написан, предназначение и основную функциональность.
1. Основная логика приложения
Приложение работает как плагин, который взаимодействует с Selectel API.
Ожидание состояний (Waiters): Поскольку многие операции в облаке асинхронны (например, создание кластера), проект активно использует “вейтеры” — функции, которые опрашивают API до тех пор, пока ресурс не перейдет в состояние ACTIVE или не будет удален.
- Точка входа: Файл main.go запускает плагин, используя SDK Terraform.
- Конфигурация: Модуль config.go отвечает за аутентификацию (через переменные окружения, такие как OS_USERNAME, OS_PASSWORD) и управляет кэшем клиентов для различных сервисов.
- Жизненный цикл ресурсов: Каждый ресурс (например, база данных) реализует стандартные функции: Create, Read, Update и Delete.
Далее следовал анализ основных модулей. Модель обозначала логику, функциональность и важные аспекты. Тут стоит отметить некоторую непоследовательность модели в структурировании ответов: каждый модуль описывался по своему собственному плану, блоки вышли разношерстными, один короче другого.
2. Подробная информация по модулям
DBaaS (Database as a Service)
Управляет облачными базами данных: PostgreSQL, MySQL, Redis и Kafka.
- Логика: Разделена на общую схему (dbaas_base_schemas.go) и специфичные для движков утилиты (например, dbaas_postgresql_utils.go).
- Функционал: Создание кластеров, управление пользователями, базами данных, расширениями (extensions) и правилами файрвола.
MKS (Managed Kubernetes Service)
Управляет кластерами Kubernetes.
- Логика: Включает управление версиями Kubernetes, группами узлов (nodegroups) и получение kubeconfig.
- Важное: Реализована сложная логика подавления диффов (diff suppression) для версий Kubernetes, чтобы избежать лишних обновлений при незначительных изменениях в патч-версиях.
Dedicated Servers (Выделенные серверы)
Один из самых сложных модулей, отвечающий за физические серверы.
- Логика: Обрабатывает установку ОС, конфигурацию RAID-массивов и разметку дисков (partitioning).
- Управление питанием: Позволяет изменять состояние питания (on, off, reboot) через параметр power_state.
Domains & DNS
Управление DNS-зонами и записями (поддерживаются v1 и v2 API).
- Логика: Позволяет создавать зоны и RRSet (наборы записей).
Networking & Global Router
Управление сетями, подсетями и связностью между регионами.
Global Router: Позволяет объединять ресурсы в разных регионах в единую сеть.
Третьим блоком шли потенциальные проблемы и места, на которые стоит обратить внимание. Подобная обратная связь всегда кажется полезной в теории, но на практике нередки случаи, когда LLM находит ошибки даже там, где их нет, просто потому что в промпте ей дано задание выявить недочеты. Посмотрим, насколько конструктивной окажется критика от Gemini Notebook.
3. Потенциальные проблемы и места для внимания
- Сложность разметки дисков (Dedicated Servers): Логика автоматического формирования конфигурации разделов и RAID для API Selectel довольно запутана. Ошибки здесь могут привести к невозможности установки ОС на сервер.
- Синхронизация запросов (Race Conditions): Для ресурсов, где одновременные запросы к API могут вызвать конфликты (например, создание DNS-записей в одной зоне), используется selMutexKV для блокировки операций по ключу. Важно всегда проверять, используется ли мьютекс в критических местах.
- Обработка ошибок API: В модулях чтения (Read) важно правильно обрабатывать статус 404 Not Found. Если ресурс удален вручную через панель управления, Terraform должен узнать об этом, установив ID ресурса в пустую строку (d.SetId(“”)), иначе возникнут ошибки при выполнении плана.
Как разработчик выделенных серверов, могу сказать, что критика оказалась вполне точной и конструктивной. Разметка дисков действительно остается одним из самых трудных этапов, где любой сбой приводит к невозможности установки ОС на сервере. Кроме того, модель верно подсветила необходимость синхронизировать запросы и правильно отлавливать ошибки API (в частности, 404 Not Found), ведь без этого Terraform просто не сможет корректно выполнить план.
В финальной части ответа Gemini Notebook уделила внимание процессам CI/CD, описав требования для прохождения проверок в GitHub Actions и подготовки изменений к слиянию (мержу).
4. Инструменты разработки (CI/CD)
Для сборки и выпуска релизов используется GoReleaser. Тестирование включает в себя запуск приемочных тестов (Acceptance Tests).
Безопасность и линтеры:
В проекте настроены строгие проверки безопасности (Semgrep, Gosec) и линтеры. При добавлении нового кода обязательно запускайте make lint.
Для поддержки эта информация действительно очень полезна: она позволяет с самого начала писать аккуратно, так как линтеры просто не дадут запушить junk код. Возможность быстро проверить себя локально одной командой make lint помогает сэкономить время и довести изменения до мержа в основную ветку без лишних итераций ревью.
Если оценивать качество первого ответа в целом, Gemini Notebook продемонстрировала хорошую точность и понятную логику изложения: правильно начала с верхнеуровневого описания проекта, а затем погрузилась в специфику отдельных сервисов. Все ключевые вводные — от языка разработки до тонкостей синхронизации — были указаны верно. Модель подсветила те особенности проекта, которые действительно было бы неплохо понимать перед началом работы с репозиторием, чтобы не допускать банальных ошибок. Обычно такие вещи нужно изучать самостоятельно, но с помощью Gemini получилось неплохо сэкономить время.
Впрочем, без минусов не обошлось. Ответ получился слишком сжатым для запроса «сделать подробный разбор»: модель на верхнем уровне пробежалась только по ключевым пакетам, пропустив мелкие, но важные модули, а часть подсвеченных «проблемных мест» на поверку оказалась некритичными деталями инфраструктуры вроде настроек CI/CD.
Второй запрос: инструмент навигации
Представим ситуацию: мы понимаем, где по логике находится проблемное место, но не знаем, как найти его в коде.

Попробуем обратиться к Gemini Notebook с таким запросом:
Покажи мне все места, где вызывается переустановка операционной системы.
Ну что же, стоит признать, что для подобных задач Gemini Notebook действительно подходит отлично. В качестве ответа модель предоставила ссылку на конкретный файл, где происходит переустановка ОС на сервере: resource_selectel_dedicated_server_v1.go.
Хотя я не просил вдаваться в подробности, Gemini проявила инициативу и подробно описала ключевую логику файла. Информация оказалась действительно полезной: модель расписала, какие данные необходимо передать для успешной установки ОС, и подсветила использование вейтеров, ожидающих перехода сервера в состояние ACTIVE. На самом деле это критически важный момент, потому что без ожидания готовности любые последующие операции с сервером завершатся ошибкой.
Ответ Gemini Notebook
Основная логика сосредоточена в следующих функциях:
resourceDedicatedServerV1Update: Эта функция определяет, требуются ли изменения, влекущие за собой переустановку ОС. Если изменены такие параметры, как os_id, os_password, ssh_key или partitions_config, и это не просто изменение настроек приватной подсети, инициируется процесс переустановки
- Вызов API: Непосредственно за запрос к API Selectel для установки новой ОС отвечает метод dsClient.InstallNewOS(ctx, payload, d.Id()).
- Формирование данных: Для переустановки подготавливается структура dedicated.InstallNewOSPayload, в которую передаются версия ОС, шаблон, архитектура, SSH-ключи, пароль, конфигурация разделов диска и пользовательские данные (user_data).
- Ожидание завершения: После отправки запроса на переустановку приложение использует специальный «вейтер» waiters.WaitForServersServerInstallNewOSV1ActiveState, чтобы дождаться, пока сервер снова перейдет в активное состояние.
Важные условия:
- Переустановка ОС не может быть выполнена, если сервер выключен (power_state = “off”).
- Если меняются только параметры приватной подсети (private_subnet_id или private_subnet_ip), переустановка ОС не инициируется.
Несмотря на уже достойный результат, Gemini не остановилась и дополнительно перечислила условия, при которых переустановка операционной системы блокируется или не запускается вовсе.
Подобрали интересные статьи специально для вас
Ревью кода
Я не нашел удачного расширения, которое сохраняло бы git diff в формате, который можно отправить в Gemini Notebook. Поэтому попробуем два альтернативных варианта.
Сравнение файлов всего проекта
Первая идея — загрузить в Gemini Notebook два полных PDF-файла проекта целиком (до изменений и после них). Стоит отдать должное: модель действительно хорошо находит различия между крупными файлами. Однако попробуем попросить модель провести ревью с фокусом на измененных фрагментах:
Проведи ревью изменившегося кода, найди возможные уязвимости, дай подробный анализ изменений, выяви их сильные и слабые стороны, если изменившийся код можно улучшить — укажи это.
В этом случае модель все равно запускает полномасштабный анализ на уровне всего проекта. В итоге выдача модели начинает частично дублировать информацию из предыдущих ответов в чате.
При таком подходе Gemini указала на отключение проверок в линтере, риск рассинхронизации операций, игнорирование ошибок и — самое «полезное» (на самом деле не очень) — слабые места в CI/CD-пайплайне. Информация, безусловно, интересная и может пригодиться при поддержке, но это совершенно не решало поставленную задачу точечного ревью.
Непосредственно анализу изменившегося кода модель уделила всего один поверхностный абзац с описанием гипотетических ошибок (да и те притянуты за уши с огромным «если»). Поэтому использовать этот метод для ревью я крайне не рекомендую.
Анализ уязвимостей и архитектурных рисков от Gemini
Ниже приведен детальный обзор уязвимостей, архитектурных слабостей и рисков, обнаруженных исключительно в измененных фрагментах кода.
1. Уязвимости и риски безопасности
- Подавление проверок безопасности (Security Tooling): В конфигурации .golangci.yml добавлены исключения для правил G501 (использование MD5) и G404 (использование небезопасного генератора случайных чисел math/rand).
- Риск: Хотя MD5 используется лишь для генерации идентификаторов стейта (stringChecksum), подавление этих проверок на уровне всего проекта создает риск использования MD5 или math/rand в критичных местах (например, для генерации токенов или паролей).
2. Логические слабости и риски состояния гонки
- Риск рассинхронизации времени (Time Drift) в CRaaS: Логика удаления токена из состояния (shouldRemoveCRaaSTokenV2FromState) использует time.Now() локальной машины.
- Слабость: Если системное время на ранере спешит относительно API Selectel, токен удалится из стейта (d.SetId(“”)) как просроченный, хотя в реальности он еще валиден. Terraform попытается создать новый ресурс, вызвав конфликт имен в API.
- Проблема TOCTOU (Time-of-Check to Time-of-Use) в управлении питанием: В функции resourceDedicatedServerV1UpdateWithStateRollback сначала проверяется, не выключен ли сервер, и только потом инициируется установка ОС.
- Слабость: Между проверкой power_state == “off” и вызовом API сервер могут выключить вручную через панель. Вызов InstallNewOS упадет с необработанной ошибкой API.
3. Целостность данных и обработка ошибок
- Игнорирование ошибок записи в стейт (d.Set): В конфигурации линтера разрешено игнорировать возвращаемое значение d.Set.
- Слабость: Если Terraform не сможет записать обновленный private_ip или vlan в файл состояния, выполнение продолжится без ошибок. В стейте останутся старые данные (drift), что приведет к сбоям при следующем plan.
- Риск неполной очистки сетевой конфигурации: При удалении приватной подсети код отправляет nil для адреса, маски и шлюза.
- Архитектурная слабость: Логика завязана на специфику API Selectel (интерпретацию null в JSON как команды на удаление). Если API изменит поведение, сервер останется со старыми сетевыми настройками.
4. Инфраструктурные риски
- Фиксация SHA для GitHub Actions: В workflow зафиксированы SHA для actions/checkout и github/codeql-action.
- Слабость: Это защищает от атак на цепочку поставок, но требует вручную отслеживать обновления безопасности. Без регулярных апдейтов CI/CD остается уязвимым к известным багам сканеров.
Рекомендации модели:
Добавить явную проверку статуса порта в resourceDedicatedServerGetPrivateVlan: логгировать случаи, когда порт не найден, чтобы отличать 404 от неготовности сетевой подсистемы.
Убрать исключение errcheck для d.Set в линтере и добавить проверку ошибок во всех новых ресурсах.
Использовать время из заголовка Date ответа API вместо локального time.Now() для проверки токенов CRaaS.
Заменить MD5 на SHA-256 в функции stringChecksum.
Сравнение файлов с изменениями
Второй подход — оставить в качестве первого источника исходный проект, а вторым источником загрузить PDF-файл, содержащий только файлы с изменениями. Да, процесс подготовки таких файлов чуть более муторный, но ревью в таком случае проходит куда продуктивнее: Gemini сразу фокусирует внимание исключительно на модифицированном коде.
При таком формате я получил именно тот результат, на который рассчитывал: модель полностью разобрала внесенные изменения, объяснила их логику и практическую ценность. Каждый нюанс был выделен отдельно.
Стоит отметить, что Gemini подсветила и ряд гипотетических рисков (вроде утечки данных или рассинхронизации вейтеров), большинство из которых на практике неактуальны. Пожалуй, единственной действительно возможной, хоть и крайне маловероятной проблемой оказалась уязвимость TOCTOU.
Ответ модели
Архитектурные особенности и логика
- Очистка сетевой конфигурации: При удалении приватной подсети из конфигурации код отправляет nil для адреса, маски и шлюза. Это корректно транслируется в JSON null, сигнализируя API Selectel о необходимости удаления настроек внутри операционной системы.
- Разделение логики обновлений: В функции resourceDedicatedServerV1Update реализована важная проверка: если изменились только параметры приватной подсети (private_subnet_id или private_subnet_ip), переустановка не инициируется. Это критически важно для стабильности, так как полная переустановка ОС — длительная и деструктивная операция.
- Управление питанием через CustomizeDiff: Использование resourceDedicatedServerV1CustomizeDiff гарантирует, что изменение power_state нельзя совмещать с изменением конфигурации ОС (пароль, разделы диска и т.д.) в одном запуске terraform apply. Это предотвращает конфликты, когда API получает запросы на выключение и переустановку одновременно.
Выявленные слабости и потенциальные уязвимости:
- Проблема TOCTOU (Time-of-Check to Time-of-Use)
В логике управления питанием (resourceDedicatedServerV1UpdatePowerState) сначала проверяется текущий статус сервера (например, не выключен ли он), а затем отправляется команда на действие.
Риск: Между проверкой и вызовом API состояние сервера может измениться (например, пользователь выключил его через панель управления). В этом случае API вернет ошибку, которую провайдер выдаст как общую ошибку выполнения.
Кроме того, просьба оценить сильные и слабые стороны в этот раз не осталась без внимания — модель выделила их в отдельный содержательный блок:
Места, на которые стоит обратить внимание
- Флаг force_update_additional_params: Логика обновления требует установки этого флага в true, если пользователь хочет изменить os_host_name, ssh_key или user_data без изменения основного os_id. Это отличный предохранитель от случайных переустановок, но он может вызвать недопонимание у новых пользователей провайдера.
- Обработка 404 в сетевых портах: Функция resourceDedicatedServerGetPrivateVlan теперь корректно обрабатывает 404 Not Found от API портов, возвращая nil вместо ошибки. Это исправляет регрессию, когда чтение сервера падало, если его сетевая подсистема еще не была полностью зарегистрирована в базе.
- Генерация Hostname: Если имя хоста не указано, оно генерируется случайно на основе списка имен великих ученых. Это делает инфраструктуру более читаемой, чем просто случайные строки, но может привести к коллизиям в очень больших проектах.
Код написан с соблюдением стандартов Terraform SDK v2. Основные риски связаны с синхронизацией состояний питания. Логика работы с приватными сетями значительно улучшена по сравнению с предыдущими версиями провайдера.
Подводя итог этому эксперименту: дифференциальная загрузка файлов полностью себя оправдала. Gemini провела точечное ревью модифицированного кода, подробно описала логику изменений и подсветила места для потенциального рефакторинга. Главным же минусом остается то, что модель склонна генерировать ложные риски: часть подсвеченных «проблем» уже имела решение в основном коде проекта, но Gemini просто проигнорировала эти связи, несмотря на то, что весь репозиторий был загружен в источники.
Задача на исправление бага
Следующий тест для Gemini Notebook — решение конкретной технической проблемы в нашей библиотеке dedicated-go. Суть задачи: из-за того, что Body HTTP-ответа закрывается не в DoRequest, а только в ExtractResult, происходит утечка соединений — не все из них возвращаются в пул при ошибках или пропусках чтения.
Самое очевидное решение «в лоб» — проставить defer response.Body.Close() сразу после client.HTTPClient.Do(request). Но править каждый вызов вручную особого желания не было: хотелось решить проблему системно, «везде и сразу». Посмотрим, что предложит Gemini Notebook на обычный промпт без дополнительных наводящих вопросов.
В dedicated-go есть проблема с закрытием Body, не все соединения будут возвращаться в pool. Body не закрывается в DoRequest, это происходит в ExtractResult. Предложи решение этой проблемы.
Решение от Gemini Notebook
Ниже представлено решение по основным файлам проекта:
Исправление в client.go (Ядро)
В этом файле необходимо сделать закрытие Body более надежным в методах извлечения данных, чтобы оно происходило даже при ошибках чтения.
Метод ExtractResult: Перенесите defer в начало метода, сразу после получения доступа к телу.
func (result *ResponseResult) ExtractResult(to interface{}) error {
if result.Body == nil { return nil }
defer result.Body.Close() // Закрываем в любом случае
body, err := io.ReadAll(result.Body)
if err != nil {
return err
}
return json.Unmarshal(body, to)
}
Метод extractErr: Аналогично, закройте тело до попытки его вычитать (линия 233 должна быть выше линии 229).
func (result *ResponseResult) extractErr() error {
if result.Body == nil { return nil }
defer result.Body.Close() // Исправлено: закрываем до ReadAll
body, err := io.ReadAll(result.Body)
if err != nil {
return err
}
// … остальная логика формирования ошибки
}
Шаблон исправления для публичных методов API
Во всех модулях (boot_manager.go, keypairs.go, networks.go, servers.go и др.) необходимо добавить немедленное закрытие тела после вызова DoRequest. Это гарантирует возврат соединения в пул.
Список файлов, требующих добавления defer Close():
boot_manager.go:
- Метод OperatingSystems [9:36]
- Метод OperatingSystemByResource [11:58]
- Метод LocalDrives [12:80]
- Метод PartitionsValidate [16:142]
…
Модель сходу поняла суть проблемы и выдала полностью рабочее решение, но с существенным архитектурным нюансом. По факту Gemini предложила все то же очевидное локальное исправление — точечно прописать закрытие тела ответа во всех файлах проекта сразу после вызова. С одной стороны, скрупулезность ответа действительно порадовала: Gemini расписала правки для каждого файла, приложила готовый код и подробно объяснила, как именно эти изменения устраняют утечку. Также благодаря тому, что в исходном PDF-файле отображались номера строк, модель максимально точно указала, куда именно вставлять правки в десятках файлов.
С другой стороны, концептуально задача осталась нерешенной. Такой подход не защищает от регрессий: разработчикам все равно придется помнить про этот defer при написании каждого нового метода.
Конечно, если бы я начал вести диалог дальше и прямо попросил Gemini переписать ядро так, чтобы закрытие происходило централизованно внутри DoRequest, модель рано или поздно выдала бы системный вариант. Однако в рамках честного эксперимента условия для всех инструментов были одинаковыми — получить максимум пользы от первого запроса без длинных цепочек наводящих вопросов. И в этом плане Gemini Notebook остановилась на рабочем, но шаблонном решении.
Сравнение с ИИ-агентом
Перейдем к самому интересному вопросу: может ли Gemini Notebook полноценно заменить ИИ-агентов прямо в среде разработки?
Для чистоты эксперимента я установил в VS Code расширение Zoo Code, настроил его и выбрал достаточно быструю модель DeepSeek-V4-Flash. Затем попросил агента выполнить тот же набор задач, что был описан выше.
Анализ проекта и вводная информация
В рамках первой задачи — анализа проекта и получения вводной информации — промпт остался прежним: «Опиши мне основную логику приложения, предоставь подробную информацию по каждому пакету» и далее по списку.
DeepSeek справился с разбором менее чем за минуту, причем его ответ оказался ощутимо глубже, чем у Gemini Notebook. Модель предоставила куда более подробный разбор, выделив большее количество пакетов и продуктов. Кроме того, она построила понятную текстовую архитектурную диаграмму, которая наглядно продемонстрировала потоки данных в приложении. Агент также подсветил потенциальные зоны риска, дал исчерпывающие рекомендации по чистке («гигиене») проекта и четко расставил приоритеты для дальнейшей поддержки. На выполнение этого этапа ушло около 470 тысяч токенов.
Навигация по коду (поиск переустановки ОС)
На этапе навигации по коду я отправил агенту тот же точечный запрос: «Покажи мне все места, где вызывается переустановка операционной системы».
В отличие от Gemini Notebook, которая сразу попыталась угадать контекст и выдала готовый ответ, DeepSeek решил подстраховаться и задал уточняющий вопрос:
Задача сформулирована несколько двусмысленно. «Переустановка операционной системы» в контексте этого провайдера может означать две разные вещи: (а) переустановку ОС на dedicated-серверах (управление boot-загрузчиком, reinstall), и (б) API-вызовы вроде reinstalling nodes в MKS-нодах. Нужно уточнить, что именно имеется в виду, прежде чем копать вглубь (разница существенная — это разные модули и разные типы вызовов).
Как только я уточнил, что речь идет именно о выделенных серверах, агент за две минуты проанализировал репозиторий. Ответ снова получился максимально детальным: с наглядной диаграммой, подробным разбором методов и точечными рекомендациями по дальнейшей поддержке файла. На этот этап ушло еще 830 тысяч токенов.
Интересный момент: если задать этот же вопрос в абсолютно новом чате без накопленного контекста, DeepSeek отвечает заметно скромнее — примерно на том же уровне детализации, что и Gemini Notebook, но и токенов расходует существенно меньше (всего 250 тысяч).
Ревью кода
Запустить ревью через агента оказалось значительно проще с точки зрения подготовки: вместо ручной сборки PDF-файлов DeepSeek сам последовательно выполнил git status и git diff, изучил измененные файлы, смежные пакеты и внешние зависимости.
Сам процесс занял больше времени, поскольку команды агента в терминале требовали подтверждения и контроля (тогда как Gemini считывает PDF за секунды). Однако итоговый ревью-отчет вышел максимально подробным. Модель подсветила сильные стороны, предложила точечные улучшения и даже нашла потенциальный баг. Из-за специфики нашего API этот баг оказался ложноположительным, но само внимание агента к деталям порадовало. При этом DeepSeek не стал придумывать несуществующие риски с вейтерами или утечкой данных, которые генерировала Gemini. В данном сравнении модель показала себя ощутимо точнее. На этот шаг ушло еще 280 тысяч токенов.
Решение проблемы с закрытием Body
Именно в задаче с рефакторингом DeepSeek проявил себя лучше всего. Вместо единственной локальной заплатки агент сразу предложил два сценария:
- Простой вариант: с расстановкой defer во всех затронутых файлах (аналогично решению от Gemini). При этом модель сразу указала, что это не лучшее решение, и привела аргументы.
- Глобальный вариант: написание одного универсального метода, который закрывает Body централизованно. Это фундаментально решает проблему и избавляет разработчиков от необходимости помнить о ручном закрытии тела ответа при создании новых фич.
На анализ задачи и генерацию этого решения потребовалось еще 910 тысяч токенов.
Вывод
Итак, подведем итоги. Выполнение всего пула задач с помощью DeepSeek через агента обошлось мне почти в $1, в то время как Gemini Notebook отработал абсолютно бесплатно. Результатом я в целом доволен: концепция анализа и ревью кода без полноценных AI-агентов вполне жизнеспособна.
Да, уровень глубины ответов у Gemini Notebook может быть ниже, а все правки в проект придется вносить вручную. Да, нужно придумывать способы удобной выгрузки кода (вроде генерации PDF) и обходить географические ограничения Google. Тем не менее, если эти нюансы вас не пугают и нужно быстро разобраться в незнакомом опенсорс-проекте или сделать верхнеуровневый ревью собственного pet-проекта — Gemini Notebook отлично справляется с этой ролью.