文章 · Context engineering
Context engineering:浏览器 agent 每看一眼页面,到底花多少
关于 context engineering 的文章很多,大多在争论定义。很少有人算一笔账:一个浏览器 agent 每「看」一次页面要往上下文里塞多少东西,这些东西又会在后面的每一步里被反复付费。建联系统的脚本改了几版之后,这笔账我算得很清楚。
这篇回应的是 ego lite 官网的 《Context engineering for browser agents: what an observation costs》。观点是我自己的,例子来自我搭的 KOL 建联系统。
Article · Context engineering
Context engineering: what a browser agent pays every time it looks at a page
There are plenty of articles on context engineering, and most of them argue about definitions. Few do the arithmetic: how much a browser agent pushes into its context every time it looks at a page, and how that gets paid for again on every later step. After a few rewrites of my outreach scripts, I know that bill by heart.
This piece responds to the ego lite article “Context engineering for browser agents: what an observation costs”. The opinions are mine; the examples come from the KOL outreach system I built.
- Context engineering 就是决定每一轮里哪些东西进模型的上下文窗口。目标不是塞得多,而是用最少的高信号 token 换到想要的结果。
- 浏览器 agent 的上下文开销来自三处:这一次的页面观察、每次都要付的工具 schema、以及一直背在身上的历史。前两项决定了每一步的底价,第三项让成本随步数线性增长。
- 三件事最管用:让观察变小(只拿需要的那部分页面)、让工具变少(一个入口接代码,而不是几十个工具)、让历史变短(把确定性的步骤合并成一次执行)。
先把定义说清楚
Context engineering 指的是一种实践:在模型的每一轮调用里,决定上下文窗口中放什么。Anthropic 的说法是「为目标结果挑选最小的一组高信号 token」。市面上的定义在这一点上是一致的,分歧在于谁包含谁:有人认为 harness 是 context engineering 的一部分,有人反过来。
我不太关心包含关系。对一个要天天跑的浏览器 agent 来说,context engineering 就是一个成本问题:每一步进上下文的东西,决定了这一步多贵,也决定了后面每一步多贵。
和 prompt engineering 的区别也在这里。prompt engineering 关心的是你怎么说那一句话;context engineering 关心的是那句话旁边还摆着什么,而旁边那些东西往往比那句话大几十倍。
一次页面观察到底是什么
浏览器 agent 想知道页面上有什么,只有几种办法:截图、DOM、可访问性快照。每一种都是一次「观察」,每一次观察都会变成 token 进入上下文。
截图看起来最直观,但模型读图的代价不低,而且读出来的信息不精确:它知道那里有个按钮,不一定知道按钮的名字和能不能点。完整 DOM 最精确,但一个普通的后台列表页序列化出来动辄几万字符,大部分是 class 名和包装层。可访问性快照是折中:只保留角色、名字和层级,通常比 DOM 小一个数量级,而且带着可以直接操作的引用。
建联系统的「建联追踪」页是一个几十行的表格。我对比过三种观察方式拿到的东西:
| 观察方式 | 大致体量 | 拿到了什么 | 缺什么 |
|---|---|---|---|
| 整页截图 | 一张图,按模型读图计费 | 版式、颜色、大概位置 | 元素的精确名字、是否可交互 |
| 完整 DOM 序列化 | 数万字符 | 一切,包括不需要的 | 可读性;噪声淹没信号 |
| 可访问性快照 | 数千字符 | 角色、名字、层级、可操作引用 | 纯视觉信息,比如颜色 |
体量差一个数量级,意味着价格差一个数量级,而且这还只是一次观察。
成本的三个来源
把一个浏览器 agent 跑完一个任务的 token 拆开,大致来自三处。
来源一:这一次的观察
上面说的那份快照或截图。它是最显眼的一项,也是大多数人唯一会去优化的一项。
来源二:工具的 schema,开跑之前就付了
如果 agent 通过工具协议(比如 MCP)操作浏览器,每一个可用工具的名称、描述、参数定义都会进入上下文,而且每一轮都在。二三十个浏览器工具的 schema 加起来可能比一次快照还大,这笔钱在你什么都没做之前就付了,之后每一步继续付。
来源三:你一直背着的历史
每一轮的观察和结果都留在对话里。第十步的时候,前九步的快照还在上下文里,哪怕早就没用了。这是成本随步数线性增长的根源,也是为什么一个二十步的任务远不止二十倍于一步的价格。
对上下文能做的四件事
- 写。 把中间结果写到上下文之外,比如文件或数据库,需要时再读回来。建联系统的每日任务把筛出的名单写进文件,模型只看一行汇总。
- 选。 每一轮只放这一轮需要的东西。要点击一个按钮,就不需要整页的 DOM,一个带引用的局部快照就够了。
- 压。 把观察压缩成更小的表示:可访问性快照代替 DOM,表格的前几行代替全部,页面的变化部分代替整页。
- 隔。 把子任务放进独立的上下文里跑,结束后只把结论带回来,而不是把整个过程带回来。
这四件事的共同点是:决定什么不进上下文,比决定什么进更重要。
一个设计同时改掉两项
有一种设计可以同时压低第二项和第三项:不把浏览器能力拆成几十个工具,而是给 agent 一个入口,让它提交一段代码,代码在本地运行时里把多步操作一次做完。
工具 schema 从几十个变成一个,因为只剩「执行这段代码」。历史也变短了,因为原来要十轮对话的事现在是一轮:模型写一段脚本,运行时打开页面、筛选、点击、读结果,只把最后几行返回。中间那九次观察根本没有进入上下文。
这正是我在另一篇文章里讲的 heredoc 的做法。建联系统的「该催谁」任务,早期版本每次都要模型看三四次页面快照;改成一段脚本之后,模型只看脚本输出的一张小表:多少人该催,几封已发出。上下文从几万 token 降到几千,而且不随名单长度增长。
怎么自己量一遍
- 挑一个你的 agent 常跑的任务,记下它完整跑一遍的总输入 token。大多数 agent 工具会在日志里给这个数。
- 把单次观察单独量一下:同一个页面,截图、DOM、快照各拿一次,看各自多大。
- 数一下可用工具的 schema 总长度。把它乘以步数,就是你为「工具目录」付的总价。
- 看总量里有多大比例是重复的历史观察。如果超过一半,优先合并步骤,而不是优化单次观察。
量过一次之后,你会发现优化的顺序和直觉相反:先减少步数,再减少工具,最后才是把截图换成快照。
Context engineering 和 harness engineering
这两个词经常一起出现。我的理解是:harness 决定 agent 有哪些工具、怎么循环、在什么环境里行动;context engineering 决定每一轮里这些东西以什么形态进入模型。前者是结构,后者是预算。一个好的 harness 让 context engineering 变得容易,比如把观察默认做成小的快照、把多步合并成一次执行;一个差的 harness 会让你在提示词里拼命省字,却省不回工具 schema 和历史快照那几万 token。
- Context engineering is deciding, on every turn, what goes into the model's context window. The goal is not more; it is the smallest set of high-signal tokens that gets the result.
- A browser agent's context cost comes from three places: this turn's page observation, the tool schemas paid on every turn, and the history it keeps carrying. The first two set the floor per step; the third makes cost grow linearly with step count.
- Three moves matter most: make observations smaller (only the part of the page you need), make tools fewer (one entry point that takes code, not dozens of tools), and make history shorter (collapse deterministic steps into one execution).
The definition first
Context engineering is the practice of deciding what goes into the model's context window on each call. Anthropic describes it as curating the smallest set of high-signal tokens for the desired outcome. Published definitions agree on that core; they disagree about containment, whether the harness sits inside context engineering or the other way round.
I do not care much about containment. For a browser agent that runs every day, context engineering is a cost question: whatever enters the context on a step decides how expensive that step is, and how expensive every later step is.
That is also the difference from prompt engineering. Prompt engineering is about how you phrase the one sentence. Context engineering is about everything sitting next to that sentence, which is usually tens of times bigger.
What a page observation actually is
A browser agent has a few ways to learn what is on a page: a screenshot, the DOM, or an accessibility snapshot. Each is an observation, and each becomes tokens in the context.
Screenshots look the most natural, but reading an image is not cheap for a model and the information is imprecise: it knows there is a button, not necessarily its name or whether it is clickable. The full DOM is precise, but a plain back-office list page serialises to tens of thousands of characters, most of them class names and wrapper layers. An accessibility snapshot is the compromise: roles, names and hierarchy only, usually an order of magnitude smaller than the DOM, and it comes with references you can act on directly.
The outreach system's tracking page is a table of a few dozen rows. Here is what the three observations of that page look like:
| Observation | Rough size | What you get | What you miss |
|---|---|---|---|
| Full-page screenshot | One image, billed at image rates | Layout, colour, rough position | Exact element names, interactivity |
| Serialised DOM | Tens of thousands of characters | Everything, including what you do not need | Readability; noise drowns the signal |
| Accessibility snapshot | A few thousand characters | Roles, names, hierarchy, actionable refs | Purely visual information such as colour |
An order of magnitude in size is an order of magnitude in price, and that is for a single observation.
The three sources of cost
Break down the tokens a browser agent spends on one task and they come from three places.
Source one: this turn's observation
The snapshot or screenshot above. It is the most visible item, and the only one most people optimise.
Source two: tool schemas, paid before you start
If the agent drives the browser through a tool protocol such as MCP, the name, description and parameter definition of every available tool enters the context, and stays there on every turn. The schemas of twenty or thirty browser tools can outweigh a snapshot. You pay that before doing anything, and you keep paying it on every step.
Source three: the history you keep carrying
Every turn's observation and result stays in the conversation. On step ten, the snapshots from steps one to nine are still in context even though they are long useless. This is why cost grows linearly with steps, and why a twenty-step task costs far more than twenty times a one-step task.
The four things you can do with context
- Write. Put intermediate results outside the context, in files or a database, and read them back when needed. The outreach system's daily jobs write the filtered list to a file; the model reads one summary line.
- Select. On each turn, include only what that turn needs. Clicking one button does not require the whole DOM; a scoped snapshot with refs is enough.
- Compress. Replace observations with smaller representations: an accessibility snapshot instead of the DOM, the first rows of a table instead of all of them, the diff of a page instead of the page.
- Isolate. Run sub-tasks in their own context and bring back only the conclusion, not the whole trace.
What the four share: deciding what stays out of the context matters more than deciding what goes in.
One design that changes two of the three
One design lowers sources two and three at the same time: instead of splitting browser capabilities into dozens of tools, give the agent a single entry point that accepts a block of code, and let a local runtime execute the multi-step work in one go.
Tool schemas shrink from dozens to one, because the only tool is “run this code”. History shrinks too, because what used to be ten turns is now one: the model writes a script, the runtime opens the page, filters, clicks and reads, and returns only the last few lines. The nine intermediate observations never enter the context.
This is the heredoc approach I describe in another article. The outreach system's “who is due” job used to need three or four snapshot reads per run; as a script, the model sees only the small table the script prints: how many are due, how many follow-ups went out. Context dropped from tens of thousands of tokens to a few thousand, and it no longer grows with the length of the list.
How to measure it yourself
- Pick a task your agent runs often and record the total input tokens for one full run. Most agent tools report this in their logs.
- Measure a single observation on its own: take a screenshot, the DOM and a snapshot of the same page and compare sizes.
- Add up the length of all available tool schemas. Multiply by the step count: that is what you pay for the tool catalogue.
- Check how much of the total is repeated historical observations. If it is over half, merge steps first rather than optimising single observations.
Once you have measured it, the order of optimisation turns out to be the opposite of intuition: fewer steps first, fewer tools second, and swapping screenshots for snapshots last.
Context engineering vs harness engineering
The two terms travel together. My reading: the harness decides which tools the agent has, how it loops and what environment it acts in; context engineering decides the shape in which those things reach the model on each turn. One is structure, the other is budget. A good harness makes context engineering easy, by defaulting observations to small snapshots and collapsing steps into one execution. A poor harness has you trimming words in the prompt while the tool schemas and historical snapshots quietly cost tens of thousands of tokens.
常见问题
会漏掉纯视觉的信息,比如颜色、图片内容和精确位置。对表单、列表、按钮这类操作任务,它几乎总是够用;需要判断视觉状态时,再补一张局部截图。
窗口大不等于便宜,也不等于模型会更专注。上下文里噪声越多,模型越容易抓错东西,而且每一步都要为整个窗口付费。更大的窗口只是把问题推迟,没有解决它。
三个成本来源对所有带工具的 agent 都成立,只是浏览器把问题放大了:页面是最大的一种观察,浏览器工具也是最多的一类工具。
It misses purely visual information such as colour, image content and exact position. For forms, lists and buttons it is almost always enough; when visual state matters, add one scoped screenshot.
Bigger is not cheaper, and it does not make the model more focused. More noise in context means more chances to grab the wrong thing, and every step pays for the whole window. A larger window postpones the problem rather than solving it.
The three cost sources hold for any tool-using agent. Browsers just amplify them: a page is the largest kind of observation, and browser tooling is the largest kind of tool set.
More about me
Wanna know more? 👇