拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AI代理遇验证码?用本地视觉模型+人工接管实现稳定自动化

如果你最近研究过“AI代理自动下单”的 Demo大概率会栽在同一个环节程序把餐品加进购物车、点开结算页屏幕上弹出一个“确认你不是机器人”的验证框整个流程直接卡死。这不是某个代理框架的 bug而是 AI 代理与反自动化机制的一次正面碰撞。Uber Eats 这类平台使用人机验证目的就是把“看起来不像真人”的访问者挡在交易流程之外。对于开发者来说这件事的关键问题不是“能不能绕过”而是“应该怎么设计架构让 AI 代理在验证码边界上有合规且稳定的工程化处理方案”。所以本文不讨论任何绕过验证码的技巧而是给出一套可落地的思路AI 代理负责大部分自动化操作通过本地视觉模型辅助判断是否出现人机验证一旦检测到验证码就自动暂停并移交人工确认确认后代理继续执行。读完这篇文章你会理解人机验证的识别逻辑也会拿到一套基于 Python Playwright 的最小实现。如果你正在开发 Agent 应用尤其涉及登录、下单、支付这类高风控场景这篇文章的内容可以直接用于你的项目设计。1. AI 代理下单为什么会撞上人机验证首先要明确一个事实Uber Eats 这类平台并不恨“自动化工具”它们真正在意的是“不可信行为”。一个 AI 代理下单时访问节奏、鼠标轨迹、页面停留时间、浏览器指纹都和一个正常用户有明显差异风控系统很容易把它判定为非真人操作。AI 代理的常见工作方式是“大模型规划 浏览器自动化执行”。大模型把“帮我点一份晚餐”拆成多个子任务打开外卖平台、搜索餐厅、选择餐品、加入购物车、进入结算、确认支付。每一个子任务看起来都很简单但组合起来行为特征就会暴露自动化本质。例如一个正常用户从打开页面到点击结算中间通常会有几秒钟的犹豫和鼠标移动而 AI 代理调用 Playwright 执行点击时动作间隔非常稳定几乎没有任何噪声。风控系统正是从这些信号里识别出代理痕迹。人机验证出现的时机也比较有规律登录时、加购后、结算前、支付前。对 AI 代理来说越接近交易核心环节风控强度越高。所以“下单到一半被验证码拦住”不是偶然而是平台有意设置的关键节点。如果我们把 AI 代理的落地当成一个工程问题验证码就是一个外部依赖的“故障点”。它无法被彻底消灭只可以被工程化处理。因此与其纠结用更强大的模型去识别验证码不如先接受一个前提验证码是代理流程中的一个状态而不是需要“破解”的障碍。2. 人机验证到底在验证什么很多开发者把验证码理解成“图片识别题”认为只要视觉模型足够强就能自动完成验证。这个理解在技术上不完整在合规上也存在明显风险。人机验证的核心是“信任评估”不是单纯识别图片。平台会综合设备指纹、IP 信誉、浏览器自动化标记、用户行为轨迹、当前会话风险等级最后才会决定是否弹出验证码。即使 AI 代理能认出图片里的斑马线也无法伪造一个真实可信的浏览器环境。常见的人机验证类型可以参考下面这张表验证码类型基本机制对 AI 代理的挑战文字识别类识别扭曲字符视觉模型可能识别但自动化识别用户协议通常不允许图像选择类从多张图中选出目标物体需要视觉理解能力且行为轨迹仍然可疑滑动拼图类拖动滑块到缺口位置表面是图片理解实际更多是行为轨迹分析复选框类点击“我不是机器人”通常结合设备指纹和行为分析点击本身很简单隐形验证码无弹窗后台持续评估代理可能在毫无感知的情况下被降低权限或拉黑二次验证短信、邮箱、扫码确认需要真实身份凭证自动化无法替代从这张表可以看出验证码早已不是“看得懂图片”就能解决的问题。一个 AI 代理即使通过视觉模型读出了滑块缺口也会因为拖动轨迹过于直线、速度过快、缺少人类抖动而被风控系统拦截。这里有一个关键判断人机验证是平台设置的“信任边界”不是一道客观存在的数学题。它背后的参数对开发者并不透明这意味着任何尝试用固定规则绕过验证码的方案都会随着平台策略升级而失效。本地视觉模型在其中的合理定位应该是检测“页面上是否出现了人机验证”并把这一信号交给流程管理器而不是去生成验证答案。这样既利用了视觉模型的能力又没有越界。3. AI 代理助手加本地模型的分层架构最近“AI 代理助手加本地模型”这个方向很热核心原因是纯云端方案在真实 Agent 场景里会遇到延迟、成本和隐私问题。如果你让云端大模型持续观察浏览器截图、判断每一步结果推理费用会非常高而且每次截图上传的隐私风险也很难控制。更稳妥的架构是把 Agent 拆成多层任务编排层负责任务拆解、状态管理、步骤调度。规划层由大模型云端或本地根据任务目标生成下一步动作。行动层负责真实浏览器操作比如 Playwright、Selenium。感知层通过页面 DOM、截图、视觉模型判断当前页面状态。人工接管层在验证码、支付确认、账号异常时介入。在这个分层里大模型负责“想清楚做什么”本地视觉模型负责“看懂屏幕”Playwright 负责“把动作执行出来”人工只负责“最终信任确认”。每一层的职责都很清晰替换成本也低。AI 代理助手加本地模型的组合最典型的用法就是把截图丢给本地视觉模型让它回答“当前页面是否出现了验证码”“页面上是否有错误提示”“按钮是否可用”。这类感知任务不需要强大的推理能力一个小规模视觉模型足够完成而且响应时间远低于云端 API。对比一下两种方案维度纯云端大模型云端大模型 本地视觉模型延迟截图上传和推理延迟较高本地推理延迟低云端只处理复杂规划成本每次截图都产生 API 费用大部分感知任务在本地完成成本低隐私页面截图离开本机敏感页面截图只留在本地稳定性依赖网络和 API 可用性本地服务可控离线也能做部分判断这套思路用在验证码场景里就是让本地视觉模型帮我们做“检测”而不是“识别答案”。检测结果是触发人工接管流程的依据整个 Agent 架构因此变得稳定、可解释、可审计。4. 验证码边界的工程化处理自动执行加人工接管正确的人机验证处理方案并不是“让 AI 更强”而是“让流程更诚实”。代理自动执行到验证码边界时自动暂停并请人工确认确认后继续执行。这个模式通常叫 human-in-the-loop也就是人工在环。为什么这是最可靠的方案从合规角度看平台的服务条款通常会禁止未经授权的自动化访问。如果开发者用代理去处理验证码、绕过风控本质上是与服务条款对抗。而人工接管模式则不同代理完成了绝大多数繁琐操作最终身份确认由真人完成整体仍然属于“辅助操作”而不是“替代身份”。从工程角度看人机验证是一个外部不确定因素它的出现时机、样式、频率都无法预测。把“异常处理”交给系统而不是让人盯着才是稳定方案。人工只需要在验证码真正出现时才介入不会造成大量人力浪费。推荐的处理时序如下AI 代理按步骤执行任务。每个关键操作后调用验证码检测器。检测到验证码后保存当前页面截图、记录上下文、暂停当前任务。通过终端提示、状态文件、Webhook 或消息队列通知人工。人工在真实浏览器中完成安全验证。人工确认后代理恢复执行并继续后续步骤。这里要特别强调不要让代理自己调用“打码平台”也不要试图用脚本模拟真人滑动轨迹。这类方案短期可能有效但平台风控一旦升级账号风险会直接落在真实用户头上。对产品化项目来说这是不可接受的稳定性隐患。人工接管也不代表“人工下单”。在实际流程中代理完成了从打开页面到提交订单前的大部分操作人工只处理验证码和最终确认整体效率仍然远高于纯人工操作。这也是 AI 代理落地真实业务最合理的方式。5. 环境准备与代码实战下面实现一个最小可运行的示例通过 Playwright 操作浏览器在每个关键步骤后检测是否出现人机验证如果检测到暂停并请人工处理。代码只演示通用流程不绑定具体站点读者可以替换成自己有权限测试的页面。5.1 环境依赖示例使用 Python 3.10 以上版本Playwright 版本以官方最新稳定版为准。这里不会写死具体版本号因为浏览器驱动更新很快。python -m venv .venv source .venv/bin/activate pip install playwright requests playwright install chromium如果想体验本地视觉模型检测可以再安装 Ollama并拉取一个支持图片输入的视觉模型。本文代码中的模型名称只是示例请以你本地实际安装的模型名为准。5.2 验证码检测模块这一模块通过多种信号判断页面是否出现了验证码页面文本、URL、iframe、本地视觉模型截图分析。# captcha_detector.py import json import re from pathlib import Path class CaptchaDetector: def __init__(self, vision_endpointNone, vision_modelNone, enable_visionTrue): self.vision_endpoint vision_endpoint self.vision_model vision_model self.enable_vision enable_vision self.text_markers [ captcha, 安全验证, 请完成验证, 确认你不是机器人, verify you are human, security check, 人机验证, ] def detect(self, page): # 1. 页面文本判断 try: body_text page.locator(body).inner_text(timeout2000).lower() except Exception: body_text for marker in self.text_markers: if marker.lower() in body_text: return { detected: True, type: text_marker, marker: marker, } # 2. URL 判断 current_url page.url.lower() if captcha in current_url or security-check in current_url or verify in current_url: return { detected: True, type: url_marker, url: page.url, } # 3. iframe 判断 for frame in page.frames: frame_url frame.url.lower() if captcha in frame_url or challenge in frame_url or recaptcha in frame_url: return { detected: True, type: frame_marker, frame_url: frame.url, } # 4. 可选本地视觉模型截图判断 if self.enable_vision and self.vision_endpoint: screenshot_path Path(/tmp/agent_screenshot.png) page.screenshot(pathstr(screenshot_path), full_pageFalse) vision_result self._detect_by_vision(screenshot_path) if vision_result and vision_result.get(detected): return vision_result return {detected: False} def _detect_by_vision(self, screenshot_path): import base64 import requests with open(screenshot_path, rb) as f: img_b64 base64.b64encode(f.read()).decode(utf-8) # 这里只让模型判断“是否出现验证码”不生成验证答案。 prompt 请判断这张网页截图中是否包含人机验证组件或验证码。只回答 yes 或 no。 payload { model: self.vision_model or qwen2.5-vl:7b, prompt: prompt, images: [img_b64], stream: False, } try: resp requests.post( self.vision_endpoint.rstrip(/) /api/generate, jsonpayload, timeout30, ) resp.raise_for_status() answer resp.json().get(response, ).strip().lower() if yes in answer: return { detected: True, type: vision_model, answer: answer, } except Exception as exc: print(f[warn] vision detection failed: {exc}) return {detected: False}这个检测器是可扩展的。如果你的项目已经接入了更复杂的页面理解模型完全可以替换detect方法内部逻辑但对外接口保持不变这样主流程不需要改动。5.3 人工接管模块人工接管模块负责保存现场截图、写入状态文件、等待人工确认、在人工确认后更新状态。# human_verification.py import json import time from pathlib import Path class HumanVerification: def __init__(self, state_filevar/human_state.json): self.state_file Path(state_file) self.state_file.parent.mkdir(parentsTrue, exist_okTrue) def request(self, page, reason, screenshot_pathvar/captcha_screenshot.png): page.screenshot(pathscreenshot_path, full_pageTrue) self._write_state(WAIT_HUMAN, reason, screenshot_path) print(f[human] 检测到人机验证等待人工处理: {reason}) print(f[human] 截图已保存: {screenshot_path}) print([human] 请在浏览器中完成安全验证后回到终端按回车继续...) input() self._write_state(CONFIRMED, reason, screenshot_path, confirmedTrue) print([human] 已完成状态确认代理继续执行。) def _write_state(self, status, reason, screenshot_path, confirmedFalse): state { status: status, reason: reason, screenshot: screenshot_path, confirmed_at: time.strftime(%Y-%m-%d %H:%M:%S) if confirmed else None, updated_at: time.strftime(%Y-%m-%d %H:%M:%S), } self.state_file.write_text( json.dumps(state, ensure_asciiFalse, indent2), encodingutf-8, )在真实项目中这里可以改成 Webhook 通知、飞书或钉钉消息、Redis 状态等。对最小示例来说终端阻塞等待已经足够说明问题。5.4 主代理脚本主脚本把前面的模块串起来。代理按步骤执行任务每个步骤执行后都检测验证码遇到验证码就转交人工。# agent.py import os from playwright.sync_api import sync_playwright from captcha_detector import CaptchaDetector from human_verification import HumanVerification # 下面的 URL 和登录信息请替换为你自己的授权测试环境。 BASE_URL os.getenv(AGENT_BASE_URL, https://example.com/login) USERNAME os.getenv(AGENT_USERNAME, ) PASSWORD os.getenv(AGENT_PASSWORD, ) def run_step(step_name, fn, page, detector, human): print(f[agent] 执行步骤: {step_name}) fn(page) page.wait_for_load_state(networkidle, timeout10000) check detector.detect(page) if check.get(detected): print(f[agent] 检测到人机验证: {check.get(type)}) human.request(page, reasonstep_name) print(f[agent] 步骤完成: {step_name}) def step_open(page): page.goto(BASE_URL, wait_untildomcontentloaded) def step_login(page): page.get_by_label(用户名).fill(USERNAME) page.get_by_label(密码).fill(PASSWORD) page.get_by_role(button, name登录).click() def step_add_to_cart(page): page.get_by_role(button, name加入购物车).first.click() def step_checkout(page): page.get_by_role(button, name去结算).click() page.wait_for_load_state(networkidle, timeout10000) def main(): with sync_playwright() as p: browser p.chromium.launch(headlessFalse) context browser.new_context(localezh-CN) page context.new_page() detector CaptchaDetector( vision_endpointos.getenv(OLLAMA_BASE_URL), vision_modelos.getenv(OLLAMA_MODEL), ) human HumanVerification() steps [ (打开首页, step_open), (登录账号, step_login), (加入购物车, step_add_to_cart), (去结算, step_checkout), ] for name, fn in steps: run_step(name, fn, page, detector, human) print([agent] 下单流程结束请人工确认结果。) browser.close() if __name__ __main__: main()示例代码中的选择器和步骤都依赖目标页面结构读者需要根据实际情况调整。重点是理解“执行步骤 - 检测验证码 - 人工接管 - 继续执行”这个循环。6. 运行结果与效果验证运行主脚本前先配置环境变量。这里使用测试站点地址避免对真实平台造成压力。export AGENT_BASE_URLhttps://your-test-site.com/login export AGENT_USERNAMEyour_username export AGENT_PASSWORDyour_password python agent.py一个典型的运行输出如下[agent] 执行步骤: 打开首页 [agent] 步骤完成: 打开首页 [agent] 执行步骤: 登录账号 [agent] 检测到人机验证: text_marker [human] 检测到人机验证等待人工处理: 登录账号 [human] 截图已保存: var/captcha_screenshot.png [human] 请在浏览器中完成安全验证后回到终端按回车继续...此时浏览器页面停留在验证码界面人工完成验证后回到终端按回车程序会继续输出[human] 已完成状态确认代理继续执行。 [agent] 步骤完成: 登录账号 [agent] 执行步骤: 加入购物车 [agent] 步骤完成: 加入购物车 [agent] 执行步骤: 去结算 [agent] 下单流程结束请人工确认结果。如果流程成功说明“自动执行 人工接管”的闭环已经跑通。如果失败优先检查页面选择器是否和当前测试页面匹配。验证码检测器是否真的捕获到了验证码信号。浏览器是否以有头模式启动。网络是否稳定是否被目标站点限流。7. 常见问题与排查思路问题现象可能原因排查方式解决方案检测不到验证码验证码在 iframe 或新页面中文本临时变化查看截图、页面 frames、URL 变化增加 iframe 和 URL 规则或接入本地视觉模型检测到验证码但人工确认后流程失败人工操作导致页面状态变化元素定位失效查看状态文件、当前页面 URL人工确认后重新定位关键元素用状态机恢复步骤浏览器被站点拒绝访问数据中心 IP、自动化指纹、高频访问检查网络出口、查看浏览器控制台降低访问频率使用授权测试环境必要时申请官方 API本地视觉模型 API 报错Ollama 未启动或模型名称不对执行ollama list用 curl 测试接口先启动本地服务换成实际已安装的模型名页面加载超时页面资源较多或网络环境复杂调大 timeout先使用domcontentloaded按步骤等待关键元素避免依赖全局networkidle登录状态失效Cookie 过期或风控强制退出登录检查浏览器登录状态使用更长的会话保持策略必要时人工扫码登录从实际项目经验看最容易踩坑的是“验证码检测”和“人工确认后的状态恢复”。检测模块要覆盖文本、URL、iframe 三种信号因为不同站点嵌入验证码的方式差异很大。状态恢复则需要记录当前执行到哪一步人工确认后不能简单从零重跑。8. 最佳实践与工程建议第一先确认目标平台的自动化政策。如果平台服务条款明确禁止自动化访问就不要用 Playwright 去对抗风控。正确做法是申请官方 API或者在授权测试环境中验证流程。第二使用最小权限测试账号。不要在真实高权限账号上反复实验避免账号被限制。所有测试操作都应以低风险、可回滚为前提。第三把人工接管实现成一个真正的状态机。最小示例里用input()阻塞等待生产环境建议使用任务队列加 Webhook。状态至少包括RUNNING、WAIT_HUMAN、CONFIRMED、FAILED、FINISHED每次状态变化都要写日志。第四截图和日志是排查问题的第一手资料。遇到验证码时要保存完整截图、页面 URL、当前步骤名、浏览器控制台日志。日志中绝对不能出现明文密码、Cookie、Token。第五合理设置超时和重试。不要把同一个请求无脑重试要使用指数退避策略。每次重试前检查页面是否发生了跳转避免在错误页面上重复点击。第六本地视觉模型只做感知不做高风险决策。比如判断“是否出现验证码”“按钮是否可点击”是合理的试图让模型生成验证码答案则是错误方向既不稳定也不合规。第七版本管理要慎重。Playwright 和浏览器驱动版本升级很快建议在项目里锁定版本升级后先跑一轮回归用例再进入真实流程。第八如果使用“AI 代理助手加本地模型”的组合要把本地服务的健康检查纳入代理启动流程。本地模型不是常驻进程也可能崩溃代理运行时需要处理这类依赖故障。9. 总结与后续学习方向人机验证对于 AI 代理来说不是一道数学题而是一条边界自动化的边界由平台规则和信任模型共同划定。想让代理真正走进真实业务与其研究怎么越过边界不如把边界变成工程流程的一部分。本文给出的“规则检测 本地视觉模型 人工接管”只是最小闭环。再往后你可以把它扩展成完整的任务状态机、分布式任务队列、多代理协作系统。也可以在感知层接入更强的多模态模型让代理更好地理解页面状态但始终保留人工确认的兜底环节。如果代理项目也卡在验证码这一环建议先别急着上更强的识别模型先把暂停、人工确认、恢复执行这个循环跑通。这个框架不只在点外卖场景适用任何涉及登录、支付、风控系统的 Agent 应用都可以复用。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门