CAPSOLVER
博客
如何在AutoGen代理中解决Cloudflare Turnstile问题

如何在 AutoGen 智能体中解决 Cloudflare 人机验证

Logo of CapSolver

Ethan Collins

How to use CapSolver

25-Aug-2026

TL;DR

  • 使用 AutoGen 注册一个狭窄的 solve_turnstile Python 函数,而不是允许代理编写任意求解代码。
  • 使用 CapSolver 的文档中 AntiTurnstileTaskProxyLess 任务,提供 websiteURLwebsiteKey
  • 仅在授权页面上存在 Turnstile 的 actioncdata 时包含这些可选参数。
  • 将解决方案令牌返回给确定性浏览器层,该层应注入令牌并提交原始工作流。
  • 将 API 密钥、浏览器会话和目标权限保留在语言模型提示之外。

引言

在 AutoGen 中最安全的解决 Cloudflare Turnstile 的方法是将 CapSolver 注册为类型化、作用域狭窄的函数工具。AutoGen 可以决定工作流是否需要 Turnstile 解决方案,但确定性的 Python 代码应验证目标 URL 和站点密钥,创建文档中的 AntiTurnstileTaskProxyLess,并仅返回结果令牌。然后浏览器层将该令牌应用于相同的授权工作流并继续。这种架构遵循 CapSolver AI 代理文档的“模型决定,核心执行”边界和 AutoGen 的官方工具注册模型。在本指南中,您将创建求解函数,将其注册到调用者和执行者代理,处理可选的小部件元数据,添加有限重试,并设计生产控制措施,以防止凭证或无限制目标到达模型。

为什么使用工具而不是代理生成的代码?

AutoGen 工具是代理可以调用的预定义函数。 官方 AutoGen 工具使用指南 解释了工具比允许代理生成任意可执行代码更有效地限制代理可以执行的操作。使用类型提示和简洁的描述来自动创建工具模式。

这种边界对于挑战处理尤为重要。代理不应收到您的 CapSolver API 密钥,选择任意网站,或直接控制浏览器上下文。它只能为已由自动化工作流批准的页面请求解决方案。

CapSolver AI 博客 涵盖了面向代理的模式,CapSolver AI 和自动化 FAQ 解释了求解工具如何融入受控自动化。

你需要的 Cloudflare Turnstile 参数

CapSolver 的 官方 Turnstile 文档 指定了无代理任务类型 AntiTurnstileTaskProxyLess。必需的参数是 websiteURLwebsiteKey。可选元数据可以包括小部件的 actioncdata 值。

参数 必需 来源 目的
type 固定值 必须是 AntiTurnstileTaskProxyLess
websiteURL 当前授权页面 将令牌与目标页面关联
websiteKey Turnstile 小部件 识别站点的 Turnstile 配置
metadata.action data-action 属性 保留小部件使用的操作值
metadata.cdata data-cdata 属性 保留附加到小部件的客户数据

Cloudflare 文档描述了托管的、非交互式和不可见的小部件模式。 Cloudflare Turnstile 概述 描述了小部件如何评估浏览器信号并为服务器端验证生成令牌。CapSolver 自动处理支持的子类型,因此任务不需要子类型字段。

安装 AutoGen 和 CapSolver

bash 复制代码
pip install pyautogen capsolver

将凭证存储在环境变量中:

bash 复制代码
export CAPSOLVER_API_KEY="CAP-xxxxxxxxxxxxxxxx"
export OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxx"

对于用户提供的文档中描述的新版 CapSolver 代理架构,团队还可以安装核心和适配器包:

bash 复制代码
pip install git+https://github.com/capsolver-ai/capsolver-core.git
pip install git+https://github.com/capsolver-ai/capsolver-agent.git

下面的直接 capsolver.solve() 函数使用官方的 Turnstile 任务字段,并作为 AutoGen 工具包装。这使框架集成简单,并使任务负载易于审计。

创建类型化的 Turnstile 求解函数

模型应仅接收非秘密输入。CapSolver 密钥保留在函数的运行时环境中。

python 复制代码
import os
from typing import Annotated
from urllib.parse import urlparse

import capsolver

capsolver.api_key = os.environ["CAPSOLVER_API_KEY"]

ALLOWED_HOSTS = {
    "staging.example.com",
    "app.example.com",
}


