在 AI 热潮中,开发者们争先恐后地接入大模型 API、构建 Agent 应用、搭配合适的提示词链。但很少有人停下来问一个更深层的问题:当 AI 产业本身正在变成一座新的围墙花园时,开发者辛辛苦苦构建的应用,究竟是在积累自己的资产,还是在给平台方免费打工?
这个尖锐的发问,来自 Cory Doctorow 在最近一次技术对谈中反复强调的核心观点——“Enshittification”(平台腐烂/恩希提化)。他提出这个概念时,本是用来描述社交平台、电商平台如何一步步从“吸引用户”滑向“压榨用户”,最终走向衰落的。但当你把它放到当前的 AI 行业背景下重新审视,你会发现:AI 正在以极快的速度重演这套剧本,而身处其中的开发者,恰恰是最关键的角色,也是最容易受伤的角色。
这篇文章不是单纯转述一段访谈,而是把 Cory Doctorow 的“Enshittification”框架拆解到 AI 工程实践层面。我会先讲清楚这个概念的底层逻辑,然后结合大模型 API、开源模型、数据版权、供应链安全等开发者日常接触的问题,分析 AI 时代“平台腐烂”的具体表现和演进路径,最后给出对冲这些风险的工程化建议。无论你现在是正在选型大模型 API 的架构师,还是准备做 AI 产品创业的独立开发者,这篇文章都值得你收藏后反复读一遍。
1. Enshittification 到底是什么?为什么开发者必须关注
“Enshittification”不是普通的技术术语,而是一个观察互联网平台生命周期的高级隐喻。Cory Doctorow 用它来描述一个残酷的规律:
一个平台最初的诞生,往往是因为对用户友好。平台在上线初期会用各种补贴、优质内容和免费服务来吸引用户,积累用户基数。等用户规模足够大,平台开始调整规则,让企业客户、第三方开发者和广告主花更多钱才能触达用户。最后,平台为了向股东和资本交代,会进一步压榨所有参与者,包括用户、开发者和企业客户。
简而言之,这是一个“先讨好你,再收割你”的过程。用四个阶段可以清楚表示:
| 阶段 | 平台行为特征 | 真正的受益者 |
|---|---|---|
| 吸引阶段 | 免费开放、补贴用户、提供丰富 API | 用户 |
| 利用阶段 | 引入广告、限制 API、提高抽佣 | 平台自己 |
| 压榨阶段 | 降低服务质量、捆绑销售、锁定用户 | 股东 |
| 衰退阶段 | 用户流失、开发者逃离、生态萎缩 | 无 |
过去我们看 YouTube、亚马逊、淘宝的治理模式,总觉得这是电商或社交媒体的独有现象。但 Cory Doctorow 的核心判断是:任何掌握“连接供需双方”能力的数字中介,都逃不过这个周期。而 AI 模型恰好正在成为下一代超级中介。
为什么这么说?因为大模型的价值不在模型本身,而在于它成了用户与应用、开发者能力与用户需求之间的连接器。当一个平台或模型厂商掌握了这种连接能力,就自然产生了“先开放、后收紧”的激励。对开发者而言,这就带来一个极其重要的工程命题:
你所有基于某个 AI 平台构建的上层能力,是否有随时被平台规则变化切断的风险?
这个命题并不是远虑,而是近忧。过去一年多里,我们已经看到不少大模型 API 的价格从免费到收费、从低价到提价,接口权限从全面开放到灰度收紧,围绕训练数据的版权诉讼在一个接一个地出现。规模变大之后,扮演“中介”的角色一定会追求租金最大化。开发者如果现在不考虑这个问题,踩坑只是时间问题。
2. 从 API 开放到锁定:AI 平台正在重演 Enshittification 剧本
如果你熟悉平台经济的发展史,会发现 AI 平台厂商的商业动作和早期的电商平台、外卖平台高度相似。第一阶段是拼命抢开发者:开放 API、发放免费额度、推出慷慨的开发者激励计划,把模型能力包装成“人人都能用的 AI 基础设施”。这个阶段,平台方的算力成本是在补贴开发者,意在快速建立生态。
第二阶段是加深依赖:开发者逐渐习惯某个模型 API 带来的便捷,应用内的 prompt、功能链路、业务逻辑和模型输出已经深度耦合,迁移成本变得很高。此时,平台方开始调整价格策略、改动调用规则、限制并发数、提高最低消费要求。对于已经在生产环境跑起来的应用来说,这部分增加的成本不再是可选项,而是一项被迫承受的税。
第三阶段就是锁定后的收割:开发者发现自己的应用已经离不开某个模型,因为重新训练模型、更换 API、迁移数据流程的代价实在太大了。平台方完全可以在此时进一步压缩开发者的利润空间,甚至推出与开发者应用直接竞争的自营功能。
用工程语言来说,这里的核心风险就是厂商锁定(Vendor Lock-in)。AI 领域由于模型能力的不可替代性、训练数据的私有性、微调成本的高昂,锁定的程度比传统 IT 基础设施更严重。
传统的数据库锁定,我们至少还知道表结构、SQL 语句和备份策略,换一个云厂商可以慢慢迁移。但当你依赖了一个 AI 模型 API 时,你依赖的其实是一团不可解释的权重参数。一旦该模型被下架、被更新成行为完全不同的版本,你的应用会出现什么样的问题,很难预估。
3. 模型训练数据的“公地悲剧”:谁在免费搭车,谁在付出代价
除了 API 锁定,Enshittification 在 AI 行业还有另一个隐蔽而致命的形态:训练数据的公地悲剧。
Cory Doctorow 在演讲中最先成名的论断之一,就是对平台通过用户生成内容获利,却从不给予用户适当回报的批判。在生成式 AI 时代,这个问题呈现为一种全球性的规模失序:
- 模型厂商从互联网上大规模抓取文本、图片、视频作为训练语料;
- 数据生产者(内容平台、独立创作者、开源社区维护者)没有得到补偿,甚至没有得到足够的选择退出机制;
- 模型通过学习这些数据获得了商业价值,但模型的使用又反过来通过生成替代品,挤压了原有内容创作者的市场空间。
对开发者来说,这个问题看起来似乎是“别人的版权争议”,但实际影响一点都不遥远。如果你的 AI 应用依赖某个模型生成代码、文案或结构化数据,而这些数据的训练来源本身就处于灰色地带,那么你的产品将来可能面临以下风险:
合规风险:法律诉讼的判决可能导致模型被下架或修改行为,你的应用随之失效。
数据质量风险:网络上充斥着 AI 生成的低质量内容,它们已经循环回训练数据集里,模型的输出质量会逐步下降。
公地腐烂:当所有人都开始向模型/数据平台贡献自己的内容,而不是从平台中获得等量的价值,原创内容的供给就会枯竭。这意味着后续模型的训练语料会越来越差,AI 应用的基础设施就像一片被过度放牧的公共牧场,最终走向退化。
对开发者而言,这一层逻辑的价值在于:不要盲目假设一个模型现在的表现会永远如此。模型的能力边界、数据合规状态、内容政策,都可能在今天构建的 AI 应用生命周期内发生剧烈变化。
4. AI 工程中的供应链风险:不只是 API,整个依赖链都值得检查
除了模型 API 的锁定逻辑,AI 工程实践的供应链承受着多层级的风险。
第一层是模型依赖:你的应用调用 GPT-4o 还是 Claude 3.5,本质上是在依赖一个黑盒。模型更新行为不透明、上下文窗口限制、安全策略调整——任何一个环节的细小变化,都会传导到你的业务逻辑中。
第二层是框架依赖:你的项目可能使用了 LangChain、LlamaIndex、Spring AI 等第三方框架。这些框架本身在快速发展,API 变动频繁,依赖升级版本很容易带来不兼容问题。需要注意的是,框架的上层封装越厚,开发者距离底层大模型越远,被工具链绑架的可能就越大。
第三层是部署依赖:如果需要自己部署开源大模型,你又要依赖推理引擎、向量数据库、GPU 驱动、容器编排工具等一系列开源组件。任何一组依赖出现安全漏洞或版本质量问题,都可能成为整个 AI 应用系统的不稳定因素。
第四层是合规和安全依赖:如果模型在生成过程中泄露了企业敏感数据、用户隐私,或触犯法律法规,这个风险最终由开发者承担,而不是模型供应商。
用传统软件工程的话来说,这就像你引入了一个第三方 SDK,却无法通过读源码来验证它的行为和边界。在传统开源软件中,至少可以 fork 一个版本自行维护;而大模型的训练数据和权重往往受到严格控制,即使开源模型也通常只是提供了权重,而非完整的训练数据。这种不可验证性,使得 AI 工程的供应链风险比传统软件工程更大。
5. 开源模型与开放标准:对抗“平台腐烂”的技术防线
这是面对 AI Enshittification 最关键的“反脆弱”策略。Cory Doctorow 在多个场合都强调过:对抗垄断和平台腐烂的终极手段,不是呼吁平台自律,而是让用户和开发者拥有自由退出和自由选择的能力。
把这个判断落到 AI 工程,可以被翻译成一句非常具体的话:如果某个 API 不好用,你最好真的有能力换掉它。
近年来开源大模型的进展,为开发者提供了这种“退出权”的现实基础。像 Llama 系列、Mistral、Qwen、DeepSeek 等开源模型的能力已经越来越接近商业闭源模型,尤其在中低参数规模、垂直领域微调、私有化部署等场景中,使用开源模型完全可行。开源的模型权重意味着你可以:
- 本地部署,数据不出域,绕开数据私有化监管风险;
- 自由微调,针对自己的业务数据做定制;
- 固定版本,不受上游 API 更新影响;
- 成本可控,不承担平台方定价调整的压力。
但开源模型也不等于零风险。开源是把“退出权”交还给了开发者,但也把“运维责任”交还给了开发者。你不再只是调用一个 API,你可能需要自己维护推理服务、监控模型质量、处理 GPU 故障。因此,更稳妥的技术路线不应该是“闭源模型 or 开源模型”的二选一,而是分层设计,让上层应用对底层模型可用解耦替换。
这条技术路线要求在工程架构上做到:
- 把模型调用封装在一个独立的服务层;
- 定义统一的模型交互接口,让不同模型实现同一个协议;
- 所有模型相关配置能够动态调整,而不是硬编码在业务代码中;
- 对模型输出做标准化的后处理,减少对特定模型输出格式的依赖。
一句话总结,就是“模型可以换,业务不用改”。这是目前应对 AI 平台腐烂最具操作性的工程措施。
6. 识别 AI 平台“腐烂”的信号:一个开发者自查清单
你可能会有疑问:AI 平台现在还处于白热化竞争阶段,各家都在降价、送额度、抢用户,哪有这么快进入腐烂期?这正是 Enshittification 最聪明的设计——危险信号从来不会一步到位,而是循序渐进、温水煮青蛙一般出现。
如果把“模型厂商当作一个平台”,下面这些信号值得开发者定期检测:
| 风险信号 | 具体表现 | 风险等级 |
|---|---|---|
| 价格变化 | API 价格从免费到收费,或频繁调价且解释不清 | 中 |
| 接口变更 | 模型版本更新后输出格式不兼容,同一 prompt 结果漂移严重 | 高 |
| 权限收紧 | 逐渐提高调用配额门槛、压缩免费额度、限制并发 | 中 |
| 社区反馈 | 开发者论坛里关于服务质量的负面评价增多 | 中 |
| 透明性下降 | 不再公开模型能力评估细节、训练数据范围更新不透明 | 低 |
| 自营竞争 | 平台开始推出与生态内开发者应用相似的功能 | 高 |
| 数据政策变动 | 模型服务条款新增对用户输入数据的训练权声明 | 极高 |
不要等到风险信号全部出现之后再动手,到那时转换成本已经成为沉没成本。
7. 对冲 AI 平台风险的工程实践:从架构到部署
既然问题和风险都很明确,那么最终的落点一定是工程实践。下面给出一个可操作的技术方案,用于构建一个“模型中立”的 AI 应用层。
7.1 统一模型接口层:把“换模型”变成配置操作
首先,在项目的服务层定义一个统一的模型调用接口。下面用 Java 示例说明,因为 Java + Spring AI 在后端工程中很常见。
// 文件路径:src/main/java/com/example/aimiddleware/llm/LlmClient.java public interface LlmClient { LlmResponse complete(LlmRequest request); }// 文件路径:src/main/java/com/example/aimiddleware/llm/LlmRequest.java public class LlmRequest { private String prompt; private Double temperature; private Integer maxTokens; // 构造方法、getter/setter 略 }// 文件路径:src/main/java/com/example/aimiddleware/llm/LlmResponse.java public class LlmResponse { private String text; private Integer promptTokens; private Integer completionTokens; // 构造方法、getter/setter 略 }然后为不同的模型供应商提供不同的实现。
// 文件路径:src/main/java/com/example/aimiddleware/llm/OpenAiLlmClient.java @Component public class OpenAiLlmClient implements LlmClient { @Value("${llm.openai.api-key}") private String apiKey; @Value("${llm.openai.model}") private String model; @Override public LlmResponse complete(LlmRequest request) { // 调用 OpenAI 风格 API // 这里使用 RestTemplate 或 WebClient,具体实现略 return new LlmResponse("openai result", 0, 0); } }// 文件路径:src/main/java/com/example/aimiddleware/llm/LocalOllamaLlmClient.java @Component public class LocalOllamaLlmClient implements LlmClient { @Value("${llm.ollama.endpoint}") private String endpoint; @Value("${llm.ollama.model}") private String model; @Override public LlmResponse complete(LlmRequest request) { // 调用本地的 Ollama 服务 // 具体实现略 return new LlmResponse("ollama result", 0, 0); } }最后通过配置来决定真正注入哪个实现:
// 文件路径:src/main/java/com/example/aimiddleware/config/LlmConfig.java @Configuration public class LlmConfig { @Bean @ConditionalOnProperty(name = "llm.provider", havingValue = "openai") public LlmClient openAiLlmClient() { return new OpenAiLlmClient(); } @Bean @ConditionalOnProperty(name = "llm.provider", havingValue = "ollama") public LlmClient localOllamaLlmClient() { return new LocalOllamaLlmClient(); } }配置文件:
# 文件路径:src/main/resources/application.yml llm: provider: openai openai: api-key: ${OPENAI_API_KEY} model: gpt-4o-mini ollama: endpoint: http://localhost:11434 model: qwen2.5:7b这样一来,业务层只需要注入LlmClient接口,而不需要关心底层到底是哪家模型。当某一天上游模型涨价或者停服时,修改配置文件即可完成模型切换。这听起来非常简单,但实际项目中大量代码是直接调用 SDK 方法,并在业务类里写死了模型名称,导致切换成本巨大。
7.2 添加模型输出格式适配层
另一个容易踩坑的细节是:不同模型的输出格式存在差异。有些模型输出天然带 Markdown,有些会附加额外的解释文字,有些对 JSON 响应的格式控制不佳。
为了避免上层应用因模型输出差异而挂掉,应该增加一个后处理适配层:
# 文件路径:src/model_adapter.py import json import re def extract_json(text: str): """从模型输出中提取 JSON 内容""" # 去除 markdown 代码块标记 json_match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", text, re.DOTALL) if json_match: text = json_match.group(1) # 直接尝试解析 try: return json.loads(text) except json.JSONDecodeError: # 如果失败,尝试截取第一个 { 到最后一个 } start = text.find("{") end = text.rfind("}") if start == -1 or end == -1: raise ValueError(f"无法从模型输出中提取 JSON: {text}") return json.loads(text[start:end + 1])7.3 建立模型质量监控与 A/B 回退机制
换模型不是一次性动作。生产环境中,应该像对待线上服务一样对待模型。建议从第一个版本就建立三个基本能力:
- 模型输出质量评估日志:记录每次调用的 prompt、输出、耗时、token 折算成本。
- 离线评估集:维护一组带标准答案的业务问题,用于发布新模型版本前做回归测试。
- 流量灰度与即时回退:以配置中心或数据库开关实现同质化模型服务的流量百分比切换,一旦新模型表现不佳,可以快速切回旧模型。
7.4 把“数据”和“模型”分离:向量数据库与模型解耦
很多 AI 应用的价值来自 RAG(检索增强生成),也就是把自身业务知识存在知识库中,然后通过向量检索出相关内容,交给大模型生成答案。
这是一个天然的解耦机会:知识库的数据是开发商自己的资产,模型只是阅读器。只要你的数据存储独立、检索接口标准化,将来换模型的影响范围就可以控制在非常小的范围内。反过来,如果你把业务数据塞进模型提供方的私有向量数据库中,那就等于主动交出了数据主权,将来模型服务商有更多理由锁定你。
建议在项目初期就明确数据边界:
- 业务知识库优先使用自建向量数据库(如 Milvus、Qdrant、pgvector);
- 私有数据不直接写入模型厂商的托管向量库;
- 检索结果可以缓存,减少模型调用频率和成本,也降低对模型 API 的实时依赖。
7.5 多模型路由与成本控制
在设计验证合理之后,可以进一步引入多模型路由,根据任务难度把请求分发到不同模型。例如:
- 简单分类任务:走轻量级模型(如 gpt-4o-mini 或本地小模型),成本低、延迟低;
- 复杂推理任务:走强模型(如 claude-3.5-sonnet 或更大参数的开源模型);
- 离线批处理任务:走本地开源模型或价格较低的非高峰时段接口。
这本质上是一种“模型层的负载均衡”,也是对抗平台 API 价格波动的有效工程手法。
8. 常见问题与排查思路
在实践“模型中立”架构的过程中,最常遇到的问题集中在几个方面。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 切换模型后返回结果跟预期差异很大 | 不同模型对 prompt 的敏感度不同 | 对比同一 prompt 在不同模型上的输出 | 为不同模型配置独立的 prompt 模板 |
| 输出 JSON 解析失败 | 模型追加了额外解释文字或 Markdown 代码块 | 打印原始输出,查看前后缀 | 在后处理层做 JSON 截取和清洗 |
| 本地模型推理延迟过高 | GPU 资源不足或模型过大 | 使用nvidia-smi查看 GPU 利用率和显存 | 选择更小的量化模型或增加并发控制 |
| API 调用报 429 | 触发了限流 | 查看响应头和平台控制台配额 | 增加重试退避,启用多模型分流 |
| 同模型不同时间段输出不稳定 | 模型服务商默默进行了模型更新 | 用固定测试集每日跑回归 | 记录输出日志,必要时锁定模型版本 |
| 平台政策变动导致服务不可用 | 商家调整了服务条款或下架模型 | 关注平台公告和邮件通知 | 采用多供应商冗余架构,提前切换 |
9. 最佳实践与工程建议
针对 AI 应用长期可持续运行,下面这些实践建议是我经过多个项目验证后的积累。
第一,Prompt 也要做版本管理。很多团队用 Git 管理代码,却让 prompt 散落在数据库和代码注释里。建议将 prompt 作为独立资源文件(如 YAML、JSON)管理,纳入 Git 版本控制,同时记录它所适配的模型版本。这样换模型时才能定位到具体哪个 prompt 需要修改。
第二,模型输出必须做结构化校验。不要天真地认为模型一定会输出合法的 JSON、XML 或其他格式。在后处理层增加 schema 校验、字段缺失检测和类型转换,避免脏数据渗透到下游业务。
第三,所有模型调用要带上 trace id 和业务上下文。当模型输出出现问题时,没有trace信息很难定位。建议在调用链中统一注入请求 ID,并把输入输出全量记录到日志系统。
第四,对模型价格保持敏感,但不要只盯 surface-level 的价格。一个便宜的模型如果经常需要重试、解析失败、用户反复反馈不佳,真实成本远高于表面价格。每次模型选型都应该建立一个基于业务结果的小型评估体系,而不是只看基准测试分数。
第五,认真考虑数据出境的合规约束。如果业务涉及企业内部敏感数据,优先走私有化部署的开源模型,或者采用“数据不出域、模型云端部署”的教育隔离方案。AI 平台可以迭代,但数据泄露的后果是不可逆的。
第六,不要在市场窗口期做唯一绑定。AI 领域格局变化的速度是传统软件的数倍。即使你当前觉得某个 API 很好用,也值得花时间做一层薄薄的适配器。这层适配器可能只需要 200 行代码,但它给了你的项目未来二十种选择的可能。
10. 总结:AI 开发者的反脆弱姿势
回到 Cory Doctorow 的演讲,他真正想表达的,不仅是“平台会变坏”这个观察,更是“好的系统设计应当包含失败和逃离机制”这一工程常识。在 Enshittification 时代,AI 开发者最需要培养的能力,已经不是“如何更快接入某个新模型”,而是“如何保持随时可以离开某个供应商的能力”。
从工程架构来看,这意味着:
- 用统一接口层解耦业务与模型;
- 用本地模型和开源模型保持退出权;
- 用数据独立和标准检索避免数据绑架;
- 用监控、日志和回归测试保证模型切换的可控性。
从认知层面来说,更重要的判断是:AI 模型不是终点,而只是当前技术周期中的一种实现方式。如果你把项目的地基浇筑在某个具体模型上,未来必然会被模型升级和价格波动打得措手不及。如果你把地基浇筑在数据资产、流程引擎和稳健的工程架构上,模型就只是可替换的零件。
Cory Doctorow 的故事提醒我们,技术史上没有一个“中介”能永远保持初心。真正稳健的策略,永远是让每个参与者都拥有随时退出的权利。在这个 AI 方兴未艾、平台格局尚未定型的窗口期,提前建立这种反脆弱的工程姿态,或许是对未来十年最好的投资。
建议收藏这篇文章,并在下一次做 AI 技术选型时拿出来对照看看——当你发现自己越来越难以回答“换掉这个模型会怎样”时,你就知道 Enshittification 已经在你脚下了。