DEV Community

Cover image for Cómo crear un agente de IA para PC con Qwen 3.7 Plus
Roobia
Roobia

Posted on • Originally published at apidog.com

Cómo crear un agente de IA para PC con Qwen 3.7 Plus

Qwen 3.7 Plus obtiene 79.0 en ScreenSpot Pro, un benchmark que mide si un modelo puede mirar una captura de pantalla y devolver coordenadas exactas de píxeles para hacer clic. Esa capacidad permite construir un agente de uso de computadora: un bucle que ve la pantalla, decide la siguiente acción y la ejecuta. En esta guía implementarás uno funcional en Python.

Prueba Apidog hoy

Vas a construir el bucle del agente, definir un prompt con salida JSON, ejecutar acciones en un navegador con Playwright y añadir límites de costo y seguridad. Si necesitas contexto del modelo, consulta la descripción general de Qwen 3.7 Plus. Para el formato de solicitud multimodal, revisa la guía de API de Qwen 3.7 Plus. También puedes probar las llamadas del agente en Apidog mientras iteras.

TL;DR

Un agente de uso de computadora ejecuta este ciclo:

  1. Captura la pantalla.
  2. Envía la imagen y el objetivo a Qwen 3.7 Plus.
  3. Recibe una acción estructurada, por ejemplo click(x, y).
  4. Ejecuta la acción con Playwright u otro controlador.
  5. Repite hasta completar el objetivo o alcanzar un límite.

Qwen 3.7 Plus encaja porque entiende interfaces gráficas, puede devolver coordenadas accionables y tiene un costo multimodal bajo. La parte crítica de la implementación no es solo llamar al modelo, sino controlar el bucle: limitar pasos, validar JSON, escalar coordenadas, reducir tokens y aislar las acciones.

Qué hace realmente un agente de uso de computadora

El patrón base tiene cuatro pasos:

  1. Percibir: tomar una captura de pantalla de la página, ventana o escritorio.
  2. Decidir: enviar la captura y el objetivo al modelo.
  3. Actuar: ejecutar la acción devuelta: clic, escritura, scroll, etc.
  4. Verificar: capturar de nuevo y comprobar si el objetivo ya se cumplió.

El modelo solo decide. La captura, ejecución, validación, logging y seguridad son responsabilidad de tu código.

            <video src="https://assets.apidog.com/blog-next/2026/06/V1tXD8Bnm5DAtobB.mp4" poster="https://img.spacergif.org/v1/1920x1080/0a/spacer.png" width="1920" height="1080" loop="" autoplay="" muted="" playsinline="" preload="metadata"></video>


                    <svg xmlns="http://www.w3.org/2000/svg">
                        <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
                    </svg>





                        <svg xmlns="http://www.w3.org/2000/svg">
                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
                        </svg>


                        <svg xmlns="http://www.w3.org/2000/svg">
                            <rect width="7" height="22" rx="1.5" ry="1.5"></rect>
                            <rect width="7" height="22" rx="1.5" ry="1.5"></rect>
                        </svg>

                    <span>0:00</span>

                        /<span>1:26</span>


                    1×

                        <svg xmlns="http://www.w3.org/2000/svg">
                            <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
                        </svg>


                        <svg xmlns="http://www.w3.org/2000/svg">
                            <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
                        </svg>
Enter fullscreen mode Exit fullscreen mode

Por qué Qwen 3.7 Plus encaja

Qwen 3.7 Plus es útil para este tipo de agente por tres motivos:

  • Comprensión de GUI: puede interpretar elementos visuales y devolver coordenadas utilizables.
  • Flujos híbridos GUI/CLI: el mismo diseño de agente puede alternar entre clics, escritura y comandos si tu controlador lo permite.
  • Costo multimodal bajo: a $0.40 por millón de tokens de entrada, permite ejecutar bucles con múltiples capturas de pantalla.

Para ver la comparación con el modelo insignia solo de texto, consulta la comparación de Qwen 3.7 Plus vs Max.

Paso 1: define acciones mínimas y salida JSON

No pidas al modelo una explicación. Pídele una acción ejecutable.

Un esquema pequeño reduce errores:

{"action": "click", "x": 100, "y": 200}
{"action": "type", "text": "texto"}
{"action": "scroll", "dy": 500}
{"action": "done", "reason": "objetivo completado"}
Enter fullscreen mode Exit fullscreen mode

Ejemplo en Python usando el SDK compatible con OpenAI:

import os
import json
import base64
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DASHSCOPE_API_KEY"],
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