def solve_turnstile(
    website_url: Annotated[str, "包含 Turnstile 的批准页面 URL"],
    website_key: Annotated[str, "小部件的 Turnstile 站点密钥"],
    action: Annotated[str, "可选的 data-action 值"] = "",
    cdata: Annotated[str, "可选的 data-cdata 值"] = "",
) -> dict:
    """为批准的页面求解 Turnstile 并返回令牌。"""
    parsed = urlparse(website_url)
    if parsed.scheme != "https" or parsed.hostname not in ALLOWED_HOSTS:
        return {
            "success": False,
            "error": "目标不在批准的主机允许列表中",
        }

    if not website_key.startswith("0x4"):
        return {
            "success": False,
            "error": "意外的 Turnstile 站点密钥格式",
        }

    task = {
        "type": "AntiTurnstileTaskProxyLess",
        "websiteURL": website_url,
        "websiteKey": website_key,
    }

    metadata = {}
    if action:
        metadata["action"] = action
    if cdata:
        metadata["cdata"] = cdata
    if metadata:
        task["metadata"] = metadata

    try:
        solution = capsolver.solve(task)
        token = solution.get("token")
        if not token:
            return {"success": False, "error": "未返回 Turnstile 令牌"}
        return {
            "success": True,
            "token": token,
            "solution_type": solution.get("type", "turnstile"),
        }
    except Exception as exc:
        return {"success": False, "error": str(exc)}

允许列表是故意设置的。没有它,提示可能会指示代理提交无关的目标。生产系统可以从租户配置、作业权限或签名的工作流清单中构建允许列表。

使用 AutoGen 注册函数

AutoGen 的经典 AgentChat API 将提出工具调用的代理与执行它的执行者分开。官方文档提供了 register_function() 作为将同一函数注册到两个代理的便捷方式。

python 复制代码
import os
from autogen import ConversableAgent, register_function

assistant = ConversableAgent(
    name="TurnstileCoordinator",
    system_message=(
        "仅继续批准的自动化工作流。"
        "当应用程序报告 Turnstile 小部件并提供确切的页面 URL 和站点密钥时,仅调用 solve_turnstile。"
        "永远不要虚构目标或请求凭证。"
        "如果工具失败两次,请停止并请求操作员审查。"
    ),
    llm_config={
        "config_list": [{
            "model": "gpt-4o-mini",
            "api_key": os.environ["OPENAI_API_KEY"],
        }]
    },
)

executor = ConversableAgent(
    name="TurnstileToolExecutor",
    llm_config=False,
    human_input_mode="NEVER",
)

register_function(
    solve_turnstile,
    caller=assistant,
    executor=executor,
    name="solve_turnstile",
    description=(
        "使用其确切的站点密钥和可选的 action/cdata 值,为批准的 HTTPS 页面求解 Cloudflare Turnstile。"
    ),
)

AutoGen 从函数签名和类型注释生成工具模式。保持描述操作性和具体性,以便模型了解何时适合使用该工具。

对于其他框架模式,请查看 CapSolver 自动化教程CapSolver 产品页面

启动工具调用对话

浏览器或编排层应检测小部件并提供确切参数。模型不应检查秘密或刮取任意页面以发现目标。

python 复制代码
chat_result = executor.initiate_chat(
    assistant,
    message=(
        "批准的测试工作流遇到了 Cloudflare Turnstile。\n"
        "website_url=https://staging.example.com/account-check\n"
        "website_key=0x4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
        "action=account_check\n"
        "cdata=\n"
        "调用注册的工具一次并返回结构化结果。"
    ),
    max_turns=4,
)

在生产设计中,结构化的应用程序代码应从验证的运行时数据构造此消息。不要直接从不受信任的自然语言输入接受站点密钥或目标 URL。

在浏览器层应用令牌

Turnstile 令牌通常由原始表单或服务器请求消耗。确切的集成取决于授权的应用程序。对于浏览器工作流,将返回的令牌传回知道小部件和提交路径的确定性代码。

python 复制代码
async def apply_turnstile_token(page, token: str):
    await page.evaluate(
        """
        (token) => {
          const response = document.querySelector(
            'input[name="cf-turnstile-response"]'
          );
          if (!response) {
            throw new Error('Turnstile response field not found');
          }
          response.value = token;
          response.dispatchEvent(new Event('input', { bubbles: true }));
          response.dispatchEvent(new Event('change', { bubbles: true }));
        }
        """,
        token,
    )

