3.1 观察:页面如何变成模型可读的情报 本节摘要:模型不"上网",它读情报。每一拍开始时,框架把当前页面压缩成一份结构化简报:带编号的可交互元素清单,加上可选的页面截图。本节讲清这份简报怎么生成、编号体系怎么运作、视觉模式补什么短板——情报质量直接决定决策上限,这是排错时先查的一拍。 为什么先讲情报而不是模型 一个直觉问题:页面有几万个字符、几百个元素,全塞给模型?第一塞不下,第二塞了也读不明白——模型在一堆无关的样式脚本里找按钮,准确率会掉到惨不忍睹。所以观察拍的核心工作不是"搬运页面",而是压缩:只保留与操作相关的骨架,让模型像收到一张标注好的侦察地图。地图画错了,司令再英明也要打败仗——这就是为什么排错的顺序永远是先查情报、再查决策。
本节摘要:模型不"上网",它读情报。每一拍开始时,框架把当前页面压缩成一份结构化简报:带编号的可交互元素清单,加上可选的页面截图。本节讲清这份简报怎么生成、编号体系怎么运作、视觉模式补什么短板——情报质量直接决定决策上限,这是排错时先查的一拍。
一个直觉问题:页面有几万个字符、几百个元素,全塞给模型?第一塞不下,第二塞了也读不明白——模型在一堆无关的样式脚本里找按钮,准确率会掉到惨不忍睹。所以观察拍的核心工作不是"搬运页面",而是压缩:只保留与操作相关的骨架,让模型像收到一张标注好的侦察地图。地图画错了,司令再英明也要打败仗——这就是为什么排错的顺序永远是先查情报、再查决策。

看一份简化后的情报简报长什么样(示意数据):
[1] 输入框 占位符"搜索商品、店铺" 可见 [2] 按钮 文本"搜索" 可见 [3] 链接 文本"今日特价" 可见 [4] 下拉框 文本"全部分类" 可见 [5] 链接 文本"购物车(3)" 可见 [6] 输入框 类型密码 可见
模型要搜索,就回一个决策"对元素 1 输入某关键词,然后点元素 2"。这份编号表就是人机之间的动作协议:编号只在当前一拍有效,页面一变(弹窗、翻页、展开折叠),下一拍重新编号。理解这一点能解释很多"灵异现象":模型有时连续两拍点"同一个编号",其实页面已经刷新,编号换了主人——这不是模型犯傻,是地图换版而司令没换图。
与其背描述,不如抓一次现场。用回调把每一拍收到的情报打出来看:
from browser_use import Agent, Browser from langchain_openai import ChatOpenAI agent = Agent( task="打开电商演示站,把购物车里的商品数量报给我", llm=ChatOpenAI(model="gpt-4o"), browser=Browser(), ) # 每拍结束回调:拿到本拍的页面状态对象 def 盯梢(state): els = state.element_tree.clickable_elements_to_string() # 序列化编号清单 print("当前页:", state.url) print("情报前两百字:", els[:200]) # 太长只看头部,感受格式即可 result = agent.run(max_steps=8, on_step_end=盯梢) print(result)
预期输出中会出现类似“索引1 输入框 placeholder=搜索…”的片段——那就是简报的原始长相。盯着它看两分钟,很多后续概念(为什么有的元素模型看不见、为什么点击偶尔落空)会自己浮出答案。
纯文本情报有个盲区:画布类界面。图片里的按钮、Canvas 图表上的控件、验证码、用图形而非 DOM 元素呈现的一切——筛选工序一把就把它们筛没了,编号表里根本没有。视觉模式是补丁:给模型同时递一张页面截图,靠图像理解直接认位置。
agent = Agent( task="在画板演示页上,点击色板里的深绿色方块", llm=ChatOpenAI(model="gpt-4o"), # 视觉任务必须用支持图像的模型 browser=Browser(), use_vision=True, # 打开视觉:截图随情报一起上送 )
取舍账本:开视觉,识别面宽了,但每拍请求变大、变慢、变贵,且对文本型页面提升有限。我的建议是默认关、按需开——文本情报覆盖九成常规页面,画布、验证码、强视觉交互再开。别把视觉当万能保险,第 6 章会见到开视觉反而被页面上伪装内容带偏的案例。
**例一:藏在弹层里。**模型答"页面没有设置入口",肉眼一看明明在右上角齿轮里。原因:齿轮是悬浮按钮,点开才出现设置面板——第一拍的简报里自然没有设置项。处方:任务单加一句"先点开右上角设置图标再找",把两拍拆成两步写明。
**例二:懒加载没触发。**长列表页面,第 20 条之后的内容要滚动到底才会加载。模型的简报里永远只有前 20 条。处方:任务单写"先滚动到页面底部,等新内容出现后再提取"。滚动类动作(4.1)在这里就是为情报服务的。
例三:藏在图片里。价格写成了图片格式的促销标签,DOM 里只有一张图没有文本。纯文本情报天然看不见。处方:开视觉模式(本章后面讲)或换有文本替代描述的元素取数。三例的共同教训:"模型没找到"先假设是地图问题,别急着怀疑它笨——地图补上,它立刻就找到。
接手一个陌生站点,别直接下作战任务。先跑一次纯侦察:任务单只要求"列出页面上所有可点击元素的编号与文字,不做任何操作"。拿到的就是一份干净的编号简报——你按它核对目标元素在不在、叫什么名字,再写正式任务单,命中率立涨。侦察花一拍的钱,作战省三拍的弯路,这笔账怎么算都划算。
把"编号只在一拍内有效"往下推,能得到三条实用的推论。推论一:任务单里永远不写编号。"点击索引 7"这类指令必然落空——你写单时它是 7,模型执行时早换了主人。任务单只描述语义("点击搜索按钮"),编号的翻译是模型的事。**推论二:跨拍引用不可靠。**连招里第二击引用第一击之前的编号,是同一类错误——正确的连招写法是让每击的编号来自上一击之后的地图,这活模型自己会做,你只需要别抢。**推论三:日志里记录编号意义不大,记录文字才有用。**排查时"点击 索引 12"一文不值,"点击 提交订单按钮"一眼可读——这也解释了为什么黑匣子要连思考一起打,思考区里的文字描述才是可复盘的部分。
三条推论归拢成一句命令台术语:编号是弹药,文字才是目标坐标——弹药每场都换,坐标长期有效。后续章节里凡是涉及"指定目标"的地方,一律走文字语义,这条纪律从本节开始生效。
情报在手,下一拍看司令怎么用它选动作——以及你手上有哪几个旋钮能干预这次选择。