Привет! Меня зовут Александр Карташов, и я Android-lead в IT-подразделении компании Спортмастер. Сегодня я расскажу вам о том, как настроить Android Studio для работы с LLM в режиме агента, получить максимум эффекта даже от небольших моделей на компьютерах, не обладающих мощной видеокартой, о тонкостях и некоторых важных настройках плагинов, особенностях запросов к нейронке. Эта статья-гайд поможет вам развеять страх того, что локальные модели для кодинга — это сложно, и позволит вам почувствовать лёгкий корпоративный вайб-кодинг даже внутри закрытого корпоративного контура.
В современном мире разработка программного обеспечения и инновационных технологий идёт стремительными темпами. Однако вместе с прогрессом возникают и новые вызовы, особенно в контексте корпоративной защиты интеллектуальной собственности. Одной из ключевых проблем является необходимость предотвращения утечки исходных кодов и другой конфиденциальной информации из компаний.
Передача исходных кодов третьим лицам, в том числе известным нейросетевым сервисам, может представлять серьёзный риск для бизнеса. Это не только нарушает права интеллектуальной собственности, но и может привести к потере конкурентных преимуществ. В связи с этим разработчики и компании ищут альтернативные решения, которые позволят сохранить конфиденциальность и при этом использовать преимущества современных технологий.
«Спортмастер» объединяет в себе несколько торговых сетей: «Спортмастер», «O’Stin», «FunDay», «Urban Vibes» и другие. Для автоматизации процессов поставок, продаж, рутины внутри магазина, взаимодействия с покупателями, в нашем IT создаётся множество программных решений совершенно разного плана, например «Спортмастер» — приложение-лицо компании, и целый зоопарк «внутренних» приложений как для сотрудников магазина, так и для поставщиков из совершенно разных стран.
Как и в любой разработке, есть множество рутинных задач, которые хотелось бы себе облегчить или автоматизировать. Например, высокое покрытие тестами, генерации более-менее осознанных превью, автокомплит, соответствующий общей стилистике кода. Ещё было бы приятно загрузить портянку требований и увидеть блок-схему по ним, чтобы программисту было проще структурировать их у себя в голове.
При всей гибкости ИТ-подразделения уровень безопасности настолько высок, что использование популярных внешних сервисов нейронных сетей (ChatGPT, Deepseek, Kimi и прочих) невозможен.
Так перед нами встала задача: дать возможность разработчикам облегчить свою работу нейронными сетями и соблюсти все особенности работы в защищённом контуре в большой компании.
Типовой компьютер разработчика — Macbook Pro с процессором Apple M1 Max и 32ГиБ памяти. Исходя из этого, сформируем предстоящую задачу:
Локальная работа — ничего не передаём за пределы компании
Относительно небольшое потребление ресурсов RAM — Android Studio + мессенджеры + тонны вкладок браузера + эмулятор — если ещё нейронки будут требовать много памяти, то всё уйдёт в своп.
Скорость работы — разработчику должно быть быстрее получить результат нейронками
Интеграция с IDE (Android Studio / IDEA) — тут всё понятно, это основной инструмент разработчика
Простая настройка — не надо нагружать техподдержку, разработчик сможет сам быстро всё настроить.
Адекватный результат даже при малом контексте — некоторые проекты имеют кодовую базу размером более ста тысяч строк, и полезность должна прослеживаться даже при небольшом контексте
Разработчику должно захотеться самому настроить инструмент и пользоваться им, мы никого ни к чему не принуждаем.
Также нам важно показать разработчику, как этим пользоваться, что может инструмент «из коробки, простыми запросами», ибо установить, настроить, и никогда не пользоваться — типичное дело.
Я рассмотрю два популярных инструмента: Ollama и LMStudio, ввиду того, что это наиболее простой способ «завести» локальные нейросети.
Для IDE был выбран, пожалуй, самый популярный плагин для работы с LLM — Continue. Он прекрасно интегрируется с IDE и поддерживает работу как с внешними сервисными нейросетями, так и с локальными, включая Ollama, LMStudio.
Ollama показал себя быстрее в тестах на рабочем Mac, что является важным критерием при выборе инструмента для работы. Кроме того, Ollama предлагает как cli (интерфейс командной строки), так и gui (графический интерфейс) «из коробки», что обеспечивает гибкость и удобство использования.
Ещё один аргумент в пользу Ollama — практически автоматическая стартовая настройка с Continue делают настройку ещё проще.
LMStudio — тоже мощный инструмент для работы с локальными нейросетями, и у него могут быть свои преимущества. Однако для меня решающим фактором стали скорость работы Ollama на моём устройстве и удобство интеграции с IDE через плагин Continue. Из преимуществ следует заметить значительно более богатый GUI и встроенный браузер моделей, что может быть очень полезно для начинающих.
В итоге выбор пал на Ollama ввиду большей важности критерия скорости работы.
Здесь всё просто — скачиваем с официального сайта дистрибутив для вашей системы и устанавливаем. Важно: Ollama по умолчанию использует порт 11434 и работает как сервис (локально), однако, можно опубликовать её и в локальную сеть. В моём случае (MacOS) достаточно перетащить приложение в каталог приложений.
При первом запуске появится предупреждение, всё в порядке, подтверждаем запуск.
На панели появится иконка ламы — установка Ollama завершена!
Официальный сайт плагина, установка рекомендуется из маркетплейса, однако в РФ попытка установить или обновить плагин будет выдавать вам ошибку.
На помощь пришли ребята из https://openide.ru/ — с их маркетплейса можно скачать плагины, сами плагины зеркалируются из репозиториев IDEA.
Скачиваем zip-архив плагина с сайта https://marketplace.openide.ru/plugin/continue/328/
Устанавливаем в IDE.
Плагин загрузится, откроется readme, но нас будет ждать ошибка: ему нужен JRE с JCEF! В последней версии плагина будет даже инструкция по тому, как сменить Boot runtime for IDE.
Меняем boot runtime в IDE: нажимаем быстро два раза shift, в появившемся универсальном поиске пишем boot runtime, выбираем опцию смены рантайма.
Выбираем любой подходящий «with JCEF».
Перезапускаем Android-Studio, и плагин радостно нас встречает лендингом!
Выбираем опцию работы со своими моделями.
Далее — работу с локальными моделями.
Плагин «увидит» локально работающую Ollama, предложит небольшие модели для работы с разными ролями, а также shell-команды для их загрузки.
Последовательно выполняем терминале команды загрузки моделей:
ollama pull llama3.1:8b
ollama pull qwen2.5-coder:1.5b-base
ollama pull nomic-embed-text:latest
Как видите, используется команда, очень схожая с одноименной командой GIT. Визуально происходит нечто похожее: в терминале отображаются хеши с diff-ами.
Этой же командой можно обновлять данные по моделям, будут загружены только обновления:
С доступными моделями можно ознакомится на официальном сайте Ollama.
Затем переходим в IDE, плагин оповестит о том, что увидел установленные модели, и сделает доступной кнопку «Connect».
Нажав Continue, мы увидим получившийся файл конфигурации (при публикации — текст в виде «Code»).
Как видите, есть несколько наиболее интересных опций секции models:
name — отображаемое имя, можно указать что-то произвольное / понятное для вас
provider — технология предоставления модели. Можно комбинировать модели разных провайдеров. Например, у вас может быть установлена LMStudio, или же (не в нашем случае) — внешний провайдер, вроде chatgpt, для определённых ролей
model — идентификатор модели внутри провайдера. Здесь путать нельзя, иначе просто не будет работать, а если случайно укажете модель, которая есть в провайдере, некоторые (можно настроить такое поведение в LMStudio) загрузят их в память
roles — роли, для которых выбрана данная модель.
chat — «Чат-модель» — это языковая модель, обученная отвечать в диалоговом формате. Поскольку они должны уметь отвечать на общие вопросы и генерировать сложный код, лучшие чат-модели обычно имеют большой размер, часто несколько млрд параметров. Обеспечивает общение в чате и используется в чате плагина (по умолчанию справа).
autocomplete — «Модель автозаполнения» — это языковая модель, обученная на специальном формате под названием fill-in-the-middle (FIM). Этот формат предполагает наличие префикса и суффикса в файле с кодом, а также прогнозирование того, что находится между ними. Эта задача очень специфична, что, с одной стороны, означает, что модели могут быть меньше по размеру (даже модель с 3 миллиардами параметров может хорошо справляться с задачей). С другой стороны — чат-модели, несмотря на больший размер, часто работают плохо даже при обширных подсказках. Обеспечивает предложения автоматических дополнений в редакторе кода.
edit — Модель генерации кода, основанного на запросах редактирования («Edit» из всплывающего меню редактора). Часто бывает полезно выбрать для ответов на запросы «Edit» другую модель, а не ту, которая используется для ответов на запросы в чате, поскольку запросы «Edit» чаще связаны с кодом и могут требовать меньшей читабельности в разговорном стиле.
apply — Определяет, как применить результаты к файлу. При редактировании кода выходные данные моделей Chat и Edit часто не соответствуют существующему коду. Модель с apply-ролью используется для создания более точного сравнения, чтобы можно было применить изменения к файлу.
embed — «Модель встраивания» обучается преобразовывать фрагмент текста в вектор, который впоследствии можно быстро сравнить с другими векторами, чтобы определить сходство между фрагментами текста. Модели встраивания обычно намного меньше, чем большие языковые модели, и по сравнению с ними работают очень быстро и дёшево. (@Codebase и @Docs контекст-провайдеры).
rerank — «Модель повторного ранжирования» обучается на двух фрагментах текста (часто это вопрос пользователя и документ) и возвращает показатель релевантности в диапазоне от 0 до 1, оценивая, насколько полезен документ для ответа на вопрос. Модели повторного ранжирования обычно намного меньше больших языковых моделей и по сравнению с ними работают очень быстро и дёшево.
Можно указать несколько моделей для одной и той же роли, выбрать ту или иную модель можно в соответствующем меню плагина.
Как видите, плагин отображает сконфигурированные модели, и подключен в режиме агента. Дополнительно есть возможность выбрать чат-модель непосредственно в меню чата внизу.
Обратим внимание и на вкладку «tools», где можно указать поведение агента в плане действий: запрещено / спросить / автоматически (разрешено всегда). Для большего удобства я рекомендую, как минимум, разрешить всегда читать текущий файл.
Однако, если вы всё же решите использовать не локальные модели, не стоит разрешать автоматическое чтение, ведь вы можете смотреть на файл с секретами.
Базовая настройка плагина завершена, теперь включим режим offline в Ollama
Заглянем в настройки Ollama. Нажимаем иконку ламы → settings.
В открывшемся окошке «Airplane mode» — и есть наш оффлайн-режим.
Из интересного — можно настроить размер контекста для моделей, а также включить доступность нашей ollama в сети, на случай, если вы работаете из дома и запускаете более тяжёлые модели на своём мощном ПК, а подключаетесь к ним с рабочего компьютера.
Давайте проверим, что все наши шаги выполнены верно, создав пустой проект и спросив нейронку, что происходит в текущем файле:
Как видим, плагин получил доступ к текущему файлу, нейросеть проанализировала и сделала резюме по текущему файлу, можно переходить к практике!
Итак, мы уже познакомились с окошком чата плагина, однако, использование плагина возможно и из всплывающих действий редактора, которые появляются рядом с курсором / кареткой / областью выделения:
Контекст при работе с нейросетью — это дополнительная информация, влияющая на обработку данных и ответ. В нашем случае это участки кода, файлы, директории, правила, пре-промпты, diff, вывод терминала, сообщения об ошибках, история чата. Если вы задаёте вопрос нейросети, и ей недостаёт контекста, то она начинает генерировать «нечто похожее».
Рассмотрим на примере, когда нам может помочь контекст. Для примеров я буду использовать проект с кодовым названием IT-Driven, это экосистема приложений, доступных сотруднику магазина для рутинных задач ритейла: приёмки машин, обработка интернет-заказов, инвентаризации, печати ценников и прочие процессы.
Кодовая база проекта более 100 тысяч строк кода, стек — Compose, Kotlin, Room, MQTT для пушей внутри корпконтура, IPC для взаимодействия приложений, Coroutines для многозадачности, чистая архитектура с UDF «аля MVI по-домашнему», работа с «железом» терминалов сбора данных (сканирующее оборудование, термопринтеры). Большинство UI-элементов используется из корпоративного фреймворка Flexo.
Итак, попросим сгенерировать Composable-Preview для функции со следующей сигнатурой:
@Composable
fun ColorModelList(
itemsMap: Map<WorkItemState, List<ColorModelItemData>>,
showStartButton: MutableState<Boolean>,
showFilterBadge: MutableState<Boolean>,
progressState: MutableState<CurrentProgressState>,
onColorModelClick: (String) -> Unit,
onStartTaskClick: () -> Unit,
state: LazyListState,
onFilterClick: () -> Unit
)
Запрос «Напиши Composable превью для Composable функции ColorModelList в текущем файле». Замечу, что Composable-функция в текущем открытом файле редактора только одна.
Выглядит хорошо, верно? Однако, оно нерабочее, так как itemsMap
заполнена некорректно: WorkItemState
не содержит элементов, которые представлены в сгенерированном коде, а ещё ColorModelItemData
не содержит конструктора, который сгенерировала нейросеть. CurrentProgressState
— полная отсебятина.
Давайте будем честны, если бы вам дали только представленную сигнатуру, вы бы тоже не смогли написать рабочий код с первого раза и задали бы резонный вопрос: а можно посмотреть, что такое WorkItemState
, ColorModelItemData
, CurrentProgressState
?
Что ж, в мире, к сожалению, пока нет «ИИ», а только нейронные сети. Давайте предоставим нейронке контекст. В окошке чата напечатаем «@», и нам любезно предложат приложить контекст. Вносите ясность, если вам нужно, например, прописать imports. Новый запрос будет выглядеть уже так:
@WorkltemState.kt @ColorModelltemData.kt @CurrentProgressState.kt Напиши Composable превью для Composable функции в текущем файле ColorModelList, не забудь про import
В чате мы увидим сворачиваемый список контекста, который был передан
Теперь preview было сгенерировано корректно, и Android Studio решила её нам показать
Важно! Лишний контекст может мешать генерации, так как у модели могут быть «мешающие знания», которые она обязательно захочет использовать.
Правила используются для предоставления модели инструкций по запросам «Agent», «Chat» и «Edit». Плагин позволяет вам настраивать правила, для этого выберите соответствующее меню
Правила могут быть достаточно разными, например, с их помощью вы можете явно задать, что работа ведётся с определённым стеком, а для чата, например, попросить не объяснять решения
Для наиболее частых запросов рекомендую занести их в «Prompts». При помощи команды CMD + J вызывается меню, в котором вы можете выбрать заранее подготовленный запрос. В примере запрос просит нейросеть сгенерировать тесты для представленного кода
После включения плагина вы можете увидеть, что при простое появляется строка автодополнения. При этом зачастую предлагаются варианты, соответствующие стилю и смыслу текущего файла, например, сходу предлагает создать превью:
Или же добавить схему в xml:
Если вы не пользовались ранее нейросетями для кодинга, возможно, у вас поначалу будет небольшой ступор «А что же делать?». Предлагаю наиболее частые задачи, с которыми можно попробовать поработать. Ранее в статье мы рассмотрели генерацию Preview для Composable. Как же ещё может нам помочь небольшая модель?
Запрос и результат виден на скрине, прикреплён контекст.
Где-то он немного выдумал, даже имея контекст (несуществующий конструктор), но бóльшая часть рутинной работы выполнена.
Спросим о непокрытых кейсах, предоставив контекст.
Рассуждений много, и, хоть и у модели «заплетается язык», выводы в конце сообщения дают мысли для размышления. Крайне полезно в качестве второго мнения.
Тут всё просто: выделяем код, в появившемся бабле выбираем «Edit» и пишем запрос.
Достаточно быстро, пара правок — и часть нелюбимой многими рутины готова, осталось только нажать «Accept All».
Выделяем нужный участок кода, и, по аналогии с запросом выше, просим об изменении. Стоит отметить, что сложные изменения даже большим нейронкам даются тяжело, поэтому рекомендую декомпозировать на более простые подзапросы в виде элементарных действий, вроде: «добавь кнопку с текстом», «измени так, чтобы кнопка занимала половину ширины», «измени цвет», «добавь анимацию изменения размера», «добавь анимацию элементам списка».
Всё просто — спрашиваем о наболевшем, получаем второе мнение, например, об организации кеша.
Для небольшого проекта возможно и такое действие, следует заметить пользу контекстного параметра @Codebase, который укажет модели найти все подходящие файлы. Для задачи был использован другой проект, имеющий имя RuScanner, позволяющий поставщикам из разных стран формировать грузовые партии для отправки. Проект давно не дорабатывался и служит верой и правдой, поэтому в его стеке заметны переходные периоды. Стек — View, переходящий в Compose, kotlin, старые кусочки на Java, MLKit, работа с железом (сканирующее оборудование, считывание RFID).
Здесь он не угадал только с файлом IoSessionConfig.java, однако в итоге дал неплохой промежуточный результат.
Меняя Boot Runtime для IDE, вы можете обнаружить, что ваши эмуляторы исчезли из device list. После возвращения Boot Runtime в изначальное вы снова их обнаружите там, где и оставили.
В некоторых сочетаниях Boot Runtime + версия плагина могут некорректно отрисовываться контекстные меню, например, при вводе @ для прикрепления контекста
Несмотря на закрытую инфраструктуру и строгие политики безопасности, разработчики больших компаний могут почувствовать легкий корпоративный вайб-кодинг, способный при достаточном навыке значительно сократить рутину и позволить сфокусироваться на задачах, требующих большей экспертизы.
Надеюсь, эта статья-гайд показала вам, что локальные нейросети могут быть запущены даже без мощной видеокарты и приносить пользу даже на компьютерах средней мощности, а их настройка достаточно тривиальна. Плагин Continue достаточно прост в базовой конфигурации, однако позволяет очень тонкую настройку, а множество моделей открывают в выборе конфигурации, позволяя подобрать оптимальные значения потребления ресурсов, скорости работы и точности.
А как вы используете нейросети в больших компаниях со строгими политиками безопасности? Возможно, есть хороший путь использовать и внешние модели, но по-хитрому отправлять запросы, чтобы у третьих лиц не было доступа к целостной картине кода?
Предлагаю поделиться своими историями в комментариях ;-)