宣传片在 promo/index-single.html,clone 下来双击就能看;懒得 clone 就点在线版。
取数不经过模型。 每条命令输出一行一条 JSON,可以互相串:
seed-browser call bilibili.com search 电影解说 --limit 5 | seed-browser call bilibili.com comments - --limit 3中间那几百条评论在进程之间流,模型只看最后 3 条。工具调用那一套是每个结果都要回到模型上下文里,token 花在数据上;这里是模型只下指令,token 花在指令上。而且每段命令都是跑完就退的进程,状态在 daemon 里,串十段也不会把登录态和标签串丢。
站点函数会腐烂。 所以每个函数都带一个能真跑的 @example,seed-browser lib test 跑一遍就知道哪些失效了;网站改版会抛 CHANGED,agent 自己重新取数,顺手把那个函数改掉。
你让 AI 帮你查一句话:“昨晚发的那个 xxx 模型,大家都怎么评价?”
它去 X,要登录。去知乎,弹验证码。Reddit 直接 403。好不容易打开一页,几十万字符的 HTML 灌进来,上下文当场爆掉。最后它只能跟你说:抱歉,我访问不了这些网站。
可这些网站,你浏览器里明明全都登录着。
seed-browser 干的事就一件:让 AI 借你的浏览器上网。
同一句话再问一遍。这回它借你的浏览器,同时去 X、Reddit、HN、知乎、B 站、V2EX 搜一圈,回来给你一份报告:哪儿在夸、哪儿在骂、跑分和实测哪里对不上,每条都带出处。
别的活也一样。查线上故障(“全挂了,是不是云服务出事了”)、看新手机口碑、查某只股票今天为什么涨停,都是一句话的事。
办法很土,不另起一个浏览器,借你平时用的那个。
比如 AI 想读一条知乎回答,它敲的就是这一条:
seed-browser read https://www.zhihu.com/question/xxxx -b这条命令是这么走的:
AI agent
│ seed-browser read …(一次性进程,跑完就退出)
▼
CLI ──RPC──▶ daemon(后台常驻,第一次用时自动启动)
│ WebSocket
▼
浏览器插件(装在你日常用的 Chrome / Edge / Vivaldi 里)
│ chrome.debugger
▼
你的浏览器里开一个后台标签,带着你的登录状态打开页面
- CLI 把命令交给 daemon。
- daemon 通过插件,在你的浏览器里开个后台标签,不抢你的焦点。
- 页面在你的浏览器里加载,登录用的是你的,所以对网站来说,来的就是你本人。
- daemon 把几十万字符的页面压成几行文字,交回 AI 手里。
要长期留着的东西全归 daemon 管:浏览器连接、开着的标签、元素编号、网络记录。CLI 是跑完就退的一次性进程,它退不退都不影响这些,下次按编号(t5 这种)还能把同一个标签要回来。
为什么非得插件:Chrome 136 之后,默认用户目录不吃
--remote-debugging-port了,想复用日常浏览器的登录态就只能走插件。插件用chrome.debugger把 CDP 转出来,能力跟直连 CDP 一样。不想动自己的浏览器也行,seed-browser browser launch起一个专用的(可以无头),两种模式对上层是同一套接口。
这是最常用的命令。一个 B 站视频页,原始 HTML 二十三万字符,read 完两千字左右,该有的都在:
$ seed-browser read https://www.bilibili.com/video/BV1GJ411x7h7 -b
# 【官方 MV】Never Gonna Give You Up - Rick Astley
https://www.bilibili.com/video/BV1GJ411x7h7/
type: video · via: lib:bilibili.com · author: 索尼音乐中国 · published: 2019-12-31 23:43
video:
bvid: BV1GJ411x7h7
duration: 3:33
up: 索尼音乐中国 (mid 486906719)
stat: 播放 107145243 · 点赞 2951744 · 投币 1282325 · 收藏 1552657 · 评论 237317
分段(seed-browser read --section <id>):
- comments: 评论(237317 条,按热度)(按需加载)
- related: 相关推荐(40 个)
这个网站有函数库 bilibili.com(seed-browser call bilibili.com <函数> [参数]):
search(keyword, { limit = 20, type = 'video', order = 'totalrank' } = {}) — 搜索视频
comments(id, { limit = 50, sort = 'hot' } = {}) — 视频评论。sort:hot 热门 / time 最新
subtitles(id, { lang = '', text = false } = {}) — 视频字幕,按时间一句一行
summary(id) — B 站官方的 AI 视频总结:摘要 + 带时间点的提纲
… 共 17 个函数
标题、作者、播放数据、评论有多少条、怎么展开,一眼能看完。
长文章只关心其中几件事,就加 --grep '关键词1|关键词2',它只给你命中的段落,还标出这段在全文的位置(〔@6831〕),想接着读就 --offset 6831 跳过去。
我觉得最有用的是结尾那几行:读完页面,它顺手告诉 AI 这个网站有哪些现成的函数,AI 不用猜下一步能干什么。
seed-browser read <网址> # 后台开标签,读完关掉
seed-browser read -t t5 -b # 读已打开的标签,只看概要和分段
seed-browser read -s comments # 展开某一段
seed-browser read --grep '思考模式|测试集' -C 0
seed-browser read --offset 6000 # 接着往下读提取顺序是这样:这个域名的函数库里有 read 就用它;没有就走通用提取,先把结构化数据(meta / JSON-LD / __NEXT_DATA__)挑出来,然后是正文(Readability → Markdown)、列表(识别重复结构)、大纲。
每个网站的常用功能就是一个普通 JS 文件,导出几个 async 函数:
/* 站点笔记(B 站):评论接口的 oid 要用 aid,不是 bvid … */
/** 视频评论。sort:hot 热门 / time 最新
* @example comments('BV1GJ411x7h7', { limit: 20 }) */
export async function comments(id, { limit = 50, sort = 'hot' } = {}) {
const tab = await seedBrowser.tab('bilibili.com') // 复用你已登录的 B 站标签,没有就后台开一个
const v = await tab.fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${id}`)
…
await seedBrowser.sleep(300) // 翻页之间停 300ms,不然会被风控
}几句说明:
- 函数签名本身就是说明书。
limit = 50是数字,full = false是开关,帮助信息从签名和注释生成,不用再声明一遍 args 和 opts。 - 注释里写的例子是真会跑的。
seed-browser lib test bilibili.com把每个@example执行一遍,告诉你哪些坏了。 - 站点笔记写在文件最开头:接口怎么调、哪里有坑(签名、风控码、字段什么意思)。
seed-browser lib list bilibili.com时会显示出来,踩过一次的坑不用踩第二次。 - 错误码是统一的:
NEED_LOGIN/BLOCKED/EMPTY/NOT_FOUND/CHANGED,AI 看到 code 就知道该干什么。 - 找文件的顺序:
<项目>/.seed-browser/lib/→~/.seed-browser/lib/→ 仓库lib/,先找完整域名,再找上一级。
seed-browser lib list # 有哪些网站
seed-browser lib list bilibili.com # 签名、说明、例子、站点笔记
seed-browser lib test bilibili.com # 跑一遍 @example
seed-browser call bilibili.com comments BV1GJ411x7h7 --limit 20内置 50 多个网站,装了就能用(seed-browser lib list 看全部,带登录要求标记):
| 分类 | 网站 |
|---|---|
| 搜索 | google.com(含新闻、联想词、热搜、Trends)、bing.com、duckduckgo.com、baidu.com |
| 学术 / AI | arxiv.org、semanticscholar.org、openreview.net、huggingface.co、aistudio.google.com |
| 技术社区 | news.ycombinator.com、reddit.com、github.com、stackoverflow.com、v2ex.com、linux.do、medium.com、x.com、lobste.rs、producthunt.com |
| 视频 | youtube.com(含评论、字幕)、bilibili.com(含字幕、AI 总结、下载)、douyin.com |
| 中文资讯 / 社交 | weibo.com、zhihu.com、xiaohongshu.com、toutiao.com、weixin.qq.com、36kr.com |
| 外文新闻 / 参考 | reuters.com、bloomberg.com、bbc.com、substack.com、wikipedia.org、archive.org |
| 金融 | xueqiu.com、eastmoney.com、sina.com.cn、10jqka.com.cn、tdx.com.cn、finance.yahoo.com、barchart.com、binance.com、coingecko.com |
| 包和漏洞 | npmjs.com、pypi.org、crates.io、nvd.nist.gov、osv.dev |
| 政策 | gov.cn(国务院 / 部委文件列表、全文搜索、正文和附件) |
写函数库的细节见 docs/lib.md。
有些活没有接口,只能填表。比如发版上架,三个应用市场,三套不一样的表单,要填的资料散在 release/v2.4 文件夹里。AI 先把文件读一遍,然后开工。
先找标签、看页面。seed-browser tab list 找到你开着的三个后台,seed-browser snapshot 看一眼页面,每个输入框都带编号,哪些必填一眼就看得出来。
$ seed-browser snapshot -i -t t192
- textbox "* 版本号" [ref=e2]
- spinbutton "* 版本代码" [ref=e3]
- textbox "* 更新说明" [ref=e4]
- combobox "* 应用分类" [ref=e5]: 请选择 {options: 效率办公 | 学习教育 | 实用工具}
- button "* 应用截图(3–5 张)" [ref=e8]: 未选择任何文件
- button "提交审核" [ref=e11]
填就一条命令,传截图也是:
seed-browser fill e2=2.4.0 e3=240 e4=@更新说明.md e5=效率办公 -t t192
seed-browser upload e8 截图/01.png 截图/02.png 截图/03.png -t t192它不瞎猜。按名字点“提交审核”,页面上有两个,它把候选都列出来,不替你挑:
✗ [AMBIGUOUS] getByRole('button', { name: "提交审核" }) 匹配到 2 个元素
→ 候选:
1. button "提交审核" (标题栏)
2. button "提交审核" (底部操作栏)
操作完还会告诉你发生了什么。换成编号点,返回值直接说弹了确认框、页面跳走了:
$ seed-browser click e11 -t t192
ok: true
changes:
url: https://dev.xinghe-store.com/…/review/XH-20261013-0042
navigated: soft
dialogs:
- "confirm: 确认提交审核?… (accepted)"
编号过期它会提醒。三步向导点完“下一步”,旧编号就作废了,它让 AI 重新 snapshot,而不是点错地方:
✗ [STALE_REF] 编号 e1 无效:当前页面还没有 snapshot,或页面已经跳转
→ 先执行 `seed-browser snapshot` 获取新编号
每个错误都带错误码和下一步该做什么(→ 后面那行)。这些输出其实是写给 AI 看的。
其它给 AI 准备的细节:
- 目标元素四种写法:编号
e15、CSS 选择器(能穿透 open shadow DOM)、getByRole(...)/getByLabel(...)/getByText(...)。 - 页面局部重绘之后,旧编号会按“角色 + 名字 + 第几个”自动重新找,结果里会注明“重新定位过”。
- 带点击事件的 div / li 在 snapshot 里显示成
clickable,也有编号;canvas、地图这类用mouse click x y。 - 点之前会检查有没有被遮罩挡住,挡了就直接说是谁挡的(
COVERED)。 upload的目标可以是“点了会弹选文件窗口”的按钮;click --download会等下载完成,返回文件路径。
整个过程可以用 trace 录:点了哪、填了什么、最后提交给了哪个接口。
seed-browser trace start publish --goal "拾光笔记上架:三家应用市场"
# … snapshot / fill / upload / click(AI 操作,或者你自己在浏览器里点一遍)
seed-browser trace stop # 自动生成调查报告 ~/.seed-browser/traces/publish/report.md报告里有操作时间线、每一步触发了哪些接口、数据来自哪个接口的哪个字段、签名和翻页参数从哪来。AI 照着报告写成 publish.js,下次发版一条命令三家一起填完:
seed-browser run -f publish.js release/v2.5详见 docs/trace.md。
函数和函数之间可以用管道接。B 站搜出来的视频一行一条,直接流进下一个函数,评论就出来了:
seed-browser call bilibili.com search "xxx模型 实测" --limit 2 | seed-browser call bilibili.com comments - --limit 3 -o table
seed-browser call bilibili.com rank 知识 --limit 10 | seed-browser call bilibili.com video - -o csv > 知识区.csv这里我想说一下为什么把它做成管道:走管道,数据就不经过模型。
现在常见的做法是工具调用那一种,每调一次,结果都回到模型上下文里。你要取 5 个站的评论做交叉分析,就是 5 份原始结果全灌进上下文,token 全花在数据上。
管道不是。中间数据在进程之间流,模型只看到最后那一小段:
seed-browser call bilibili.com search 电影解说 --limit 5 | seed-browser call bilibili.com comments - --limit 3这条命令模型只发了一次,B 站返回的几百条评论它一条没看见,只看见 3 条。token 花在指令上,不是花在数据上。
能这么串,是因为每段命令都是跑完就退的一次性进程,状态都在 daemon 里,串十段也不会把登录态和标签串丢。每一步的结果还能落成文件,想重跑哪一步就重跑哪一步。
要更自由的组合,就用 seed-browser run 写几行 JS,几个网站随便拼:
seed-browser run 'await seedBrowser.tabs()'
seed-browser run 'const t = await seedBrowser.tab("zhihu.com"); return t.fetch("https://www.zhihu.com/api/v4/me")'
seed-browser run -f step1.js代码按 ES 模块执行,能顶层 await、能 import node:fs,return 的值会打印出来;结果太大就写到 ~/.seed-browser/out/,只打印摘要和路径。全局有个 seedBrowser:
seedBrowser.tab('t5') / seedBrowser.tab('zhihu.com') seedBrowser.open(url) seedBrowser.tabs() seedBrowser.read(url) seedBrowser.lib('reddit.com').search('x')
tab.eval(fn) tab.fetch(url) tab.click(目标) tab.fill(目标, 文字) tab.snapshot() tab.waitResponse(...) …
for await (const res of tab.collect('/api/search', { more: () => tab.scroll() })) { … } // 带签名的接口:让网站自己发请求,接住返回回到开头那个问题,AI 是这么一步步查清楚的:
- 广撒网:6 个网站同时搜(
Promise.allSettled,一个站挂了不影响别的),结果规整成同一种格式。B 站搜出来一堆上一代模型的旧视频,看一眼标题就跳过。 - 深挖讨论:说法正好相反,有人说吊打一切,有人说是在刷榜。
- 查一手资料:官方技术报告、公开榜单、网友的独立复测。
- 写报告:矛盾的说法摆在一起,每一条都带出处。
中间结果全写进文件(posts.json、threads.json 这些),哪一步都能单独重跑,上下文也不会被撑爆。完整示例见 skill/seed-browser/examples/cross-site-research。
一个网站从陌生到熟悉,大概是这么个过程:
seed-browser read 看一眼 → seed-browser run 里试(tab.eval 看页面数据、seed-browser net log 找接口、tab.fetch 调一下)
→ 试通了存成 ~/.seed-browser/lib/<域名>.js → 以后 seed-browser call / seedBrowser.lib() 直接用
摸通的网站存成函数,做过的流程存成脚本,用得越多它越熟这个互联网。
需要 Node 22.18+(直接运行 .ts),推荐 Node 24。
npm install
npm link # 之后就能直接用 seed-browser(或者 node bin/seed-browser.js)连你日常用的浏览器(推荐这个):打开 chrome://extensions → 开“开发者模式” → “加载已解压的扩展程序” → 选 extension/ 目录。想同时连多个浏览器或多个 profile,在插件设置里给它们各起个名字。升级 seed-browser 之后记得回扩展页点一下“重新加载”。
不想动自己的浏览器,就用专用的:
seed-browser browser launch # 独立 profile,存在 ~/.seed-browser/profiles/seed-browser,登录一次就一直在
seed-browser browser launch ci --headless接到 AI agent 上:把 skill/seed-browser/ 扔进你 agent 的 skills 目录(Claude Code、pi 这些认 SKILL.md 的都行),它遇到要上网的活就自己会用 seed-browser。
seed-browser help 看全部,seed-browser <命令> --help 看详情。所有命令都支持 -t <标签> 和 -o text|json|yaml|jsonl|csv|table。
| 分类 | 命令 |
|---|---|
| 浏览器 | browser list / launch / connect / disconnect |
| 标签 | tab list / open / use / close / activate / current,标签组 group list / create / update / ungroup(插件模式) |
| 看页面 | read [网址]、snapshot、find、shot、eval、console、dialogs、cookies |
| 操作 | goto back forward reload click fill type press select check uncheck hover scroll upload drag wait |
| 按坐标 / 按住键 | mouse click / move / down / up / wheel / drag、key down / up |
| 函数库 / 脚本 | run、call、lib list、lib test |
| 注入 / 网络 | inject add / list / rm、net log / show / wait / clear、net route add / list / rm |
| 录制 | trace start / mark / add / stop / list / digest / show / find / rm |
| 其它 | cdp <method> [json](直接发 CDP,逃生通道) |
bin/seed-browser.js 入口
src/cli/ 命令解析、输出格式、seed-browser run(run.ts)、seed-browser call / lib list(call.ts)、lib test(libtest.ts)
src/sdk/ 全局 seedBrowser 对象和 Tab 类(index.ts)、函数库加载和签名解析(lib.ts)
src/daemon/ daemon:注册表、会话、snapshot、元素定位(locate.ts)、操作、read
src/daemon/drivers/ 插件驱动 / CDP 驱动
src/inject/extract.js 注入页面的通用提取器
src/daemon/trace.ts trace 录制
src/trace/digest.ts 调查报告:去噪、归纳、数据溯源、参数溯源
extension/ 浏览器插件(MV3)
lib/ 内置函数库(_ 开头的是共享代码)
skill/seed-browser/ 给 AI agent 用的 skill(SKILL.md + 跨站调研示例)
promo/ 宣传片(HTML + 合成旁白),index-single.html 是单文件版
docs/ 设计文档、函数库和 trace 的详细说明
test/ 端到端测试(npm test)
npm test # 启动本地测试站点 + 无头 Chrome,跑端到端测试- 跨域 iframe(OOPIF)的 snapshot 和点击。要先实测插件模式下
chrome.debugger能不能往子 session 发命令,Vivaldi 上也要试。 - 后台标签防降速。现在 seed-browser 后台开的标签会打开
Emulation.setFocusEmulationEnabled(SEED_BROWSER_NO_FOCUS_EMULATION=1关掉),在懒加载页面上效果怎么样还要实测,必要时再加Page.setWebLifecycleState。 - 写操作确认、标签归属和借用、按域名的隐私策略,标签编号跨重启不变。
设计思路见 docs/design.md。