
Sora Fujimoto
AI Solutions Architect

202チャレンジ応答または405CAPTCHA応答を返すことがあります。エージェントにルーティングする前に、ステータスとx-amzn-waf-actionヘッダーの両方を確認してください。capsolver-core上のエージェントアダプターをドキュメント化しており、準備済みのLangChainツールとブラウザ指向の検出およびフィルバックメソッドを提供しています。resolved、not_needed、review、deniedなどの小さなタイプ付き結果のみを提供してください。AWS WAFのチャレンジおよびCAPTCHAアクションは、通常のリクエストパスを変更します。AWS WAFアクションドキュメントによると、有効なトークンを持つリクエストは次のルールに進みます。有効なトークンのないリクエストは、チャレンジ応答を受けることがあります。
チャレンジの場合、AWSはx-amzn-waf-action: challengeの応答ヘッダーとHTTPステータス202をドキュメント化しています。CAPTCHAの場合、x-amzn-waf-action: captchaとステータス405をドキュメント化しています。クライアントがHTMLを期待している場合、AWS WAFはJavaScriptのインターポジットを返すことがあります。成功した相互作用により、トークンが更新され、元のリクエストが再送信されます。
この動作がエージェントに影響を与える理由は、一般的なHTTPクライアントが応答を通常のページ、一時的なサーバーエラー、または空の結果として解釈する可能性があるためです。言語モデルはどのケースが発生したかを推測してはなりません。ホストアプリケーションは応答を分類し、認証を確認し、制御された復元ステップを通じてワークフローをルーティングする必要があります。
目標はチャレンジ処理を目に見えなくすることではなく、明示的で、境界が明確で、観測可能で、運用者が所有するシステムまたはテストに許可されたシステムでのみ合法な自動化に限定することです。
プロダクション設計には5つの別々な責任があります:
CapSolverの公式エージェントツールガイドでは、capsolver-agentをcapsolver-core上の薄いアダプターとして説明しています。コアパッケージはsolve、detect、solve_on_pageなどの操作を実行し、エージェントパッケージはフレームワークに優しいツールスキーマを提供します。ドキュメント化されたLangChain経路はget_langchain_tools()を通じて準備済みのツールを提供します。
この境界は役立ちます。モデルは生の資格情報、トークン、ブラウザオブジェクト、または制限のないネットワーク機能を必要としません。決定論的なアプリケーションコードがツールが実行できるタイミングを制御する間、モデルは狭いツール契約を受け取ります。
エージェントコードを書く前に、運用境界を定義してください:
CAPSOLVER_API_KEYとモデル資格情報のシークレットストア;隔離されたPython環境を使用してください。以下のインストールコマンドは現在のCapSolverエージェントガイドに従います:
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
ソースコード管理から資格情報を別途保存してください:
export CAPSOLVER_API_KEY="set-this-in-your-secret-manager"
export OPENAI_API_KEY="set-this-in-your-secret-manager"
本物のシークレットをプロンプト、トレース、ノートブック、イシュー、チェックポイントに貼り付けないでください。環境変数はローカルの例では便利ですが、展開されたシステムでは管理されたシークレットストアが望ましいです。
最初の決定論的なコンポーネントは応答を分類する必要があります。この例では、AWSがドキュメント化したステータスとヘッダーの組み合わせを使用します:
from dataclasses import dataclass
from typing import Mapping, Literal
WafAction = Literal["challenge", "captcha", "none", "unknown"]
@dataclass(frozen=True)
class WafSignal:
action: WafAction
status_code: int
needs_review: bool = False
def classify_aws_waf_response(
status_code: int,
headers: Mapping[str, str],
) -> WafSignal:
normalized = {key.lower(): value.lower() for key, value in headers.items()}
action = normalized.get("x-amzn-waf-action", "")
if action == "challenge" and status_code == 202:
return WafSignal(action="challenge", status_code=status_code)
if action == "captcha" and status_code == 405:
return WafSignal(action="captcha", status_code=status_code)
if action in {"challenge", "captcha"}:
return WafSignal(
action="unknown",
status_code=status_code,
needs_review=True,
)
return WafSignal(action="none", status_code=status_code)
両方のシグナルを必要とします。202のみは有効なアプリケーション応答である可能性があり、405のみはエンドポイントがHTTPメソッドを許可していないことを意味する可能性があります。予期しない組み合わせは自動復元ループをトリガーするのではなく、レビューに送る必要があります。
AWSは、オリジン間で実行されるブラウザJavaScriptがCORSを介してx-amzn-waf-actionヘッダーにアクセスできないことを指摘しています。このような状況では、ブラウザオートメーション層でネットワーク応答を分類するか、所有する同じオリジンの統合を使用してください。ページテキストのみでチャレンジを推測しないでください。
CapSolverボーナスコードを取得してください
すぐに自動化予算を増やしましょう!
CapSolverアカウントにチャージする際にボーナスコードCAP26を使用すると、すべてのチャージで5%のボーナスが追加されます—制限なし。
CapSolverダッシュボードで今すぐ取得してください
チャレンジ処理は、モデルが言及できるすべてのURLで利用可能にしてはなりません。エージェントツールが実行される前にターゲットをチェックしてください:
from dataclasses import dataclass
from urllib.parse import urlparse
@dataclass(frozen=True)
class PolicyDecision:
allowed: bool
reason: str
ALLOWED_HOSTS = {"staging.example.com", "research.example.org"}
ALLOWED_PURPOSES = {"qa-validation", "authorized-research"}
def authorize_recovery(
url: str,
purpose: str,
attempts: int,
) -> PolicyDecision:
host = (urlparse(url).hostname or "").lower()
if host not in ALLOWED_HOSTS:
return PolicyDecision(False, "host-not-allowed")
if purpose not in ALLOWED_PURPOSES:
return PolicyDecision(False, "purpose-not-allowed")
if attempts >= 2:
return PolicyDecision(False, "retry-budget-exhausted")
return PolicyDecision(True, "authorized")
この関数を言語モデルの外に保持してください。プロダクションでは、バージョン化された構成から承認されたホストと目的を読み込み、別のホストへのリダイレクトを拒否し、非センシティブな決定メタデータのみを記録してください。
ドキュメント化されたエージェントパッケージはLangChain互換ツールを公開できます。最小限の設定は次のようになります:
import os
from capsolver_agent.langchain import get_langchain_tools
capsolver_tools = get_langchain_tools(
api_key=os.environ["CAPSOLVER_API_KEY"],
)
エージェント構築APIはLangChainおよびLangGraphのリリースごとに変更される可能性があります。CapSolverツールの取得を小さなアダプターモジュールに保持し、テスト済みの依存関係バージョンをピン止めし、capsolver_toolsをそのバージョンでサポートされるエージェントビルダーを通じて接続してください。
すべてのエージェントにすべてのツールを提供しないでください。より安全なパターンは、authorize_recovery()がallowed=Trueを返した後で実行される復元サブグラフまたは専用エグゼキューターにのみチャレンジツールを公開することです。
CapSolverは高レベルでエージェントツールマッピングをドキュメント化しています:
solve_captchaはコアのsolve機能を呼び出します;detect_captchasはコアのdetect機能を呼び出します;solve_on_pageはコアのsolve_on_page機能を呼び出します;統合に必要な最小限のツールのみを使用してください。ライブブラウザセッションでは、ブラウザ指向の検出およびフィルバックワークフローはモデルが生の解決を操作するよりも多くのコンテキストを保持する傾向があります。
AWS WAFトークンはクライアントセッションの一部です。AWS WAFトークンドキュメントは、チャレンジおよびCAPTCHAアクションが成功した相互作用を追跡するためにトークンを使用することを説明しています。検出とリトライの間にブラウザを置き換えるか、クッキーを失うとその状態が破棄される可能性があります。
LangChainメッセージまたはグラフチェックポイントにPlaywright Pageをシリアライズしないでください。アプリケーション所有のレジストリに保存してください:
class BrowserRegistry:
def __init__(self) -> None:
self._pages: dict[str, object] = {}
def register(self, page_id: str, page: object) -> None:
self._pages[page_id] = page
def get(self, page_id: str) -> object:
if page_id not in self._pages:
raise KeyError("browser page is not registered")
return self._pages[page_id]
async def close(self, page_id: str) -> None:
page = self._pages.pop(page_id, None)
if page is not None:
await page.close()
エージェント状態には、不透明なpage_id、現在のURL、目的、試行回数、ステータスのみを含めます。クッキー、ローカルストレージ、解決トークン、APIキー、および生のHTMLを含めないでください。
モデルが低レベルの応答を再解釈できないように、小さな結果タイプを使用してください:
from typing import Literal, TypedDict
RecoveryStatus = Literal[
"not_needed",
"authorized",
"resolved",
"retry",
"review",
"denied",
]
class RecoveryState(TypedDict, total=False):
request_id: str
purpose: str
current_url: str
page_id: str
attempts: int
waf_action: str
recovery_status: RecoveryStatus
error_code: str | None
final_assertion_passed: bool
def route_after_detection(state: RecoveryState) -> str:
if state.get("waf_action") not in {"challenge", "captcha"}:
return "continue"
if state.get("recovery_status") == "authorized":
return "recover"
if state.get("recovery_status") in {"denied", "review"}:
return "human_review"
return "authorize"
def route_after_recovery(state: RecoveryState) -> str:
status = state.get("recovery_status")
if status == "resolved":
return "verify"
if status == "retry":
return "authorize"
return "human_review"
復元ノードは承認されたCapSolverブラウザツールを呼び出すことができますが、返されるのはステータスと安定したエラーコードのみです。生のツール応答を次のモデルプロンプトに配置しないでください。
チャレンジの完了は、元のビジネス操作が成功したことを証明しません。同じセッションで意図したナビゲーションまたはリクエストを繰り返し、所有するアプリケーションのシグナルを検証してください:
async def verify_expected_page(page, expected_url_prefix: str) -> bool:
await page.wait_for_load_state("domcontentloaded")
if not page.url.startswith(expected_url_prefix):
return False
marker = page.get_by_test_id("authorized-content")
try:
await marker.wait_for(state="visible", timeout=15_000)
return True
except Exception:
return False
アプリケーションが制御する安定したマーカーを選択してください:テストID、特定のAPI応答、または既知の状態遷移。エラーページが類似した単語を含む可能性があるため、「ページにテキストが含まれている」などの広範なアサーションは避けてください。
検証に失敗した場合、すぐにソルバーを呼び出さないでください。現在の応答を再分類し、セッションが変更されたかを確認し、リトライ予算を強制し、曖昧なケースを人間のレビューに送ってください。
制限付きワークフローは少なくとも次のケースを区別する必要があります:
| 条件 | 推奨経路 |
|---|---|
| AWS WAFシグナルなし | 通常のワークフローを続ける |
| 承認されたホストでの既知のシグナル | 承認された復元ノードを実行する |
| 知らないステータス/ヘッダーコンビネーション | ヒューマンレビュー |
| 承認されていないホストへのリダイレクト | 拒否 |
| チャレンジツールのタイムアウト | リトライ予算が許す限り1回リトライ |
| 復元が成功を報告するがページアサーションに失敗 | 再分類し、レビュー |
| リトライ制限に達した | 停止し、安定したエラーコードを記録 |
| 資格情報またはブラウザセッションが見つからない | 設定エラー; モデルに修復を依頼しない |
一時的なトランスポートエラーには指数バックオフを使用してくださいが、無限ループは使用しないでください。リトライカウンターは決定論的な状態に属し、モデルメモリではありません。
waf_signal_detected、policy_allowed、recovery_started、recovery_finished、page_verifiedなどのイベントをログに記録してください。リクエストID、ホスト、期間、試行回数、エラーコードを含めてください。資格情報、クッキー、トークン、生のチャレンジペイロード、および機密ページコンテンツは除外してください。
エージェントのトレースはワークフローが決定した内容を示します。AWSメトリクスは保護レイヤーが観測した内容を示します。AWSは、チャレンジおよびCAPTCHAアクティビティのCloudWatchメトリクスをリストアップしており、リクエスト、試行、解決、有効トークン数などのカウントが含まれています。詳細は、WAFメトリクスリファレンスを参照してください。
役立つ運用上の質問には、以下のようなものがあります。
内部リクエストIDを使用してシステムを関連付け、資格情報やトークンではなく、内部リクエストIDを使用してください。チャレンジトラフィックの急増は、デフォルトでより大きなリトライ予算を設定するのではなく、診断をトリガーすべきです。
テキストは曖昧で変更しやすいです。ドキュメント化された応答ステータスとヘッダー、ブラウザのネットワークイベント、またはアプリケーション所有のシグナルを優先してください。
新しいブラウザはクッキーとトークンの状態を失う可能性があります。検出、回復、リトライ、検証の間、同じ承認済みセッションを保持してください。
モデルはそれらを必要としません。機械的なアダプタ内で機密値を保持し、タイプ付きステータスを返してください。
常に意図した操作を繰り返し、ドメイン固有のアサーションを確認してください。
ホスト名許可リスト、目的の確認、リダイレクトの確認、リトライ予算の設定、モデルの外でのルートのレビューを強制してください。
LangChainとLangGraphの構築APIは進化しています。テストに合格したバージョンをピン留めし、フレームワークの接続を1つのモジュールに隔離し、アップグレードする前に統合テストを再実行してください。
所有するステージングページを使用し、以下のケースをカバーしてください。
ユニットテストで分類器、ポリシーゲート、検証者をモック化してください。認証された環境でのみ認証付きのエンドツーエンドテストを予約してください。ログもテストしてください:資格情報、クッキー、トークンが存在しないことをアサートしてください。
CapSolverのGetting Startedガイドは、タスクライフサイクルとサポートされているCAPTCHAカテゴリをドキュメント化しています。タスクパスを選択する際には、現在の公式ドキュメントを使用してください。古いスニペットやサードパーティの投稿からフィールドを推測しないでください。
信頼性の高いAWS WAF LangChain統合は、単一の「解決」プロンプトではなく、制御された状態機械です。ドキュメント化されたWAFシグナルを検出、ターゲットと目的を検証、狭くスコープされたツールを呼び出し、同じクライアントセッションを保持し、エージェントが進む前に元の操作を確認してください。
認証された自動化のために、CapSolverは、チャレンジ処理をLangChainに接続するためのエージェントとコアレイヤーを提供します。ポリシー、シークレット、最終的な検証はアプリケーションコードに保持されます。
CapSolverのドキュメントを使用して、現在の統合経路を検証し、所有または明示的に認可されたテスト環境でCapSolverを試してください。チャージアップ時にボーナスコードCAP26を適用すると、設定された5%のボーナスを受け取れます。
Q: LangChainエージェントはAWS WAFチャレンジをどのように検出しますか?
決定的なHTTPまたはブラウザレイヤーでHTTP 202とx-amzn-waf-action: challengeのドキュメント化された組み合わせを確認してください。ページのテキストから条件を言語モデルに推論させないでください。
Q: AWS WAF CAPTCHAアクションを示す応答はどのようなものですか?
AWSは、リクエストに有効なトークンがない場合にHTTP 405とx-amzn-waf-action: captchaをドキュメント化しています。ステータス/ヘッダーの不一致は不明と見なし、レビューにルーティングしてください。
Q: CapSolver APIキーをLangChainモデルに渡すべきですか?
いいえ。承認されたシークレットストアからホストアプリケーションまたはツールアダプタ内で読み込みます。モデルはキー、クッキー、WAFトークン、またはルーディな解決値を見ることになってはいけません。
Q: チャレンジが完了した後、エージェントは新しいブラウザを使用できますか?
可能であれば同じブラウザコンテキストを使用する必要があります。AWS WAFトークンの状態はクライアントセッションに関連付けられているため、セッションを置き換えると、繰り返しリクエストに必要な状態が失われる可能性があります。
Q: 成功したチャレンジツールの結果だけで続行すべきですか?
いいえ。意図した操作を繰り返し、アプリケーション固有の成功アサーションを確認してください。ツールの結果は中間状態に過ぎません。
Q: エージェントはどのくらいリトライすべきですか?
ワークフローのリスクと時間制限に基づいて小さな明示的なリトライ予算を設定してください。例では、アプリケーションポリシーとして2回の試行を使用していますが、これはCapSolverやAWSの保証ではありません。
Q: このワークフローはあらゆるウェブサイトで使用できますか?
いいえ。このワークフローは、所有しているシステムまたは自動化が明示的に許可されているシステムでのみ使用してください。モデルの外でターゲットと目的のチェックを強制し、不明なケースは人間のレビューにルーティングしてください。
ブラウザオートメーションにおけるAmazon AWS WAF CAPTCHAチャレンジの解決をエキスパートの戦略でマスターしましょう。CapSolverを統合して、スムーズで効率的なオートメーションワークフローを学びます。このガイドはトークンベースおよび分類ベースのソリューションをカバーしています。

AWS WAF CAPTCHAおよびチャレンジを解決するための詳細なPHPガイド:信頼性のあるスクリーピングと自動化のために