SYSTEM = """Eres un agente de GUI. Ves una captura de pantalla y un objetivo.
Responde con UNA acción JSON y nada más:
{"action": "click", "x": <int>, "y": <int>}
{"action": "type", "text": "<string>"}
{"action": "scroll", "dy": <int>}
{"action": "done", "reason": "<string>"}
Las coordenadas son píxeles en la captura de pantalla que se te proporcionó."""
Enter fullscreen mode Exit fullscreen mode

Ahora crea una función next_action() que reciba el objetivo y la captura:

def next_action(goal, png_bytes):
    b64 = base64.b64encode(png_bytes).decode()

    resp = client.chat.completions.create(
        model="qwen3.7-plus",
        messages=[
            {"role": "system", "content": SYSTEM},
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": f"Objetivo: {goal}"},
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": f"data:image/png;base64,{b64}"
                        },
                    },
                ],
            },
        ],
    )

    return json.loads(resp.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode

Antes de desplegar, confirma el identificador exacto del modelo en la documentación de Model Studio, porque los nombres de modelos pueden cambiar.

Paso 2: ejecuta el bucle con Playwright

Playwright controla un navegador real. Para evitar errores de coordenadas, usa el mismo tamaño para el viewport y la captura de pantalla. Así, un clic en (x, y) apunta al mismo píxel que vio el modelo.

Instala dependencias:

pip install openai playwright
playwright install chromium
Enter fullscreen mode Exit fullscreen mode

Implementa el bucle:

from playwright.sync_api import sync_playwright

MAX_STEPS = 15

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)

    page = browser.new_page(
        viewport={"width": 1280, "height": 800}
    )

    page.goto("https://example.com")

    goal = "Abrir la página de precios y encontrar el plan más barato"

    for step in range(MAX_STEPS):
        # La captura coincide con el viewport: 1280x800
        shot = page.screenshot()

        action = next_action(goal, shot)
        print(step, action)

        if action["action"] == "done":
            print("Objetivo completado:", action.get("reason"))
            break

        if action["action"] == "click":
            page.mouse.click(action["x"], action["y"])

        elif action["action"] == "type":
            page.keyboard.type(action["text"])

        elif action["action"] == "scroll":
            page.mouse.wheel(0, action["dy"])

        else:
            raise ValueError(f"Acción no soportada: {action}")

        # Espera breve para que la UI actualice antes de la siguiente captura.
        page.wait_for_timeout(800)

    browser.close()
Enter fullscreen mode Exit fullscreen mode

Ese es el agente mínimo: observa, decide, actúa y verifica en cada iteración.

Para aplicaciones de escritorio, el patrón es el mismo: cambia Playwright por una biblioteca de automatización de escritorio y captura la ventana del sistema operativo.

Paso 3: valida la respuesta del modelo

No ejecutes directamente cualquier JSON devuelto. Valida campos, tipos y rangos.

Ejemplo simple:

def validate_action(action, width=1280, height=800):
    if not isinstance(action, dict):
        raise ValueError("La acción debe ser un objeto JSON")

    kind = action.get("action")

    if kind == "click":
        x = action.get("x")
        y = action.get("y")

        if not isinstance(x, int) or not isinstance(y, int):
            raise ValueError("click requiere x e y enteros")

        if not (0 <= x < width and 0 <= y < height):
            raise ValueError("click fuera del viewport")

        return action

    if kind == "type":
        if not isinstance(action.get("text"), str):
            raise ValueError("type requiere text")
        return action

    if kind == "scroll":
        if not isinstance(action.get("dy"), int):
            raise ValueError("scroll requiere dy entero")
        return action

    if kind == "done":
        return action

    raise ValueError(f"Acción desconocida: {kind}")
Enter fullscreen mode Exit fullscreen mode

Úsala antes de actuar:

action = validate_action(next_action(goal, shot))
Enter fullscreen mode Exit fullscreen mode

Costo y fiabilidad

Las capturas de pantalla son la parte costosa. Cada imagen se convierte en tokens. Una captura de 1280 px de ancho puede consumir unos pocos miles de tokens, y un bucle de 15 pasos multiplica ese costo.

Para mantenerlo bajo control:

  • Reduce resolución: usa la imagen más pequeña que el modelo pueda leer.
  • Recorta la región relevante: si solo importa un panel, no envíes toda la pantalla.
  • Limita pasos: usa siempre MAX_STEPS.
  • Verifica después de cada acción: cada nueva captura confirma si el clic, escritura o scroll funcionó.
  • Registra las acciones: guarda step, captura, acción y resultado.

Ejemplo de logging mínimo:

import pathlib

log_dir = pathlib.Path("agent_logs")
log_dir.mkdir(exist_ok=True)

for step in range(MAX_STEPS):
    shot = page.screenshot()
    (log_dir / f"step_{step}.png").write_bytes(shot)

    action = validate_action(next_action(goal, shot))
    (log_dir / f"step_{step}.json").write_text(
        json.dumps(action, ensure_ascii=False, indent=2)
    )

    # ejecutar acción...
