docs: add gorzil
This commit is contained in:
1 parent
540154a9e6
commit
11cb916228
1 file changed
+98
@@ -0,0 +1,98 @@
|
||||
---
|
||||
authors: cqh963852
|
||||
---
|
||||
|
||||
> 文章结构整理自 glm-5.3
|
||||
|
||||
# gorzil:面向多人协作的 AI 原生工具开发自述
|
||||
|
||||
## 为什么做
|
||||
|
||||
作为一个在工程效率上纠缠多年的工程师,我最近观察到一个现象:AI 编码工具越来越强,但它们始终是"单人玩具"。Cursor、Claude Code 这类产品默认一个开发者对着一个终端,多个 AI agent 之间的协作、人与人围绕 AI 工作过程的协作,基本是空白。
|
||||
|
||||
{/* truncate */}
|
||||
|
||||
我想做的事情可以概括为:多人 + 多 agent 共享同一个工作现场的工具。人发起任务,agent 执行,所有人(包括其他 agent)看到同一份不断演进的状态。
|
||||
|
||||
## 发生了什么
|
||||
|
||||
在这个开发过程中,我只负责提 ISSUE、把控架构和技术走向。总结性、文档性的工作交给了 ai,编码工作也让 ai 处理,结果好坏参半,后续也会提到。
|
||||
|
||||
## 核心设计
|
||||
|
||||
gorzil 是一个 Rust 多 Agent 协作平台,三个关键词:CRDT 协同、看板驱动、点对点数据同步。
|
||||
|
||||
### 数据本质是共享状态,不是消息流
|
||||
|
||||
这是整个项目最重要的一个技术决策。传统 IM(Slack 式)把协作建模为消息流,但 AI 协作的场景里,任务状态是不断被多方修改的:人创建任务、agent 领取、执行中、产出物挂回任务。如果用消息流建模,状态同步就是一场灾难。
|
||||
|
||||
所以选择了 CRDT,具体是 Loro。看板/房间状态是共享文档,agent 是文档间的翻译者,图片存引用而非二进制。同步难题由 CRDT 自然消解,不需要中心服务器做仲裁。
|
||||
|
||||
### 三端架构
|
||||
|
||||
```
|
||||
coord(公网):信令 + Logto 认证 + 组织管理 + TURN
|
||||
daemon(PC):本地 agent 宿主,接受 WebRTC,Loro 同步
|
||||
app(浏览器):Dioxus Web 客户端,发起 WebRTC,Loro 同步
|
||||
```
|
||||
|
||||
coord 只做信令和认证,不碰业务数据。数据在 daemon 和 app 之间通过 WebRTC DataChannel 点对点同步,P2P 失败时降级 coturn 中继。这个"云端尽量薄"的形态是有意为之——协作数据不应该经过我的服务器。
|
||||
|
||||
### 双 AI 审查的安全模型
|
||||
|
||||
本地 agent 要执行命令、改文件,安全是绕不开的问题。软件把风险暴露给用户做决策,是很常见的偷懒行为——即对风险不做设计,弹个窗让用户选,责任就转移出去了。
|
||||
|
||||
这是一种经典的工程师做法。静态规则也是同类问题:区分不了 `rm -rf` 清理 target 和清理 home 的区别,于是干脆都问用户。
|
||||
|
||||
但协作软件要面对的是不同身份的人群。既要减少风险对用户的干扰,也要保留工程师的安全审查能力。这两件事不能靠同一个机制完成。
|
||||
|
||||
在这里,gorzil 做了如下设计:
|
||||
|
||||
1. 减少干扰上
|
||||
引入 ai 辅助审查:在 tool_calls 提取和执行之间插入一个独立的审查 AI,做意图对齐判断——主 AI 要执行的动作,是否服务于用户的原始意图。审查 AI 的输入是净化过的结构化摘要,不接收主 AI 的原始上下文,从源头切断 prompt injection 的路径。已知危险命令走硬规则,语义模糊的才交给模型。
|
||||
|
||||
对于审查 AI 的额外要求是,接入用户足够信任的模型,不做中转站之类的危险做法——安全链路上如果再引入一个不受信任的环节,那就等于白做。
|
||||
|
||||
2. 审查能力上
|
||||
要处理的是传统 ai 群聊看不到 agent 工作过程的难题。群聊里 agent 只输出结论,过程是黑盒。虽然有些聊天工具可以不断更新当前的消息,但是我想,应该没有人愿意一直盯着 ai 在干什么。那样没有节省多少时间。
|
||||
|
||||
gorzil 的做法是把工作过程结构化:看板的任务操作记录,将看板任务抽象为 thread 下的引用,操作历史跟着任务走。
|
||||
|
||||
如果要看某个 agent 是怎么做的,则通过 agent doc 检查它的历史记录。工程师不再需要盯着消息流,而是直接审计过程本身。
|
||||
|
||||
### 被否决的路线
|
||||
|
||||
点对点通信、传输层曾经动摇过,最后还是使用 WebRTC 方案。最初的方案也是 WebRTC —— 自己做信令、自己管 ICE、自己部署 coturn。每一个步骤都是琐碎的活,甚至 ai 编码留下了 bug。
|
||||
|
||||
看到 iroh 后,优雅的抽象,地址即身份,打洞内置,看起来可以砍掉一大片代码。几乎要迁过去了,甚至开始规划迁移的步骤。
|
||||
|
||||
但是在让 ai 真正动手时,ai 说“出问题啦:浏览器端的 P2P 做不了”(一些技术上的限制)。
|
||||
|
||||
而 WebRTC 那套虽然琐碎,但每一件琐碎的事我都已经理解了。迁移到 iroh 并不会省掉我熟悉的麻烦,而且增加了我不熟悉的黑盒。
|
||||
|
||||
我最终的选择是那个已经踩过坑的方案。
|
||||
|
||||
### CRDT 增量同步的坑
|
||||
|
||||
wasm 端的 CRDT 增量同步是最痛苦的一段。由于 dioxus 是跨平台,rtc 有 native、wasm 两个端。最痛苦的是,不知道 bug 长什么样。
|
||||
|
||||
bug 修复大部分是 ai 在做。因为无法定位 bug,对 ai 的修复过程既不做严格审查,也不纠结代码对不对。协作方式只有两条:
|
||||
|
||||
1. 反复告诉 ai"出错了",让 ai 打日志,再把日志喂回去
|
||||
2. 后续让他自己控制浏览器去读日志
|
||||
|
||||
折腾到快要放弃 ai 修复,准备人手工处理时,glm-5.3 发布了。用对待 ai 的老方式尝试了一下,问题解决了(绷不住了)。
|
||||
|
||||
为了这个问题,大概燃烧了 2B 的 token。
|
||||
|
||||
解决后的第一件事,没有让 ai 接着做事,而是抓紧把集成测试用例写起来。
|
||||
|
||||
让 ai 趁着神志清晰的时候,把集成测试写上。不至于出现相同的错误时,再费劲告诉 ai 应该怎么做。
|
||||
|
||||
### UI 体系
|
||||
|
||||
UI 刚开始做,所以我几乎是 1:1 的模仿 Slack。三栏布局、频道、右侧详情面板,样式体系切到 daisyUI,抽了 gorzil-ui crate,配 storybook 和 Playwright 视觉基线。这部分编码工作 ai 参与度较高,因为组件迁移是模式明确的机械劳动。
|
||||
|
||||
但模仿的过程中一个问题一直悬着:如果我的软件在形式上和 Slack 几乎接近,那 Slack 也可以解决 gorzil 能解决的问题——除了技术核心不同。这个质疑我给不出反驳。CRDT、P2P、双 AI 审查都是看不见的东西,用户看见的就是又一个聊天软件。
|
||||
|
||||
所以我还在思考:软件的形式本身是否需要变化,才能更好地揭露问题、处理问题。看板驱动是我目前的一个答案——任务状态是一等公民,消息只是状态的注释。但这个答案对不对,要等真实使用之后才知道。形式追随的还是问题本身,而不是 Slack 的截图。
|
||||
Reference in new issue
Block a user