Claude Computer Use 在同一按钮上反复点击死循环 —— 排查与修复

Claude Computer Use 不停地点击同一个按钮或输入框,迟迟无法推进 —— 通常是截图时机、焦点状态或坐标漂移的问题。本文教你如何打破死循环。

你让 Claude Computer Use 填一份表单、点提交、读确认信息。Claude 点了提交按钮。页面看起来没变化。Claude 又截图一次,发现表单还在,于是再点一次。然后再一次,再一次。十几二十轮过去,任务还在跑,聊天记录里全是”我将点击提交按钮”。模型并不蠢 —— 它只是在根据看到的画面做反应,而它看到的画面前后没有差异。这种死循环几乎只来自五种原因:截图捕捉到了错误帧、Claude 看不到的焦点状态、确认弹窗渲染到了画面外、视口尺寸变化后坐标漂移,或者点击落在了被覆盖 / disabled / z-index 错误的元素上,页面真的什么都没发生。

常见原因

按典型 Computer Use 死循环出现的概率排序。

1. 点击落在了覆盖层上(modal 遮罩、tooltip、透明 overlay)

Computer Use 是按像素坐标点击的。如果点击瞬间,目标按钮上方刚好盖着一个 tooltip、modal 背景或者 pointer-events: auto 的 overlay,那这一击就打在了覆盖层上,按钮根本没触发。下一张截图看起来一模一样,Claude 又点一次。

如何识别:手动打开页面,在按钮位置悬停,DevTools 的 Inspect 工具看那个坐标的最顶层元素。如果不是按钮本身,就是这种情况。

2. 按钮”看着可点”,其实在等异步校验

很多表单的提交按钮在视觉上看起来是 enabled 的,但点击处理函数被一个 debounce 的校验逻辑拦住,要等校验跑完才生效。Claude 点得太早,点击被静默吞掉,页面纹丝不动。

如何识别:你自己手动在输入完后立刻点按钮 —— 如果要等 500-1500ms 才有反应,就是这个原因。

3. 截图在 DOM 稳定之前就抓了

Claude 的截图工具是有一个固定延时的(通常 800-1500ms)。如果页面在做客户端路由切换,中间有一个 2 秒的 loading 转圈,Claude 截到的就是转圈那一帧,然后判断”还在加载,再点一次” —— 但此时点击早就成了误操作。

如何识别:看截图里有 spinner / skeleton 占在内容应该出现的位置,而 Claude 还在反复点那个其实已经失效的 CTA。

4. 视口 / 缩放变化后坐标漂移

如果浏览器缩放级别、devicePixelRatio 或者窗口大小在两轮之间发生了变化(自动 resize、侧边栏收起、移动端模拟时弹出虚拟键盘),Claude 之前算好的像素坐标就不再对应同一个 DOM 元素了。

如何识别:对比两张连续截图 —— 如果按钮挪了几像素,但 Claude 还在点老位置,就是坐标漂移。

5. 确认弹窗渲染在画面外或者在 Claude 看不到的 portal 里

有些 UI 把 modal portal 到 document.body 的某个位置,而 Claude 截图区域刚好没包含那里(比如挂在页面顶部,但当前滚动位置在中间)。Claude 看到的还是没变化的表单,而 modal 正在屏幕外等用户输入。

如何识别:手动把页面滚到最顶部 —— 如果那里真的有一个 modal 挡着,那 Claude 需要先被告知滚动到顶部。

6. 操作其实成功了,但成功提示太微弱

一个 200ms 淡入、停 1.5 秒再淡出的 toast。一个 800ms 就消失的绿色边框。等 Claude 下一轮截图触发的时候,成功信号已经没了,所以 Claude 判定操作失败。

如何识别:手动操作一遍,看成功提示能在画面上停留多久。如果不到 2 秒,Claude 大概率会错过。

排查前的准备

  • 把死循环里所有的截图保存下来。每轮的截图是判断 Claude 看到了什么的唯一证据。
  • 把触发这次运行的原始 prompt 记录下来 —— 像”请一直尝试直到成功”这种措辞,会让死循环更严重。
  • 留意死循环是不是确定性的(每次同一个网站都循环)还是偶发的(有时能跑通)。偶发指向时序问题,确定性指向结构问题。

需要收集的信息

  • 死循环的连续截图(至少 3 轮)。
  • 目标网站 URL 和让 Claude 做的具体操作。
  • 你用的是 API、Console 还是某个桌面端壳子接入 Computer Use —— 不同入口的默认截图延时不一样。
  • 运行时的浏览器缩放级别、视口大小、devicePixelRatio。
  • 你自定义的 system prompt 或 tool-use 指令。

一步步修复

按 ROI 排序,便宜的检查在前。

第 1 步:在 prompt 里加上明确的”等待并验证”指令

最有效的一招:

每次点击之后,等待 3 秒,截一张图,确认预期的变化出现了。
如果新截图和点击之前的截图看起来完全一样,绝对不要再点同一个元素。
改为滚动页面、扩大截图范围,或者去页面其他位置找错误信息。

