
Emma Foster
Machine Learning Engineer

capsolver-agent sebagai lapisan adapter alat atas capsolver-core, dengan alat LangChain untuk kerangka agen dan metode browser untuk sesi Playwright.Integrasi LangGraph Cloudflare Turnstile memungkinkan agen untuk pulih dari langkah verifikasi di dalam alur kerja browser yang diizinkan, lalu melanjutkan tugas asli. Grafik tidak boleh meminta model bahasa untuk mengklik atau merenungkan widget. Sebaliknya, model atau pengontrol browser mendeteksi bahwa alur kerja terblokir, graf mengevaluasi kebijakan, dan adapter deterministik memanggil kemampuan CapSolver yang didokumentasikan.
CapSolver mendokumentasikan pembagian tugas ini dalam panduan alat agen: model menangani navigasi dan keputusan, capsolver-agent mengekspos skema alat dan executor, dan capsolver-core melakukan deteksi, penyelesaian, dan pengisian kembali browser.
Arsitektur ini memberikan peran yang berguna bagi LangGraph. Ia dapat membuat pemulihan teramati, memaksa anggaran ulang coba, mengarahkan tindakan sensitif ke manusia, dan memastikan browser memverifikasi keberhasilan sebelum graf dilanjutkan.
Gunakan lingkungan Python terisolasi. Panduan resmi CapSolver saat ini menginstal paket inti dan agen dari GitHub:
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
Tempatkan CAPSOLVER_API_KEY dan kredensial model apa pun di penyimpanan rahasia yang disetujui. Jangan menulis nilai nyata ke state graf, titik pemeriksaan, prompt, peristiwa pelacakan, atau file sumber.
Anda juga memerlukan:
Hanya simpan data operasional yang tidak rahasia dalam state graf:
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[
"tidak-diperlukan", "menunggu", "diselesaikan", "ulasan", "ditolak"
]
error_code: str | None
final_assertion_passed: bool
Jangan tambahkan kredensial CapSolver, token solusi, cookie, atau konten halaman mentah. Simpan objek browser dalam daftar yang dikelola aplikasi berdasarkan page_id; titik pemeriksaan graf hanya harus berisi identifikasi yang tidak terlihat.
Otorisasi harus dijalankan sebelum alat tantangan apa pun:
from urllib.parse import urlparse
ALLOWED_HOSTS = {"staging.example.com", "research.example.com"}
ALLOWED_PURPOSES = {"validasi-qa", "penelitian-data-publik"}
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": "ditolak", "error_code": "domain"}
if state.get("purpose") not in ALLOWED_PURPOSES:
return {**state, "challenge_status": "ditolak", "error_code": "tujuan"}
if attempts >= 2:
return {**state, "challenge_status": "ulasan", "error_code": "batas-ulang"}
return {**state, "challenge_status": "menunggu"}
Node ini diverifikasi sintaks dan independen dari model. Dalam produksi, muat kebijakan dari konfigurasi yang diberi versi dan tolak bidang yang tidak dikenal.
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("halaman browser tidak terdaftar")
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()
Daftar ini mencegah serialisasi objek Playwright Page dan memberikan tempat tunggal untuk memaksa pembersihan.
Klaim Kode Bonus CapSolver Anda
Tingkatkan anggaran otomasi Anda secara instan!
Gunakan kode bonus CAP26 saat menambahkan akun CapSolver Anda untuk mendapatkan tambahan 5% bonus pada setiap penambahan — tanpa batas.
Klaim sekarang di Dasbor CapSolver Anda
SDK Core CapSolver mendokumentasikan detect(page) dan solve_on_page(page) untuk mode browser. Adapter di bawah ini menggunakan metode ini dan hanya mengembalikan keputusan graf:
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": "tidak-diperlukan",
"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": "ulasan" if attempts >= 2 else "menunggu",
"error_code": "pengisian-kembali-gagal",
}
return {
**state,
"challenge_attempts": attempts,
"challenge_status": "diselesaikan",
"error_code": None,
}
Kode ini telah diverifikasi sintaks tetapi tidak dijalankan dengan kredensial. Uji hidup memerlukan halaman yang disetujui dan rahasia. Graf tidak pernah menerima solution.token.
Token yang diisi adalah hasil sementara. Verifikasi keadaan yang diharapkan aplikasi:
async def verify_page_node(
state: AgentState,
registry: BrowserRegistry,
) -> AgentState:
page = registry.get(state["page_id"])
try:
await page.get_by_test_id("konten-terotorisasi").wait_for(timeout=15_000)
return {
**state,
"final_assertion_passed": True,
"step": "lanjutkan",
"error_code": None,
}
except Exception:
return {
**state,
"final_assertion_passed": False,
"challenge_status": "ulasan",
"error_code": "pengecekan-halaman-gagal",
}
Gunakan pengecekan yang dimiliki aplikasi Anda. Hindari selektor yang mengekspos konten halaman pribadi atau sensitif dalam log.
from langgraph.graph import END, StateGraph
def route_after_authorization(state: AgentState) -> str:
if state["challenge_status"] == "menunggu":
return "selesaikan"
if state["challenge_status"] in {"ditolak", "ulasan"}:
return "ulasan_manusia"
return "verifikasi"
def route_after_solve(state: AgentState) -> str:
if state["challenge_status"] == "diselesaikan":
return "verifikasi"
if state["challenge_status"] == "menunggu":
return "otorisasi"
return "ulasan_manusia"
def build_graph(authorize, solve, verify, human_review):
graph = StateGraph(AgentState)
graph.add_node("otorisasi", authorize)
graph.add_node("selesaikan", solve)
graph.add_node("verifikasi", verify)
graph.add_node("ulasan_manusia", human_review)
graph.set_entry_point("otorisasi")
graph.add_conditional_edges(
"otorisasi",
route_after_authorization,
{"selesaikan": "selesaikan", "verifikasi": "verifikasi", "ulasan_manusia": "ulasan_manusia"},
)
graph.add_conditional_edges(
"selesaikan",
route_after_solve,
{"otorisasi": "otorisasi", "verifikasi": "verifikasi", "ulasan_manusia": "ulasan_manusia"},
)
graph.add_edge("verifikasi", END)
graph.add_edge("ulasan_manusia", END)
return graph.compile()
Fungsi yang dimasukkan dapat menutup daftar sesi browser. Injeksi dependensi membuat kebijakan dan jalur kegagalan dapat diuji tanpa layanan hidup.
Reviewer harus menerima:
Reviewer tidak boleh menerima kredensial CapSolver atau token solusi. Tindakan yang mengubah status seperti pengiriman, pembelian, perubahan akun, atau pengiriman pesan harus memerlukan otorisasi sendiri bahkan setelah verifikasi berhasil.
Uji unit dapat mengganti node selesaikan dengan stub deterministik:
async def selesaikan_stub(state: AgentState) -> AgentState:
return {
**state,
"challenge_attempts": state.get("challenge_attempts", 0) + 1,
"challenge_status": "diselesaikan",
"error_code": None,
}
async def gagal_stub(state: AgentState) -> AgentState:
return {
**state,
"challenge_attempts": state.get("challenge_attempts", 0) + 1,
"challenge_status": "ulasan",
"error_code": "kesalahan-contoh",
}
Uji domain yang disetujui dan ditolak, tujuan yang tidak didukung, kehabisan ulang coba, halaman browser yang hilang, tantangan yang diselesaikan tetapi pengecekan halaman gagal, dan pembersihan setelah status terminal.
Mode browser sesuai ketika agen sudah mengendalikan halaman Playwright. Mode token bisa lebih sederhana ketika aplikasi Anda mengetahui URL halaman Turnstile dan kunci situs publik. CapSolver mendokumentasikan tugas AntiTurnstileTaskProxyLess dengan websiteURL dan websiteKey yang diperlukan, plus metadata.action dan metadata.cdata opsional.
Jangan biarkan model menciptakan bidang ini. Ekstrak secara deterministik dari halaman yang disetujui atau konfigurasi aplikasi.
Lacak:
Jangan lacak prompt yang berisi kredensial, cookie browser, token mentah, atau data formulir yang tidak dirahasiakan. Tetapkan aturan retensi dan akses untuk screenshot dan bukti DOM.
Pastikan halaman selesai dimuat, browser menggunakan sesi yang dimaksud, dan versi SDK mendukung jenis tantangan. Anggap hasil deteksi kosong sebagai "tidak diperlukan" hanya jika pengecekan halaman masih bisa berhasil.
Catat kategori kesalahan, bandingkan parameter dengan dokumentasi CapSolver saat ini, dan hentikan setelah anggaran ulang coba. Jangan tingkatkan ulang coba secara otomatis.
Pertahankan halaman browser yang sama, tinjau perilaku callback atau widget, dan pastikan navigasi halaman tidak mengganti konteks.
Simpan dan terapkan challenge_attempts. Arahkan ke ulasan manusia setelah batas yang dikonfigurasi.
Pertahankan pemulihan CAPTCHA terpisah dari tindakan downstream. Graf harus menampilkan kesalahan tindakan itu sendiri, bukan menyelesaikan tantangan lagi.
Integrasi LangGraph Cloudflare Turnstile paling andal ketika berperilaku seperti alur kerja pemulihan terbatas: deteksi, otorisasi, selesaikan, verifikasi, lanjutkan, atau hentikan. Graf menyediakan routing dan observabilitas; kode deterministik menyediakan kebijakan; CapSolver menyediakan lapisan pengenalan yang didokumentasikan.
Gunakan CapSolver hanya untuk otomasi yang sah dan diizinkan. Tinjau dokumentasi alat agen saat ini, panduan SDK Core, dan tutorial blog CapSolver terkait sebelum menetapkan implementasi.
Q: Apakah LangGraph menyelesaikan Cloudflare Turnstile sendiri?
Tidak. LangGraph mengontrol state dan routing alur kerja; adapter CapSolver memanggil layanan pengenalan dan metode browser.
Q: Apakah token solusi dikembalikan ke model?
Tidak. Terapkan di dalam adapter browser yang dikendalikan dan kembalikan hanya status, kategori kesalahan, dan hasil verifikasi.
Q: Metode CapSolver apa yang digunakan dengan Playwright?
SDK Core saat ini mendokumentasikan detect(page), get_captcha_info(page), dan solve_on_page(page) untuk mode browser.
Q: Berapa jumlah ulang coba yang harus graf izinkan?
Gunakan anggaran eksplisit kecil berdasarkan alur kerja Anda dan arahkan ke ulasan daripada memungkinkan loop tak terbatas.
Q: Apakah agen dapat memanggil node pemulihan untuk URL apa pun?
Tidak. Terapkan daftar domain dan tujuan yang diizinkan secara deterministik sebelum node dapat memanggil CapSolver.
Q: Apa yang membuktikan tantangan telah ditangani secara sukses?
Sebuah penyataan aplikasi tingkat halaman membuktikan pemulihan alur kerja; status penyedia atau token yang diisi saja tidak cukup.
Buat alat agen penyelesaian CAPTCHA LangChain dengan CapSolver, skema alat yang aman, anggaran ulang coba, dan verifikasi untuk reCAPTCHA dan Cloudflare Turnstile.

Bangun alur kerja solver CAPTCHA untuk Komputer Claude dengan pengaman CapSolver, ID bukti visual, pemeriksaan kebijakan, dan verifikasi yang andal.
