CAPSOLVER
ブログ
Cloudflare TurnstileをLangGraphエージェントで解決する方法

クラウドフレア トゥルネスティールを解決する方法 ラングラフ エージェントで

Logo of CapSolver

Sora Fujimoto

AI Solutions Architect

23-Jul-2026

TL;DR

  • LangGraph Cloudflare Turnstileソルバーの統合は、CAPTCHA処理を制御された復元ノードとしてモデル化すべきであり、すべてのルートで利用可能な制限のないツールとしては扱わない。
  • CapSolverはcapsolver-agentcapsolver-core上のツールアダプター層としてドキュメント化しており、LangChainツールによるエージェントフレームワークとPlaywrightセッション用のブラウザメソッドを提供している。
  • ナビゲーションの決定はグラフに残し、アプリケーションコードで決定論的な認証を行い、CapSolverサービスで認識処理を行う。
  • 検出、解決、フィルバック、最終的なページ検証を通じて1つのブラウザセッションを保持し、モデルに元のトークンを返さない。
  • 繰り返し制限を設定し、明示的な終了状態を設定し、トレースをマスキングし、状態変更や曖昧なアクションに対して人間のレビューを実施する。
  • 下記の例のグラフには、状態定義、ポリシールーティング、CapSolver復元ノード、失敗処理、検証が含まれている。

LangGraph Cloudflare Turnstile統合が行うべきこと

LangGraph Cloudflare Turnstile統合は、認証されたブラウザワークフロー内で検証ステップから回復し、元のタスクを再開できるエージェントを提供します。グラフは言語モデルにボタンクリックやウィジェットの論理的処理を依頼してはなりません。代わりに、モデルまたはブラウザコントローラーがワークフローがブロックされていることを検出すると、グラフはポリシーを評価し、決定論的なアダプターがドキュメント化されたCapSolver機能を呼び出します。

CapSolverは、エージェントツールガイドでこの労働分業をドキュメント化しています。モデルはナビゲーションと決定を担当し、capsolver-agentはツールのスキーマと実行者を公開し、capsolver-coreは検出、解決、ブラウザフィルバックを担当します。

このアーキテクチャにより、LangGraphは役立つ役割を果たします。復元を観測可能にし、リトライ予算を強制し、センシティブなアクションを人間へルーティングし、グラフが進行する前にブラウザが成功を検証することを保証できます。

必要条件とサポートされる統合経路

隔離されたPython環境を使用してください。CapSolverの現在の公式ガイドでは、コアとエージェントパッケージを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

CAPSOLVER_API_KEYと任意のモデル資格情報を承認されたシークレットストアに配置してください。実際の値をグラフ状態、チェックポイント、プロンプト、トレースイベント、ソースファイルに記述しないでください。

また必要なもの:

  • 所有または明示的に許可されたターゲット;
  • ドメインの許可リスト;
  • 定義されたビジネス目的;
  • ブラウザセッションの登録;
  • 最大リトライ回数;
  • タイムアウト予算;
  • 最終的なページ検証;
  • 重大なアクションのためのヒューマンレビュー規則。

LangGraphの状態を設計する

グラフ状態に非シークレットな運用データのみを保持してください:

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

CapSolverの資格情報、解決トークン、クッキー、または元のページコンテンツを追加しないでください。ブラウザオブジェクトはpage_idをキーにしたアプリケーション所有の登録に保存してください。グラフのチェックポイントにはオパックな識別子のみを含めます。

決定論的な認証ノードを構築する

認証は、すべてのチャレンジツールの前に実行する必要があります:

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"}

このノードは構文検証されており、モデルとは独立しています。本番環境では、バージョン化された構成からポリシーを読み込み、未知のフィールドを拒否してください。

グラフ状態外にブラウザセッションを登録する

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()

この登録はPlaywright Pageのシリアライズを防ぎ、ホストがクリーンアップを強制するための場所を提供します。

CapSolverボーナスコードを取得する

自動化予算を即座に増やす!
CapSolverアカウントにチャージする際にボーナスコード CAP26 を使用すると、すべてのチャージで 5%のボーナス を受け取れます — 限界なし。
CapSolverダッシュボードで今すぐ利用してください
ボーナスコード

CapSolver復元ノードを実装する

CapSolverのCore SDKはブラウザモード用にdetect(page)solve_on_page(page)をドキュメント化しています。以下のアダプターはこれらのメソッドを使用し、グラフの決定のみを返します:

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,
    }

このコードは構文チェックされていますが、資格情報で実行されていません。ライブテストには承認されたページとシークレットが必要です。グラフはsolution.tokenを受信しません。

