Skip to content
← 全部文章

把一个 AGPL 面板改造成产品:一份公开的建造日志

把开源项目 fork 成一个有自己名字的东西,实际要做哪些事——埋点、商业位、起名,以及那些做错了的部分。

5 分钟读完 建造日志开源

GambaOS 起初是 ClawPanel 的一个分支——一个 AGPL 许可的 AI Agent 控制面板。这篇记的是「把它变成一个独立维护的产品」实际都干了些什么。趁它还没做完就写,因为一旦东西正式上线,有意思的细节就都被磨平了。

我是一个人、用晚上的时间、当副业在做这件事。下面的一切请当作一个人的经验,而不是方法论。

为什么是 fork,而不是自己写

老实的回答是:这类面板真正的难点不在想法,而在面积——Agent 运行时、模型服务商、渠道适配、会话管理、定时任务、日志。这是一大堆基本属于管道工的集成工作,从零复刻一遍最后到达同一个位置,是对我唯一真正缺的那个资源——时间——的糟糕使用。

我想加进去的是一个观点:自部署 Agent 真正会出事的就两件事,网络暴露和成本失控;面板应该围绕「让人注意到这两件事」来建,而不是围绕「罗列功能」来建。

AGPL 在一个意义上让这件事很直接——fork 的权利是明文的;在另一个意义上又立了个具体的义务:我做的东西必须以同一个许可证保持开源。这个约束塑造了整个商业计划,后面会说回来。

大部分工作是在做减法

我以为开头那段时间会花在加功能上。实际上花在了删东西上。

埋点。 上游带了使用情况统计。我是把代码删掉,而不是加一个开关去关掉它。这件事比听上去重要:「有个开关可以关掉」和「代码根本不在那儿」是两种不同的声明,而只有后者经得起一个读者自己去核。既然整套说辞的前提是请人把 API 密钥交给这个面板,这个区别本身就是产品。

商业位。 开源项目需要钱,上游做的是合理的事:赞助位、返佣码、打赏地址、兄弟产品链接。这些必须全部拿掉——一个带着别人返佣码的分支不是独立产品,是个联盟营销站。

替代方案是一个数据驱动的空槽位:一个什么都没有的列表,因此什么都不渲染。等我自己有了合作,加一条数据,UI 就自动出现。另外还有一个测试,一旦源码里重新出现任何旧返佣码就会失败——因为这种事现实中发生的方式不是有意为之,而是几个月后一次不小心的合并。

改名。 一个 fork 里残留原名的地方比你以为的多得多:配置路径、应用标识符、存储键、User-Agent、窗口标题、文档。这次改名动了 174 个文件。

真正需要小心的是运行时状态。已有的安装是用旧身份写下数据的,而一次「悄悄弄丢别人配置」的升级,是那种和外观 bug 不在一个量级上的、不可原谅的事故。所以运行时标记新旧两种形式都能识别,在读取时做迁移。这是一段不好看的兼容代码,而且得留很久。

给产品起名比听起来更痛苦

我在六轮里过了大约两百个域名候选。在显而易见的语义空间里——agent、claw、control、ops、panel——几乎所有能念出来的都已经被注册、被停放,或者被标成了溢价域名。

最后奏效的做法是彻底放弃这个语义空间,改用一个公式:一个亲切的具体词 + 一个表示范围的后缀。「Gamba」在西班牙语里是虾,同时也读得出日语的 ganbatte——大致是「加油」。「OS」比「panel」能罩住更宽的产品线,又不把话说死。

两点实务备注。拼写比含义重要:我最终选的是目标语言母语者第一次就能拼对的写法,这条规则淘汰掉了好几个更好听的选项。预算上,我只注册了 .com。防御性注册和 .ai 是有收入之后才该买的东西——一个有四个防御域名却没有用户的副业,优化错了地方。

调研之后,商业计划改了

最初的计划是 API 中转:代理模型访问,赚差价。认真查了一遍之后,它死于两个各自独立的理由。

转售服务商的 token,与你所转售的那些服务商的服务条款相冲突。 把生意建立在一条随时可能被执行的条款上,那不是生意,是个倒计时。

另外,运营一个把境内用户路由到境外模型的服务,会撞上国内的生成式 AI 相关规定。那不是一个可以靠机灵绕过去的灰色地带。

所以现在的模式是:面板保持免费开源,能收费的价值放在那些不需要我待在请求路径上的地方。没有任何人的 token 流经我运行的任何东西——这同时也是「为什么你可以把密钥交给它」这个问题的更好答案。

哪些地方做错了

我毁掉了 git 历史。 迁到新仓库时,我初始化了一段全新历史,没有把上游的带过来。眼前的结果是一个干净的仓库。真实的结果是我再也没法 cherry-pick 上游的安全修复了——从此每一条都得手工 diff、手工应用。我把原始历史备份在了仓库之外,所以还能恢复,但这是一个实打实的错误,我不会再犯第二次。「整洁」不值这个价。

仓库是私有的,而这件事影响的东西比预期多。 免费计划下的私有仓库意味着没有 GitHub Pages,而 Pages 本来是要用来托管面板拉取的更新清单的。它同时也意味着「用 Releases 兜底下载」这条路对除我之外的任何人都不通。两件事都得改道。

CI 因为成本被关掉了。 构建矩阵覆盖三个平台,包含 macOS,而 macOS 的计费倍率是 10 倍。在私有仓库上,一次全量推送要吃掉月度额度里相当大的一块,所以 Actions 被整仓禁用了。这是个合理决定,但它也意味着没有自动构建——这正是本站现在在「下载」按钮的位置上摆着一个等候名单的直接原因。

最后这条值得挑明说:你正在读的这个网站,上线时它所描述的那个产品还下载不了。面板是能跑的——我自己在用——但确实没有打包好的安装程序可以给你,而挂一个点开是 404 的下载链接,比承认这个缺口更糟。

接下来做什么

把安装包放出来。这意味着解决 CI 的成本问题、搭好下载用的对象存储,以及决定仓库的可见性——反正 AGPL 最终也会把这件事定下来。

之后,把这一切围绕着建的那两个功能好好写成文档;成本管家也需要在一段比我现在拥有的更长的真实用量窗口上验一遍。

如果你想知道什么时候开放下载,本站的那个表单就是干这个的,不干别的。如果你也在做类似的事,而上面任何一条能帮你省下一周,那这篇就没白写。

上线时第一时间拿到 GambaOS

这篇文章里说的那个面板很快开放下载。留个邮箱,第一批进来。

上线时发一封邮件,随时可以退订。