写在前面 我们已经把 辣椒AI 里的两个能力抽出来开源了:Bramble(AI 思维导图)和 Zine(AI 知识卡片)。这篇讲讲背后的想法——包括那些不太好听的部分。
一、抽离的成本比想象中高
先说实话:把一个功能从产品里抽出来做成独立开源项目,工作量远大于"把文件夹复制出来"。
实际要做的事:
切断所有内部依赖
产品里的模块会用到内部的鉴权、配置、日志、错误处理、埋点。开源版本必须把这些全部剥掉或替换成通用实现。
一个具体的例子:Bramble 在产品里调用的是内部的 LLM 网关(带了鉴权、限流、计费),抽出来必须变成"一个环境变量就能配置"的通用调用。这不仅仅是替换几行代码——意味着要支持多种 API 协议、要处理没有鉴权头的情况、要在没有内部错误码体系的情况下给出有意义的报错。
重新设计对外接口
内部调用可以很随意——你知道调用方是谁、知道数据格式长什么样、改个接口参数通知一下隔壁同事就行。公开的 API 需要考虑向后兼容和使用者的心智。
我们定了一条规则:对外接口的每一次修改都要回答"现有的集成者能不能平滑升级"。 答案是"能"就通过,答案是"不能"就要提供迁移路径(deprecation warning + 一个版本的共存期)。
补文档
内部代码靠口口相传和一起写代码就能维护,开源项目必须有能让陌生人跑起来的文档。
好的文档至少包含三个层次:
- 五分钟能跑起来:一个 clone + install + start 就能看到效果的快速起步
- 知道怎么用:API 参考和使用示例
- 知道为什么这么设计:架构决策的说明(为什么选 Markdown 而不是 JSON,为什么做双包结构,等等)
做一个能跑的示例
只给库不给示例,大部分人试都不会试。我们的示例项目用了 Docker Compose——一条命令起来前后端,不需要装 Python 依赖、Node 版本对齐这些折腾。
核许可
依赖树里每一个包的许可都要过一遍,包括那些"参考过"的上游。这一条我们在 Zine 上花了不少时间,也确实发现了问题——上游项目的 LICENSE 和注释里记录的许可不一致,最终导致我们做了一次 clean-room 重写(详见 Zine 那篇)。
持续维护
开了源就有人提 issue,不回应比不开源更伤。维护意愿是我们判断一个模块"能不能开源"的条件之一——如果抽出来之后就打算不管了,那不如不开。
这些成本都是真的。如果只是为了"我们也有开源项目"这句话,不建议做。
二、我们还是做了,理由有三个
第一,能抽出来本身就是对架构的检验
一个功能如果和产品其他部分纠缠太深,抽不出来——那说明它的边界设计有问题。抽离的过程会逼你把接口定清楚、把依赖理干净。这个过程发现的问题,在产品内部可能永远不会暴露。
Bramble 抽出来之后,我们反过来把产品里的实现也换成了开源版本。现在两边是同一套代码,改一处两边都受益,不存在版本漂移。
这是一个很实在的企业工程收益:开源版本质量越高,你自己的产品受益越大。
第二,通用解法应该被更多人验证
Bramble 的核心思路——让模型输出 Markdown 大纲而不是 JSON 树——不是什么秘密武器,是一条通用经验。捂着它没有意义,公开出来被更多场景检验,我们自己也能从反馈里改进。
这里有一个反直觉的点:开源意味着让渡了"独家"的优势,但换来了"更多人帮你踩坑"的优势。 不同场景下的边界条件(不同语言、不同模型、不同规模的数据)是我们自己不可能全部覆盖的。社区的反馈和贡献是免费的测试覆盖。
第三,这是我们展示工程能力的方式
我们做企业交付。客户判断一家技术公司靠不靠谱,看官网上的形容词是没用的。能公开的代码,比任何介绍都有说服力。
一个典型的场景:在技术选型时,客户方的工程师会去看候选供应商有没有开源项目、代码质量怎么样。没有开源项目的公司靠 PPT 展示能力,有开源项目的公司靠代码证明能力——后者在工程师之间的信任度天然高一档。
三、什么该开源,什么不该
我们的判断标准:
| 类型 | 是否开源 | 原因 |
|---|---|---|
| 通用的技术解法 | ✅ 适合 | 价值在于被验证,不在于独占 |
| 独立的功能组件 | ✅ 适合 | 边界清晰,抽离成本可控 |
| 与业务数据耦合的逻辑 | ❌ 不适合 | 抽出来别人也用不了 |
| 核心的业务规则和运营策略 | ❌ 不适合 | 这才是真正的差异化 |
| 客户数据相关的任何东西 | ❌ 绝不 | 不需要理由 |
一个常见的误解是"开源等于把家底交出去"。实际上产品的竞争力极少来自某个算法或某段代码,更多来自对用户场景的理解、数据的积累和持续迭代的速度。这些东西开源不走。
"核心"和"通用"的判断练习
如果拿不准一个模块该不该开源,可以做一个测试:如果你把它开源了,竞品用了你的代码,他们得到的好处是什么?
- 如果答案是"他们省了一个月的研发时间"——那没什么,代码本来就是工具
- 如果答案是"他们获得了和我们一模一样的用户体验"——那这个模块耦合了太多产品逻辑,不该开源
- 如果答案是"他们还得重新理解场景、积累数据、建立用户关系"——说明核心技术壁垒不在代码里,可以放心开
四、我们的实践方式
两个项目都遵循同样的规范:
- MIT 协议——最宽松,商用无障碍
- 双包结构——后端引擎 + 前端组件,可以独立使用。后端引擎不依赖前端框架,前端组件不绑定特定模型——各自独立选用
- 完整可跑的示例——不是代码片段,是能
docker compose up起来的完整应用 - 模型无关——支持 Anthropic 与 OpenAI 两种协议,本地部署的模型同样可用。这是对企业用户的核心价值
- NOTICE 文件说清楚——哪些是我们的原创、哪些是依赖、各自什么许可
最后一条是我们希望更多国内项目能做到的。许可信息模糊的开源项目,企业用户根本不敢用。
五、接下来
我们内部还有一些组件在评估是否适合抽离,标准仍然是前面那张表。不会为了数量而开源。
如果你用了这两个项目、或者对我们的做法有意见,欢迎在仓库里直说。
想在你的业务里试试同样的做法?
告诉我们业务问题与数据现状,我们会给出方案建议与落地路径。
需要帮助?
联系我们的团队,获取贴合你业务场景的方案建议。