我的文章保存在本地 Markdown 文件里,修改由 Git 记录,站点可以静态构建。从内容格式到发布结果,看起来一切都在自己手中。

但写作过程已经不再完全发生在本地。我会让 LLM 帮助分析旧文、整理结构、检查代码和翻译文章;构建和部署依赖托管服务;外链检查还要访问许多不受我控制的网站。如果模型 API 明天停止服务、改变价格、封禁账户,或者调整了我无法接受的使用政策,这套工作流还能剩下多少?

这是我最近重新思考“软件自由”时遇到的问题。

过去谈自由软件,我们通常先问:能否运行程序,能否研究和修改源代码,能否把修改后的版本交给别人。这些问题仍然重要。但在 AI 系统中,源代码只是其中一层。一个应用可以把代码完整放在公开仓库里,同时把模型、数据、记忆、权限和身份锁在无法迁移的平台中。

如果一个系统可以查看源代码,却无法带走自己的内容;可以修改客户端,却不能替换背后的模型;可以让 Agent 自动执行任务,却不知道它读取了什么、修改了什么,那么“开源”还没有回答自由的全部问题。

我最初理解的自由#

我从 2019 年开始接触开源。真正吸引我的,不只是可以免费使用软件,而是一种不同的参与关系。

在开源社区里,有人维护终端工具,有人打磨配置,有人修复一个并不紧急的 bug,也有人认真补上一段文档。这些事情不一定来自 KPI、课程要求或商业任务。参与者愿意投入时间,是因为他们认同项目,或者希望后来的人少走一点弯路。

那是我第一次具体地理解“自愿参与”。自由并不等于不承担责任。恰恰因为没人强迫,一个人仍然愿意提交代码、回应问题和维护结果,这种责任才有了不同的含义。

后来我暂停过站点,也清理过公开内容。重新建立个人站点时,一个想法已经变得非常明确:不要让内容与某个平台永久绑定。域名、框架和部署方式都可以变化,但原始文字应该能够被完整保存、迁移和重新发布。

那时我理解的自由,主要是拥有代码和内容。AI 的出现让我意识到,还需要继续追问:当软件开始替我阅读、判断和行动时,我究竟把什么交了出去?

控制转移到了新的位置#

传统软件的依赖通常比较容易辨认:源代码、编译器、运行库、操作系统和硬件。AI 工作流在这些层面之外增加了新的控制点。

首先是数据。文章也许保存在本地,但对话历史、向量索引、模型记忆和反馈记录可能只存在于服务商的账户里。网页上的“导出”按钮并不自动等于可迁移:导出的文件是否完整,格式是否公开,换一个工具后能否继续使用,都是不同的问题。

其次是模型。两个 API 即使接受相似的消息格式,也可能在工具调用、上下文长度、结构化输出和安全策略上有完全不同的行为。如果应用把这些差异散落在业务逻辑里,更换模型就不再是改一个名称,而是重写整套工作流。

然后是权限。普通聊天只产生文字,Agent 却可能读取文件、执行命令、修改仓库、访问浏览器,甚至向外部系统发送信息。能力越强,“它能做什么”和“它刚刚做了什么”就越需要被清楚记录。否则,自动化带来的不是自由,而是把控制权从一个不透明的界面转移到另一个不透明的界面。

最后是身份。很多服务把模型、数据、计费和权限绑定在一个账户上。账户一旦不可用,消失的不只是某个工具,也可能包括长期积累的上下文和整个工作入口。

这些依赖说明,一个开源客户端不一定构成一个自由的系统。反过来,使用闭源服务也不必然意味着完全失去自由。真正需要判断的是:依赖是否清楚,数据是否可带走,关键能力是否可替换,离开之后工作是否还能继续。

自由不是把一切重新实现#

我曾经很容易把“自主”理解成“自己实现”。如果不喜欢现有工具,就重新做一个;如果某个依赖太复杂,就把它换成自己能控制的代码。

mdout 最后没有沿着这条路走到底。

