AI Agent跨平台部署测评:3个月浏览器迁移实战经验
在开发 CreatorWeave 时,一个棘手的问题长期困扰着我: Agent 的核心循环究竟该自行实现,还是直接复用现成方案?
自己手写的话,bug 层出不穷,LLM 的边界条件——流式中断、工具调用嵌套、不同 Provider 间的行为差异——远比预想的复杂。选现成方案呢?LangChain JS 过于臃肿,Vercel AI SDK 灵活性不足,其余框架要么缺失浏览器支持,要么 API 设计让人感觉像在写 Java。
最终选择了 @earendil-works/pi-agent-core。
本文就来聊聊选型理由,以及浏览器端踩过的那些坑。
pi-agent-core 到底是什么?
先简单介绍下它。
最初关注 pi-agent-core,源于 OpenClaw ——那个被全网“饲养”的“小龙虾”项目。2026 年初突然爆红,短短数月 GitHub 星标超过 25 万,问鼎有史以来增长最快的开源项目。翻阅其源码时,发现核心循环异常精简——顺着线索就找到了 pi。
pi 的哲学只有一句话: 不需要的,绝不画蛇添足。
它只提供四个工具:read、write、edit、bash。系统提示词不足 1000 token。不设 Plan 模式,不支持 MCP,没有子 Agent,也没有待办事项。运行模式?YOLO——全权交给你,后果自负。
听起来很激进吧?但正是这套极简主义架构,支撑起了目前全网最热门的编程 Agent。
pi 的架构分为三层:
| 层级 | 包名 | 职责 |
|---|---|---|
| LLM 统一 API | pi-ai | 多 Provider 适配、流式处理、工具调用、跨 Provider 上下文切换 |
| Agent 核心循环 | pi-agent-core | 工具调度、事件流、消息队列 |
| 终端产品 | pi-coding-agent | CLI 界面、会话管理、主题 |
实际只需要中间两层。
但表格只说明了 pi 自身,没有呈现 CreatorWeave 在其上的扩展。附一张完整架构图:
┌─────────────────────────────────────────────────┐
│ CreatorWeave 扩展层 │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ToolRegistry│ │ SubAgent │ │Context Manager│ │
│ │ 30+ 工具 │ │ 独立Agent │ │ 压缩+智能截断 │ │
│ └──────────┘ └───────────┘ └───────────────┘ │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │VFS 抽象 │ │ ToolPolicy│ │Prompt 增强 │ │
│ │3套存储统一│ │ 安全钩子 │ │STABLE+DYNAMIC │ │
│ └──────────┘ └───────────┘ └───────────────┘ │
├─────────────────────────────────────────────────┤
│ pi-agent-core 层 │
│ Agent 循环 · 事件流 · 消息队列 │
├─────────────────────────────────────────────────┤
│ pi-ai 层 │
│ 多 Provider 适配 · 流式 · 工具调用 │
└─────────────────────────────────────────────────┘
底层两层属于 pi,上面六块则是 CreatorWeave 自造的轮子。接下来详细说明。
选择它的理由
选型时,我认真对比了几个备选方案:
LangChain JS — 功能全面,但过于臃肿。仅 @langchain/core 就拖入大量依赖,浏览器打包后的体积令人咋舌。加之其 Agent 抽象层级过多,编写一个工具需要继承类、实现接口、注册到 registry……整套流程下来,感觉不像在写 Agent,更像在写 Java。
Vercel AI SDK — 轻量级,与 React 集成优秀,但它面向的是“对话式 UI”,而非“Agent 工具循环”。若想精细控制工具执行、上下文压缩、事件流等,这些都需要自行添加。
完全自研 — 并非没有考虑。但 LLM 的边界状况实在太多:OpenAI 的 reasoning_content 与 Anthropic 的 thinking 是不同字段;Cerebras 不支持 store 参数;Mistral 要求使用 max_tokens 而非 max_completion_tokens……这些陷阱,pi-ai 已经全部踩平。
最终选择 pi-agent-core,理由十分实在:
- 体积小巧 — 无黑魔法、无隐式注入,代码可读性高
- 浏览器友好 — pi-ai 原生支持浏览器运行,CORS 已妥善处理
- 事件流设计 — 每个步骤都触发事件(message_start、tool_execution_start、tool_execution_end),非常适合构建用户界面
- TypeBox schema — 工具参数类型安全,前端开发者倍感舒适
- 跨 Provider 支持 — 切换模型如同切换电台般流畅,上下文自动适配
归根结底: 它恰好够用,且不碍事。
浏览器端:五大棘手挑战
选完框架仅仅是开始。真正令人头疼的是: pi-agent-core 本为终端环境设计,现在却要跑在浏览器里。
两者环境差异,好比在自家厨房做饭(厨具齐全)与在野外露营(仅有一个便携炉子和两根木柴)的区别。
挑战一:缺失文件系统
终端中的 Agent 读文件?cat package.json。写文件?echo "hello" > file.txt。查找文件?find . -name "*.ts"。简单直接,一切皆可 bash。
浏览器呢?没有文件系统。你只能依靠 File System Access API ——用户手动授权一个文件夹后,才能读写其中的文件。未经授权?抱歉,无法接触。
而且浏览器中的文件操作全部是异步的,无法像 Node.js 的 fs.readFileSync 那样同步执行。当 Agent 要求“读取 package.json”,总不能让它等待 500ms 的异步回调吧?
解决方案: 构建了一个 VFS(虚拟文件系统)后端抽象层,统一管理三种存储:
| 存储后端 | 用途 | 底层实现 |
|---|---|---|
| workspace | 用户授权的本地文件 | File System Access API |
| agent | Agent 工作缓存 | OPFS |
| assets | 用户上传的临时文件 | OPFS |
对 Agent 而言,read("src/main.ts") 与终端操作一样自然——它无需知晓底层是本地文件还是 OPFS 缓存,也无须关心。
挑战二:没有 bash 环境
这是最令人头疼的问题。
pi-coding-agent 的哲学是“bash 搞定一切”——安装依赖?npm install。查看日志?tail -f。运行测试?pytest。一个工具包打天下。
浏览器中没有 bash、没有 shell、没有 npm、没有终端。如果你尝试 exec("ls -la"),浏览器只会茫然回应:你谁?我在哪?
解决方案: 将 bash 的功能拆解为 30 多个专用工具。看似数量庞大,但每个工具职责单一,比 bash 更精确:
bash: "cat src/main.ts | head -20" → read(path, limit: 20)
bash: "grep -r 'TODO' src/" → search(query: "TODO", path: "src/")
bash: "ls src/components/" → ls(path: "src/components/")
bash: "sed -i 's/old/new/g' file.ts" → edit(path, old_text, new_text)
bash: "python3 analyze.py" → python(code: "...")
有些事情确实无法替代——例如网页搜索,可通过浏览器扩展桥接。但大多数常见操作,专用工具比 bash 更安全、更可控,且消耗更少 token。
用 30 个精确工具替代一个万能 bash,本质是用约束换取安全。 浏览器不允许你持有一把万能钥匙,那就为每扇门配备专属钥匙——虽然数量增加,但每把钥匙只能打开对应的门。
挑战三:工具数量从 4 个膨胀至 30 多个
pi-coding-agent 仅用 4 个工具,系统提示词不足 1000 token。
CreatorWeave 呢?30+ 内置工具、MCP 工具、WebMCP 工具、WASM 插件、Skills 工具。工具描述合计消耗数千 token。
问题随之而来: 工具越多,LLM 越容易误选。
如果你要求“帮我搜一下项目中的 TODO”,它可能调用 search(正确),也可能调用 read(错误),甚至可能调用 python 并写一段 grep 代码(离谱但真实发生过)。
解决方案:
- 工具分组 — 按功能类别划分(文件操作、执行、Git、SubAgent 等),指导 LLM “对应需求寻找对应工具”
- 模式过滤 — Plan 模式仅暴露只读工具,Act 模式才允许写操作。如此 Agent 在“观察”阶段不会擅自修改代码
- 工具推荐 — 在系统提示词中加入工具使用规则,明确指示 LLM:“搜索文件请用 search,不要用 python 写 grep”
但这些仅是权宜之计。LLM 接口能容纳的工具数量存在上限,一旦 WebMCP 正式发布,工具列表可能急剧膨胀——从几十个到几百个。到那时仅靠分组和过滤将难以应对。后续需要研究 tool search:让 LLM 先搜索可用工具,再决定调用哪个,而不是将全部工具描述塞入上下文。
挑战四:上下文窗口更加紧俏
终端环境通常每个会话只处理一个问题。浏览器端呢?用户可能同时打开 3 个工作区,每个工作区拥有独立的对话历史。
而且浏览器端工具返回的结果可能非常庞大——例如 search 一个大项目,返回 200 条匹配,每条附带 3 行上下文,总计 600 行。塞进上下文?窗口直接爆满。
解决方案:三道防线
- 分层 Prompt 缓存 — 系统提示词分为 STABLE 层(人格+模式,利于缓存)和 DYNAMIC 层(Skills+日期,每轮变化),最大化利用 LLM 的 Prompt Cache
- 上下文压缩 — 上下文使用量超过 85% 时自动触发压缩,利用 LLM 生成摘要替换旧消息。同时引入 Baseline 机制:记录压缩截止时间戳,下次仅加载 [摘要] + [新消息]
- 工具结果智能截断 — search 结果过大?使用二分查找确定最多能容纳的结果条数。并非粗暴截断后半部分,而是确保返回的始终是合法 JSON
你没看错,在 Agent 系统中实现了二分查找——查找插入点,确保返回的永远是完整合法的 JSON,而非截断一半的乱码。现实就是这么魔幻。
挑战五:安全模型迥异
pi-coding-agent 的态度是:YOLO(你只管上,后果自负)。赋予全部权限,由你自己负责。这非常 Unix 哲学,也很省心。
浏览器的态度截然相反: 默认沙盒隔离,按需授权。
用户授权了 A 文件夹,读取 B 文件夹即属越权。Agent 想删除 .env 文件?不允许。Agent 想执行 rm -rf /?绝无可能。
但这并非限制, 而是优势。 浏览器的沙盒机制天生更安全,也更贴合普通用户的需求——多数用户不愿赋予 AI 全部权限,只希望 AI 在指定范围内工作。工作区隔离使得多个工作区能同时处理不同任务,互不干扰。
解决方案:双重防护 + 变更审批
- Plan/Act 双模式 — Plan 模式下只暴露只读工具(read、search、ls),Agent 只能查看不能修改。用户确认后再切换到 Act 模式。类似于 Git 的 dry-run,先审查变更再执行
- ToolPolicy — 在工具执行前设置钩子,检查路径是否位于保护列表(
.env、.git、.ssh),检查命令是否匹配危险模式(rm -rf /、curl | sh)。命中则拦截 - 变更审批 — 基于 OPFS 实现类似 Git 的版本管理,所有文件修改先进入待审批状态,用户确认后才正式生效。每个工作区独立隔离,多工作区并行互不干扰
我们打造了哪些轮子
总结一下,在 pi-agent-core 之上,CreatorWeave 增加的层级:
ToolRegistry — 工具注册中心
采用单例模式,支持运行时动态注册/注销。内置工具为基石,MCP/WebMCP/WASM Plugin/Skills 按需注入。所有工具输出统一为 ToolEnvelopeV2 信封格式——{ ok: true, data } 或 { ok: false, error }。前端解析工具结果时再无需猜测格式。
SubAgent 子系统
每个子 Agent 都是一个完整的 AgentLoop 实例——并非执行预定义脚本的傀儡,而是具有独立上下文、能自主调用工具的“分身”。状态转换采用 CAS(Compare-And-Swap)进行乐观并发控制,使用 SQLite 实现持久化。页面刷新?没问题,活跃任务会被标记为 SESSION_INTERRUPTED,下次打开可继续执行。
另外实现了健康检测:若子 Agent 状态显示“完成”,但输出内容极短且伴随大量工具调用,大概率是 API 中断——自动检测到该情况,并提示用户恢复执行。
上下文管理器
上下文压缩、Baseline 机制、工具结果智能截断——挑战四中提到的三道防线,均由它统一协调。
提示词增强
IntelligenceCoordinator 负责注入人格、记忆、项目上下文。提示词分为 STABLE(利于缓存)和 DYNAMIC(每轮变化)两层,最大化利用 LLM 的 Prompt Cache,节省成本与时间。
经验总结
- 终端极简合理,但浏览器不能盲目极简 — pi-coding-agent 凭借 4 个工具成就了全网最火的编程 Agent,少即是多;但浏览器场景过于复杂,4 个工具难以覆盖,总不能要求用户在浏览器里运行 bash。这矛盾吗?不——终端与浏览器是不同世界,各有其“恰到好处”的配置
- 工具增多伴随代价 — 30 个工具的描述占用数千 token,LLM 更易误选。选对工具远比增加工具重要,后续可能需要引入 tool search 解决膨胀问题
- 上下文是最稀缺资源 — 每次工具调用都在消耗窗口容量,必须精打细算。二分查找截断、上下文压缩、分层缓存,本质都是在争夺窗口空间
- 浏览器沙盒是优势而非限制 — 默认隔离、按需授权、变更审批、工作区隔离,这些并非“不如终端”,而是比 YOLO 更适合“面向普通用户”的产品设计
pi-agent-core 是一个优秀的起点——小巧、清爽、不添堵。但它并非为浏览器场景设计。CreatorWeave 在其上构建了一层“浏览器端 Agent 基础设施”,专门处理文件系统、工具编排、上下文管理、安全管控等浏览器特有的问题。
这套方案仍在持续迭代。如果你对浏览器端 AI Agent 感兴趣,欢迎查阅源码、提交 PR,或直接拍砖讨论。
