升级一个SDK,15个文件报错,4个供应商接口全变。第二次发生时,作者知道还会有第三次。
他定了一条铁律:整个代码库只允许2个文件导入LLM SDK。结果下次升级只改了2个文件,28个文件纹丝不动。更意外的是,这次重构删掉688行代码,只新增192行——但真正的收获不是SDK解耦,而是发现自己把7种认知操作重复写了21遍。
SDK瘟疫:从"小升级"到"全天救火"
作者的项目是个24/7运行的个人助手,处理邮件分拣、会议准备、晨间简报、CRM更新、社媒情报、求职者打分等任务,全部由一个持久化工作流引擎调度,核心就是大量LLM调用。
重构前的依赖结构像一张蜘蛛网:
活动层(Activity Layer):21个文件直接内嵌SDK调用,每个文件都从"ai"和"@ai-sdk/*"导入generateText()、generateObject()、tool()
路由层(ModelRouter):负责模型选择和预算控制,但返回的是原始SDK模型对象,活动层直接拿来用
供应商层:@ai-sdk/anthropic、@ai-sdk/openai等
SDK同时出现在路由层和活动层,意味着升级成本呈指数级扩散。Vercel AI SDK从v4到v6的改动清单很机械:maxTokens改成maxOutputTokens,CoreMessage改成ModelMessage,generateObject()废弃,tool调用的args改成input——但分散在15+个文件的不同用法里,漏改一个就是运行时崩溃,编译器不会提醒你。
更隐蔽的是提示词瘟疫。5个活动用5种不同结构做内容分类,9个活动用9种不同方式注入语气。改了一处的分类提示,得记得去另外4处同步。作者「经常忘记」。
两文件隔离法:把供应商变成可插拔的电源
新架构的核心是端口与适配器模式(Ports and Adapters),作者把它比作电源插座:
整个代码库只有Adapter和Provider Registry两个文件知道SDK存在
18个活动文件、10个代理文件、全部工作流对供应商、模型、SDK细节零感知
具体实现分三层:
端口层定义抽象接口:generateText、generateObject、tool调用全部标准化,返回结构固定。活动层只依赖这些接口,像电器只认插座形状,不关心电网来自火电还是风电。
适配器层做翻译:每个供应商一个适配器,把OpenAI的格式、Anthropic的格式、本地模型的格式,全部转成端口层的标准结构。SDK升级时,只改适配器内部的映射逻辑。
注册表层管路由:根据预算、任务类型、延迟要求选择模型,但返回的是端口抽象而非原始SDK对象。切换供应商变成改配置,不是改代码。
效果立竿见影。下一次SDK升级,改动范围从15+文件压缩到2个文件。28个业务文件零变更,编译通过即部署。
意外收获:7种认知操作的"标准化手术"
SDK解耦完成后,作者发现更深层的问题:21处LLM调用不是在解决21个不同问题,而是在用21种略有差异的方式重复实现7种基础操作。
分类(Classify):给内容打标签,判断优先级
起草(Draft):生成回复、摘要、报告
评分(Score):数值化评估质量、匹配度、风险
摘要(Summarize):压缩长文本
提取(Extract):结构化抽取实体、日期、关键信息
规划(Plan):分解任务步骤
分析(Analyze):推理、归因、趋势判断
原来每个活动都内嵌了"分类"的完整实现——提示词结构、温度参数、重试逻辑、错误处理,全部手写。5个分类调用就是5份独立代码,改进一处,四处遗漏。
作者把这7种操作提取成标准工具,像编程语言的内置函数。活动层不再写"怎么调用模型做分类",而是直接调用classify(content, options),内部实现统一优化。提示词版本管理、A/B测试、成本监控,全部收敛到7个入口。
从"供应商锁定"到"认知层锁定"
这次重构的终局数据很克制:192行新增,688行删除。净减500行代码,但复杂度下降了一个数量级。
作者的原话是:「解决SDK耦合暴露了一个更大的问题——我在21个地方重复实现7种认知操作。修复这个比SDK隔离本身更有价值。」
这指向一个被忽视的架构陷阱。大家忙着讨论"不要被OpenAI锁定",却很少有人意识到:提示词工程、链式调用模式、认知任务分解方式,这些才是真正难以迁移的资产。换个供应商只是改API端点,换个认知架构才是伤筋动骨。
两文件隔离法的本质,是把"认知层"和"执行层"彻底切开。活动文件描述"我要分类这批邮件",适配器文件决定"用哪个模型、什么温度、怎么重试"。前者稳定,后者随技术迭代频繁变动。
当你的代码库里有21个generateText调用时,你拥有的是21份需要独立维护的债务。当这21个调用收敛到7个标准操作时,你拥有的是可组合、可优化、可审计的认知基础设施。
作者最后提到,他的个人助手现在处理着比 refactor 前多3倍的LLM调用量,但维护成本反而下降了。下一次供应商推出新模型,他的改动范围是两个文件——而竞争对手可能还在翻找那15个散落在各处的调用点。
你的代码库里,有多少个generateText在自由生长?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.