复合AI系统设计精讲:从模型中心到系统中心的工程实践
最近又在带组内同学精读 CS329Z 第一讲的阅读材料前后一共读了三遍。第一遍是拿到课程大纲时自己通读第二遍是带着大家逐段拆解最近一遍是为了把这套思路迁移到我们自己的 RAG 项目里。越读越觉得这三篇材料放在第一讲是有意为之——它们看起来是在讲概念其实是在给一整个学期的内容立骨架。这篇博客就当是一份阅读材料精讲按三篇的顺序拆开讲重点放在 Compound AI Systems 这篇核心材料上另外两篇讲清楚它们和主线的关联最后落到工程实践上。先说清楚这套材料适合谁。如果你正准备从“调接口写 prompt”升级到“设计一个能上线、能退化、能排查的 AI 功能”或者你对 Agent、RAG、多模型协作这些词已经听得很多但心里没底那这套材料会帮你把零散经验串起来。如果你是学生正在自学这门课也可以拿这篇精讲当导读。1. CS329Z 在讲什么为什么第一讲先谈“系统视角”1.1 课程定位与三篇材料的布局CS329Z 是某顶尖高校计算机系的一门 AI 系统设计课程英文名直译过来是“AI 系统设计原理”。它跟大多数一上来就讲 Transformer 结构、微调技巧的课不一样整门课默认你已经会训练模型、会写推理代码重点关注的是当 AI 能力进入真实产品时系统层面的问题怎么解决——延迟怎么控、成本怎么算、效果怎么测、坏了怎么查。这门课的第一讲更像是一个“世界观”的铺垫。理解这一点你再看它布置的阅读材料就顺了第一讲不会让你立刻去写代码而是先逼你想清楚一个根本问题——我们口中的“AI 应用”到底是一个模型还是一套由多个模型、工具、数据源组成的系统想清楚这个问题后面所有关于缓存、批处理、路由、评测的讨论才有落脚点。三篇材料的分工很清晰第一篇是定义性的提出“Compound AI Systems”这个概念相当于给出整套课的命名体系第二篇把其中一种具体的设计模式——语言模型级联——展开讲透让你知道概念怎么落实到策略上第三篇解决的是“既然是系统那怎么判断它好还是坏”的问题也就是评测与可观测性。一篇立概念一篇讲机制一篇给方法。三篇都围着一个核心转别再只盯着单个模型看。1.2 为什么这学期的主角不是“模型”而是“系统”我见过不少同学第一次读第一篇材料时的反应“这讲的不就是搭积木吗把检索、生成、工具调用拼接起来这有什么好写一篇论文的”这种反应恰恰说明我们平时用顺了端到端的单模型方案很少停下来问一句为什么单个大模型撑不起一个稳定好用的产品核心原因有三个。第一单个模型的能力天花板是固定的它的知识截止、上下文窗口、计算能力都是硬边界。你可以靠换更大参数的模型突破但成本增速远高于收益增速。第二真实业务任务的容错率极低比如医疗、金融、客服这类场景中一次严重的幻觉就可能让整个产品失去信任单模型很难同时满足“知识准确”和“表达自然”两个要求。第三单模型的每次调用都是一个黑盒出了问题你只能改 prompt 再试没有任何中间变量可以检查。如果换一个视角把模型当成系统里的一个“零件”问题就出现了转机。检索器负责找知识语言模型负责生成表达代码解释器负责算数规则引擎负责兜底每个零件用自己最擅长的方式工作最后由系统的编排逻辑来保证整体输出的质量和可控性。这就是“复合系统”思路的核心不追求一个全知全能的大模型而是组合多个“专科医生”来会诊。这个视角的转变看似简单实际上是把 AI 应用的设计方法论从“炼丹”拉回到了“做工程”。2. Compound AI Systems 精讲把大模型当成零件来设计2.1 从“模型中心”到“系统中心”到底转了什么第一篇材料最关键的贡献是把过去一年里大家隐约在做的事情概括成了一个可讨论、可发展的概念Compound AI System即由多个相互作用的组件组成的、专门处理 AI 任务的系统。这里的组件可以是多个模型也可以是非模型组件——检索器、数据库、外部工具、规则脚本甚至人机协作流程。作者在文章里做了一个很尖锐的观察近期的性能提升很大一部分不是来自单个模型的智能而是来自系统设计。举个例子GPT-4 单独做数学题和给它接一个代码解释器让它写程序计算结果差异巨大。模型还是那个模型但系统不同输出质量就不同。数据、模型、系统三者的关系在这套框架里其实可以比作“发动机、车架和整车设计”——发动机再强没有配合合理的变速箱和悬挂整车也跑不出好成绩。这套思路的立足点在于四个工程指标的全面改善可靠性、可扩展性、成本、可控性。一个模型出错了你不知道改哪里但一个系统里你可以单独替换组件、增加校验环节、回退到规则兜底一个模型处理不了超长上下文但系统可以用“检索 摘要 生成”的方式把任务拆小所有请求都用大模型太贵系统可以按任务难度分流到不同模型。读这篇文章的时候建议你带着一个问题我目前做的 AI 功能如果出错了我能定位到具体是哪一步吗答案如果是“不能”那你就已经站在单模型黑盒的困境里了这篇文章就是为你写的。2.2 四个设计维度组合方式、模型数量、记忆机制、反馈机制文章的精髓在中间部分它不满足于只说“你要建系统”而是给出了一套设计坐标。任何一个复合 AI 系统都可以从四个维度去描述它、设计它。第一个维度是组件如何组合。最简单的是顺序流水线比如“检索 → 重排 → 生成”的经典 RAG复杂一点的是有向无环图比如两个检索器并行跑然后结果合并再复杂的是层次结构主任务先拆成多个子任务每个子任务各自跑一条子流程。还有一个容易忽略的堆叠模式多个模型投票或集成提高稳定性。定系统的第一步就是在纸上把组件之间的数据流画清楚。第二个维度是使用多少个模型。有的系统自始至终只用一个大模型但会在流程里多次调用它每次调用扮演不同角色有的系统让不同规模的模型各司其职比如小模型做意图识别大模型做最终生成。我在实际项目中体会很深的一点是“不一定模型越多越好”每多一个模型就多一个故障点组件内部的不确定性会互相干扰。第三个维度是系统是否有记忆。无状态系统每次请求独立处理好处是简单、容易重放有状态系统会缓存中间结果、保存对话历史、甚至跨会话记住用户偏好。记忆让系统更“聪明”但同时也引入了缓存一致性、时效性、隐私这些问题。在设计阶段就明确“状态放在哪一层”比事后补要省事得多。第四个维度是系统能否自我修正。开环系统跑完一条流程就出结果闭环系统则会在输出之后增加一个验证或反馈的步骤。我之前在项目里把“写作助手”加了第三遍自检逻辑先让它按用户要求写出文章再让它从“审稿人”视角挑毛病最后要求它带着修改意见重写。就这么一个闭环客户报告的明显错误数量直接降了一个量级。这就是第四个维度的力量。这四个维度不是彼此独立的选择题而是互相嵌套的组合空间。文章给的设计坐标更像是一个生成器——你可以用它描述任何现有的 AI 应用也可以用它从零设计一套新方案。建议你拿自己手头的项目对着这四个维度过一遍会很快发现自己系统里那些“没想过”的取舍。2.3 两个系统怎么做拆分RAG 问答与内容审核光讲维度比较抽象我们用两个例子看看“拆系统”的实际效果。先说最熟悉的 RAG 问答。单模型方案是直接把问题和文档内容拼进一个超长 prompt让模型回答效果常常是文档一长就“迷路”回答内容看着合理但其实引用了无关段落。拆成复合系统之后流程变清晰了——先是查询改写对用户的模糊问题做一次改写然后召回用向量检索找出最相关的 20 个片段再来一个重排器把这 20 个片段按与问题的真实相关性重新排序只留前 5 个最后才交给生成模型同时把片段出处塞进 prompt 要求它做引用标注。每个环节都有自己的质量指标检索环节看召回率重排环节看排序的命中率生成环节看引用准确率。任何一个环节质量掉了都能立刻定位。再举个例子一个图文内容审核系统。输入端要同时处理文本和图片单模型方案让人工看不现实。拆成系统之后第一步用文本分类模型做粗筛高危直接转人工安全直接放行模棱两可的进第二步第二步用多模态模型对不确定的内容做细判输出一个置信度分数第三步规则引擎对品牌敏感词、竞品词做硬校验这是在模型之外加一道“物理屏障”。这个系统有意思的地方在于规则引擎和模型是串联关系前者兜住模型不擅长的精确匹配后者处理规则做不了的语义判断。两个例子的共同套路都是把单一智能拆成“感知 → 决策 → 校验”三段每段交给最合适的组件做。组件的问题是局部的系统的问题是全局的。这套思路让开发者和维护者都能在稳定的框架下迭代而不是永远面对一整个黑盒祈祷它输出正常。2.4 风险与边界输出质检、级联误差与成本失控把 AI 应用改成复合系统之后并不是万事大吉三个问题是我在实际项目中反复遇到的。第一个是级联误差。系统输出的错误来自任何一个中间环节而且错误会一路放大。检索阶段排到第 10 名的片段重排以后进了前 5生成模型对它信赖有加最终导出一个错误的结论——哪怕生成模型单独拿出来表现得相当好。解决方案是分阶段质检每个环节的输出都保留一个可观察的中间结果同时可以在高风险路径里增加“置信度阈值 人工审查”的兜底。第二个是成本失控。组件一多每一条用户请求背后可能对应着多次模型调用。我见过一个系统把“简单意图识别”也交给大模型做结果每次聊天都要烧掉好几万 token。合理的做法是引入级联策略下一篇材料重点讲让简单请求走便宜路径复杂请求才走贵路径。必要的时候还要给系统加“预算表”就像前端性能预算一样约束每次交互的成本上限。第三个是安全与边界问题这是容易被忽视的。聪明的组件越多系统的攻击面越大。一个开放的 Agent 系统如果接入了搜索引擎攻击者可以通过操纵网页内容来间接影响系统的最终行为。设计系统时要给外部工具加上白名单、给模型输出加上内容过滤层、对高度敏感操作保留人工确认环节。这些看起来“不智能”的设计恰恰是让智能系统能在真实环境里活下去的前提。读这篇文章时我还建议你去看看文末列出的那些相关工作——它提到了工具增强、多智能体协作、模块化系统等方向。这篇论文没有想垄断所有概念它更像是把散落在各处的思想收敛到了一把统一的伞下面方便后来的研究者和工程师有一个共同的讨论语境。3. 语言模型级联让“便宜模型”干大部分活3.1 级联思路的核心不该大材小用第二篇材料的主题是语言模型级联它把第一篇里那个“切换不同规模模型”的思路具体化了。核心思想一句话总结用最便宜的模型处理大多数请求只有在小模型搞不定的时候才把请求升级给大模型。这听起来有点像人解决问题的方式。你写一封日常邮件不会去找领域里最资深的老专家只有遇到棘手的法律条款才会上专家资源。AI 系统也一样如果所有流量都打给最强模型系统会稳定运行但成本曲线会非常难看如果所有流量都打给小模型省钱但体验撑不住。级联要解决的就是这个折中问题。平时我们总习惯把所有请求同等对待级联思维真正落地之后系统每天都在做“成本与质量的动态取舍”。一个有意思的工程判断是大多数产品的用户请求中八成以上属于常见场景只有两成需要复杂推理。如果你的系统能让八成的请求运行在成本极低的路径上整体开销可以下降一个数量级同时保持最终质量不跌。3.2 两种级联方式顺序执行与条件升级语言模型级联在工程上主要分两种形态。第一种是顺序级联。请求先进小模型另一个“验证模型”检查小模型的输出如果验证不通过再用大模型重做一遍。这种形态适合那些无法轻易获得确定性对错标签的开放式任务比如文章摘要、对话回复。但要注意验证模型本身的成本必须小到可以忽略否则省下来的钱又全花在验证上了。实际操作中大家常用一个小分类模型做验证几千 token 的规模就能跑得很好。第二种是条件级联。小模型除了生成结果还要输出一个置信度分数或“可完成标志”只有分数低于阈值时才跳到大模型。这种方式在分类、实体抽取这类结构化任务里非常可靠因为这类任务的判定边界相对清晰。我给一个关键词抽取系统做过一次改造BERT 小模型先抽取置信度高于 0.9 的直接输出低于阈值的交给大模型走一次 Few-shot 抽取结果整体准确率提升了 5 个百分点单请求成本只多花了 12%。这种小投入大回报的改造是级联设计最典型的收益模式。两种方式不是说非要二选一。复杂的系统里可以在流程的不同节点分别使用不同的级联策略比如入口用条件级联做路由出口用顺序级联做质量验证共同组成一个多级防线。3.3 级联在工程中怎么落地阈值、监控与成本账级联真正落地时最麻烦的不是搭链路而是定阈值。定得太高大量请求被上抛成本控制失效定得太低小模型输出的错误结果直接流出质量受损。我的经验是先用一周线上日志做离线回放把历史请求按小模型、大模型分别跑一遍观察哪些请求在小模型上出错、出错时的特征分分布再反过来选阈值。选好阈值后还需要持续监控。我建议至少盯三个指标小模型处理占比、上抛率和整体质量波动。小模型处理占比突然下降说明流量结构变了可能是某个新场景涌入上抛率过高往往意味着阈值设定和真实分布不匹配质量波动则要关注是否出现了小模型在特定话题上系统性失误的“死角”。成本账也值得仔细算。假设小模型单次成本是 0.1 元大模型是 1 元上抛率设为 20%那么单次请求期望成本就是 0.1 × 0.8 1 × 0.2 0.28 元相比全部使用大模型的 1 元省了 72%。当然这是简化计算实际还要加上验证模型成本、缓存命中情况和 prompt 长度差异。建议每个系统上线前都做一次这样的估算数字会非常直观地告诉你级联值不值得做。这篇文章和第一篇的连接点在这里级联并不是另一个独立概念它就是 Compound AI System 的一种设计模式是“组合方式”维度里明显常见、回报率最高的一种实例。理解第一篇给的设计语言再读到这篇的实例你会更有“原来如此”的通透感。4. 评测与可观测性先学会测量再谈优化4.1 端到端指标掩盖了真相第三篇材料是容易被初学者跳过、却最值得细读的一篇。它讲的是复合系统的评测和可观测性。单模型时代一套准确率走天下。但复合系统拆开之后端到端准确率就像一门考试的总分——学生数学考砸了语文考好了总分看着过得去但你根本不知道补哪个学科。如果一个 RAG 系统最终回答错了可能是检索没召回关键文档可能是重排器把关键文档排到了后面也可能是生成模型没有忠实引用文档内容。三条链路三个故障源端到端分数完全无法告诉你问题出在哪。更麻烦的是复合系统的输出往往没有标准答案。一篇摘要好不好、一段客服回复得不得体本身就带主观性。这要求我们在设计评测方案时不仅要做端到端打分更要做分环节指标拆解用多个测量工具拼出完整真相。4.2 分层评测组件级、链路级与系统级我用一个 RAG 系统举例把评测拆成三层。组件级评测。每一步单独测。检索器的指标可以用召回率衡量正确答案在不在召回结果里重排器可以用排序质量指标生成模型可以用忠实度和答案相关性前者看它有没有胡编内容后者看它有没有回答用户的问题。这层指标最好的地方在于每个组件都可以离线用一个相对固定的测试集来跑快速暴露某个零件的退化。链路级评测。检查两两协作之间有没有断点。最强的问题是“检索结果明明对生成时却没用上”这经常是 prompt 措辞导致的样式问题。链路级测试会构造一些可控样例把前一步的输出固定住只调后一步的参数来验证组件之间的接口是否正常。系统级评测。回到用户视角做端到端评估。可以用一批有“标准答案”的测试问答题同时请人按几个维度打分——有用性、准确性、语气、格式。系统级分数不需要每次开发期都跑可以放到发布前的回归流程里。但三层评估组合起来等于给系统装了一套从微观到宏观的体检设备。4.3 日志、追踪与失败重放让系统可以被审计有了指标体系还不够还得让系统在出问题时可以被“回放”。最基础的是结构化的日志。每个组件的输入输出都必须落盘带唯一请求 ID这样任何一次线上问题都能按 ID 拉出整条链路。其次是链路追踪用一个中间件框架把每个调用步骤的耗时、token 数、状态码记录成一条 trace。这一步在分布式系统里是老生常谈但在 AI 系统里往往被忽略——很多人觉得模型调用不就是一个 HTTP 请求嘛没必要上追踪。但一旦出现“检索耗时 3 秒 生成耗时 20 秒”这种组合没有 trace 你只能干瞪眼。再进一步可以做失败重放。把线上真实失败的请求收集进一个测试集每次系统迭代后跑一遍确认改进没有让曾经修好的问题复发。这个做法相当于给 AI 系统建了一组“回归测试”是防止质量反复横跳的最可靠手段。我见过一个团队花了整整两周做 trace 和日志标准化换来的是之后每次线上事故都能在半小时内定位到具体组件。这笔账怎么算都不亏。5. 三篇材料的逻辑串联往自己的项目里搬5.1 把三篇拧成一股绳的“系统设计检查单”读完三篇材料我的习惯是把它们压缩成一页检查单。每次开始设计一个新的 AI 功能之前我都会拿着它逐条过一遍。第一我的系统是单模型还是复合系统如果单模型能力明显不够我的组件拆分点在哪里第二组件之间的数据流是顺序、并行还是树状我先画图再写代码。第三系统有没有记忆状态放在哪一层如果需要长期记忆更新和失效策略是什么第四系统有没有自我修正机制输出之后要不要校验校验的成本能不能承受第五有没有考虑用级联控制成本简单请求走便宜路径的具体阈值是多少第六评测方案定了没有有没有组件级、链路级、系统级三层指标第七线上可观测性怎么做每个组件的日志、trace 是否都能拉出来如果你愿意把这三篇的笔记整理成这样一张检查单后面用到时会发现它的价值远超读十遍论文。5.2 最小落地路径从画图到跑通从论文到项目我推荐一个“最小系统”路径。第一步在纸上画出组件图和每个组件间的接口协议也就是输入输出格式第二步用假的接口或者高度简化的组件先把流程跑通这一步的目的是验证编排逻辑本身成立。有人会急着先把生成模型接上但真正容易出错的地方往往在接口定义和异常处理第三步再逐个替换成真实组件每替换一个就做一次链路级验证观察另一个组件是否受到负面影响。这个路径最大的好处是降低“复合已复杂”的调试难度。你会清楚地记得每一步改动对应哪个环节而不是把所有代码一股脑写完后再面对一团乱麻。带新人做项目时我尤其推荐这种方式他们能直观感受到系统设计带来的秩序感。5.3 高效精读方法读论文别只看字面精读这类系统设计论文用“三遍法”效率最高。第一遍只读摘要、引言和结论回答三个问题作者想解决什么问题、提出的核心概念是什么、和你手头的项目有什么关系。第二遍通读全文重点划出每个章节的“主张”和“证据”分清哪些是观点、哪些是实验结论同时对作者使用的案例做笔记。第三遍才是对读价值最高的合上论文把它解决的问题套到自己的项目里强行逼迫自己写出“如果按这篇的思路改造我的项目第一步会改什么、预期收益是什么”。第三遍做不下去说明这篇论文你其实没读懂。这套精读方法对任何领域的论文都适用但对 CS329Z 的这份阅读清单尤其合适。因为这三篇材料不是纯理论推导它们的设计思想需要放回真实应用里才能被真正理解。6. 常见问题与排查技巧实录6.1 高频问题快查表整理一下我在实践和带教过程中反复遇到的典型问题。现象可能原因排查方向复合系统效果反而不如单模型某个组件质量太差拉低了整体结果组件间接口信息丢失逐组件单独评测先找出最大的短板回答质量整体下降上游检索或路由逻辑发生变化或数据分布漂移拉 trace 看链路中哪个环节指标变化系统成本快速增长大量请求走了大模型路径或出现了重复调用检查级联上抛率、缓存命中率、循环调用次数模型开始出现幻觉系统记忆模块引入了过期或冲突信息检查写入更新的记忆内容与当前上下文的一致性线上偶发失败无法复现日志缺失、状态未保存补全从请求入口到最终输出的全链路日志这张表是通用定位起点不代表答案本身。排查系统问题时永远先相信数据不要凭感觉猜组件。6.2 一次 RAG 回答质量下降的排查实录我印象很深的一次线上事故某 RAG 系统整体回答准确率从 92% 掉到 84%用户反馈明显增多。初始直觉是生成模型出了问题但单跑生成模型离线测试准确率完全正常。这让我怀疑问题在上游。把 trace 拉出来逐条看之后发现检索器的召回结果里正确答案命中率下降了 6 个百分点。追溯原因才知道运营团队在前一天给知识库导入了大量新文档向量化时的切分粒度变了影响了相似度计算的分布。模型的生成能力没问题是“喂给模型的知识候选”变差了。这次排查的收获不是那个具体原因而是方法论端到端指标崩了先不要碰模型。沿着数据流从上游往下游逐环节看大多数问题根本不在最贵的组件上而是在数据或接口层。系统复杂之后调试谁最贵往往谁最无辜。6.3 避坑心得与长期使用建议几个经验之谈都是踩过坑换来的。不要在评测体系还没建立之前就去优化效果。系统优化就像在比赛中跑步却不知道终点线和计时器在哪跑得再快也是盲目的。先把三层指标跑起来哪怕一开始测不准也好过不测。不要给每个组件都上最先进的技术。模块化系统的魅力在于可以局部替换如果一开始每个零件都上最前沿方案组合之后反而更难定位问题。先上成熟稳定组件跑通后再逐个升级收益最大的环节。要养成“设计时想退化路径”的习惯。无论是级联、检索还是 Agent 循环都要提前想好“如果这个组件超时/返回空/返回乱码用户会看到什么系统怎么降级”。很多线上事故不是模型不够聪明而是异常路径没设计。还有一条长期建议每个 AI 系统项目维护一个“系统设计备忘录”记录当时的组件图、关键指标、已知风险。项目做到第 6 个月时回看这份备忘录的价值会比想象中大得多。最后再分享一个小技巧把 CS329Z 第一讲的这份检查单做成一个模板每做一个新 AI 功能前都过一遍。时间长了你会发现那些“凭感觉做的功能”和“按系统思考做的功能”在可维护性上的差距会越来越明显。这个习惯比记住任何具体组件都重要。