ページの結果を検証する

フィルされたトークンは中間結果です。アプリケーションの期待される状態を検証してください:

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",
        }

アプリケーション所有のアサーションを使用してください。ログに個人または機密ページコンテンツを露出するセレクターは避けてください。

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()

挿入された関数はブラウザ登録をクロージャーとして保持できます。依存関係の注入により、ライブサービスなしでポリシーと失敗ルートをテスト可能です。

ヒューマンレビューノードを追加する

レビュワーに以下の情報を提供してください:

  • 要求ID;
  • 承認された目的;
  • ホスト名;
  • 実行されたアクション;
  • リトライ回数;
  • マスキングされたエラーカテゴリ;
  • 許可された場合の安全なスクリーンショット参照;
  • 提案された次のステップ。

レビュワーにCapSolverの資格情報や解決トークンを提供しないでください。送信、購入、アカウント変更、メッセージ送信などの状態変更アクションは、検証が成功した後でも独自の認証を必要とします。

外部サービスを呼び出さずにグラフをテストする

ユニットテストでは、solveノードを決定論的なスタブに置き換えることができます:

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",
    }

承認されたドメインと拒否されたドメイン、サポートされていない目的、リトライの枯渇、欠如しているブラウザページ、解決したチャレンジでページ検証が失敗した場合、終了状態後のクリーンアップをテストしてください。

ページパラメータが既知の場合はトークンモードを使用する

エージェントが既にPlaywrightページを制御している場合、ブラウザモードは適切です。アプリケーションがTurnstileページのURLと公開サイトキーを既知の場合は、トークンモードがより単純です。CapSolverはAntiTurnstileTaskProxyLessタスクをドキュメント化しており、必要なwebsiteURLwebsiteKeyに加えて、オプションのmetadata.actionmetadata.cdataを提供しています。

モデルがこれらのフィールドを生成しないようにしてください。これらは承認されたページまたはアプリケーション構成から決定論的に抽出してください。

シークレット漏洩なしの観測性

トレース:

  • グラフノード;
  • 要求ID;
  • ポリシー決定;
  • ホスト名;
  • チャレンジタイプ;
  • トライ回数;
  • 経過時間;
  • エラーカテゴリ;
  • フィルバックブーリアン;
  • 最終的なアサーションブーリアン。

プロンプトに資格情報、ブラウザクッキー、元のトークン、またはマスキングされていないフォームデータをトレースしないでください。スクリーンショットとDOM証拠の保持およびアクセスルールを定義してください。

エラーの種類と修正

チャレンジが検出されない

ページが読み込みが完了したか、ブラウザが意図されたセッションを使用しているか、SDKバージョンがチャレンジタイプをサポートしているかを確認してください。ページアサーションがまだ成功できる場合、空の検出結果はnot-neededとして扱ってください。

タスクが準備できないうちに失敗する

エラーカテゴリを記録し、パラメータを現在のCapSolverドキュメントと比較し、リトライ予算を超えた後は停止してください。自動的にリトライ回数を増やさないでください。

トークンフィルバックに失敗する

同じブラウザページを保持し、コールバックまたはウィジェットの動作をレビューし、ページナビゲーションがコンテキストを置き換えているかを確認してください。

グラフが無限ループする

challenge_attemptsを保存し、設定された制限後にヒューマンレビューにルーティングしてください。

検証が成功するがビジネスアクションが失敗する

CAPTCHA回復を下流アクションから分離してください。グラフはチャレンジの再解決ではなく、アクション固有のエラーを表示する必要があります。

プロダクションチェックリスト

  • 依存関係のバージョンまたはコミットをピン止めしてください。
  • ステージングとプロダクションのポリシーを別々に使用してください。
  • シークレットをグラフ状態から別途保存してください。
  • ドメインと目的を制限してください。
  • コールごとおよび合計のタイムアウトを設定してください。
  • 1つのブラウザセッションを保持してください。
  • トークンとクッキーをマスキングしてください。
  • フィルバック後にページを検証してください。
  • 重大なアクションにヒューマンレビューを追加してください。
  • クリーンアップとキャンセルをテストしてください。
  • 拒否、エラー、回復、アサーションのレートをモニタリングしてください。
  • コード変更などのポリシー変更をレビューしてください。

結論:チャレンジ処理をグラフの復元状態として扱う

LangGraph Cloudflare Turnstile統合は、検出、認証、解決、検証、継続、または停止する有限の復元ワークフローとして動作する場合、最も信頼性が高くなります。グラフはルーティングと観測性を提供し、決定論的なコードはポリシーを提供し、CapSolverはドキュメント化された認識レイヤーを提供します。

