开源Libretto让AI代劳浏览器自动化维护,可录屏、抓API、修脚本,把脆弱的UI自动化变成稳定的网络请求调用。
我们为什么需要Libretto
如果你写过任何需要登录网站才能抓数据的脚本,你一定经历过这种绝望:上周还好好的代码,这周就因为一个按钮的class名字从“submit-btn”变成了“submit-button”,整个程序直接崩溃。你打开浏览器调试工具,像个考古学家一样在DOM树里翻来翻去,试图找到那个该死的选择器到底变成了什么。
这种痛苦Saffron Health团队太懂了。他们每天要跟各种医疗软件对接,那些软件的UI变化比时尚杂志的封面还快。但他们没有选择继续在痛苦中挣扎,而是造了一个工具叫Libretto。这个工具的核心逻辑特别反讽:你不是总抱怨浏览器自动化脚本太脆弱吗?那我们就给你的AI编程助手配一个真正的浏览器,让它亲眼看着网页长什么样,而不是靠你手工写的那些碰运气选择器。
Libretto的本质是一个工具包,它让你代码里的AI助手能直接操控一个真实的浏览器实例。这意味着当你对AI说“去LinkedIn把前十条帖子的内容、点赞数和评论都扒下来”时,它不会给你生成一段瞎子摸象般的Playwright代码,而是自己打开浏览器窗口,自己登录,自己滚动页面,自己提取数据。你只需要坐在旁边喝茶,欣赏它为你表演。
安装流程:一条命令搞定,比你点外卖还简单
安装Libretto的第一步就是运行npm install libretto。这条命令会从npm仓库把Libretto的主体代码拉到你的node_modules里。但真正有意思的是后面这条命令:npx libretto setup。这条命令会做三件事:安装技能模块、下载Chromium浏览器内核、然后把当前最适合你的AI模型配置自动写到配置文件里。
为什么说这个设计很聪明?因为大多数开发者卡在浏览器自动化工具上的第一步就是环境配置。你要手动下载对应版本的Chrome,要配置驱动路径,还要处理各种操作系统差异。Libretto直接把整个Chromium给你打包好,setup命令运行完,你的工作空间就已经准备好了。
你可以随时运行npx libretto status来检查当前的工作空间状态。这个命令会告诉你两件事:你的AI模型配置是不是健康,以及当前有没有正在运行的浏览器会话。如果setup检测到你机器上有OpenAI的API密钥,它会自动把默认模型设为gpt-5.4。如果你连密钥都没配置,它会进入一个交互式的修复流程,一步一步引导你把缺的东西补上。
如果你想手动更换AI提供商,可以用npx libretto ai configure 。这条命令会覆盖.libretto/config.json里的模型配置。你可以从OpenAI切换到Anthropic的Claude,或者切换到Google的Gemini,甚至用Vertex AI上的自定义模型。这种灵活性意味着你不必被任何一家云厂商绑定。
使用场景一:一句话生成完整脚本,AI自己登录自己爬
Libretto最让人眼前一亮的功能就是它可以通过自然语言直接生成自动化脚本。你只需要对你的编程助手说:“用Libretto技能,去LinkedIn抓取前十条帖子的内容、发布者、点赞数、前25条评论和前25条转发。”你的AI助手会立刻调用Libretto打开一个浏览器窗口,然后你自己手动登录LinkedIn(因为LinkedIn的反爬机制会拦截自动化登录),登录完成后,AI就会接管浏览器,开始自动探索页面结构。
这个过程的神奇之处在于,AI不是在靠你写的脆弱选择器定位元素,而是通过Libretto的快照分析功能实时理解当前页面的DOM树。Libretto会把页面的截图和HTML结构一起发给配置好的AI模型,让模型自己判断“内容文本在哪个div里”“点赞数在哪个span里”。这种动态分析的方式比硬编码选择器可靠得多,因为即使页面的class名变了,只要内容的结构逻辑没变,AI依然能找对地方。
你可能会问,这不就是给AI配了个视觉能力吗?没错,但Libretto的精妙之处在于它把视觉理解的开销控制得非常好。它不会把整个页面的截图原封不动塞给你的AI模型,而是先做一轮预处理,提取出最关键的可交互元素和文本块,然后用token高效的格式传给模型。这样一来,你的AI助手不会被巨量的视觉token烧穿钱包。
使用场景二:你自己点一遍,AI就能复制你的操作
Libretto的另一个变态功能是它可以录制你的操作,然后重放成自动化脚本。你只需要对你的AI助手说:“我现在要在eClinicalWorks的电子病历系统里演示一个获取病人主保险ID的工作流程,你用Libretto把它变成一个Playwright脚本,输入病人姓名和出生日期就能返回保险ID。”
然后你就可以在Libretto打开的浏览器里正常操作:点击菜单、输入姓名、选择日期、点击查询按钮、复制保险ID。Libretto会在后台记录你所有的点击、输入和导航动作,把这些动作存成actions.jsonl文件。等你演示完,你只需要告诉AI“用我刚刚的操作重建这个工作流”,AI就会读取这些记录,生成一个标准的Playwright脚本。
这个功能对非程序员特别友好。比如你的业务分析师或者测试人员可以自己演示一遍正确的操作流程,然后直接把录制的动作交给AI去生成代码。你不需要让不懂代码的人去写选择器,也不需要让懂代码的人去猜业务操作的具体步骤。Libretto在这里扮演了一个翻译官的角色,把人类的鼠标点击翻译成机器可以执行的自动化指令。
而且这个录制功能不是简单的坐标记录。它不会傻到记下“在坐标(350, 480)的位置点击”,而是分析你点击的元素,提取出稳定的选择器特征,比如文本内容、aria标签、或者相对位置路径。这样即使浏览器窗口大小变了,或者页面布局微调了,重放的时候依然能找到正确的元素。
使用场景三:把UI自动化变成网络请求,又快又稳
Libretto最反直觉的功能是它能帮你从UI自动化逆向出网络请求脚本。你可以对它说:“我们有个integration.ts脚本,它用浏览器自动打开Hacker News然后抓取前十篇文章。你把它转成直接调用网络请求的脚本,用Libretto技能。”
Libretto会打开那个脚本里指定的URL,然后一边执行一边记录浏览器发出的所有网络请求。这些请求会存在.libretto/sessions/<会话名>/network.jsonl文件里。然后Libretto会分析这些请求,找出哪个请求返回了页面上的文章列表数据。通常网站都会有一个API接口返回JSON格式的数据,比如/api/v1/topstories.json。Libretto会把这个接口的URL、请求方法、请求头、参数全部提取出来,然后生成一段直接调用这个接口的Node.js脚本。
直接调用API比操作浏览器快得多,也稳定得多。浏览器自动化需要等待页面加载、等待JavaScript执行、等待DOM树渲染,每一步都有不确定的延迟。而直接调用API就是一个HTTP请求的事,几十毫秒就能拿到数据。而且API的接口变化频率远低于UI的变化频率,所以这种脚本的维护成本会大幅下降。
你还可以让Libretto做安全分析。它会检查这些网络请求里有没有常见的认证cookie,比如sessionid、token、authorization之类的字段。这样你就能判断直接用网络请求的方式是不是安全的。如果一个网站把用户身份信息放在cookie里,而且这个cookie在非浏览器环境下也能用,那你的网络请求脚本就能正常跑。如果网站用了某些只能在浏览器环境里生成的反爬token,那你可能还得老老实实用UI自动化。
使用场景四:脚本坏了?让Libretto自己修自己
你可能遇到过这种情况:你写好的自动化脚本跑了一个月,突然某天报了一个“找不到选择器”的错误。你打开浏览器,发现那个按钮从“Next”变成了“Continue”,class也变了。传统做法是你手动打开开发者工具,重新找一遍选择器,然后改代码,再跑一遍测试。
Libretto把这个过程也自动化了。你可以对你的AI助手说:“我们有个integration.ts脚本,它应该去Availity系统里给病人做资格检查,但我运行的时候报了一个选择器错误。你帮我修一下,用Libretto技能。”
AI会调用Libretto重新运行这个失败的脚本。当脚本在某个步骤卡住的时候,Libretto不会直接崩溃退出,而是会暂停执行,然后对当前页面做一个快照。这个快照包括截图和HTML结构,然后Libretto会把快照发给AI模型,让模型分析为什么之前的选择器现在失效了。模型可能会发现“原来那个按钮的文本从‘Check Eligibility’变成了‘Verify Coverage’,所以你应该用新的文本去定位”。
然后AI会自动修改脚本里的选择器,重新运行一遍,如果还失败就继续分析,直到脚本能完整跑通为止。整个过程不需要你手动介入。这就像你雇了一个永远不会累的实习生,专门盯着你的自动化脚本,一有异常就自己想办法修。
命令行工具详解:每个开关都有它的脾气
Libretto也可以直接在命令行里使用,不一定要通过AI助手。所有命令都接受--session <名称>参数,用来指定你要操作哪个浏览器会话。如果你不指定,Libretto会使用一个默认的会话。
npx libretto open <网址>会启动一个浏览器并打开指定的URL。默认是有头模式,也就是你会看到一个真正的浏览器窗口弹出来。如果你喜欢安静的后台运行,可以加--headless参数。
npx libretto snapshot --objective “目标描述” --context “上下文信息”是Libretto的核心命令。它会截取当前页面的截图和HTML快照,然后发送给你配置好的AI模型进行分析。--objective参数告诉模型你要在这个页面上达成什么目标,比如“找到登录表单”。--context参数提供额外的背景信息,比如“这个页面是医疗门户的首页”。模型会根据截图和HTML给出具体的操作建议或者元素选择器。
npx libretto exec “<代码>”允许你直接在当前打开的页面上执行Playwright TypeScript代码。比如你可以执行npx libretto exec “await page.click(‘text=登录’)”来点击页面上文本为“登录”的按钮。这个命令接受单引号包裹的代码字符串。你也可以用管道输入:echo “await page.click(‘text=登录’)” | npx libretto exec -,那个短横线表示从标准输入读取代码。
npx libretto run <文件>会运行一个导出了默认工作流的文件。这个工作流是一个标准的Playwright测试脚本,Libretto会加载并执行它。如果工作流里调用了await libretto.pause(),执行会暂停,然后你可以用npx libretto resume命令恢复运行。这个暂停恢复机制在调试复杂交互的时候特别好用,你可以暂停下来,手动检查页面状态,然后继续让脚本跑。
npx libretto pages会列出当前会话里所有打开的页面,包括每个页面的标题和URL。npx libretto save <域名>会把当前浏览器会话的cookie和localStorage保存下来,存成一个profile文件。下次你对着同一个域名跑自动化时,可以用npx libretto open --profile <域名> <网址>来复用之前保存的登录状态。这意味着你不需要在每次跑脚本的时候都手动登录一遍。
npx libretto close会关闭当前会话的浏览器。如果你忘了关也没关系,Libretto会在一段时间后自动清理僵尸进程。
配置文件揭秘:你的设置都藏在.libretto里
Libretto的所有状态都存放在项目根目录下的.libretto/文件夹里。这个文件夹应该被加入.gitignore,因为它里面存的是运行时状态,不是项目源码。
配置文件只管两件事:用哪个AI和窗口多大
.libretto/config.json是这个工具的核心配置文件。它的内容很简单:
{ |
ai.model字段指定了Libretto用哪个AI模型来做快照分析。这个模型的职责是分析页面的截图和HTML,然后帮你找出正确的选择器、判断可交互元素、诊断步骤失败的原因。viewport字段设置了浏览器窗口的默认尺寸。这两个字段都是可选的,如果你不配置viewport,Libretto会用1280x800作为默认值。
npx libretto setup会自动配置AI模型。它会扫描你机器上的环境变量,找到第一个可用的提供商密钥,然后把对应的默认模型写进config.json。扫描顺序通常是OpenAI、Anthropic、Gemini、Vertex。如果你同时有OpenAI和Anthropic的密钥,它会优先选OpenAI。如果你想强制换一个提供商,用ai configure命令就行。
提供商密钥的读取方式也很灵活。Libretto会读环境变量,也会读项目根目录下的.env文件。对应的变量名是:OPENAI_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY或GOOGLE_GENERATIVE_AI_API_KEY,以及Vertex用的GOOGLE_CLOUD_PROJECT。如果你不想让Libretto读取.env文件,可以设置环境变量LIBRETTO_DISABLE_DOTENV=1。
会话管理:每个浏览器实例都有自己的户口本
每个Libretto会话在.libretto/sessions/<会话名>/下面有自己的文件夹,里面存着运行时状态。这个文件夹被git忽略,不会污染仓库。具体内容:
- state.json存调试端口、进程ID、会话状态
- logs.jsonl存结构化日志
- network.jsonl存抓到的所有网络请求
- actions.jsonl存录下的用户操作
- snapshots/文件夹存截图和HTML快照
你可以随时翻看这些文件,复盘AI当时看到了什么页面、发了什么请求。调试的时候特别有用,比如AI选错了按钮,你打开截图一看就知道页面改版了。
这套档案系统让你可以完整复盘一个自动化脚本的整个生命周期。如果某个脚本在凌晨三点崩溃了,你第二天早上可以打开snapshots/文件夹,看看崩溃那一刻的页面到底长什么样。你也可以打开network.jsonl,检查是不是某个API请求返回了500错误。这种可追溯性是调试复杂自动化问题的重要武器。
保存登录状态,下次直接用,不用重复扫码
很多网站每次登录都要扫码或者二次验证,烦得要死。
Libretto的profile功能帮你解决这个问题。
用npx libretto save <域名>就能把当前浏览器会话的cookie和localStorage存下来,存在.libretto/profiles/<域名>.json里。下次用npx libretto open --profile那个域名,浏览器自动恢复登录状态,直接干活。
这个文件也是本地专属,不会提交到git。