AI Agent跨平台部署测评:3个月浏览器迁移实战经验

2026-06-20阅读 0热度 0
浏览器

在开发 CreatorWeave 时,一个棘手的问题长期困扰着我: Agent 的核心循环究竟该自行实现,还是直接复用现成方案?

我花了3个月,把一个终端 AI 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 统一 APIpi-ai多 Provider 适配、流式处理、工具调用、跨 Provider 上下文切换
Agent 核心循环pi-agent-core工具调度、事件流、消息队列
终端产品pi-coding-agentCLI 界面、会话管理、主题

实际只需要中间两层。

但表格只说明了 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,理由十分实在:

  1. 体积小巧 — 无黑魔法、无隐式注入,代码可读性高
  2. 浏览器友好 — pi-ai 原生支持浏览器运行,CORS 已妥善处理
  3. 事件流设计 — 每个步骤都触发事件(message_start、tool_execution_start、tool_execution_end),非常适合构建用户界面
  4. TypeBox schema — 工具参数类型安全,前端开发者倍感舒适
  5. 跨 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
agentAgent 工作缓存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 代码(离谱但真实发生过)。

解决方案:

  1. 工具分组 — 按功能类别划分(文件操作、执行、Git、SubAgent 等),指导 LLM “对应需求寻找对应工具”
  2. 模式过滤 — Plan 模式仅暴露只读工具,Act 模式才允许写操作。如此 Agent 在“观察”阶段不会擅自修改代码
  3. 工具推荐 — 在系统提示词中加入工具使用规则,明确指示 LLM:“搜索文件请用 search,不要用 python 写 grep”

但这些仅是权宜之计。LLM 接口能容纳的工具数量存在上限,一旦 WebMCP 正式发布,工具列表可能急剧膨胀——从几十个到几百个。到那时仅靠分组和过滤将难以应对。后续需要研究 tool search:让 LLM 先搜索可用工具,再决定调用哪个,而不是将全部工具描述塞入上下文。

挑战四:上下文窗口更加紧俏

终端环境通常每个会话只处理一个问题。浏览器端呢?用户可能同时打开 3 个工作区,每个工作区拥有独立的对话历史。

而且浏览器端工具返回的结果可能非常庞大——例如 search 一个大项目,返回 200 条匹配,每条附带 3 行上下文,总计 600 行。塞进上下文?窗口直接爆满。

解决方案:三道防线

  1. 分层 Prompt 缓存 — 系统提示词分为 STABLE 层(人格+模式,利于缓存)和 DYNAMIC 层(Skills+日期,每轮变化),最大化利用 LLM 的 Prompt Cache
  2. 上下文压缩 — 上下文使用量超过 85% 时自动触发压缩,利用 LLM 生成摘要替换旧消息。同时引入 Baseline 机制:记录压缩截止时间戳,下次仅加载 [摘要] + [新消息]
  3. 工具结果智能截断 — search 结果过大?使用二分查找确定最多能容纳的结果条数。并非粗暴截断后半部分,而是确保返回的始终是合法 JSON

你没看错,在 Agent 系统中实现了二分查找——查找插入点,确保返回的永远是完整合法的 JSON,而非截断一半的乱码。现实就是这么魔幻。

挑战五:安全模型迥异

pi-coding-agent 的态度是:YOLO(你只管上,后果自负)。赋予全部权限,由你自己负责。这非常 Unix 哲学,也很省心。

浏览器的态度截然相反: 默认沙盒隔离,按需授权。

用户授权了 A 文件夹,读取 B 文件夹即属越权。Agent 想删除 .env 文件?不允许。Agent 想执行 rm -rf /?绝无可能。

但这并非限制, 而是优势。 浏览器的沙盒机制天生更安全,也更贴合普通用户的需求——多数用户不愿赋予 AI 全部权限,只希望 AI 在指定范围内工作。工作区隔离使得多个工作区能同时处理不同任务,互不干扰。

解决方案:双重防护 + 变更审批

  1. Plan/Act 双模式 — Plan 模式下只暴露只读工具(read、search、ls),Agent 只能查看不能修改。用户确认后再切换到 Act 模式。类似于 Git 的 dry-run,先审查变更再执行
  2. ToolPolicy — 在工具执行前设置钩子,检查路径是否位于保护列表(.env.git.ssh),检查命令是否匹配危险模式(rm -rf /curl | sh)。命中则拦截
  3. 变更审批 — 基于 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,节省成本与时间。

经验总结

  1. 终端极简合理,但浏览器不能盲目极简 — pi-coding-agent 凭借 4 个工具成就了全网最火的编程 Agent,少即是多;但浏览器场景过于复杂,4 个工具难以覆盖,总不能要求用户在浏览器里运行 bash。这矛盾吗?不——终端与浏览器是不同世界,各有其“恰到好处”的配置
  2. 工具增多伴随代价 — 30 个工具的描述占用数千 token,LLM 更易误选。选对工具远比增加工具重要,后续可能需要引入 tool search 解决膨胀问题
  3. 上下文是最稀缺资源 — 每次工具调用都在消耗窗口容量,必须精打细算。二分查找截断、上下文压缩、分层缓存,本质都是在争夺窗口空间
  4. 浏览器沙盒是优势而非限制 — 默认隔离、按需授权、变更审批、工作区隔离,这些并非“不如终端”,而是比 YOLO 更适合“面向普通用户”的产品设计

pi-agent-core 是一个优秀的起点——小巧、清爽、不添堵。但它并非为浏览器场景设计。CreatorWeave 在其上构建了一层“浏览器端 Agent 基础设施”,专门处理文件系统、工具编排、上下文管理、安全管控等浏览器特有的问题。

这套方案仍在持续迭代。如果你对浏览器端 AI Agent 感兴趣,欢迎查阅源码、提交 PR,或直接拍砖讨论。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策