这条规则能在大多数情况下打破第 1、2、3、6 类死循环 —— 因为 Claude 不再盲目重试了。

第 2 步:在判定状态前先强制滚到顶部

如果你怀疑确认信息渲染在当前滚动位置之上:

在判断操作是否成功之前,先把页面滚到最顶,等 1 秒,再截图。
modal 和 toast 经常 portal 到 document.body 的顶部。

第 3 步:能用文字标签定位的就别用坐标

Computer Use 可以通过 prompt 引导用”按标签点击”的模式。在 prompt 里加:

点击按钮时优先用按钮上可见的文字标签来识别,而不是像素坐标。
如果同一坐标连续两次点击失败,说明按钮可能已经挪了位置 —— 
请重新按标签定位。

这可以基本消除视口变化后的坐标漂移问题。

第 4 步:固定运行期间的视口尺寸

如果你能控制浏览器会话,在启动前把视口尺寸钉死:

# Computer Use 环境启动时
export COMPUTER_USE_VIEWPORT_WIDTH=1280
export COMPUTER_USE_VIEWPORT_HEIGHT=800
export COMPUTER_USE_DEVICE_PIXEL_RATIO=1

或者在 API 调用里通过 tool config 显式传入,避免运行中途被动 resize。

第 5 步:在 wrapper 里加一道硬性 loop-breaker

用代码包一层,检测连续相同的截图:

import hashlib

last_hash = None
identical_count = 0

def on_screenshot(image_bytes):
    global last_hash, identical_count
    h = hashlib.sha256(image_bytes).hexdigest()
    if h == last_hash:
        identical_count += 1
        if identical_count >= 3:
            raise StopIteration("3 张截图完全一致 —— 中止循环")
    else:
        identical_count = 0
    last_hash = h

连续 3 张截图哈希完全一致,基本可以判定卡死。直接 abort 抛给用户处理。

第 6 步:对”惯犯网站”,尴尬的那一步用脚本预编排

有些网站(银行、老旧企业系统)对 Computer Use 特别不友好。对这种站,把点击 + 等待那一步交给 Playwright / Selenium 之类的确定性脚本,只把需要推理的部分留给 Claude。

验证

  • 用新 prompt 重跑一遍原任务,确认 Claude 不再连续三次点同一个元素。
  • 看截图序列:连续两次操作之间,截图应当肉眼可见地不同(弹窗打开了、页面变了、toast 出现了)。
  • 任务的总轮数比原来的死循环跑法至少降低 40%。

长期预防

  • 把每一次 Computer Use prompt 都当作一个状态机:“点 X,然后验证 Y 出现,再做下一步。“把验证步骤显式写进去。
  • 在 system prompt 模板里固化一条”不允许在状态没有变化的情况下重复点击同一元素”的规则。
  • Computer Use 会话一定要锁定视口尺寸和 devicePixelRatio,绝不留给宿主环境去自动调整。
  • 对高价值的网站,提前录一组”成功态截图”,当作 Claude 判断”完成”的参照。
  • 把截图都落到文件系统,这样失败的运行可以离线复盘,不必再烧 API 重跑一次。

常见坑

  • 在 prompt 里写”请更努力一点”或”持续尝试” —— 这就是死循环的助燃剂。
  • 完全信任按钮的视觉 enabled 状态,不去检查它背后是否还有异步校验在拦截。
  • 跑 Computer Use 不设最大轮数预算 —— 一个死循环可以烧掉几百轮、几十美金。
  • 把已经被限流 / 被验证码挡住的页面当作”只是慢一点”,Claude 会一直点下去。
  • wrapper 日志里不区分”坐标点击”和”标签点击” —— 不区分就没法定位坐标漂移问题。

FAQ

Q:Claude 点对了按钮,但页面突然变白了,怎么办?

很可能点击触发了一个被沙箱拦掉的外发请求 —— CSP 或网络策略问题。手动重做一遍,看 Network 面板是不是有 CORS / CSP 报错。如果是,沙箱需要加白对应域名。也可参考 Claude 文件连接器陷入重新授权死循环

Q:为什么死循环只发生在某些网站上,别的网站没事?

客户端路由重度、portal 渲染 modal、异步校验多的站,最容易循环。纯静态 HTML 表单几乎不会。修复手段是针对单站调 prompt,而不是一刀切全局参数。

Q:能不能把 max-turns 调大,赌它最后能成功?

不行。一旦开始循环就会一直循环 —— 输入没变,Claude 的推理也不会变。要么打破输入(滚动、等待、重新定位),要么直接 abort。

Q:用长上下文模型版本能解决吗?

略有帮助 —— 至少能让 Claude 记住”这个按钮我已经点过两次了”。但截图本身的同质化问题不是上下文问题,所以收益有限。prompt 上的修复才是关键。

相关阅读

标签: #排查 #Claude #computer-use #automation #agent