AI 代理浏览网页狂烧 Token?我用「命令封装」把成本砍了 98%

上周我做了个实验:让 AI 代理连续 10 天每天去掘金搜索「Rust tutorial」。

结果光是浏览器操作就烧了 26,000 tokens。而且每一天的执行流程都一模一样:找搜索框、输入关键词、等加载、提取文本。AI 把每次访问都当成第一次,每天都在从零开始摸索。

我算了笔账,按 GPT-4o 的定价,相当于每次都要多掏 0.40–0.60 美元。钱不多,但真正让人心疼的是,这些 token 全花在了纯粹的重复劳动上

为什么 AI 代理做浏览器任务这么费 Token?

举个例子。我让 AI 去 CSDN 搜一篇文章,它要经历什么?

第一次(探索阶段):

# AI 截图分析页面布局,消耗大量 token
[Agent] Screenshots the page to analyze layout...... ~800 tokens
# 尝试定位搜索框,第一次猜测 #search-box
[Agent] Tries to locate search box → guesses #search-box... ~600 tokens
# 选择器不对,重新检查 DOM
[Agent] Selector doesn't exist, inspects DOM to find the real one... ~500 tokens
# 终于找到:input[placeholder="搜CSDN"]
[Agent] Found it: input[placeholder="搜CSDN"]
# 输入关键词、等待页面加载
[Agent] Types search term, waits for page load... ~400 tokens
# 提取搜索结果文本
[Agent] Extracts search result list text... ~300 tokens
Total: ~2,600 tokens

第二次(完全相同的任务):

# AI 再次截图分析页面,重复昨天的动作
[Agent] Screenshots the page to analyze layout...... ~800 tokens (again)
# 再次定位搜索框,再次猜测
[Agent] Locates search box... ~600 tokens (guessing again)
# 再次猜错,再次重试
[Agent] Guesses wrong once... ~500 tokens (retrying again)
# 再次输入、等待、提取
[Agent] Types, waits, extracts... ~700 tokens
Total: ~2,600 tokens

10 次下来就是 26,000 tokens,路径几乎完全一致。

我把这个问题拆成了四个根因:

  • 没有跨会话记忆:昨天刚弄明白掘金搜索框是 input[placeholder="探索"],今天全忘光,明天继续重新探索。
  • 选择器全靠猜:AI 分析页面结构基本靠截图或 DOM 快照,猜对 selector 是运气,猜错一次就是几百 tokens 打水漂。复杂页面平均要试错 2–3 次。
  • 页面数据撑爆上下文:一个网页 HTML 几十 KB,一张截图几百 KB,光是传输页面结构就要 800–1,500 tokens。
  • 零复用性:第一次探索出来的 selector、流程、异常处理经验, Session 一结束就消失。每天都是《土拨鼠之日》,每次都要交同样的学费。

核心思路:把探索结果变成可复用的命令

想通之后,解决方案简单得有点尴尬:

让 AI 只探索一次。把学到的东西(selector、流程)记下来,以后直接调用。

举个例子。第一次搜完掘金后,我把经验固化成了一段配置:

# 掘金搜索配置:将首次探索的结果固化为可复用命令
Juejin Search:
  # 搜索框的 CSS 选择器,避免每次都重新猜测
  - Search box selector: input[placeholder="探索"]
  # 搜索结果列表项的选择器
  - Result list: .content-main .entry
  # 标准操作流程:点击 -> 输入 -> 回车 -> 等待 -> 提取
  - Flow: click search box → type keyword → press Enter → wait for load → extract text

然后把它包成一条 CLI 命令:

# 封装后的 CLI 命令:AI 只需生成这一行,无需操作浏览器
juejin search "Rust 教程" --json

从此以后,AI 只需要拼出这行命令就行,再也不用分析页面了。

Token 消耗对比:

  • AI 直接操作浏览器:单次约 2,600 tokens,10 次总计约 26,000,重复率 100%
  • 调用预封装命令:单次约 50 tokens,10 次总计约 500,重复率 0%
  • 效果:从 26,000 降到 500,降幅达 98%

这 50 tokens 仅仅是 AI 组装命令字符串的成本。

实战:从 3,000+ Tokens 压到 50

来看一个真实场景:「AI 代理每天监控一次京东商品价格。」

之前:AI 手动操作浏览器(每次约 3,000 tokens)

AI 每次都要从零生成这样的代码:

// AI 每次从零生成的浏览器操作代码,过程冗长且重复
const page = await browser.newPage();
// 访问商品页面,等待 DOM 加载完成
await page.goto('https://item.jd.com/100012043978.html', {
  waitUntil: 'domcontentloaded'
});

// 第一次尝试:猜测价格选择器
let price = await page.('.p-price span', el => el.textContent).catch(() => null);
if (!price) {
  // 第二次尝试:换另一个猜测的选择器
  price = await page.('.price J-p-100012043978', el => el.textContent).catch(() => null);
}
if (!price) {
  // 第三次尝试:失败后退回到获取整个页面 HTML 重新解析
  const html = await page.content();
  // 从原始 HTML 中重新定位价格元素...
  price = await page.('[class*="price"] span', el => el.textContent);
}

// 实际场景中,AI 还会生成大量 try-catch、注释和调试日志,
// 因为它在「边想边写」。

这段代码看着还行?问题是 AI 每次都要重新生成一遍。而且真实情况下 AI 写的代码会更臃肿,充满了多余的异常处理、注释和调试日志。

