Свой нативный клиент для AI-агентов за 3 дня: зачем делать харнес и как устроен BB на iPhone и Mac
Сейчас пошёл тренд на настраиваемые харнесы, то есть оболочки вокруг AI-агентов. На этом выстрелил BB, то же дают DeepSeek Harness, T3 Code и Claude Code. Главный плюс BB для меня в том, что туда подключаются разные подписки (Claude, Codex, DeepSeek, Gemini) и процесс настраивается чисто под свои задачи без привязки к одному провайдеру.
Месяц я докручивал веб-версию BB плагинами, но хотелось полного контроля и скорости на телефоне, без мелких кнопок, прыгающей вёрстки и засыпающих вкладок. 13 ноября решили собрать своё нативное приложение под iPhone и Mac. За 3 дня (82 коммита) готов рабочий клиент: ~18 000 строк на Swift, 4 000 на TypeScript и 79 тестов.
Как это собралось за 3 дня
Код лежит на Mac mini без Xcode, его пишут агенты. Чтобы они не правили UI вслепую, встроили автопроверку: приложение само открывает экран, делает снимок окна и закрывается. Билд на iPhone собирает один скрипт: кидает код на MacBook, подписывает, ставит на телефон и возвращает скриншот.
Как устроено внутри
На сервере стоит лёгкий «переводчик» (плагин-шлюз): привязка к ядру агентов спрятана в одном месте, наружу идёт стабильный контракт. Обновлю систему агентов — клиент пересобирать не нужно.
Само приложение написано на чистом SwiftUI без лишних библиотек, один код для iPhone и Mac. Обновления идут через поток событий поверх HTTPS (SSE), а не веб-сокеты: он проходит через домашний VPN, шлёт сигнал «есть новый ответ», и клиент забирает данные.
Как работают конкретные фишки
• Иконка и стиль. Иконку-атом нарисовал скрипт на Python, а цвета и отступы перенесли из веб-темы в единый справочник стилей.
• Блик активной задачи. Пока агент думает, по названию бежит светлый градиент. Нативная маска SwiftUI без браузерных анимаций.
• Текст и схемы. Свой парсер Markdown вместо встроенного браузера. У шрифта не было курсива, и система наклоняет буквы на 12° математически. Схемы Mermaid рисуются нативными блоками и стрелками.
• Голосовой ввод. Микрофон пишет звук движком Apple и шлёт в локальный Whisper. Шкалу громкости вынесли отдельно: она тикает 15 раз/с, и в общем состоянии перерисовывала бы весь чат 15 раз в секунду.
• Жесты и файлы. Меню выезжает свайпом с размытием фона (в покое оно отключается, чтобы не грузить графику). PDF и отчёты открываются в окне просмотра, пока файл докачивается.
Почему быстрее и удобнее веба
Веб-версия как матрёшка: браузер грузит страницу, парсит мегабайты JS, строит DOM и шлёт запросы по очереди. Сервер отвечает за 1–30 мс, так что тормозил сам браузер и цепочки сети.
Что ускорили по замерам:
• Отвязали ленту от поля ввода: при наборе 10 букв интерфейс делает 0 перерисовок абзацев вместо 169. Клавиатура не лагает.
• Пустили сеть параллельно, кэшировали 10 чатов в памяти и список на диске. Список открывается за 0,5 мс против 33 мс ожидания сети.
• Плюсы системы: ключи в защищённом хранилище, вибрация и кнопка отправки, сразу меняющаяся на «стоп».
Чек-лист: как собрать свой харнес
1. Поставьте «переводчик» перед агентами. Спрячьте скрипты за простым API с лимитами (до 150 сообщений и обрезка логов).
2. Берите SSE вместо WebSocket под VPN. Поток не рвётся на прокси и держит мобильную сеть.
3. Отделяйте быстрые обновления от ленты. Ввод и микрофон не должны перерисовывать чат.
4. Кэшируйте списки и шлите запросы параллельно. На мобильной связи лишний круг сети даёт паузу.
5. Давайте нейросетям точные цифры и эталон. Цвета, размеры и скриншот работают точнее просьбы «сделай красиво».
6. Дайте агентам глаза и автодеплой. Снимок окна и сборка одной командой сжимают недели в пару дней.
7. Не тащите всё в натив сразу. Редкие настройки оставьте в веб-окне, нативно делайте рутину: список, чат, голос и сводку.