CAPSOLVER
Blog
Como resolver o Cloudflare Turnstile nos agentes do LangGraph

Como resolver o Cloudflare Turnstile nos agentes LangGraph

Logo of CapSolver

Adélia Cruz

Neural Network Developer

23-Jul-2026

TL;DR

  • Uma integração de solucionador de Cloudflare Turnstile com LangGraph deve modelar o tratamento de CAPTCHA como um nó de recuperação controlado, não como uma ferramenta sem restrições disponível em todas as rotas.
  • A CapSolver documenta capsolver-agent como a camada de adaptador de ferramentas sobre capsolver-core, com ferramentas da LangChain para frameworks de agentes e métodos de navegador para sessões do Playwright.
  • Mantenha as decisões de navegação no gráfico, a autorização determinística no código da aplicação e a reconhecimento no serviço da CapSolver.
  • Preserve uma sessão do navegador através da detecção, resolução, preenchimento de volta e afirmação final da página; nunca retorne o token bruto para o modelo.
  • Use retriados limitados, estados terminais explícitos, rastreamento redigido e revisão humana para ações que mudem de estado ou sejam ambíguas.
  • O gráfico abaixo inclui definições de estado, roteamento de política, um nó de recuperação da CapSolver, tratamento de falhas e verificação.

O que uma integração LangGraph Cloudflare Turnstile deve fazer

Uma integração LangGraph Cloudflare Turnstile permite que um agente recupere de um passo de verificação dentro de um fluxo de trabalho autorizado do navegador e depois retome a tarefa original. O gráfico não deve pedir ao modelo de linguagem para clicar ou raciocinar sobre o widget. Em vez disso, o modelo ou controlador do navegador detecta que o fluxo está bloqueado, o gráfico avalia a política e um adaptador determinístico chama a capacidade documentada da CapSolver.

CapSolver documenta essa divisão de tarefas em seu guia de ferramentas para agentes: o modelo lida com navegação e decisões, capsolver-agent expõe esquemas de ferramentas e um executor, e capsolver-core realiza detecção, resolução e preenchimento de volta no navegador.

Essa arquitetura dá ao LangGraph um papel útil. Ele pode tornar a recuperação observável, impor orçamentos de retriados, rotear ações sensíveis para um humano e garantir que o navegador verifique o sucesso antes que o gráfico continue.

Pré-requisitos e caminho de integração suportado

Use um ambiente Python isolado. A atual guia oficial da CapSolver instala os pacotes core e agent a partir do GitHub:

bash Copy
python -m venv .venv
source .venv/bin/activate
pip install git+https://github.com/capsolver-ai/capsolver-core.git
pip install "capsolver-agent[langchain] @ git+https://github.com/capsolver-ai/capsolver-agent.git"
pip install langchain-openai langgraph playwright
playwright install chromium

Coloque CAPSOLVER_API_KEY e quaisquer credenciais de modelo em um repositório de segredos aprovado. Não escreva valores reais no estado do gráfico, checkpoints, prompts, eventos de rastreamento ou arquivos de origem.

Você também precisa de:

  • um alvo proprietário ou explicitamente autorizado;
  • uma lista de domínios permitidos;
  • um propósito de negócio definido;
  • um registro de sessão do navegador;
  • um número máximo de retriados;
  • um orçamento de tempo limite;
  • uma afirmação final da página;
  • uma regra de revisão humana para ações significativas.

Projete o estado do LangGraph

Mantenha apenas dados operacionais não secretos no estado do gráfico:

python Copy
from typing import Literal, TypedDict

class AgentState(TypedDict, total=False):
    request_id: str
    purpose: str
    page_id: str
    current_url: str
    step: str
    challenge_detected: bool
    challenge_attempts: int
    challenge_status: Literal[
        "not-needed", "pending", "resolved", "review", "denied"
    ]
    error_code: str | None
    final_assertion_passed: bool

