Настройка Claude Computer Use для автоматизации десктопа: скриншоты, клики, набор текста. Docker-контейнер + Python SDK для полного управления GUI.
Claude Computer Use работает внутри Docker-контейнера с виртуальным дисплеем Xvfb. Сначала клонируем репозиторий и запускаем образ. Контейнер включает xdotool для эмуляции действий мыши и клавиатуры, а также VNC-сервер для наблюдения за действиями агента в реальном времени.
# Клонируем репозиторий с эталонной реализацией git clone https://github.com/anthropics/anthropic-quickstarts.git cd anthropic-quickstarts/computer-use-demo # Билдим и запускаем Docker-образ export ANTHROPIC_API_KEY="sk-ant-..." docker build -t computer-use-demo . docker run -d \ -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \ -p 5900:5900 -p 8501:8501 -p 8888:8888 \ --name computer-use computer-use-demo # VNC доступен на порту 5900, Streamlit UI на 8501, noVNC на 8888
Устанавливаем Anthropic SDK и отправляем Claude скриншот виртуального десктопа. Модель анализирует изображение и возвращает конкретное действие: координаты клика, текст для ввода или комбинацию клавиш. Используем бета-заголовок computer-use-2024-10-22.
import base64 import os from anthropic import Anthropic client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]) def get_computer_action(screenshot_path: str, task: str) -> dict: """Отправляет скриншот Claude и получает следующее действие.""" with open(screenshot_path, "rb") as f: image_data = base64.b64encode(f.read()).decode() response = client.beta.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, betas=["computer-use-2024-10-22"], tools=[{ "type": "computer_20241022", "name": "computer", "display_width_px": 1024, "display_height_px": 768, "display_number": 1 }], messages=[{ "role": "user", "content": [ {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": image_data}}, {"type": "text", "text": task} ] }] ) return response.content
Claude возвращает действия в формате tool_use блока. Парсим ответ и исполняем: клики мышью через xdotool, ввод текста, скролл, горячие клавиши. Каждое действие логируется в консоль для отладки.
import subprocess import time # DISPLAY должен указывать на Xvfb DISPLAY = ":99" def execute_action(action_block: dict): """Исполняет действие, полученное от Claude.""" name = action_block["name"] inp = action_block["input"] if name == "left_click": subprocess.run(["xdotool", "mousemove", str(inp["x"]), str(inp["y"])], env={"DISPLAY": DISPLAY}) subprocess.run(["xdotool", "click", "1"], env={"DISPLAY": DISPLAY}) print(f"🖱️ Click at ({inp['x']}, {inp['y']})") elif name == "type": subprocess.run(["xdotool", "type", inp["text"]], env={"DISPLAY": DISPLAY}) print(f"⌨️ Typed: {inp['text'][:50]}") elif name == "key": subprocess.run(["xdotool", "key", inp["text"]], env={"DISPLAY": DISPLAY}) elif name == "scroll": scroll_y = inp["scroll_y"] subprocess.run(["xdotool", "click", "5" if scroll_y < 0 else "4"], env={"DISPLAY": DISPLAY}) time.sleep(0.5) # даём интерфейсу обновиться
Объединяем всё в асинхронный цикл. Агент делает скриншот экрана через ImageMagick, отправляет Claude, получает действие, исполняет его — и повторяет, пока задача не будет выполнена. Ограничиваем 50 итерациями для безопасности.
def take_screenshot(output_path: str = "/tmp/screen.png"): subprocess.run(["import", "-window", "root", output_path], env={"DISPLAY": DISPLAY}) def run_agent_loop(task: str, max_steps: int = 50): """Главный цикл Computer Use агента.""" messages = [{"role": "user", "content": task}] for step in range(max_steps): print(f"\n--- Step {step + 1}/{max_steps} ---") # 1. Скриншот take_screenshot() # 2. Отправляем Claude action = get_computer_action("/tmp/screen.png", task) # 3. Если модель решила, что задача выполнена if action[0].type == "text" and "done" in str(action[0].text).lower(): print("✅ Task completed!") break # 4. Исполняем действие for block in action: if block.type == "tool_use": execute_action({ "name": block.name, "input": block.input }) # Запуск: открыть Firefox, найти погоду в Москве run_agent_loop( "Открой Firefox, перейди на google.com, " "найди погоду в Москве и запиши результат в текстовый файл" )
Практический пример: агент открывает браузер, переходит на сайт с формой обратной связи, заполняет поля и отправляет. Вся навигация происходит через анализ скриншотов, а не через DOM — поэтому работает с любым сайтом, включая SPA и Canvas-приложения.
# Сценарий: заполнить форму на сайте компании form_task = """ 1. Открой Firefox (иконка на рабочем столе) 2. В адресной строке введи https://example.com/contact 3. Найди поле "Имя" и введи "Иван Петров" 4. Найди поле "Email" и введи "ivan@company.ru" 5. Найди поле "Сообщение" и введи "Здравствуйте, интересует демо" 6. Нажми кнопку "Отправить" 7. Дождись сообщения об успешной отправке """ run_agent_loop(form_task) # Claude сам определит координаты полей по скриншотам # и будет кликать/печатать без CSS-селекторов
В реальной работе интерфейс может измениться, появиться неожиданное модальное окно или alert. Добавляем обработку ошибок и механизм восстановления: если Claude не смог выполнить действие три раза подряд — делаем скриншот всей ситуации и запрашиваем новую стратегию.
def robust_agent_loop(task: str): """Цикл с восстановлением после ошибок.""" consecutive_failures = 0 for step in range(50): try: take_screenshot() action = get_computer_action("/tmp/screen.png", task) if action[0].type == "text": text = action[0].text.lower() if "unexpected" in text or "error" in text: consecutive_failures += 1 if consecutive_failures >= 3: # Запрашиваем новую стратегию task += "\nЧто-то пошло не так. Опиши, что видишь на экране, и предложи новый план." continue else: consecutive_failures = 0 for block in action: if block.type == "tool_use": execute_action({"name": block.name, "input": block.input}) except Exception as e: print(f"⚠️ Error: {e}, retrying...") consecutive_failures += 1 time.sleep(2)
Claude Computer Use — это мощный подход к автоматизации GUI, не требующий селекторов и знания DOM. Агент видит экран как человек и принимает решения на основе визуального контекста. Решение идеально подходит для автоматизации legacy-приложений, тестирования UI и задач, где нет API. Полный цикл «скриншот → анализ → действие» укладывается в 2-5 секунд на шаг при использовании Claude Sonnet.