CapSolverは、法的で承認された自動化にのみ使用してください。実装をピン止めする前に、現在のエージェントツールドキュメントCore SDKガイド、および関連するCapSolverブログチュートリアルを確認してください。

FAQ

Q: LangGraphはCloudflare Turnstileを自分で解決しますか?

いいえ。LangGraphはワークフローの状態とルーティングを制御し、CapSolverアダプターが認識サービスとブラウザメソッドを呼び出します。

Q: 解決トークンをモデルに返すべきですか?

いいえ。制御されたブラウザアダプター内で適用し、ステータス、エラーカテゴリ、検証結果のみを返してください。

Q: Playwrightで使用されるCapSolverのメソッドはどれですか?

現在のCore SDKはブラウザモード用にdetect(page)get_captcha_info(page)solve_on_page(page)をドキュメント化しています。

Q: グラフはどのくらいのリトライを許可すべきですか?

ワークフローに基づいて小さな明示的な予算を使用し、無制限のループを避けてレビューにルーティングしてください。

Q: エージェントは任意のURLで復元ノードを呼び出せますか?

いいえ。ノードがCapSolverを呼び出す前に、決定論的なドメインと目的の許可リストを強制してください。

Q: チャレンジが成功裏に処理されたことを何が証明しますか?
ページレベルのアプリケーションアサーションはワークフローの復元を証明する; プロバイダのステータスまたは満たされたトークンだけでは十分ではない。

コンプライアンス免責事項: このブログで提供される情報は、情報提供のみを目的としています。CapSolverは、すべての適用される法律および規制の遵守に努めています。CapSolverネットワークの不法、詐欺、または悪用の目的での使用は厳格に禁止され、調査されます。私たちのキャプチャ解決ソリューションは、公共データのクローリング中にキャプチャの問題を解決する際に100%のコンプライアンスを確保しながら、ユーザーエクスペリエンスを向上させます。私たちは、サービスの責任ある使用を奨励します。詳細については、サービス利用規約およびプライバシーポリシーをご覧ください。

もっと見る

TinyFish AgentQでキャプチャを解く
TinyFish AgentQLを使ってCAPTCHAを解決する方法 – CapSolverを使用したステップバイステップガイド

CapSolverをTinyFish AgentQLに統合する方法を学び、reCAPTCHAやCloudflare TurnstileなどのCAPTCHAを自動的に解決する方法を学びましょう。PythonとJavaScript SDKの例を含むステップバイステップのチュートリアルで、シームレスなAI駆動のウェブ自動化を実現します。

ai
Logo of CapSolver

Sora Fujimoto

05-Aug-2026

ラマインデックスのエージェントでキャプチャをどうやって解決するか
LlamaIndexエージェントにおけるCAPTCHAの解決方法

CAPTCHAの解決をLlamaIndexエージェントにFunctionToolとCapSolverを使用してウェブデータのインジェストパイプラインに統合する。

ai
Logo of CapSolver

Sora Fujimoto

31-Jul-2026

CAPTCHAをMCP CapSolverサービスで解決する方法
MCPを使用したCAPTCHAの解き方: キャプソルバー モデル コンテキスト プロトコル サービス

Claude Desktop、Cursor、および任意のMCPクライアントでゼロコードでCAPTCHAを解くためのCapSolver MCPサービスを設定してください。

ai
Logo of CapSolver

Sora Fujimoto

31-Jul-2026

OpenAI Agents SDKにおけるreCAPTCHA v3の解き方
reCAPTCHA v3をOpenAIエージェントSDKで解く方法

OpenAI Agents SDKで、CapSolverのfunction_toolを使用して、高スコアのreCAPTCHA v3トークンを生成します。

ai
Logo of CapSolver

Sora Fujimoto

30-Jul-2026

クラウドフレアトゥルニスティールを解決する方法 クリューAIエージェントで
Cloudflare Turnstile の解決方法: CrewAI エージェントでの

CrewAIのマルチエージェントワークフローにCloudflare Turnstileの解決を統合し、CapSolverを用いて行います。

ai
Logo of CapSolver

Sora Fujimoto

30-Jul-2026

CAPTCHAを解く方法: AutoGen AIエージェントでCapSolverを使う
CAPTCHAを解決する方法: AutoGenエージェント

Microsoft AutoGenのマルチエージェント会話にCAPTCHAの解決を統合する完全なガイド – register_functionとグループチャットのパターンを使用してCapSolverで

ai
Logo of CapSolver

Sora Fujimoto

29-Jul-2026