它使用 Rust 完成内容检查、版本诊断、外链检查和构建封装,但 Markdown 解析、模板、代码高亮、RSS、搜索索引和开发服务器仍然交给 Zola。如果为了减少依赖而重新实现这些能力,我会得到更多属于自己的代码,也会得到更多只有自己能够维护的问题。

选择 Zola 没有让我失去自由,因为这段依赖关系足够清楚:内容仍然是 Markdown,配置和模板在仓库里,构建可以在本地完成,输出是普通静态文件。即使将来替换 Zola,文章本身也不需要从一个封闭数据库里抢救出来。

这个经历改变了我对自由的理解:

自由不是依赖数量为零,而是依赖关系可见、边界稳定,替换成本可以被理解和承受。

托管服务也可以是合理选择。它们节省硬件、运维和时间,让个人能够使用原本负担不起的能力。问题不在于使用别人的系统,而在于便利是否悄悄取消了其他选择。

AI 工作流中的五种自由#

面对模型和 Agent,我现在更关心五种具体能力。

理解#

我应该知道系统向模型发送了哪些上下文,开放了哪些工具,允许访问哪些目录和外部服务。模型内部不可能完全透明,但输入、权限和操作边界不应成为秘密。

带走#

文章、对话、配置、提示词和必要的历史应当能够以可读、可处理的格式导出。只有截图和平台专用备份,不足以构成真正的数据所有权。

替换#

工作流不应把某个模型的特殊行为当成永远不变的基础。接口可以适配,模型可以切换,关键数据结构应尽量独立于供应商。替换不必毫无成本,但成本不能大到等同于重做整个系统。

撤销#

生成一段文字和删除一批文件不是同一等级的操作。自动化修改需要差异记录,重要动作需要确认,失败后需要回滚路径。系统越有行动能力,撤销能力就越重要。

退出#

退出是前四种能力的最终检验。当我不再接受某项服务的价格、政策或产品方向时,是否还能继续写作、构建、搜索和发布?如果答案是否定的,那么过去拥有的只是使用许可,而不是稳定的选择。

不能离开的选择,很难称为真正的选择。

开放模型也不是自动答案#

开放权重和开放代码扩大了选择空间,这是重要进展。但仅凭“开放”标签,仍然不能判断一个 AI 系统是否自由。

模型可能允许下载,实际运行却需要个人无法负担的硬件;权重可能开放,训练数据和处理过程仍然无法检查;模型可以在本地运行,围绕它的记忆、工具平台和身份系统仍然是封闭的;应用可以替换模型,却无法导出用户多年积累的数据。

因此,不能把问题压缩成简单的对立:

开放模型 = 自由
闭源模型 = 不自由

许可证决定了重要的一部分权利,但系统自由还取决于可迁移性、可观察性、权限设计和撤销机制。一个能够本地运行却会悄悄修改文件的开放 Agent,并不比一个权限清楚、操作可审计的托管工具更值得信任。

自由不是一个产品标签,而是一组可以被实际验证的系统性质。

保留说“不”之后继续工作的能力#

我仍然会使用模型 API、GitHub、Zola 和其他外部服务。拒绝所有依赖不会让我更自由,只会让我把时间耗费在重复建设上。

但我希望每次引入便利时,都知道自己交换了什么:数据去了哪里,操作能否检查,结果能否撤销,替代方案是否存在。如果一个服务消失,我可以暂时失去效率,却不应该同时失去自己的内容和继续工作的能力。

这也是我今天理解的软件自由。

它不要求一个人完成所有事情,也不要求每个模型都在自己的机器上运行。它要求人在越来越强大的自动化面前,仍然能够看见依赖、划定边界、带走成果,并为最终决定负责。

自由不是不依赖别人,而是不让任何一个依赖决定自己能否继续工作。

AI 可以替我生成下一段文字,但是否接受它、把它放在哪里,以及何时停止使用这个系统,应该始终是我能够作出的选择。