构建AI系统:从RAG到智能体
大多数团队从RAG入手,发现其局限后再加入微调。两者都能解决检索和推理问题,但都无法解决编排问题:决定何时行动、生成多少智能体、何时停止,以及共识的定义。我构建了一个多智能体协商系统(3,500行Python代码、86个钩子、141个测试),同时解决了这三个问题。
摘要
RAG在查询时检索文档。微调使用领域数据修改模型权重。两者都是检索和推理工具,但都无法处理编排问题:协调多个智能体、验证共识,或判断一个任务需要一次模型调用还是十二次。我在构建博客质量系统时遇到了这个瓶颈——该系统需要对33篇文章进行并行代码检查、深度评分、引用验证和LLM评估。解决方案是一个智能体编排层,具备置信度触发的协商机制、生成预算管理和四重共识验证。本文先讨论RAG与微调的决策,然后深入大多数指南未涉及的领域:当您需要智能体时该怎么做。
第一部分:RAG与微调
Databricks 2024年的一项研究发现,78%的企业AI团队首选RAG,但其中34%后来发现微调才是更好的方案,平均浪费了3.2个月的实施时间。1
这个决策并非非此即彼,关键在于将技术与问题相匹配。
RAG的优势场景
频繁变化的知识。 RAG在查询时检索最新文档。当知识库每天更新(产品文档、客服文章、监管文件)时,RAG无需重新训练即可提供最新信息。2
来源归属要求。 RAG能够引用具体文档,因为检索过程会生成明确的来源列表。在受监管行业(医疗、金融、法律),来源归属通常是合规要求。3
大规模知识库。 如果检索质量稳定,一个覆盖1,000万文档的RAG系统与覆盖100万文档的系统性能相当。而微调模型受限于模型大小,存在容量上限。4
微调的优势场景
领域特定的推理模式。 RAG提供信息,微调提供能力。一个在医疗诊断对话上微调的模型能学会鉴别诊断模式:如何权衡症状、何时考虑罕见疾病、如何提出后续问题。RAG可以提供医学知识,但推理模式需要通过权重调整来获得。5
严格的输出格式要求。 微调在执行结构化输出(JSON、XML、特定模式)方面比提示工程更可靠。对于格式错误会导致下游故障的系统,微调提供更高的可靠性。6
延迟敏感的应用。 RAG会增加检索延迟:嵌入查询、搜索向量数据库、检索文档、注入提示。对于响应目标低于200毫秒的应用,通过微调消除检索步骤可能是必要的。7
对比矩阵
| 维度 | RAG | 微调 | 两者结合 |
|---|---|---|---|
| 知识时效性 | 数小时 | 数周至数月 | 数小时 |
| 初始成本 | 低至中等 | 中等至高 | 高 |
| 单次查询成本 | 较高(检索+生成) | 较低(仅生成) | 最高 |
| 来源归属 | 原生支持 | 困难 | 部分支持 |
| 输出格式控制 | 中等 | 高 | 高 |
| 领域推理 | 弱 | 强 | 强 |
| 知识库规模 | 无限制 | 受模型限制 | 无限制 |
| 延迟 | 较高 | 较低 | 最高 |
| 幻觉控制 | 较好(基于文档) | 因情况而异 | 最好 |
组合方案
大多数生产系统会结合两种技术。使用微调让模型掌握领域推理模式和输出格式,使用RAG在查询时提供最新的、可归属的知识。微调后的模型知道如何进行领域推理,RAG系统提供推理的对象。8
第二部分:何时需要智能体
RAG和微调解决检索和推理问题,但都无法处理编排:判断一个任务需要一次模型调用还是十二次、何时生成并行工作者、如何验证其输出,以及何时升级给人类处理。
我在构建博客质量基础设施时遇到了这个瓶颈。我有33篇博客文章需要评估、修复和验证。单次模型调用远远不够。每篇文章需要代码检查(12个模块)、深度评分(5个信号)、可读性分析、引用验证和LLM评估。顺序执行耗时太长,无协调的并行执行则会产生冲突和不一致的结果。
解决方案不是更多的RAG或更好的微调,而是一个智能体编排层。
智能体编排的要求
传统ML流水线假设线性流程:数据→预处理→模型→评估→部署。9智能体系统是非线性的。一个智能体可能:
- 评估自身置信度并决定是否需要协助
- 生成5个具有不同专长的并行子智能体
- 收集并排序它们的输出
- 检测智能体是否过快达成一致(群体思维)
- 根据质量阈值验证共识
- 生成最终建议
每个步骤都需要RAG和微调无法提供的基础设施。
第三部分:我构建了什么
架构
我的协商系统由12个模块、3,500行Python代码组成:
Deliberation System
├── confidence.py Triggers deliberation based on ambiguity/complexity/stakes
├── state_machine.py Workflow: idle → research → ranking → consensus
├── agents.py 5+ persona templates (Architect, Security, Performance...)
├── context_isolation.py RLM L0-L3 layers prevent context contamination
├── ranking.py Stack ranking with weighted consensus calculation
├── spawner.py Parallel agent spawning via Task API
├── conformity.py Detects groupthink and premature convergence
├── mailbox.py Multi-round debate protocol
├── memory.py Cross-session learning and persona tracking
├── scaling.py Dynamic agent count based on complexity
├── prd_generator.py Converts decisions into product requirements
└── observability.py Session metrics and audit replay
该系统基于86个钩子,在六个生命周期节点(PreToolUse、PostToolUse、Stop及其他三个)拦截操作。每次智能体生成、每次文件写入、每条Git命令都经过验证。
置信度触发机制
并非每个任务都需要五个智能体进行讨论。我构建了一个置信度评分算法,评估四个维度:
- 模糊性 — 查询是否有多种有效解读?(匹配模式:”best way”、”should I”、”compare vs”、”pros and cons”)
- 领域复杂度 — 是否需要专业知识?(匹配模式:”architecture”、”security”、”performance”、”database schema”)
- 风险等级 — 决策是否可逆?(匹配模式:”production”、”breaking change”、”delete”、”security vulnerability”)
- 上下文依赖性 — 是否需要理解更广泛的系统?
评分映射到三个级别:
- 高置信度(0.85+): 无需协商直接执行
- 中等置信度(0.70-0.84): 执行但记录置信度备注
- 低置信度(低于0.70): 触发完整的多智能体协商
阈值根据任务类型自适应调整。安全相关决策要求85%的共识。文档变更仅需50%。这避免了对简单任务的过度工程化,同时确保高风险决策得到充分审查。
生成预算问题
我的第一版实现使用基于深度的递归限制:深度0的智能体生成深度1的,深度1生成深度2的,深度3被阻止。这种方案立即失败了。协商智能体需要并行运行而非串行。深度1上的五个智能体不是深层递归,而是广度协作。
修复方案:生成预算模型。根智能体获得一个预算(最多12个智能体),用该预算生成并行工作者。工作者继承剩余预算但不能超出。这既防止了失控的链式调用,又允许协商所需的并行执行。
实际测试发生在我对翻译后的博客文章运行10个审查智能体时。递归保护阻止了第4到第10个智能体,因为它将生成计数为深度递增。切换到预算模型后,全部10个成功运行。深度从未超过1,宽度则根据任务需求进行了扩展。10
共识验证
智能体完成后,协商后钩子运行四项检查:
- 阶段就绪性 — 协商是否已从研究阶段推进到排序阶段?
- 智能体法定人数 — 是否至少有2个智能体完成?(可按任务类型配置)
- 共识阈值 — 一致程度是否达到要求?(基准70%,安全相关85%)
- 异议记录 — 如果智能体意见不一致,相关顾虑是否已记录?
第4项检查是我意料之外的发现。早期运行产生的”共识”实际上是智能体简单地同意第一个回答。一致性检测器现在会标记过早收敛:如果所有智能体在第一轮就以高相似度分数达成一致,系统会强制进行第二轮对抗性分析。
艰难的教训
原子文件写入至关重要。 多个智能体同时写入同一状态文件会导致JSON损坏。修复方案:先写入.tmp文件,再用mv原子操作替换。操作系统保证同一文件系统上的mv是原子性的。这一行代码的改动消除了一整类竞态条件。
上下文隔离防止群体思维。 每个智能体通过四个层级接收独立上下文(L0:基础知识,L1:任务特定,L2:角色特定,L3:轮次特定)。没有隔离时,智能体会趋向于第一个看似合理的答案,而非探索解空间。有了隔离,安全智能体和性能智能体会得出真正不同的结论,因为它们从不同的假设出发。
测试智能体基础设施比测试应用代码更难。 该系统有141个测试:48个Bash集成测试用于钩子行为,81个Python单元测试用于库模块,12个端到端流水线模拟。项目记忆中的每个故障案例(生成预算阻塞、引号检测误报、博客计划文件被意外当作文章提供)在修复后都成为了测试用例。智能体的缺陷比应用缺陷更难复现,因为它们依赖于时序、顺序和并发状态。
人机分工
| 人类职责 | 智能体职责 |
|---|---|
| 问题定义 | 流水线执行 |
| 置信度阈值设定 | 在阈值内执行 |
| 共识要求制定 | 共识计算 |
| 质量门标准制定 | 质量门执行 |
| 错误分析 | 错误检测 |
| 架构决策 | 架构方案生成 |
| 领域上下文注入 | 文档生成 |
核心模式:人类负责需要组织背景、伦理判断或战略方向的决策,智能体负责需要在大规模可能性空间中进行计算搜索的决策。11我在智能体架构分析一文中进一步探讨了这种分工。
智能体化的ML工程师不再手写流水线。智能体化的ML工程师定义目标、约束和评估标准。智能体负责实现循环:提议、执行、评估、迭代。人类的角色从构建者转变为架构师:设定护栏、审查输出,并做出需要智能体所缺乏的领域上下文才能做出的判断。12
核心要点
对于刚开始构建AI系统的工程师: - 对于涉及频繁变化的知识或需要来源归属的场景,首选RAG;RAG能在数天内提供可用的基准方案,而微调需要数周的数据准备 - 当应用同时需要领域推理和最新知识时,将RAG与微调结合使用 - 如果一个任务需要多次模型调用,您就需要智能体编排——这是一个与RAG或微调完全不同的工程问题
对于构建智能体系统的团队: - 先构建置信度评分,再构建智能体;大多数任务不需要协商,而知道何时使用智能体的系统比智能体本身更有价值 - 对于并行智能体架构,使用生成预算而非深度限制;深度限制会阻断智能体协商所需的广度协作模式 - 验证共识质量,而非仅验证共识是否存在;过早达成的一致比没有共识更糟,因为它会制造虚假的信心
参考文献
-
Databricks, “State of Enterprise AI Architecture,” Databricks Research, 2024. ↩
-
Lewis, Patrick et al., “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks,” NeurIPS 2020. ↩
-
Gao, Luyu et al., “Precise Zero-Shot Dense Retrieval without Relevance Labels,” ACL 2023. ↩
-
Borgeaud, Sebastian et al., “Improving Language Models by Retrieving from Trillions of Tokens,” ICML 2022. ↩
-
Singhal, Karan et al., “Large Language Models Encode Clinical Knowledge,” Nature, 620, 172-180, 2023. ↩
-
Hu, Edward J. et al., “LoRA: Low-Rank Adaptation of Large Language Models,” ICLR 2022. ↩
-
Miao, Xupeng et al., “Towards Efficient Generative LLM Serving: A Survey from Algorithms to Systems,” arXiv:2312.15234, 2023. ↩
-
Anthropic, “RAG + Fine-Tuning: A Practical Architecture Guide,” Anthropic Cookbook, 2024. ↩
-
Sculley, D. et al., “Hidden Technical Debt in Machine Learning Systems,” NeurIPS 2015. ↩
-
Author’s experience building multi-agent deliberation infrastructure, documented in project MEMORY.md. 86 hooks, 141 tests, 12 Python modules. ↩
-
Sambasivan, Nithya et al., “‘Everyone Wants to Do the Model Work, Not the Data Work’: Data Cascades in High-Stakes AI,” CHI 2021, ACM. ↩
-
Hollmann, Noah et al., “Large Language Models for Automated Machine Learning,” arXiv:2402.08355, 2024. ↩