浏览器自动化的"持久身份":多会话认证与Agent技能的无缝集成实践
引言:Agent的"失忆症"困境
想象你雇佣了一个助理,他每天上班第一件事就是重新注册账号、重新登录所有系统、重新填写所有表单。这是不可想象的------但目前的AI Agent恰恰就是这样工作的。
在传统的浏览器自动化中,Agent面临一个根本性的身份困境:每个会话都是一张白纸。登录状态在会话结束时丢失,Cookie在重启后被清空,密码暴露在对话历史中,Selenium和Playwright驱动的Agent被网站轻松识别为机器人并拦截。当你的Agent需要执行需要认证的长时任务时,这种"失忆症"就成了致命的瓶颈。
"持久身份"(Persistent Identity)的概念正在改变这一现状。通过将浏览器会话、认证状态和凭证管理从Agent的临时执行环境中剥离出来,形成独立、可复用、跨会话持久的"浏览器身份",AI Agent终于能够像人类一样"记住"自己是谁。
一、核心概念:什么是"持久身份"?
持久身份是指为AI Agent分配一个独立、持久、隔离的浏览器环境,该环境具有以下特征:
- 会话持久化:Cookie、LocalStorage、IndexedDB、登录状态在Agent重启后仍然存活
- 凭证隔离:密码在容器内生成和存储,Agent从不接触原始凭证
- 抗检测性:通过OS级输入和真实浏览器指纹,绕过Selenium/Playwright触发的机器人检测
- 多身份并行:每个身份在自己的隔离容器中运行,拥有独立的Cookie、凭证和历史记录
#mermaid-svg-a6AxCr4hv9NiKCGY{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-a6AxCr4hv9NiKCGY .error-icon{fill:#552222;}#mermaid-svg-a6AxCr4hv9NiKCGY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-a6AxCr4hv9NiKCGY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-a6AxCr4hv9NiKCGY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-a6AxCr4hv9NiKCGY .marker.cross{stroke:#333333;}#mermaid-svg-a6AxCr4hv9NiKCGY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-a6AxCr4hv9NiKCGY p{margin:0;}#mermaid-svg-a6AxCr4hv9NiKCGY .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY .cluster-label text{fill:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY .cluster-label span{color:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY .cluster-label span p{background-color:transparent;}#mermaid-svg-a6AxCr4hv9NiKCGY .label text,#mermaid-svg-a6AxCr4hv9NiKCGY span{fill:#333;color:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY .node rect,#mermaid-svg-a6AxCr4hv9NiKCGY .node circle,#mermaid-svg-a6AxCr4hv9NiKCGY .node ellipse,#mermaid-svg-a6AxCr4hv9NiKCGY .node polygon,#mermaid-svg-a6AxCr4hv9NiKCGY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-a6AxCr4hv9NiKCGY .rough-node .label text,#mermaid-svg-a6AxCr4hv9NiKCGY .node .label text,#mermaid-svg-a6AxCr4hv9NiKCGY .image-shape .label,#mermaid-svg-a6AxCr4hv9NiKCGY .icon-shape .label{text-anchor:middle;}#mermaid-svg-a6AxCr4hv9NiKCGY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-a6AxCr4hv9NiKCGY .rough-node .label,#mermaid-svg-a6AxCr4hv9NiKCGY .node .label,#mermaid-svg-a6AxCr4hv9NiKCGY .image-shape .label,#mermaid-svg-a6AxCr4hv9NiKCGY .icon-shape .label{text-align:center;}#mermaid-svg-a6AxCr4hv9NiKCGY .node.clickable{cursor:pointer;}#mermaid-svg-a6AxCr4hv9NiKCGY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-a6AxCr4hv9NiKCGY .arrowheadPath{fill:#333333;}#mermaid-svg-a6AxCr4hv9NiKCGY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-a6AxCr4hv9NiKCGY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-a6AxCr4hv9NiKCGY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-a6AxCr4hv9NiKCGY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-a6AxCr4hv9NiKCGY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-a6AxCr4hv9NiKCGY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-a6AxCr4hv9NiKCGY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-a6AxCr4hv9NiKCGY .cluster text{fill:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY .cluster span{color:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-a6AxCr4hv9NiKCGY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-a6AxCr4hv9NiKCGY rect.text{fill:none;stroke-width:0;}#mermaid-svg-a6AxCr4hv9NiKCGY .icon-shape,#mermaid-svg-a6AxCr4hv9NiKCGY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-a6AxCr4hv9NiKCGY .icon-shape p,#mermaid-svg-a6AxCr4hv9NiKCGY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-a6AxCr4hv9NiKCGY .icon-shape .label rect,#mermaid-svg-a6AxCr4hv9NiKCGY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-a6AxCr4hv9NiKCGY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-a6AxCr4hv9NiKCGY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-a6AxCr4hv9NiKCGY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} AI Agent
持久身份1
持久身份2
持久身份N
隔离浏览器容器
隔离浏览器容器
隔离浏览器容器
凭证保险库
凭证保险库
凭证保险库
自动填充登录表单
Agent从未看到密码
二、会话持久化的三种实现模式
2.1 状态文件导出/导入
这是最基础的模式:将认证状态导出为JSON文件,在后续会话中导入。适用于需要在不同环境或不同Agent之间共享认证的场景。
Browser Use的实现:
python
from browser_use import Browser, Agent
# 导出认证状态
browser = Browser.from_system_chrome()
await browser.start()
await browser.export_storage_state('auth.json')
await browser.stop()
# 在后续会话中加载
browser = Browser(storage_state='auth.json')
agent = Agent(
task='检查我的通知',
browser=browser,
llm=ChatBrowserUse(),
)
await agent.run()
Browser Use在启动时自动从文件加载Cookie,并在运行期间持续保存更新。
agent-browser的实现:
bash
# 从已认证的Chrome导入认证状态
agent-browser --auto-connect state save ./my-auth.json
# 在后续会话中加载
agent-browser --state ./my-auth.json open https://app.example.com/dashboard
agent-browser支持通过--auto-connect直接读取正在运行的Chrome的会话状态,无需手动登录。
2.2 持久用户数据目录
使用Chrome的用户数据目录(userDataDir)实现真正的"一次登录,永久有效"。这种方式不需要显式的导出/导入操作,所有状态(Cookie、LocalStorage、IndexedDB、Service Workers)都在浏览器重启后自动恢复。
bash
# 第一次运行:登录一次
agent-browser --profile ~/.myapp-profile open https://app.example.com/login
# ... 完成登录流程 ...
# 后续运行:自动已认证
agent-browser --profile ~/.myapp-profile open https://app.example.com/dashboard
不同的Profile路径可以用于不同的项目或测试用户,实现身份隔离。
2.3 命名会话自动持久化
--session-name是agent-browser提供的更高级的抽象:无需手动管理文件路径,只需为会话命名,系统自动保存和恢复状态。
bash
# 自动保存状态,自动恢复
agent-browser --session-name twitter open https://twitter.com
# ... 完成工作 ...
# 下次启动,状态自动恢复
agent-browser --session-name twitter open https://twitter.com
结合加密功能,可以实现安全的认证状态存储。
三、安全凭证管理:Agent"看不见"的密码
持久身份的另一个核心能力是凭证管理。传统做法中,凭证要么硬编码在代码中,要么通过聊天传递,都会暴露给Agent和日志系统。
Navvi 提供了一种更安全的模式:凭证在容器内生成和存储,通过autofill自动填入表单,Agent全程看不见原始密码。
json
// 在 Claude Code 的 .mcp.json 中配置 Navvi
{
"mcpServers": {
"navvi": {
"command": "uvx",
"args": ["navvi@latest"],
"env": {
"NAVVI_GPG_PASSPHRASE": "your-passphrase-here"
}
}
}
}
// Agent只需用自然语言触发登录
"Log into Tutanota with stored credentials"
Navvi的Journey工具(navvi_browse、navvi_login)内部处理导航、元素查找、点击、输入和截图,Agent无需手动分步操作。
Camoufox Browser的Auth Vault采用AES-256-GCM加密存储凭证,Agent调用时仅通过填充操作触发自动填写,凭证从不输出到stdout:
bash
# 保存凭证(交互式输入主密码)
camofox auth save myprofile --url https://example.com
# 在浏览器中注入凭证(LLM安全)
camofox auth load myprofile
四、多会话隔离:并行身份的工程实践
在多用户或多任务场景中,需要同时运行多个独立的浏览器会话,每个拥有独立的Cookie、LocalStorage和浏览状态。
agent-browser的多会话支持:
bash
# 会话1:认证流程
agent-browser --session auth open https://app.example.com/login
# 会话2:公共浏览(独立的Cookie和存储)
agent-browser --session public open https://example.com
# 会话1的命令不会影响会话2
agent-browser --session auth fill @e1 "user@example.com"
agent-browser --session public get text body
每个会话拥有独立的:
- Cookies
- LocalStorage / SessionStorage
- IndexedDB
- 缓存
- 浏览历史
- 打开的标签页
并发抓取模式:
bash
# 启动所有会话
agent-browser --session site1 open https://site1.com &
agent-browser --session site2 open https://site2.com &
agent-browser --session site3 open https://site3.com &
wait
# 从各自会话中提取数据
agent-browser --session site1 get text body > site1.txt
agent-browser --session site2 get text body > site2.txt
agent-browser --session site3 get text body > site3.txt
OpenBrowser更进一步,提供了一个经纪人(Broker)架构,允许多个Agent共享一个浏览器池,每个Agent租用隔离的Chrome插槽,避免了多个Agent争抢同一CDP端口的问题。
五、Agent技能的无缝集成
持久身份的真正价值在于与Agent工作流的无缝集成。现代Agent框架通过两种方式实现这一点:
5.1 MCP Server集成
Navvi作为MCP Server运行,通过navvi_login、navvi_signup等工具将浏览能力暴露给Agent。Agent调用这些工具时,所有浏览器操作(导航、表单填充、凭证管理)都在MCP Server内部完成,Agent只需声明目标。
5.2 Skill封装
安装Navvi Skills后,Agent获得专用的浏览能力,将浏览器工作与主对话隔离:
bash
# 安装Navvi Skills
npx skills add fellowship-dev/navvi
包含的Skills:
- navvi-browse:视觉驱动的自主网页浏览
- navvi-login:使用存储凭证登录,处理reCAPTCHA和2FA
- navvi-signup:使用自动生成的凭证创建新账户
六、实践指南与最佳实践
6.1 优先使用持久Profile
对于需要长期认证的Agent,使用--profile或--session-name而非手动管理状态文件,避免额外复杂度。
6.2 安全处理状态文件
bash
# 不要提交到版本控制
echo "*.auth-state.json" >> .gitignore
# 使用加密
export AGENT_BROWSER_ENCRYPTION_KEY=$(openssl rand -hex 32)
6.3 使用命名会话语义化命名
bash
# 好的命名
agent-browser --session github-auth open https://github.com
agent-browser --session docs-scrape open https://docs.example.com
# 避免无意义命名
agent-browser --session s1 open https://github.com
6.4 显式清理会话
bash
agent-browser --session auth close
七、总结
浏览器自动化的"持久身份"正在将AI Agent从"一次性的访客"转变为"可信的长期用户"。通过会话持久化、安全凭证管理和多身份并行,Agent能够在跨会话中保持认证状态、管理多个身份、安全处理敏感凭证。
当你的Agent能够记住"我是谁"时,它才真正从"工具"进化为"助手"。