
Aloísio Vítor
Image Processing Expert

pageAction, y la política de puntuación desde un registro del lado del servidor en lugar de desde texto generado por el modelo.La forma más segura de resolver reCAPTCHA v3 en CrewAI es exponer CapSolver a través de una herramienta tipada y controlada por políticas. CrewAI debe decidir cuándo se necesita verificación, pero el código de aplicación confiable debe resolver el destino aprobado, la clave del sitio, la acción de página, el modo de proxy y la política de puntuación. La documentación de reCAPTCHA v3 de CapSolver define los tipos de tarea y parámetros admitidos, mientras que el SDK de Agente proporcionado por el usuario mapea llamadas de herramientas estructuradas a capsolver-core. La herramienta debe enviar el token del lado del servidor, verificar el estado de la página resultante y dar al crew un resultado pequeño como verificado, revisión requerida o detenido. Este diseño previene el desvío de URL, el adivino de acciones, la fuga de secretos, soluciones duplicadas y señales falsas de éxito.
reCAPTCHA v3 es basado en puntuación y generalmente se ejecuta sin un casillero visible. La aplicación de destino invoca una acción, recibe un token y evalúa ese token en el servidor. Por lo tanto, un flujo de trabajo de CrewAI puede fallar incluso cuando nunca ve un desafío visual.
Las causas comunes son operativas en lugar de conversacionales:
pageAction no coincidió con la acción de la página en tiempo de ejecución;El blog de reCAPTCHA de CapSolver contiene guías de implementación de apoyo, mientras que la FAQ de IA y automatización ayuda a definir los límites seguros de los agentes.
Un equipo de agentes múltiples funciona mejor cuando la responsabilidad es explícita.
| Rol | Responsabilidad permitida | No debe controlar |
|---|---|---|
| Navegador | Observar el estado de la aplicación aprobada | Clave API, credencial de proxy, token sin procesar |
| Planificador de verificación | Decidir si el paso aprobado necesita la herramienta | URL arbitraria o clave del sitio |
| Herramienta CapSolver | Resolver la política, crear una tarea, enviar el token | Reinicios ilimitados o navegación no relacionada |
| Validador de estado | Confirmar la ruta esperada y los marcadores semánticos | Decisiones de aprobación comercial |
| Revisor | Inspeccionar la evidencia eliminada en caso de fallo | Material de sesión secreta |
El modelo puede elegir un ID de destino registrado. No debe construir la URL de destino o los parámetros del desafío.
La documentación de herramientas personalizadas de CrewAI soporta BaseTool con un args_schema de Pydantic, el decorador @tool, resultados tipados y herramientas asíncronas para operaciones de E/S.
La documentación del Agente CapSolver proporcionada por el usuario explica que capsolver-agent envuelve capsolver-core: create_executor() crea el ejecutor, y executor.execute("solve_captcha", args) envía la solicitud tipada al motor principal.
Instalar los paquetes documentados:
pip install git+https://github.com/capsolver-ai/capsolver-core.git
pip install git+https://github.com/capsolver-ai/capsolver-agent.git
pip install crewai
export CAPSOLVER_API_KEY="CAP-..."
Mantener las claves en el almacén de secretos en tiempo de ejecución. No colocarlas en prompts de crew, descripciones de tareas o resultados de herramientas.
from dataclasses import dataclass
@dataclass(frozen=True)
class RecaptchaV3Policy:
target_id: str
website_url: str
website_key: str
page_action: str
minimum_score: float
enterprise: bool
proxy_profile: str | None
allowed_crew_role: str
max_attempts: int = 1
TARGETS = {
"approved_login_test": RecaptchaV3Policy(
target_id="approved_login_test",
website_url="https://approved.example.com/login",
website_key="PUBLIC_SITE_KEY",
page_action="login",
minimum_score=0.7,
enterprise=False,
proxy_profile=None,
allowed_crew_role="verification_specialist",
)
}
La clave del sitio pública no es un secreto de cuenta, pero aún así debe provenir de una configuración confiable para que el modelo no redirija la herramienta.
pageAction en lugar de adivinarloLa documentación de reCAPTCHA v3 de CapSolver lista pageAction como un campo de tarea opcional y explica que el valor puede encontrarse en la llamada grecaptcha.execute de la página.
@dataclass(frozen=True)
class PageObservation:
target_id: str
current_url: str
observed_action: str
observed_site_key: str
form_state: str
observed_at: str
def validate_observation(
observation: PageObservation,
policy: RecaptchaV3Policy,
) -> None:
if observation.current_url != policy.website_url:
raise PermissionError("La URL observada no coincide con la política")
if observation.observed_site_key != policy.website_key:
raise ValueError("La clave del sitio observada no coincide con la política")
if observation.observed_action != policy.page_action:
raise ValueError("La acción de página observada no coincide con la política")
if observation.form_state != "READY_FOR_VERIFICATION":
raise ValueError("El estado de la aplicación no está listo")
La herramienta debe rechazar las discrepancias en lugar de crear un token para parámetros inciertos.
| Parámetro | Propósito | Regla de política |
|---|---|---|
captcha_type |
Selecciona reCAPTCHA v3 en el SDK del Agente | Fijo a reCaptchaV3 |
website_url |
Página que aloja el desafío | Cargado desde el registro |
website_key |
Clave del sitio pública | Cargado desde el registro y verificado contra la página |
page_action |
Acción de v3 en tiempo de ejecución | Debe coincidir con la observación |
min_score |
Puntuación mínima solicitada | Establecido por la política de destino |
enterprise |
Ruta estándar o empresarial | Fijado por la configuración de integración |
proxy |
Identidad de red opcional | Resuelto desde un perfil de secreto si es necesario |
CapSolver documenta variantes de tarea estándar, empresarial, proxy y sin proxy. Su resultado puede contener gRecaptchaResponse, datos de agente de usuario y valores de sesión cuando el modo correspondiente esté habilitado.
La página de productos de CapSolver ayuda a confirmar la familia de tareas admitida antes de la implementación.
import os
from typing import Literal
from crewai.tools import tool
from pydantic import BaseModel, Field
from capsolver_agent.schema import create_executor
executor = create_executor(api_key=os.environ["CAPSOLVER_API_KEY"])
class SolveRequest(BaseModel):
target_id: str = Field(description="Identificador de destino registrado")
crew_role: str = Field(description="Rol que solicita la verificación")
observed_action: str = Field(description="Acción observada en la página en vivo")
observed_site_key: str = Field(description="Clave del sitio observada en la página en vivo")
state_id: str = Field(description="Identificador de estado de aplicación del lado del servidor")
class SolveResult(BaseModel):
status: Literal["verified", "review_required", "stopped"]
target_id: str
state_id: str
reason: str
task_attempted: bool
El modelo de resultado excluye deliberadamente el token, la clave API, el proxy, las cookies y la respuesta del proveedor sin procesar.
PROXY_VAULT = {
"approved_proxy": os.environ.get("APPROVED_PROXY")
}
async def submit_token_and_verify(
*,
state_id: str,
token: str,
policy: RecaptchaV3Policy,
) -> bool:
"""Función de envío y verificación propiedad de la aplicación."""
response = await application_sessions.submit_recaptcha_v3(
state_id=state_id,
token=token,
expected_action=policy.page_action,
)
return (
response.current_url.startswith("https://approved.example.com/account")
and response.semantic_marker == "AUTHENTICATED_ACCOUNT_PAGE"
and response.challenge_present is False
)
application_sessions representa su servicio de sesión de navegador o HTTP autorizado. La herramienta solucionadora lo usa, pero el modelo no recibe sus credenciales.
@tool("Resolver reCAPTCHA v3 aprobado", result_schema=SolveResult)
async def solve_approved_recaptcha_v3(
target_id: str,
crew_role: str,
observed_action: str,
observed_site_key: str,
state_id: str,
) -> dict:
"""Resolver un paso de reCAPTCHA v3 registrado y verificar el estado de la aplicación."""
policy = TARGETS.get(target_id)
if policy is None:
return SolveResult(
status="stopped",
target_id=target_id,
state_id=state_id,
reason="Destino desconocido",
task_attempted=False,
).model_dump()
if crew_role != policy.allowed_crew_role:
return SolveResult(
status="stopped",
target_id=target_id,
state_id=state_id,
reason="El rol no está permitido para llamar a esta herramienta",
task_attempted=False,
).model_dump()
if observed_action != policy.page_action:
return SolveResult(
status="review_required",
target_id=target_id,
state_id=state_id,
reason="La acción observada no coincide con la política de destino",
task_attempted=False,
).model_dump()
if observed_site_key != policy.website_key:
return SolveResult(
status="review_required",
target_id=target_id,
state_id=state_id,
reason="La clave del sitio observada no coincide con la política de destino",
task_attempted=False,
).model_dump()
args = {
"captcha_type": "reCaptchaV3",
"website_url": policy.website_url,
"website_key": policy.website_key,
"page_action": policy.page_action,
"min_score": policy.minimum_score,
"enterprise": policy.enterprise,
}
if policy.proxy_profile:
args["proxy"] = PROXY_VAULT[policy.proxy_profile]
result = await executor.execute("solve_captcha", args)
if not result.get("success"):
return SolveResult(
status="review_required",
target_id=target_id,
state_id=state_id,
reason="La tarea de CapSolver no se completó",
task_attempted=True,
).model_dump()
solution = result.get("solution") or {}
token = solution.get("token")
if not token:
return SolveResult(
status="review_required",
target_id=target_id,
state_id=state_id,
reason="El resultado de la tarea no contenía un token",
task_attempted=True,
).model_dump()
verified = await submit_token_and_verify(
state_id=state_id,
token=token,
policy=policy,
)
return SolveResult(
status="verified" if verified else "review_required",
target_id=target_id,
state_id=state_id,
reason="El estado de la aplicación fue verificado" if verified else "El estado de la aplicación no fue verificado",
task_attempted=True,
).model_dump()
Esta implementación mantiene las credenciales dentro del código confiable y da al crew solo un estado seguro según la política.
from crewai import Agent, Crew, Process, Task
verification_agent = Agent(
role="verification_specialist",
goal="Completar solo los pasos de verificación registrados y reportar el estado verificado",
backstory=(
"Usted opera herramientas de verificación aprobadas. Nunca inventa identificadores de destino, "
"claves del sitio, acciones, credenciales o estados de éxito."
),
tools=[solve_approved_recaptcha_v3],
allow_delegation=False,
verbose=True,
)
verification_task = Task(
description=(
"Para el destino registrado en la observación proporcionada, llame a la herramienta una sola vez "
"solo si la URL, la clave del sitio, la acción y el estado están confirmados. Devuelva el "
"resultado estructurado sin secretos."
),
expected_output="Un resultado estructurado, review_required o stopped.",
agent=verification_agent,
)
crew = Crew(
agents=[verification_agent],
tasks=[verification_task],
process=Process.sequential,
verbose=True,
)
No adjunte la herramienta solucionadora a cada agente. Limitarla a un solo rol hace más claro la autorización y la auditoría.
from datetime import datetime, timedelta, timezone
ATTEMPTS: dict[tuple[str, str], datetime] = {}
def claim_attempt(target_id: str, state_id: str) -> bool:
key = (target_id, state_id)
now = datetime.now(timezone.utc)
prior = ATTEMPTS.get(key)
if prior and now - prior < timedelta(minutes=2):
return False
ATTEMPTS[key] = now
return True
Llame a claim_attempt() antes de executor.execute(). Un mensaje repetido de crew no debe crear un segundo token para el mismo estado de aplicación.
La memoria, trazas y registros detallados de CrewAI pueden preservar la salida de herramientas. Devuelva solo:
{
"status": "verified",
"target_id": "approved_login_test",
"state_id": "state_7c19",
"reason": "El estado de la aplicación fue verificado",
"task_attempted": true
}
Nunca devuelva el token, la clave API de CapSolver, el valor de proxy, la cookie del navegador, HTML sin procesar, contraseña o datos de formulario personales.
La FAQ de errores y solución de problemas de CapSolver puede apoyar la clasificación de errores del proveedor sin exponer la respuesta cruda al crew.
El validador debe requerir varios señales independientes:
@dataclass(frozen=True)
class StateCheck:
expected_path_prefix: str
required_marker: str
forbidden_markers: tuple[str, ...]
def is_verified(page, check: StateCheck) -> bool:
return (
page.url.path.startswith(check.expected_path_prefix)
and page.has_semantic_marker(check.required_marker)
and not any(page.contains(marker) for marker in check.forbidden_markers)
and page.http_status == 200
)
Un cambio de URL solo no es suficiente. Requiere la ruta esperada, el marcador semántico, el estado y la ausencia de estados de desafío o error conocidos.
CapSolver documenta las variantes empresariales y el modo de sesión opcional. No permita que la tripulación infiera estas opciones.
@dataclass(frozen=True)
class RecaptchaV3Policy:
target_id: str
website_url: str
website_key: str
page_action: str
minimum_score: float
enterprise: bool
is_session: bool
proxy_profile: str | None
allowed_crew_role: str
max_attempts: int = 1
Si el objetivo aprobado usa Enterprise, almacene este hecho en la política. Si se necesita el modo de sesión, maneje los valores de sesión devueltos dentro del servicio de sesión de la aplicación y manténgalos fuera de la salida de la tripulación.
| Diseño | Integridad de parámetros | Seguridad de secretos | Aseguramiento del estado de la página | Recomendación |
|---|---|---|---|---|
| El modelo proporciona URL, clave y acción | Baja | Baja | Baja | Evitar |
| La herramienta devuelve el token a la tripulación | Media | Baja | Baja | Evitar |
| La herramienta resuelta por el registro envía y verifica | Alta | Alta | Alta | Preferido |
| Paso de verificación humano único | Alta | Alta | Alta | Usar para estados sensibles o inciertos |
El diseño preferido otorga autoridad de decisión al modelo pero mantiene la autoridad de ejecución dentro del código confiable.
Supervise campos redactados como:
SAFE_FIELDS = {
"target_id",
"crew_role",
"action_match",
"task_attempted",
"provider_category",
"duration_ms",
"verified",
"review_reason",
}
def safe_event(event: dict) -> dict:
return {key: event[key] for key in SAFE_FIELDS if key in event}
La página de estado de CapSolver puede ayudar a distinguir la disponibilidad del proveedor de fallos específicos de la aplicación.
import pytest
@pytest.mark.asyncio
async def test_unknown_target_stops_before_task():
result = await solve_approved_recaptcha_v3.run(
target_id="unknown",
crew_role="verification_specialist",
observed_action="login",
observed_site_key="x",
state_id="state-1",
)
assert result["status"] == "stopped"
assert result["task_attempted"] is False
@pytest.mark.asyncio
async def test_action_mismatch_requests_review():
result = await solve_approved_recaptcha_v3.run(
target_id="approved_login_test",
crew_role="verification_specialist",
observed_action="checkout",
observed_site_key="PUBLIC_SITE_KEY",
state_id="state-2",
)
assert result["status"] == "review_required"
assert result["task_attempted"] is False
También pruebe el bloqueo de intentos duplicados, la redacción de secretos, el manejo de tokens faltantes, la política Enterprise y los fallos de verificación de página.
Código de bonificación: Use el código WEBS en CapSolver Dashboard para obtener un 5% adicional en cada recarga.
La Página de Preguntas Frecuentes de CapSolver ofrece orientación adicional sobre la vida útil de la tarea.
Use un solucionador de reCAPTCHA v3 de CrewAI solo en sitios que posea, pruebe o tenga permiso explícito para automatizar. Respete los términos, límites de tasa, límites de autenticación, obligaciones de privacidad y políticas de acceso interno. Una clave de sitio pública no otorga permiso para acceder a un flujo protegido. Mantenga las solicitudes consecuentes, pagos, cambios de cuenta y decisiones sobre datos sensibles detrás de controles de aprobación separados.
Un solucionador de reCAPTCHA v3 de CrewAI en producción debe ser estrecho, tipado y controlado por políticas. CrewAI puede identificar la necesidad de verificación, pero el código confiable debe resolver el destino, clave del sitio, acción de página, puntuación, modo empresarial y configuraciones de red. CapSolver debe ejecutarse una vez por estado validado, el token debe enviarse del lado del servidor y la tripulación debe recibir solo un resultado redactado después de que se verifique la página deseada.
Comience una implementación autorizada con CapSolver, pruébelo en una página controlada y agregue pruebas de parámetros, llamadas duplicadas, redacción y estado de página antes del uso en producción.
CrewAI puede llamar a una herramienta tipada que delegue al ejecutor de CapSolver documentado. Mantenga la resolución del objetivo, secretos, envío del token y verificación dentro del código de aplicación confiable.
La URL de destino y la clave del sitio son obligatorios. La acción de página, puntuación mínima, configuración empresarial, modo de sesión y proxy dependen de la configuración aprobada del objetivo.
No. Observe la acción desde la página aprobada en vivo y compárela con el valor de política del lado del servidor.
No. Envíelo dentro del código confiable y devuelva solo un estado verificado, requerido para revisión o detenido redactado.
Use un intento por estado de aplicación observado por defecto. Un segundo intento debe requerir una nueva observación y una decisión de política explícita.
Revisión de CloakBrowser para 2026 que cubre características, precios, licencias, opciones de implementación, ventajas, limitaciones, alternativas y casos de uso ideales.

Integrar CloakBrowser con CapSolver mediante automatización en Python compatible con Playwright, incluyendo reCAPTCHA v2, tareas de imagen, código y solución de problemas.