之后:封装成命令(每次约 50 tokens)

我把常见浏览器操作打包成了插件。现在 AI 代理只需要调用一条 CLI:

# 封装为插件命令后,AI 只需生成这一行指令
xbrowser jd price --url "https://item.jd.com/100012043978.html" --json

返回结果:

{
  "price": "2999.00",
  "originalPrice": "3299.00",
  "discount": "-9.1%",
  "inStock": true,
  "timestamp": "2025-05-28T10:30:00Z"
}

50 tokens,完事。 AI 不需要知道京东的价格 selector,不需要处理反爬,不需要等待动态加载。插件内部把所有脏活都干了。

再举个例子:搜索内容平台

# 之前:AI 操作浏览器搜索掘金文章,每次约 2,600 tokens
# 之后:一条命令搞定
xbrowser juejin search "Rust async programming" --limit 5 --json

返回:

{
  "results": [
    {
      "title": "Rust 异步编程完全指南",
      "author": "xxx",
      "url": "https://juejin.cn/post/7xxx",
      "likes": 328,
      "date": "2025-05-25"
    }
  ]
}

干净、结构化、可预期。AI 拿到 JSON 就能直接推理,不用再从 HTML 里抠文字。

深层原理:把探索成本摊销成可复用资产

用了这套方法一个月后,我总结了一个简单公式:

# 总 Token 成本 = 首次探索成本 + 重复次数 × 单次操作成本
# 
# 不封装时:Total = 2,600 + N × 2,600
# 封装后:  Total = 2,600 + N × 50
#
# 当 N = 10 时:节省 98%
# 当 N = 50 时:节省 99.6%

最开始的 2,600 tokens 是必要投资——AI 总得先摸清楚页面结构。但关键是,这笔钱你只交一次

打个比方:AI 代理每天操作浏览器,就像雇了一个人每天去同一家餐厅点餐,但他每天都要重新看菜单、问服务员推荐、纠结半天。 而封装命令就像是让他记住「老样子」。下次直接报菜名,秒点单。

插件架构:一个网站一个插件

这套思路的自然延伸就是按网站封装。每个插件打包一个站点的操作,AI 随用随取:

# 搜索引擎
xbrowser baidu search "AI Agent browser automation" --json
xbrowser google search "playwright token cost" --json
xbrowser bing search "CDP protocol guide" --json

# 内容平台
xbrowser juejin search "Rust 教程" --limit 10 --json
xbrowser csdn search "TypeScript generics" --json
xbrowser zhihu search "how to learn system design" --json

# 电商平台
xbrowser jd price --url "https://item.jd.com/xxx" --json

每个插件本质上就是一个 npm 包,里面包含:

  • Selector 定义:这个网站用哪些 CSS 选择器
  • 操作流程:先做什么、后做什么、出错怎么处理
  • 数据提取:如何把原始 HTML 转成结构化 JSON

AI 根本不需要知道这些细节。 它只要知道「有这个命令能用」就行。

规模放大:远不止省 Token

一旦用顺了,你会发现收益不止于 token 效率。

可靠性

AI 猜 selector 有时候会失败。插件里写死的选择器不会猜,它知道。就算网站改版,你也只需要改一个插件文件,而不是祈祷 AI 下次能猜对。

速度

拼出一条 CLI 命令只需要 AI 推理一步。手动操作浏览器可能要 5–10 步(截图 → 分析 → 猜测 → 重试 → 执行)。这不只是省 token,更是省时间。 你的代理响应更快。

可组合性

一旦操作变成命令,你就能像写脚本一样拼接它们:

# 在多个平台搜索同一关键词,并对比结果差异
xbrowser baidu search "Rust async" --json > baidu.json
xbrowser google search "Rust async" --json > google.json
diff <(jq '.results[].title' baidu.json) <(jq '.results[].title' google.json)

换成原始的浏览器自动化,你得让 AI 管理多个会话、平衡上下文窗口、合并结果。而用命令,这就是 shell 脚本的基本功。

可审计性

出了问题,直接看命令和输出。不用再翻 AI 的完整思维链,去定位到底是哪个 selector 猜错了。

更大的图景

我觉得这里有一个更深的问题。

AI 代理最大的成本不是 API 账单,而是重复劳动的浪费。 一次浏览器操作花 3,000 tokens 不贵,重复 100 次就是 30 万 tokens。更糟的是,这些重复没有任何学习价值——AI 每天都在探索同一个页面,却永远不会变得更聪明。

把一次性探索成本转化成可复用资产,才是 AI 代理的正确工程方向。 这跟我们平时做抽象是一个道理:我们不会每次部署都手动配环境,所以有了 Docker;不会每次提交都手动编译,所以有了 CI/CD。AI 代理的浏览器操作也需要同样的「封装」思维。

想象一下,如果每个常用网站都有现成的命令库——GitHub 操作、Jira 查询、Slack 消息读取、Confluence 页面抓取——AI 代理的 token 效率会提升多少?可靠性会提高多少?(预置的命令不会猜错 selector。)

这就是从「勉强能用的 AI 代理」到「真正稳定干活的 AI 代理」的跃迁。

如果你正在做 AI 代理的浏览器自动化,强烈建议试试这种封装思路。我用的是 xbrowser,一个专门为这个场景设计的开源 CLI 工具,基于插件架构,按网站拆命令,开源在 GitHub 上,感兴趣可以去看看。

直达网址:https://github.com/dyyz1993/xbrowser

类似文章