Привет, Хабр! Меня зовут Виталий, я графический дизайнер, который однажды устал переключаться между окнами, чтобы перевести текст и исправлять опечатки с ошибками в очередном сообщении.

Полгода назад я писал о первой версии ClipGen — утилиты, которая живет в буфере обмена и по хоткею скармливает выделенный текст нейронке (Gemini). Выделил → Ctrl+F1 → Текст исправился. Быстро, бесплатно, сердито. Тогда жизнь была прекрасна: Google давал 1000 бесплатных запросов в сутки на модели Gemini. Но недавно «корпорация добра» закрутила гайки. Лимиты на Free Tier упали (на некоторых моделях до 20 запросов в день).

Ниже текст о том, как я с помощью LLM переписал архитектуру приложения, внедрил ротацию API-ключей, подружил софт с моделями Gemma и сделал нормальный UX, чтобы не гадать, почему программа молчит.

Тут всё печально
Тут всё печально

Часть 1. Open Source и вопрос безопасности

Любая утилита, которая работает с буфером обмена — это потенциальный шпион. Я это прекрасно понимаю, поэтому вопрос доверия здесь стоит на первом месте. Использовать «черный ящик», который теоретически может читать всё подряд (от паролей до личной переписки), было бы безумием. Принципиально важный момент архитектуры: ClipGen не мониторит буфер обмена в фоновом режиме. Программа не анализирует, что вы копируете в течение дня. Чтение буфера происходит исключительно в момент нажатия горячей клавиши. Пока вы не нажали условный Ctrl+F1, ClipGen «спит» и не знает, что находится у вас в буфере — будь то пароль от банка или мем с котом. Отправка данных в API происходит только по вашей явной команде. Именно поэтому ClipGen — полностью Open Source проект. Я не хочу, чтобы вы верили мне на слово. Вы можете (и должны, если вас беспокоит безопасность) зайти в репозиторий, изучить каждую строчку кода и убедиться, что никаких скрытых логгеров или фоновой отправки данных там нет. Код специально структурирован так, чтобы его было легко читать даже беглым взглядом: логика вынесена в ClipGen.py, а интерфейс — в ClipGen_view.py.

Для тех, кто «на ты» с Python: Вы можете клонировать репозиторий и запускать скрипт напрямую через интерпретатор или собрать свой билд. Для тех, кто не хочет возиться с консолью: Я собрал готовый EXE (ClipGen не требует установки), которым пользуюсь сам. Ссылку на него я оставил в своём Telegram-канале (ссылка в конце статьи) в комментариях под постом. Но выбор всегда за вами: собрать самому и быть уверенным на 100% или взять готовое решение.

Часть 2. Борьба с жадностью Google (Ротация ключей)

Главная боль новой версии — лимиты. Когда у тебя 20 запросов в день, а ты активно переписываешься и работаешь с текстом, лимит улетает за час.

Где взять ключи (и нюанс с VPN)

Процесс получения доступа максимально прост, но требует подготовки.

  1. Заходим в Google AI Studio

  2. Жмем кнопку Create API key

  3. Копируем ключ, начинающийся на AIza...

Важно: Google ограничивает доступ к API по географическому признаку. Из РФ без VPN зайти не получится, причем работают не все локации. Опытным путем проверено, что серверы США и некоторых стран Европы (например, Румыния) пускает стабильно. Лайфхак: На один Google-аккаунт можно выпустить сразу несколько ключей. Это нам очень пригодится для обхода лимитов.

Решение пришло из логики «бедных, но хитрых»: если один ключ выдохся, нужно просто взять следующий. Я реализовал систему Key Rotation.

В настройках программы можно добавить сколько угодно ключей, подписать каждый и быстро проверять работает ли ключ и видеть сколько запросов по этому ключу было сделано за последние сутки
В настройках программы можно добавить сколько угодно ключей, подписать каждый и быстро проверять работает ли ключ и видеть сколько запросов по этому ключу было сделано за последние сутки

В settings.json теперь хранится не один ключ, а список. В интерфейсе можно добавить хоть 10 бесплатных ключей от разных Google-аккаунтов.

В коде (ClipGen.py) обработка запроса завернута в цикл while. Алгоритм такой:

  1. 1.Пробуем отправить запрос с текущим активным ключом.

  2. Если прилетает 429 (Quota exceeded) или Resource exhausted:
    • Проверяем, включена ли авто-смена ключей.
    • Если да — меняем активный ключ на следующий в списке.
    • Повторяем итерацию цикла.

  3. Если ключи кончились — мигаем красной иконкой.

Кусок логики (упрощенно):

while attempt < max_attempts:
    try:
        # Конфигурируем GenAI с текущим ключом
        model = genai.GenerativeModel(self.config["active_model"])
        response = model.generate_content(...)
        return response.text
        
    except Exception as e:
        if "429" in str(e) and self.config["auto_switch_api_keys"]:
             # Логируем смену ключа
             new_key = self.switch_to_next_api_key()
             if new_key:
                 continue # Пробуем снова
        break # Иначе выходим с ошибкой

Это сделало программу практически "бессмертной" в плане лимитов.

Часть 3. Скрытые возможности: Gemma внутри Gemini

Еще одно открытие, к которому я пришел случайно. Раньше модель была жестко прописана в коде. Теперь я вынес это в настройки. Google предлагает модели семейства Gemini (flash, pro). Но оказалось, что через стандартную библиотеку google.generativeai можно обращаться и к открытым моделям Gemma, которые хостит Google, просто передав их название строкой.