Não adicione a credencial da CapSolver, o token de solução, cookies ou conteúdo bruto da página. Armazene objetos do navegador em um registro proprietário da aplicação, com chave por page_id; os checkpoints do gráfico devem conter apenas o identificador opaco.

Crie um nó de autorização determinístico

A autorização deve ocorrer antes de qualquer ferramenta de desafio:

python Copy
from urllib.parse import urlparse

ALLOWED_HOSTS = {"staging.example.com", "research.example.com"}
ALLOWED_PURPOSES = {"qa-validation", "public-data-research"}

def authorize_challenge(state: AgentState) -> AgentState:
    host = urlparse(state["current_url"]).hostname
    attempts = state.get("challenge_attempts", 0)

    if host not in ALLOWED_HOSTS:
        return {**state, "challenge_status": "denied", "error_code": "domain"}
    if state.get("purpose") not in ALLOWED_PURPOSES:
        return {**state, "challenge_status": "denied", "error_code": "purpose"}
    if attempts >= 2:
        return {**state, "challenge_status": "review", "error_code": "retry-limit"}
    return {**state, "challenge_status": "pending"}

Este nó é validado sintaticamente e independente do modelo. Na produção, carregue a política de configurações versionadas e rejeite campos desconhecidos.

python Copy
class BrowserRegistry:
    def __init__(self):
        self._pages = {}

    def register(self, page_id: str, page) -> None:
        self._pages[page_id] = page

    def get(self, page_id: str):
        if page_id not in self._pages:
            raise KeyError("browser page is not registered")
        return self._pages[page_id]

    async def remove(self, page_id: str) -> None:
        page = self._pages.pop(page_id, None)
        if page is not None:
            await page.close()

O registro evita a serialização de um Page do Playwright e fornece um único local para impor limpeza.

Resgate seu código promocional da CapSolver

Aumente seu orçamento de automação instantaneamente!
Use o código promocional CAP26 ao recarregar sua conta da CapSolver para obter um bônus adicional de 5% em cada recarga — sem limites.
Resgate-o agora em seu Painel da CapSolver
Código promocional

Implemente o nó de recuperação da CapSolver

O SDK Core da CapSolver documenta detect(page) e solve_on_page(page) para o modo de navegador. O adaptador abaixo usa esses métodos e retorna apenas uma decisão do gráfico:

python Copy
import os
from capsolver_core import create_capsolver

async def solve_turnstile_node(
    state: AgentState,
    registry: BrowserRegistry,
) -> AgentState:
    page = registry.get(state["page_id"])
    attempts = state.get("challenge_attempts", 0) + 1

    async with create_capsolver(
        api_key=os.environ["CAPSOLVER_API_KEY"],
        default_timeout=120,
        polling_interval=5,
    ) as cap:
        detected = await cap.detect(page)
        if not detected:
            return {
                **state,
                "challenge_attempts": attempts,
                "challenge_status": "not-needed",
                "error_code": None,
            }

        results = await cap.solve_on_page(page)

    failures = [item for item in results if item.error or not item.filled]
    if failures:
        return {
            **state,
            "challenge_attempts": attempts,
            "challenge_status": "review" if attempts >= 2 else "pending",
            "error_code": "fill-back-failed",
        }

    return {
        **state,
        "challenge_attempts": attempts,
        "challenge_status": "resolved",
        "error_code": None,
    }

O código foi verificado sintaticamente, mas não executado com credenciais. Um teste em produção requer uma página aprovada e segredo. O gráfico nunca recebe solution.token.

Verifique o resultado da página

Um token preenchido é um resultado intermediário. Verifique o estado esperado da aplicação:

python Copy
async def verify_page_node(
    state: AgentState,
    registry: BrowserRegistry,
) -> AgentState:
    page = registry.get(state["page_id"])
    try:
        await page.get_by_test_id("authorized-content").wait_for(timeout=15_000)
        return {
            **state,
            "final_assertion_passed": True,
            "step": "continue",
            "error_code": None,
        }
    except Exception:
        return {
            **state,
            "final_assertion_passed": False,
            "challenge_status": "review",
            "error_code": "page-assertion-failed",
        }

