跳转到内容

Agent 核心循环 — ReAct 模式在浏览器中的落地

学习目标

本章要解决什么问题:

  • Browser Use 的 Agent 核心循环如何组织浏览器环境的特殊反馈(DOM、截图、页面状态)
  • 如何在循环中集成规划、循环检测和失败恢复
  • 如何设计和调优循环参数(最大步骤、失败次数、超时)

前置知识

下文假设你已理解 Agent 核心循环的通用原理,直接聚焦 Browser Use 的具体实现。


项目实践

三步循环结构

Browser Use 的 Agent.step() 将每次循环分为三个明确的阶段:

Phase 1 — _prepare_context()

  1. 调用 get_browser_state_summary(include_screenshot=True) 获取当前页面状态
  2. 检查新下载的文件,更新 available_file_paths
  3. 根据当前 URL 更新动作模型(页面过滤动作)
  4. 调用 _message_manager.prepare_step_state() 准备消息状态
  5. 可选的消息压缩(maybe_compact_messages()
  6. 注入各类 nudge:预算警告、重规划提示、循环检测提示

Phase 2 — _get_next_action()

  1. 从 Message Manager 获取完整消息列表
  2. 调用 llm.ainvoke(messages, output_format=AgentOutput) 获取结构化输出
  3. 内置重试:如果 LLM 返回空动作,发送澄清消息并重试一次
  4. 支持超时控制(每模型独立 timeout,默认 75-90s)

Phase 3 — _execute_actions() + _post_process()

  1. 解析 LLM 输出中的 action 列表
  2. 通过事件总线分发每个动作到对应的 Watchdog 处理
  3. 收集动作结果(ActionResult 列表)
  4. 检查下载更新、更新计划状态、记录行为序列(用于循环检测)
  5. 如果动作出错,递增 consecutive_failures 计数器

循环终止条件

  • LLM 调用 done 动作(任务完成)
  • 达到 max_steps(步骤预算耗尽)
  • 连续失败次数超过 max_failures(默认 5 次)
  • 外部中断(register_should_stop_callback 返回 True)

LLM 输出结构

Browser Use 使用 Pydantic 模型约束 LLM 输出格式:

AgentOutput {
current_state: {
thinking: str # 思维链
evaluation_previous_goal: str # 上一步评估
memory: str # 短期记忆
next_goal: str # 下一步目标
}
action: list[ActionModel] # 要执行的动作列表
}

flash_mode 下,current_state 中的规划字段被移除(低能力模型不需要输出计划)。

失败恢复机制

Browser Use 实现了两层失败恢复:

动作级恢复

  • 单步失败时,错误消息作为 ActionResult(error=...) 注入下一轮上下文
  • LLM 看到错误后可以调整策略
  • 连续 N 次失败后,强制终止 Agent

LLM 级恢复

  • 当主 LLM 遇到速率限制或服务端错误(401/429/5xx)时
  • 自动切换到 fallback_llm(如果配置了的话)
  • 一旦切换,整个运行剩余部分都使用 fallback

问题与规避

Agent 在复杂页面陷入操作循环

问题:Agent 可能在页面上反复执行相似操作(如反复滚动但找不到目标元素)。

对策loop_detector 在后台追踪两个维度的异常:

  1. 动作重复:滑动窗口内相同动作名(排除 wait/done/go_back)的重复率
  2. 页面停滞:连续多步后 DOM 指纹(文本内容哈希 + 元素计数)无变化

当检测到循环时,自动注入逐步升级的 nudge 消息:

  • 第一轮:“你可能在重复操作,尝试改变策略”
  • 第二轮:“建议输出 plan_update 重新规划”
  • 最终轮:如果仍未改善,触发终止

多步任务中途失败导致前功尽弃

问题:Agent 执行 20 步后失败,之前的发现全部丢失。

对策

  • 文件系统持久化:Agent 有自己的临时目录(/tmp/browser_use_agent_{id}_{timestamp}/
  • todo.md 文件:Agent 可以记录任务进度
  • 中间文件:Agent 在提取数据时可以保存到文件系统
  • 失败时的最终结果会包含之前累积的所有发现

超时配置不当导致不必要的失败

问题:使用 Groq 时默认的 90s 超时太长(Groq 通常 30s 内完成),而 Gemini 3 Pro 思考模式下 75s 不够。

对策:Browser Use 内置了模型特定的超时规则,开箱即用:

模型族超时
Gemini(非 3-pro)75s
Gemini 3-pro90s
Groq30s
Claude / O3 / DeepSeek90s

设计取舍

同步循环 vs 异步事件驱动

方案优势代价
同步循环(当前)简单直观、易于调试单步阻塞整个 Agent
异步事件驱动可以并发处理多个任务状态管理复杂、调试困难

Browser Use 选择同步循环是因为:浏览器操作通常是顺序依赖的(先导航再点击再输入),并发收益有限。

规划集成:强制 vs 可选

  • enable_planning=True(默认):Agent 在探索后创建计划,支持动态更新
  • flash_mode=True:规划字段从输出 schema 中移除,纯 ReAct
  • 设计权衡:规划增加 Token 成本,但对复杂多步任务有显著收益

Flash Mode 的取舍

Flash Mode 是一种能力自适应设计:当使用低能力模型时,精简输出 schema(移除 planning 字段),减少 Token 消耗和推理复杂度。代价是 Agent 失去了规划和结构化思考的能力,更适合简单的单步任务。


参考来源