ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

AI工程韧性实战:RAG与Agent从原型到生产的落地指南

AI工程韧性实战:RAG与Agent从原型到生产的落地指南 1. 从能跑通到敢上线AI工程韧性到底卡在哪我见过太多团队在Demo阶段兴奋不已一到生产环境就原形毕露。一个RAG问答系统在本地跑得丝滑流畅上线第二天就开始胡言乱语一个Agent工作流在测试用例里表现完美真实用户一用就陷入死循环。问题不在于模型不够强而在于整个工程体系缺乏韧性。所谓韧性不是让系统永远不犯错而是让它在犯错时能优雅降级、快速恢复、持续可控。原型和产品的分水岭就在这里。原型只需要证明这条路走得通产品需要证明这条路在刮风下雨、车流高峰、路面施工时依然走得通。AI工程的特殊性在于它的核心组件——大语言模型——本身就是一个概率性系统输出天然带有不确定性。你没法像传统后端那样通过单元测试断言输入A必然得到B。这种不确定性会沿着调用链层层放大最终在用户侧表现为时好时坏的玄学体验。我踩过最典型的一个坑是早期做一个合同审查助手。开发阶段用几十份标准合同测试准确率相当可观。上线后遇到一份格式混乱、条款交叉引用的扫描件模型直接开始编造条款编号。更糟的是下游的摘要模块毫无察觉地接受了这些编造内容生成了一份看起来煞有介事的审查报告。整个链路没有任何一个环节说我不确定。这就是典型的原型思维——只关注主路径不关注失败路径。韧性工程的核心是把失败当作一等公民来设计。你需要假设检索可能召回无关内容模型可能产生幻觉工具调用可能超时外部API可能限流用户输入可能超出预期分布。每一个假设都对应一层防护。这不是过度设计而是AI系统从实验室走向真实世界的必修课。这篇文章面向的是已经跑通过AI原型、正准备或正在向生产环境推进的工程师和团队。我会围绕RAG、Agent、Harness、CI/CD这几个关键词拆解韧性工程的具体落地方法。不聊空泛的方法论只讲我实际用过、验证过、踩过坑的方案。2. RAG系统的韧性瓶颈检索质量决定一切上限2.1 为什么你的RAG看起来能用但实际不好用RAG检索增强生成是目前最主流的AI工程范式之一但也是最容易被低估的。很多人以为RAG就是向量数据库大模型的简单拼接实际上检索质量才是决定整个系统上限的关键变量。生成模型再强如果检索回来的上下文是错的、无关的、或者不完整的输出必然拉胯。我做过一个内部知识库问答初期用最简单的方案文档切块、embedding、余弦相似度检索、Top-K拼接进prompt。测试阶段效果不错因为测试问题都是我围绕文档内容设计的。上线后真实用户的问题五花八门有的问这个流程的审批人是谁有的问如果审批人不在怎么办有的甚至问去年这个流程和今年有什么区别。第一种问题检索效果尚可后两种直接崩盘——因为答案分散在多个文档块里或者需要跨文档推理简单的Top-K检索根本覆盖不到。这里的关键认知是RAG的瓶颈不在生成在检索。生成模型的能力已经足够强真正拖后腿的是你给它的上下文对不对。而检索质量又取决于三个环节文档切块策略、embedding模型选择、检索后的重排序与过滤。2.2 文档切块最容易被忽视的精度杀手切块策略直接决定了检索的粒度。切得太粗一个块里混了多个主题检索时容易引入噪声切得太细一个完整语义被拆散检索时可能只召回一半信息。我试过固定长度切块比如512个token也试过按段落切、按标题层级切、按语义相似度切每种都有适用场景。固定长度切块实现最简单但问题很明显它会在句子中间切断导致语义不完整。按段落切块更符合自然语言结构但遇到长段落还是会超长。按标题层级切块适合结构化文档但很多真实文档的标题层级并不规范。语义切块用embedding判断相邻句子的相似度在相似度骤降处切分效果最好但计算成本高且对短文档不友好。我目前最常用的方案是混合切块先按标题层级切大块再在大块内部按语义相似度切小块同时保留块与块之间的父子关系。检索时先定位到父块再在父块内部精确定位子块。这样既保证了语义完整性又控制了检索粒度。具体实现上我会给每个块打上元数据标签所属文档、标题路径、块类型正文/表格/列表、前后块ID。这些元数据在后续的重排序和上下文扩展时非常有用。注意切块大小没有万能参数。技术文档适合300-500token法律合同适合800-1200token聊天记录适合按对话轮次切。一定要根据你的文档类型做实验别抄别人的参数。2.3 检索后的重排序把可能相关变成确实相关向量检索的本质是语义相似度匹配它擅长找意思相近的内容但不擅长判断是否真正回答了问题。比如用户问审批人不在怎么办向量检索可能召回一段讲审批流程概述的内容因为两者都包含审批这个词的语义。但真正有用的内容是代理人机制那一段。重排序Rerank就是解决这个问题的。它的原理是先用向量检索召回一个较大的候选集比如Top-50再用一个更精细的交叉编码器Cross-Encoder对每个候选与问题的相关性打分最后取Top-5送入生成模型。交叉编码器比向量相似度慢但精度高得多因为它能同时看到问题和文档内容做细粒度的语义匹配。我实测下来加入重排序后检索准确率Top-5中包含正确答案的比例能从60%左右提升到85%以上。代价是每次查询增加200-500毫秒的延迟。这个 trade-off 在生产环境完全值得因为检索错了后面全错检索对了生成模型基本不会出大问题。重排序之后还有一步相关性阈值过滤。如果所有候选的分数都低于某个阈值说明知识库里根本没有相关内容。这时候正确的做法是让系统回答我没有找到相关信息而不是硬塞几个低分片段让模型编造。这个阈值需要通过实验确定我一般会取验证集上F1分数最高时的阈值。2.4 上下文组装别把模型当垃圾桶检索到相关片段后怎么组装进prompt也有讲究。我见过最粗暴的做法是把Top-K片段直接拼接中间加个分隔符就完事。这种做法的问题在于片段之间可能矛盾、可能重复、可能包含过时的信息。模型面对一堆互相冲突的上下文输出质量必然不稳定。我的做法是分层组装最相关的片段放在最前面和最后面利用模型对首尾位置更敏感的特性中间放次要片段。每个片段前面加上来源标注文档名、章节、更新时间让模型知道信息的出处和时效性。如果片段之间有冲突我会在prompt里明确指示如果信息冲突优先采用更新时间更近的来源。另外上下文长度不是越长越好。我做过对比实验在同一个问题上给模型3个精准片段的效果明显好于给10个包含噪声的片段。原因是长上下文会稀释模型的注意力而且噪声片段会干扰推理。所以我的策略是宁可少给不可乱给。重排序后取Top-3到Top-5每个片段控制在合理长度内总上下文不超过模型窗口的60%。3. Agent与Harness把不确定性关进笼子里3.1 Agent的本质是一个不确定的决策循环Agent和普通LLM调用的区别在于Agent会自主决定下一步做什么。它可能调用工具、可能追问用户、可能直接回答。这种自主性带来了灵活性也带来了失控的风险。我见过Agent陷入无限循环、反复调用同一个工具、或者在没有足够信息时强行给出答案。Agent的韧性设计核心是给决策循环加上边界和检查点。具体来说我会在以下几个位置设置防护最大步数限制硬性限制Agent最多执行N步比如10步超过就强制终止并返回当前最佳结果。这个N需要根据任务复杂度调整太少了任务完不成太多了浪费资源且增加失控风险。工具调用白名单不是所有工具在任何时候都能调用。比如删除数据这类危险操作必须要求Agent先获得用户确认。循环检测如果Agent连续两次调用同一个工具且参数相同说明它卡住了应该中断并提示。输出格式校验Agent的每一步输出都要经过schema校验不符合预期格式的直接拒绝并要求重试。这些防护措施看起来简单但能挡住80%以上的失控场景。我踩过最惨的一次坑是一个Agent在调用搜索工具时因为搜索关键词构造错误反复搜索同一个词每次返回空结果它又继续搜直到耗尽token预算。如果当时有循环检测这个问题在第二次重复时就会被拦住。3.2 Harness不是Agent它是Agent的测试台很多人把Harness和Agent混为一谈其实它们解决的是不同问题。Agent是干活的Harness是检验干活质量的。Harness工程的核心思想是用可重复、可度量的方式评估Agent在各種场景下的表现。一个完整的Harness应该包含场景库覆盖正常路径、边界情况、异常输入、对抗性输入。比如对于客服Agent场景库要包含用户问了一个知识库里没有的问题用户情绪激动用户输入了无关内容等。评估指标不只是准确率还要看工具调用次数、响应延迟、token消耗、失败恢复率。我特别关注失败恢复率——Agent在第一次尝试失败后能否通过调整策略最终完成任务。回归测试每次修改prompt、更换模型、调整工具定义后都要跑一遍完整场景库确保没有引入退化。这一点和传统软件的CI/CD完全一致。我目前的Harness实现是一个Python框架用YAML定义场景每个场景包含输入、预期行为不是预期输出因为LLM输出有随机性、评估函数。评估函数可以是精确匹配、关键词包含、或者用另一个LLM做judgeLLM as Judge。跑完所有场景后生成报告对比历史版本标出退化的用例。提示LLM as Judge虽然方便但本身也有偏差。我的经验是对于关键场景用规则匹配人工抽检对于大量非关键场景用LLM as Judge做初筛再对低分用例人工复核。3.3 把Harness接入CI/CD让每次变更都有据可依Harness最大的价值是让AI工程的迭代变得像传统软件一样可控。我把Harness接入了GitLab CI每次提交涉及prompt、工具定义、模型配置的变更时自动触发场景库回归测试。测试不通过MR无法合并。这个流程刚推行时团队有人觉得麻烦认为改个prompt而已不用这么大动干戈。但很快大家就真香了。有一次一个同事优化了系统prompt的措辞在几个常见场景上效果确实更好了但回归测试发现在用户输入包含否定词的场景下Agent开始错误理解意图。如果没有Harness这个问题可能要到上线后才会被用户发现。CI/CD流水线的具体配置# .gitlab-ci.yml 片段 ai-regression-test: stage: test script: - python run_harness.py --scenario-set full --output report.json - python compare_report.py --baseline baseline.json --current report.json --threshold 0.95 rules: - changes: - prompts/**/* - tools/**/* - config/model.yamlcompare_report.py会比较当前报告和基线报告如果任何关键指标下降超过5%就返回非零退出码CI失败。基线报告在每次主干合并时更新。这套机制运行半年后我们团队的AI功能上线事故率下降了70%以上。不是因为大家变聪明了而是因为问题在合并前就被拦住了。4. 韧性工程的三个实战支柱降级、可观测、反馈闭环4.1 降级策略当模型不可用时系统还能做什么AI系统依赖的外部服务模型API、向量数据库、工具API都可能不可用。韧性工程要求你为每一种依赖准备降级方案。降级不是优雅地报错而是用次优方案继续提供服务。我常用的降级层级故障场景降级方案用户体验主模型API超时切换到备用模型能力稍弱但可用响应稍慢质量略降向量数据库不可用切换到关键词检索BM25召回率下降但仍有结果重排序服务不可用跳过重排序直接用向量检索Top-K精度下降但延迟更低所有检索都失败返回暂时无法查询知识库并给出人工入口明确告知不编造工具调用失败重试2次仍失败则告知用户该功能暂不可用部分功能受限关键原则是降级路径必须提前实现并测试不能等故障发生了才临时想怎么办。我会在Harness里专门加一组故障注入场景模拟各种依赖不可用的情况验证降级逻辑是否正确触发。4.2 可观测性看不见的问题等于不存在AI系统的可观测性比传统系统更难因为错误的定义是模糊的。传统系统里HTTP 500就是错误AI系统里模型返回了一段通顺但错误的内容从技术指标上看一切正常但业务上这是严重故障。我的做法是建立三层可观测性基础设施层API延迟、错误率、token消耗、并发数。这些用常规监控工具Prometheus Grafana就能覆盖。AI质量层每次请求的检索命中率、重排序分数分布、生成内容的长度和困惑度、工具调用成功率。这些需要自定义埋点。业务效果层用户是否采纳了AI的回答、是否点击了重新生成、是否转人工、会话时长。这些是最终判断AI系统是否好用的指标。我特别想强调检索命中率这个指标。它的计算方式是在每次请求中记录重排序后Top-1片段的分数如果低于阈值就标记为低置信检索。统计低置信检索的比例如果这个比例突然升高说明知识库可能出了问题比如文档被误删、embedding模型更新导致向量空间偏移。这个指标帮我提前发现过好几次数据问题。4.3 反馈闭环让系统在运行中变强韧性不只是抗住故障还包括从故障中学习。我设计的反馈闭环包含三个环节显式反馈用户对回答的点赞/点踩、重新生成按钮、转人工按钮。这些是最直接的信号。隐式反馈用户是否复制了回答内容、是否在回答后继续追问同一话题、会话是否在AI回答后立即结束。这些行为间接反映满意度。人工标注每周抽样一批低分会话由领域专家标注正确答案应该是什么这些标注数据用于优化检索策略和prompt。收集到的反馈会进入一个待优化队列定期review。常见的优化动作包括补充知识库缺失的文档、调整切块参数、更新重排序模型、修改prompt中的指令。每次优化后用Harness跑回归测试确认没有引入退化然后上线。这个闭环跑通后系统就有了自愈能力。不是自动修复而是让团队能快速发现问题和验证修复效果。5. 从原型到生产的检查清单5.1 上线前必须回答的十个问题在把AI原型推向生产之前我会强制团队回答以下问题。任何一个答不上来就说明还没准备好。检索失败时系统会怎么表现用户会看到什么模型API超时或限流时降级方案是什么降级后的质量损失有多大有没有办法在不重新部署的情况下快速回滚prompt或模型配置如何判断一次回答是好还是坏有没有自动化的质量评估知识库更新后如何确保检索质量没有退化Agent的最大执行步数是多少超过后如何处理有没有记录每次请求的完整链路检索了什么、重排序分数、生成了什么用户反馈如何收集收集后如何进入优化流程有没有对抗性测试比如用户故意输入误导性内容系统会怎样如果明天流量翻十倍系统最先崩的是哪个环节这些问题没有标准答案但必须有答案。我见过太多团队在这些问题面前支支吾吾然后上线后手忙脚乱。5.2 我踩过的最大的三个坑第一个坑忽视embedding模型的版本管理。有一次我们升级了embedding模型忘了重新索引整个知识库。结果查询用的新模型向量文档库还是旧模型向量检索结果完全错乱。系统没有报错只是回答质量突然下降。后来我们在CI里加了检查embedding模型版本变更时强制触发全量重新索引。第二个坑prompt里的万能指令。早期我喜欢在prompt里写请尽可能准确地回答用户问题觉得这样能提升质量。后来发现这种模糊指令反而让模型困惑。改成具体的、可操作的指令后比如如果检索内容中没有明确答案请回答根据现有资料无法确定幻觉率明显下降。第三个坑没有限制Agent的工具调用权限。一个内部Agent被赋予了数据库查询权限结果它在一次任务中构造了一个全表扫描的查询直接把数据库拖垮了。后来我们给所有工具加了权限分级和查询限制危险操作必须二次确认。5.3 韧性工程的投入产出比最后说点实在的。韧性工程确实会增加前期开发成本大概比纯原型多30%-50%的工作量。但这个投入在第一次生产事故时就能回本。我经历过一次模型API大面积故障因为提前做了降级方案系统自动切换到备用模型用户几乎无感知。如果没有降级那次故障至少导致数小时的服务中断。更重要的是韧性工程让团队敢于迭代。当你知道每次变更都有Harness兜底、每次故障都有降级方案、每次优化都有数据支撑时迭代速度反而会加快。原型阶段的不敢改变成了生产阶段的放心改。AI工程和传统软件工程最大的区别是我们面对的是一个概率性的、不断变化的、边界模糊的系统。韧性不是可选项而是这个系统能够持续运行的前提。把不确定性当作设计输入而不是需要消除的bug这是从原型思维转向工程思维的关键一步。
返回列表