Enter fullscreen mode Exit fullscreen mode

La guía sobre cómo reducir los costos de tokens del agente profundiza en optimización. También puedes revisar los patrones y fallos comunes en el cableado del flujo de trabajo de agentes.

Qué hacer cuando el agente se atasca

Tres fallos aparecen con frecuencia:

1. El modelo devuelve prosa en lugar de JSON

Solución: reintenta una vez con un recordatorio corto.

def parse_action(raw):
    try:
        return json.loads(raw)
    except json.JSONDecodeError:
        raise ValueError("El modelo no devolvió JSON válido")
Enter fullscreen mode Exit fullscreen mode

En producción, puedes añadir un paso de reparación, pero mantén un límite de reintentos.

2. El clic no cambia nada

No repitas las mismas coordenadas a ciegas. Captura de nuevo y deja que el modelo reevalúe la pantalla.

previous_action = None

# Si la nueva acción es idéntica varias veces, detén el bucle.
if action == previous_action:
    repeated += 1
else:
    repeated = 0

if repeated >= 2:
    print("Acción repetida sin progreso. Requiere revisión humana.")
    break

previous_action = action
Enter fullscreen mode Exit fullscreen mode

3. El bucle gira sin progreso

Usa dos defensas:

  • límite máximo de pasos;
  • detección de acciones repetidas.

Si ambas fallan, muestra la última captura a un humano.

Seguridad

Un agente de uso de computadora hace clics reales. Antes de conectarlo a sistemas importantes:

  • Ejecútalo en un entorno aislado.
  • Usa un perfil de navegador desechable.
  • No uses tu sesión de producción.
  • Exige confirmación humana para acciones destructivas: eliminar, enviar, pagar, publicar.
  • Guarda capturas y acciones para auditoría.
  • Restringe dominios permitidos si el agente navega por la web.

Ejemplo de allowlist básica:

from urllib.parse import urlparse

ALLOWED_HOSTS = {"example.com", "docs.example.com"}

def assert_allowed_url(url):
    host = urlparse(url).hostname
    if host not in ALLOWED_HOSTS:
        raise RuntimeError(f"Dominio no permitido: {host}")
Enter fullscreen mode Exit fullscreen mode

Prueba las llamadas del agente con Apidog

Antes de conectar Playwright, valida la parte más importante: si el modelo devuelve una acción correcta.

Con Apidog puedes:

  1. Enviar una captura de pantalla de ejemplo a Qwen 3.7 Plus.
  2. Inspeccionar el JSON sin procesar.
  3. Ajustar el prompt de sistema.
  4. Guardar la clave de Model Studio por entorno.
  5. Simular el endpoint para probar el bucle sin gastar tokens en cada ejecución.

Cuando el agente encadena varias llamadas, el depurador de agentes de IA de Apidog ayuda a revisar la secuencia y encontrar el paso que descarriló el flujo.

Si quieres generar código de interfaz a partir de un diseño en lugar de controlar una UI existente, consulta la guía sobre captura de pantalla a código con Qwen 3.7 Plus.

También puedes descargar Apidog para probar y depurar las llamadas del modelo detrás de tu agente.

Preguntas frecuentes

¿Qué es un agente de uso de computadora?

Software que captura una pantalla, decide una acción con un modelo y la ejecuta mediante un controlador de automatización. Repite el proceso hasta cumplir un objetivo.

¿Puede Qwen 3.7 Plus controlar mi escritorio?

El modelo no controla nada por sí solo. Devuelve acciones. Tu código las ejecuta con Playwright, una biblioteca de automatización de escritorio u otro controlador.

¿Cuánto cuesta cada paso?

Depende sobre todo de la captura de pantalla. Una imagen puede consumir unos pocos miles de tokens de entrada a $0.40 por millón. Reducir resolución, recortar y limitar pasos son las principales palancas de costo.

¿Es fiable para producción?

Puede serlo en tareas acotadas y verificables. Para sistemas críticos o acciones destructivas, mantén aprobación humana y aislamiento.

¿Necesito escalar coordenadas?

No si la captura tiene la misma resolución que el viewport. Si son distintas, escala x e y según la relación entre ambas dimensiones.

En resumen

Un agente de uso de computadora es un bucle corto alrededor de un modelo multimodal: capturar, decidir, actuar y verificar. Qwen 3.7 Plus aporta la comprensión visual necesaria para devolver coordenadas accionables. Para hacerlo práctico, limita pasos, valida JSON, registra acciones, reduce el tamaño de las capturas y aísla el entorno. Antes de dejar que el agente haga clics, prueba el paso de decisión en Apidog.

Top comments (0)