Когда ИИ должен делать клики вместо вас
Вы открываете утром почту. 47 писем. Нужно ответить на три важных, остальные разложить по папкам, два письма пометить как спам. Вы тратите 20 минут на рутину. Каждый день. А теперь представьте, что вы пишете одну команду: "Разбери почту" - и через минуту все готово.
Это не фантастика. Это реальность 2026 года. Но есть проблема: Google Gemini 2.5 Computer Use все еще экспериментальная технология, доступная не всем. API закрыт, ждать официального релиза можно до следующего года.
А рутину делать нужно сегодня. Прямо сейчас.
Важно: мы не взламываем Gemini и не используем недокументированные API. Мы строим мост между тем, что Gemini умеет (анализировать изображения), и тем, что нам нужно (кликать по экрану).
Что такое AI Bridge и почему это не очередной макрос
AI Bridge - это система из трех компонентов:
- Глаза: Python-скрипт делает скриншот экрана
- Мозг: Gemini 2.5 Flash (самая быстрая версия на февраль 2026) анализирует скриншот и говорит, где кликнуть
- Руки: PyAutoGUI выполняет команды
Чем это отличается от обычных макросов? Представьте, что вы записали макрос для сортировки файлов. Он кликает по координатам (100, 200). Вы обновили систему, иконка сместилась на 5 пикселей. Макрос сломался.
AI Bridge каждый раз анализирует экран заново. Иконка сместилась? Не проблема. Gemini найдет ее по содержимому, а не по координатам.
Собираем инструментарий: что нужно установить
Прежде чем писать код, убедитесь, что у вас есть:
- Python 3.11 или новее (на февраль 2026 актуальна 3.12)
- API-ключ Gemini (бесплатный, 60 запросов в минуту)
- Доступ к Gemini 2.5 Flash или Gemini 3.0 Flash
1Устанавливаем зависимости
pip install google-generativeai pillow pyautogui opencv-python numpyPyAutoGUI будет кликать, Pillow делать скриншоты, OpenCV обрабатывать изображения, а google-generativeai общаться с Gemini.
PyAutoGUI на Linux требует дополнительных настроек. Если у вас Ubuntu/Debian: sudo apt-get install python3-tk python3-dev scrot
2Получаем API-ключ Gemini
Идем на Google AI Studio, создаем новый ключ. Копируем. Никому не показываем.
Архитектура моста: как все работает вместе
Вот схема работы нашей системы:
| Компонент | Что делает | Альтернатива |
|---|---|---|
| Screenshot Module | Делает скриншот всего экрана или области | mss, pygetwindow |
| Vision Analyzer | Отправляет скриншот в Gemini, получает координаты | GPT-4V, Claude 3.5 Sonnet |
| Action Executor | Выполняет клики, ввод текста | pynput, keyboard |
Главная хитрость - в промпте для Gemini. Мы должны научить модель не просто описывать скриншот, а возвращать структурированные данные для автоматизации.
Пишем код: от скриншота до клика
Часть 1: Делаем умный скриншот
import pyautogui
import time
from PIL import Image
import io
class ScreenCapture:
def __init__(self, region=None):
"""
region: (left, top, width, height) или None для всего экрана
"""
self.region = region
def capture(self, save_path=None):
"""Делает скриншот и возвращает PIL Image"""
if self.region:
screenshot = pyautogui.screenshot(region=self.region)
else:
screenshot = pyautogui.screenshot()
if save_path:
screenshot.save(save_path)
return screenshot
def capture_to_bytes(self):
"""Конвертирует скриншот в байты для отправки в API"""
screenshot = self.capture()
img_byte_arr = io.BytesIO()
screenshot.save(img_byte_arr, format='PNG')
return img_byte_arr.getvalue()Почему именно так? Потому что Gemini принимает изображения в формате base64 или байтах. Сохранять на диск каждый раз - медленно и бесполезно.
Часть 2: Говорим с Gemini на правильном языке
Вот промпт, который превращает Gemini в анализатора интерфейсов:
import google.generativeai as genai
from PIL import Image
import json
class GeminiVisionAnalyzer:
def __init__(self, api_key, model="gemini-2.5-flash"):
genai.configure(api_key=api_key)
# На февраль 2026 доступны gemini-2.5-flash и gemini-3.0-flash
self.model = genai.GenerativeModel(model)
def analyze_screen(self, image_bytes, task_description):
"""Анализирует скриншот и возвращает действия"""
prompt = f"""Ты - система автоматизации ПК. Анализируй скриншот и определи, какие действия нужно выполнить.
Задача: {task_description}
ВОЗВРАЩАЙ ТОЛЬКО JSON В СЛЕДУЮЩЕМ ФОРМАТЕ:
{{
"actions": [
{{
"type": "click" | "type" | "scroll" | "wait",
"coordinates": {{"x": number, "y": number}},
"text": "string" (только для type),
"duration": number (только для wait, в секундах)
}}
],
"confidence": 0.0-1.0,
"description": "краткое описание что будет сделано"
}}
Правила:
1. Координаты указывай относительно левого верхнего угла скриншота
2. Для клика: найди кнопку, иконку или элемент интерфейса
3. Для ввода текста: найди поле ввода
4. Если не уверен в элементе, confidence должен быть ниже 0.7
5. Не добавляй никакого текста кроме JSON"""
image = Image.open(io.BytesIO(image_bytes))
response = self.model.generate_content([
prompt,
image
])
# Извлекаем JSON из ответа
response_text = response.text.strip()
# Иногда Gemini добавляет в начале
if response_text.startswith(''):
response_text = response_text[7:-3]
elif response_text.startswith(''):
response_text = response_text[3:-3]
return json.loads(response_text)Часть 3: Исполняем команды безопасно
Самая опасная часть. PyAutoGUI может кликнуть куда угодно. Добавим защиту:
class ActionExecutor:
def __init__(self, safety_margin=50):
"""
safety_margin: минимальное расстояние от края экрана для безопасности
"""
self.safety_margin = safety_margin
self.screen_width, self.screen_height = pyautogui.size()
def execute_actions(self, actions, region_offset=(0, 0)):
"""Выполняет список действий"""
results = []
for action in actions:
action_type = action["type"]
if action_type == "click":
# Преобразуем относительные координаты в абсолютные
rel_x = action["coordinates"]["x"]
rel_y = action["coordinates"]["y"]
abs_x = rel_x + region_offset[0]
abs_y = rel_y + region_offset[1]
# Проверка безопасности
if not self._is_safe_coordinate(abs_x, abs_y):
print(f"Пропускаем небезопасные координаты: ({abs_x}, {abs_y})")
continue
pyautogui.click(abs_x, abs_y)
results.append({"type": "click", "coordinates": (abs_x, abs_y)})
elif action_type == "type":
text = action.get("text", "")
pyautogui.write(text)
results.append({"type": "type", "text": text})
elif action_type == "wait":
duration = action.get("duration", 1)
time.sleep(duration)
results.append({"type": "wait", "duration": duration})
elif action_type == "scroll":
clicks = action.get("clicks", 1)
pyautogui.scroll(clicks)
results.append({"type": "scroll", "clicks": clicks})
return results
def _is_safe_coordinate(self, x, y):
"""Проверяет, что координаты не на краю экрана"""
return (self.safety_margin <= x <= self.screen_width - self.safety_margin and
self.safety_margin <= y <= self.screen_height - self.safety_margin)Собираем все вместе: рабочий скрипт
# ai_bridge.py
import json
from screen_capture import ScreenCapture
from gemini_analyzer import GeminiVisionAnalyzer
from action_executor import ActionExecutor
class AIBridge:
def __init__(self, api_key):
self.capture = ScreenCapture()
self.analyzer = GeminiVisionAnalyzer(api_key)
self.executor = ActionExecutor()
def execute_task(self, task_description, max_steps=5):
"""Выполняет задачу, возможно в несколько шагов"""
for step in range(max_steps):
print(f"Шаг {step + 1}/{max_steps}")
# 1. Делаем скриншот
print("Делаю скриншот...")
screenshot_bytes = self.capture.capture_to_bytes()
# 2. Анализируем через Gemini
print("Анализирую через Gemini...")
analysis = self.analyzer.analyze_screen(
screenshot_bytes,
task_description
)
print(f"Уверенность: {analysis['confidence']:.2f}")
print(f"План: {analysis['description']}")
# 3. Если уверенность низкая - останавливаемся
if analysis["confidence"] < 0.6:
print("Слишком низкая уверенность. Останавливаюсь.")
break
# 4. Выполняем действия
print(f"Выполняю {len(analysis['actions'])} действий...")
results = self.executor.execute_actions(analysis["actions"])
# 5. Ждем результат
time.sleep(2)
# 6. Проверяем, выполнена ли задача
if self._is_task_complete(task_description):
print("Задача выполнена!")
break
def _is_task_complete(self, task_description):
"""Простая эвристика для проверки завершения"""
# Здесь можно добавить более сложную логику
# Например, сделать еще один скриншот и спросить у Gemini
return False
# Использование
if __name__ == "__main__":
API_KEY = "ваш_api_ключ" # НИКОГДА не коммитьте ключ в git!
bridge = AIBridge(API_KEY)
# Примеры задач
tasks = [
"Найди иконку браузера на рабочем столе и открой его",
"В открытом браузере найди адресную строку и введи 'google.com'",
"Найди поле поиска на сайте Google и введи 'автоматизация ПК'",
]
for task in tasks:
print(f"\nВыполняю задачу: {task}")
bridge.execute_task(task)Реальные кейсы: что можно автоматизировать уже сегодня
Кейс 1: Сортировка загрузок
У вас папка Downloads с 200 файлами. Нужно разложить по папкам: Images, Documents, Archives.
def sort_downloads():
"""Открывает папку загрузок и сортирует файлы"""
bridge = AIBridge(API_KEY)
# Открываем папку
bridge.execute_task("Открой папку 'Загрузки' на рабочем столе")
time.sleep(1)
# Сортируем по типам
bridge.execute_task("Выдели все файлы с расширением .jpg и .png")
bridge.execute_task("Перетащи выделенные файлы в папку 'Images'")
bridge.execute_task("Выдели все файлы с расширением .pdf и .docx")
bridge.execute_task("Перетащи выделенные файлы в папку 'Documents'")Кейс 2: Ежедневный репорт
Каждое утро нужно открыть 3 системы, скачать отчеты, собрать в один Excel.
def generate_daily_report():
"""Автоматизирует сбор ежедневной отчетности"""
# Открываем CRM систему
bridge.execute_task("Найди иконку CRM на рабочем столе")
bridge.execute_task("Введи логин и пароль в форму входа")
bridge.execute_task("Найди меню 'Отчеты' и кликни")
bridge.execute_task("Выбери 'Ежедневные продажи' и экспортируй в Excel")
# Аналогично для других систем
# ...Ошибки, которые сломают вашу автоматизацию
Ошибка 1: Абсолютные координаты
Новички часто делают так:
# НЕ ДЕЛАЙТЕ ТАК
pyautogui.click(100, 200) # Сломается при смене разрешенияПравильно - использовать относительные координаты от Gemini.
Ошибка 2: Нет задержек
Скрипт кликает быстрее, чем приложение реагирует. Добавляйте time.sleep() между действиями.
Ошибка 3: Игнорирование confidence
Если Gemini не уверен на 70%, что это нужная кнопка - не кликайте. Лучше остановиться, чем удалить важный файл.
Продвинутые техники
Точный поиск элементов
Иногда нужно найти не просто "кнопку", а конкретную кнопку с текстом. Модифицируем промпт:
prompt = f"""Найди на скриншоте элемент с ТОЧНЫМ текстом '{element_text}'.
Верни координаты центра элемента. Если элемента нет, верни confidence: 0"""Мультимониторная поддержка
PyAutoGUI не всегда правильно работает с несколькими мониторами. Используйте mss:
import mss
with mss.mss() as sct:
# Монитор 2
monitor = sct.monitors[2]
screenshot = sct.grab(monitor)
# Конвертируем в PIL Image
img = Image.frombytes("RGB", screenshot.size, screenshot.bgra, "raw", "BGRX")Что дальше? Будущее AI Bridge
Сегодня мы строим мост из подручных средств. Но уже завтра Google выпустит официальный Computer Use API, и все станет проще.
До тех пор наш подход - лучший компромисс между мощностью и доступностью. Он учит важному: автоматизация - это не про запись макросов, а про понимание интерфейсов.
Попробуйте начать с малого. Автоматизируйте одну рутинную операцию, которая отнимает 5 минут каждый день. Через неделю вы сэкономите 35 минут. Через месяц - 2.5 часа.
А потом посмотрите на эти 2.5 часа и задайте себе вопрос: что бы вы сделали, если бы у вас появилось лишних 30 часов в год?
Ответ, скорее всего, найдете в комбинации нескольких ИИ для решения более сложных задач. Но это уже другая история.