Use uma afirmação pertencente à sua aplicação. Evite seletores que exponham conteúdo de página pessoal ou sensível nos logs.

Monte o fluxo de trabalho do LangGraph

python Copy
from langgraph.graph import END, StateGraph

def route_after_authorization(state: AgentState) -> str:
    if state["challenge_status"] == "pending":
        return "solve"
    if state["challenge_status"] in {"denied", "review"}:
        return "human_review"
    return "verify"

def route_after_solve(state: AgentState) -> str:
    if state["challenge_status"] == "resolved":
        return "verify"
    if state["challenge_status"] == "pending":
        return "authorize"
    return "human_review"

def build_graph(authorize, solve, verify, human_review):
    graph = StateGraph(AgentState)
    graph.add_node("authorize", authorize)
    graph.add_node("solve", solve)
    graph.add_node("verify", verify)
    graph.add_node("human_review", human_review)
    graph.set_entry_point("authorize")
    graph.add_conditional_edges(
        "authorize",
        route_after_authorization,
        {"solve": "solve", "verify": "verify", "human_review": "human_review"},
    )
    graph.add_conditional_edges(
        "solve",
        route_after_solve,
        {"authorize": "authorize", "verify": "verify", "human_review": "human_review"},
    )
    graph.add_edge("verify", END)
    graph.add_edge("human_review", END)
    return graph.compile()

As funções injetadas podem fechar sobre o registro do navegador. A injeção de dependência torna as políticas e rotas de falha testáveis sem um serviço ativo.

Adicione um nó de revisão humana

O revisor deve receber:

  • ID da solicitação;
  • propósito aprovado;
  • hostname;
  • ação tentada;
  • contagem de retriados;
  • categoria de erro redigida;
  • referência de captura de tela segura, se permitida;
  • próximo passo proposto.

O revisor não deve receber a credencial da CapSolver ou o token de solução. Uma ação que mude o estado, como envio, compra, alteração de conta ou envio de mensagem, deve exigir sua própria autorização mesmo após a verificação ser bem-sucedida.

Teste o gráfico sem chamar serviços externos

Testes unitários podem substituir o nó de resolução por stubs determinísticos:

python Copy
async def solved_stub(state: AgentState) -> AgentState:
    return {
        **state,
        "challenge_attempts": state.get("challenge_attempts", 0) + 1,
        "challenge_status": "resolved",
        "error_code": None,
    }

async def failed_stub(state: AgentState) -> AgentState:
    return {
        **state,
        "challenge_attempts": state.get("challenge_attempts", 0) + 1,
        "challenge_status": "review",
        "error_code": "fixture-failure",
    }

Teste domínios aprovados e negados, propósitos não suportados, exaustão de retriados, páginas do navegador ausentes, desafio resolvido com afirmação de página falha e limpeza após estados terminais.

Use o modo de token quando os parâmetros da página forem conhecidos

O modo de navegador é apropriado quando o agente já controla uma página do Playwright. O modo de token pode ser mais simples quando seu aplicativo conhece a URL e a chave pública da página Turnstile. A CapSolver documenta a tarefa AntiTurnstileTaskProxyLess com websiteURL e websiteKey obrigatórios, mais metadata.action e metadata.cdata opcionais.

Não deixe o modelo inventar esses campos. Extraia-os de forma determinística da página aprovada ou da configuração do aplicativo.

Observabilidade sem vazamento de segredos

Rastreie:

  • nó do gráfico;
  • ID da solicitação;
  • decisão de política;
  • hostname;
  • tipo de desafio;
  • número de tentativas;
  • tempo decorrido;
  • categoria de erro;
  • booleano de preenchimento de volta;
  • booleano de afirmação final.

Não rastreie prompts contendo credenciais, cookies do navegador, tokens brutos ou dados de formulário não redigidos. Defina regras de retenção e acesso para capturas de tela e evidências do DOM.