一些应用程序使用基于回调的渲染或服务器管理的提交。请针对您自己的测试应用进行测试,并遵循其支持的集成方式,而不是假设设置隐藏字段就足够了。Cloudflare 的 服务器端验证文档 解释了站点所有者必须通过 Siteverify 验证令牌。

CapSolver Turnstile 指南 提供了进一步的实现上下文,CapSolver 故障排除 FAQ 帮助诊断无效或被拒绝的令牌。

添加有限重试和结构化错误

不要允许代理无限重试。限制尝试次数并分类失败,以便自动化可以安全停止。

python 复制代码
import asyncio

MAX_ATTEMPTS = 2

async def solve_with_policy(params: dict) -> dict:
    last_error = "未知错误"

    for attempt in range(1, MAX_ATTEMPTS + 1):
        result = solve_turnstile(**params)
        if result.get("success"):
            return {
                **result,
                "attempt": attempt,
            }

        last_error = result.get("error", last_error)
        if "allowlist" in last_error or "site-key" in last_error:
            break
        await asyncio.sleep(2 * attempt)

    return {
        "success": False,
        "error": last_error,
        "requires_operator_review": True,
    }

仅记录安全元数据:目标主机名、任务类型、持续时间、结果、标准化错误和尝试次数。不要记录完整解决方案令牌、API 密钥、会话 cookie 或表单内容。

附加代码:在 CapSolver 仪表板 上使用代码 WEBS,每次充值可获得额外 5% 的奖励。

生产检查清单

控制 推荐实现
目标授权 HTTPS 主机允许列表或签名作业清单
密钥隔离 CapSolver 密钥仅对执行者进程可用
工具模式 类型化参数,简洁描述
可选元数据 仅在小部件使用时发送 actioncdata
重试策略 最多两次尝试,然后人工审查
令牌处理 永远不要在日志中存储或暴露完整令牌
浏览器集成 在同一批准工作流中应用令牌
合规性 尊重条款、速率限制、隐私和用途限制

CapSolver CAPTCHA 求解 FAQ 解释了通用任务行为,CapSolver 网络爬虫 FAQ 涵盖了自动化收集的操作控制。

负责任的使用

仅在您拥有、测试或明确授权自动化的应用程序上使用此工作流。求解令牌不授予访问私有数据、提交交易、创建账户或忽略站点条款的授权。应用速率限制,保留审计记录,并在更改数据或影响用户的操作上要求确认。

结论

为了在 AutoGen 中可靠地解决 Cloudflare Turnstile,应将 CapSolver 作为受约束的工具,而不是开放的代理逻辑。AutoGen 助手决定何时适合使用该工具,执行者运行验证的 AntiTurnstileTaskProxyLess,浏览器层在相同的授权工作流中消耗结果令牌。这种分工使集成更容易测试、审计和保护。

CapSolver 开始,针对您控制的测试页面验证流程,并在生产部署前添加主机允许列表、有限重试和令牌安全日志。

FAQ

CapSolver 的 Turnstile 任务是否需要代理?

文档中的任务类型是 AntiTurnstileTaskProxyLess,因此您不需要向任务提供代理。您的更广泛的浏览器工作流可能仍有自己的网络配置。

任务需要哪些字段?

websiteURLwebsiteKey 是必需的。metadata.actionmetadata.cdata 是可选的,仅在小部件使用它们时提供。

AutoGen 能否自动发现站点密钥?

更安全的设计是确定性浏览器或应用程序层提取并验证站点密钥,然后将其提供给工具。不要让模型发明或猜测该值。

为什么使用单独的调用者和执行者代理?

调用者可以提出工具调用,而执行者运行无 LLM 的受控 Python 代码。这将秘密和运行时权限远离推理代理。

如果返回的令牌被拒绝会发生什么?

确认页面网址、站点密钥、可选操作或CDATA、令牌新鲜度和提交路径。最多重试一次或两次,然后暂停以等待操作员审核,而不是循环。

合规声明: 本博客提供的信息仅供参考。CapSolver 致力于遵守所有适用的法律和法规。严禁以非法、欺诈或滥用活动使用 CapSolver 网络,任何此类行为将受到调查。我们的验证码解决方案在确保 100% 合规的同时,帮助解决公共数据爬取过程中的验证码难题。我们鼓励负责任地使用我们的服务。如需更多信息,请访问我们的服务条款和隐私政策。

更多