Я прописал в настройках gemma-3-27b-it — и оно заработало. Без смены библиотек, без регистрации на Groq или HuggingFace.

  • Плюс: У Gemma сейчас гораздо более щедрые лимиты (около 14 500 запросов в сутки на момент написания).

  • Минус: Она работает медленнее (ответ занимает 2-4 секунды против 0.5 сек у Flash).

Теперь в настройках у меня «карусель» моделей: нужна скорость — ставлю Gemini 2.5 Flash, кончились лимиты — переключаюсь на Gemma 3.

Как добавить любую новую модель (Future-proof)

Самое приятное, что список моделей в программе не «прибит гвоздями». Архитектура устроена так, что ClipGen просто передает строковый идентификатор в API. Это значит, что вы можете добавить любую модель, которая доступна (или станет доступна) у Google.

  1. Идем на официальную страницу документации: Gemini Models

  2. Находим нужную модель и раскрываем её детали.

  3. Ищем поле Model code (например, gemini-2.5-flash).

  4. Копируем этот код, нажимаем «зеленую кнопку» в настройках ClipGen и вставляем его.

Это делает утилиту устойчивой к обновлениям. Если завтра Google выкатит условный Gemini 3.0 Flash, вам не нужно ждать, пока я обновлю программу и пересоберу EXE. Просто скопировали model code в настройки — и моделька уже у вас в буфере обмена.

В настройках можно добавить любое количество моделей и проверить её время отклика, если кнопочка покраснела, то идём в окно логов, там будет текст ошибки, из которого будет ясно что пошло не так
В настройках можно добавить любое количество моделей и проверить её время отклика, если кнопочка покраснела, то идём в окно логов, там будет текст ошибки, из которого будет ясно что пошло не так

Часть 4. UX: Светофор в трее

В первой версии программы, чтобы понять, что происходит, приходилось открывать окно с логами. Нажал Ctrl+F1 и ждешь. Зависло? VPN отвалился? Или просто модель думает?

Я решил эту проблему через динамическую иконку в трее. Она перерисовывается на лету с помощью QPainter:

Иконки состояния в трее
Иконки состояния в трее
  • Желтый квадрат с цифрами: Запрос ушел, идет обработка. Цифры показывают таймер в секундах. Ты видишь, что процесс идет.

  • Зеленый квадрат: Успех. Показывает итоговое время выполнения (например, 1.2s).

  • Красный квадрат (!): Ошибка.

Фоновый режим и видимость

Так как ClipGen — это утилита, которая должна быть всегда под рукой, я настроил поведение окна соответственно: при закрытии программа не закрывается полностью, а сворачивается в трей и продолжает слушать горячие клавиши. Полный выход — через контекстное меню.

Маленький совет для Windows-пользователей: Поскольку иконка — это единственный монитор состояния (она показывает таймер и ошибки), держать её скрытой за «стрелочкой» в трее нет смысла. Рекомендую сразу перетащить иконку ClipGen из скрытой области на саму панель задач. Так вы будете периферийным зрением контролировать процесс: если иконка стала красной — значит, отвалился VPN или ключ, и нет смысла ждать ответа.

Важный нюанс: Google API блокирует запросы из РФ. Без VPN программа работать не будет. Если VPN отвалился, иконка краснеет (ловится ConnectionError или 400-е коды).

Часть 5. Буфер обмена, Картинки и Win32

Работа с буфером обмена в Windows — это было самое сложное для меня. Для перехвата я использую комбинацию pynput (слушает хоткеи) и win32api (эмулирует нажатия).

Алгоритм действия:

  1. Юзер жмет Ctrl+F10

  2. Программа программно жмет Ctrl+C

  3. Читаем буфер

  4. 4. Магия мультимодальности: Проверяем, что там. Если текст — отправляем текст. • Если картинка (ImageGrab.grabclipboard) — отправляем объект изображения.

Это позволяет делать крутые вещи. Например, вылезла ошибка в интерфейсе программы, которую нельзя скопировать текстом. Действие: Win+Shift+S (скриншот области) -> Ctrl+F12 (мой хоткей на "извлечение текста").
Результат: ClipGen отправляет картинку в Gemini, та делает OCR и вставляет текст мне в открытое сейчас приложение или я смотрю его в логах программы.

Баги, с которыми пришлось смириться

Некоторые приложения жадные до фокуса. Например, в Figma при нажатии моего хоткея Ctrl+F6 теряется фокус с текстового поля. ClipGen отрабатывает, ответ в буфере есть, но автоматическая вставка (Ctrl+V) происходит "в никуда". Решается простым ручным нажатием Ctrl+V, но осадочек остался.

Итог

ClipGen превратился для меня из эксперимента в утилиту, без которой я уже не представляю свой рабочий процесс. Я нажимаю заветные хоткеи по 100 раз за день — от правки опечаток в мессенджерах до быстрого перевода документации и OCR скриншотов.

Немного сухих цифр:
Стек: Python 3.10, PyQt5, Google GenAI SDK.
Вес: Исходники ~100 Кб. Скомпилированный EXE (спасибо PyInstaller) — 50 Мб (да, это боль питона, с которой приходится жить).

Проект живой, и я планирую развивать его дальше. Буду очень рад вашим идеям, тестам и даже баг-репортам (куда без них). Если знаете, как сделать лучше — Pull Request'ы приветствуются.
Ссылка на репозиторий: GitHub исходный код. Изучайте, форкайте, собирайте свой билд.

Мой Telegram-канал: Вот тут публикую остальные свои проекты, новости о мелких фиксах, апдейты и выложил тот самый готовый portable EXE (в комментариях под постом), чтобы не возиться с установкой.

Скачать программу: Вот тут Архив лежит в комментах под этим постом

Комментарии (0)