Modos de falha e soluções

Nenhum desafio detectado

Confirme que a página terminou de carregar, o navegador usa a sessão desejada e a versão do SDK suporta o tipo de desafio. Trate um resultado de detecção vazio como not-needed somente quando a afirmação da página ainda puder passar.

Tarefa falha antes de estar pronta

Registre a categoria de erro, compare os parâmetros com a documentação atual da CapSolver e pare após o orçamento de retriados. Não aumente automaticamente os retriados.

Preenchimento de token falha

Mantenha a mesma página do navegador, revise o comportamento de callback ou widget e verifique se a navegação da página não substituiu o contexto.

Gráfico loop infinito

Armazene e impeça challenge_attempts. Roteie para revisão humana após o limite configurado.

Verificação bem-sucedida, mas ação de negócio falha

Mantenha a recuperação de CAPTCHA separada da ação subsequente. O gráfico deve apresentar o erro da ação em vez de reresolver o desafio.

Checklist de produção

  • Fixe versões de dependência ou commits.
  • Use políticas separadas para staging e produção.
  • Armazene segredos fora do estado do gráfico.
  • Restrinja domínios e propósitos.
  • Defina prazos por chamada e total.
  • Preservar uma sessão do navegador.
  • Redigir tokens e cookies.
  • Verificar a página após o preenchimento de volta.
  • Adicionar revisão humana para ações significativas.
  • Testar limpeza e cancelamento.
  • Monitorar taxas de negação, erro, recuperação e afirmação.
  • Revisar mudanças de política como código.

Conclusão: faça o tratamento de desafio um estado de recuperação do gráfico

Uma integração LangGraph Cloudflare Turnstile é mais confiável quando se comporta como um fluxo de recuperação finito: detectar, autorizar, resolver, verificar, continuar ou parar. O gráfico fornece roteamento e observabilidade; código determinístico fornece política; a CapSolver fornece a camada de reconhecimento documentada.

Use a CapSolver apenas para automação legal e autorizada. Revise a documentação atual das ferramentas para agentes, guia do SDK Core e tutoriais relacionados da CapSolver blog antes de fixar uma implementação.

Perguntas frequentes

Q: O LangGraph resolve o Cloudflare Turnstile por conta própria?

Não. O LangGraph controla o estado e o roteamento do fluxo de trabalho; o adaptador da CapSolver chama o serviço de reconhecimento e métodos do navegador.

Q: O token de solução deve ser retornado para o modelo?

Não. Aplicá-lo dentro do adaptador do navegador controlado e retornar apenas status, categoria de erro e resultado da verificação.

Q: Qual método da CapSolver é usado com o Playwright?

O SDK Core atual documenta detect(page), get_captcha_info(page) e solve_on_page(page) para o modo de navegador.

Q: Quantos retriados o gráfico deve permitir?

Use um orçamento pequeno e explícito baseado no seu fluxo e roteie para revisão em vez de permitir um loop sem limite.

Q: O agente pode chamar o nó de recuperação para qualquer URL?

Não. Impõe uma lista de domínios e propósitos permitidos antes que o nó possa invocar a CapSolver.

Q: O que comprova que o desafio foi tratado com sucesso?
Uma asserção de aplicação no nível da página demonstra a recuperação de fluxo de trabalho; o status do provedor ou um token preenchido sozinhos não são suficientes.

Declaração de Conformidade: As informações fornecidas neste blog são apenas para fins informativos. A CapSolver está comprometida em cumprir todas as leis e regulamentos aplicáveis. O uso da rede CapSolver para atividades ilegais, fraudulentas ou abusivas é estritamente proibido e será investigado. Nossas soluções de resolução de captcha melhoram a experiência do usuário enquanto garantem 100% de conformidade ao ajudar a resolver dificuldades de captcha durante a coleta de dados públicos. Incentivamos o uso responsável de nossos serviços. Para mais informações, visite nossos Termos de Serviço e Política de Privacidade.

Mais