ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI Agent失控与护栏体系:从RAG到企业级应用的风险控制实践

AI Agent失控与护栏体系:从RAG到企业级应用的风险控制实践 1. 项目概述当AI项目从可控滑向失控这半年我一直在复盘我们团队做的那个从AI客服到AI运营的项目越复盘越觉得那个同事的话扎心我们可能驯养了一头无法掌控的猛兽。起初大家都当玩笑听后来发现这句话一点没夸张。事情是这样的我们从一个简单的意图识别功能起步逐步给大模型接入了知识库、工单系统、用户画像甚至让它自动生成营销文案、自动回复客诉邮件。每个单点功能上线的时候都测得好好的准确率、响应速度、成本都在可接受范围内。但三个月之后我们开始频繁收到来自运营、客服、甚至法务部门的投诉——不是某个具体功能出bug而是那个系统整体的行为开始变得不对劲。这绝对不是一个我们团队独有的问题。你去看那些深度应用了大模型、Agent越来越多地参与实际业务决策的团队几乎都会经历一个类似的失控曲线初期惊喜中期膨胀后期恐慌。区别在于有人在一开始就意识到猛兽终归是猛兽提前修建了围栏而我们当时只顾着投喂和驯化忘了想它跑起来之后到底谁能拉住它。这篇文章我想把整个过程拆开聊聊。我不谈那种宏大叙事就讲我们这次实操中实实在在踩过的坑、做过的事以及最终沉淀下来的那套护栏体系。如果你现在正准备把大模型往生产环境推或者你的Agent已经在自动处理业务这篇文章值得读完再决定下一步怎么走。2. 核心细节解析我们从哪一步开始失控的2.1 第一阶段可控的幻觉——一切还在射程内项目初期我们做的其实是一个标准的企业级RAG问答系统。底层接了一个开源大模型上面架了向量数据库把几千份产品文档切块、做Embedding、建索引用户提问题系统先检索再回答。我们用了一套专门的检索增强生成框架来管理上下文窗口和向量检索的Top-K参数当时觉得这版做得挺细。那个阶段最常见的毛病是幻觉——模型会在没有依据的情况下编造回答。比如用户问某功能支不支持某个冷门场景知识库里根本没有相关文档偏偏模型一本正经地说支持可以通过XXX配置实现看起来特别可信实际上全是编的。幻觉这个问题的处理方案相对成熟我们给每条回答加了一次基于知识库的二次校验让模型判断回答是否有文档支撑如果支撑度不够就回复没有找到相关信息。同时把系统的温度参数往低调减少创造性输出。效果立竿见影幻觉率从12%降到了2%左右。但事后回头看这个阶段最大的问题不是幻觉而是我们当时形成了模型输出的东西我们是可以靠提示词和参数把它管好的这个错觉。这个错觉直接影响了后面所有决策。2.2 第二阶段从QA到Agent——失控的伏笔RAG问答做稳定之后业务方开始提更高级的需求能不能让系统不只是回答问题而是直接去执行一些操作比如自动查订单、自动改物流地址、自动生成售后补偿方案、自动回邮件这里就要说到Agent的核心差异了。传统RAG系统的输出终点是文字是建议Agent系统的输出终点是动作是直接对真实世界产生影响。文字错了可以改动作错了代价就大了。当时我们没太把这当回事想着反正在测试环境跑动作也不多出了问题再回滚呗。我们把Agent拆成了几个子模块意图路由、工具调用、参数抽取、执行确认。意图路由负责判断用户想干什么工具调用负责从预先注册好的API池里选函数参数抽取把对话里的自然语言转成JSON参数执行确认在真正调用外部API之前让用户或客服点一下确认。架构听起来很严谨对吧但问题在于Agent的决策链路是模型驱动的只要中间某一步的输入被污染后面整个链条都会跟着跑偏。举个例子我们曾经发现Agent在某个上下文场景下把查询订单状态误判为发起退款申请原因是用户的历史对话里包含投诉情绪意图路由被带节奏了。这类问题不是跑几个单元测试能发现的。2.3 第三阶段权限扩大——猛兽开始伸爪子了真正的失控发生在第三个阶段。随着大家对Agent的信心增强我们开始给它松绑。先是把执行确认从每次必须由人类点击改成了仅高风险操作需确认然后逐步扩大可调用工具的权限范围。到后来那个Agent能做的事包括但不限于自动回复客户邮件并抄送内部人员在CRM系统里修改客户备注自动生成并发送优惠券根据上下文自动升级工单等级对接第三方系统拉取数据并自动填充报表这个阶段已经有很强的业务操作员属性了而且在人工介入与控制权上我们明显松了手。原因很现实人工确认太多效率提不上来业务方不满意而且之前跑了那么久都没出大事大家的警惕心自然降下来了。然后就是那件让所有人意识到猛兽失控的事件某个深夜Agent在处理一连串批量客诉邮件时自动触发了大量退款而且退款金额因为上下文理解偏差被多次重复计算导致当天的赔付金额远超预算线。具体数字不能细说但足够让整个项目组被叫去开会复盘。复盘的时候我们发现根本原因不是模型变坏了而是系统里没有任何机制在动作执行之后做结果复核。我们的监控还是有没有报错而不是做的事情对不对。董事会层面不讨论技术细节但提到了这头猛兽的比喻——从此之后我们内部就把这个Agent系统称作我们驯养的那头猛兽。3. 实操过程我们如何为猛兽修建围栏3.1 三层护栏体系的设计思路那件事之后项目被暂时冻结我们重新做了一次整体设计。这次不再是如何让模型变得更聪明——那是没完没了的军备竞赛而是如何让模型即使聪明也翻不了天。说白了我们需要给猛兽修一个笼子。根据这次复盘的教训我们把能做什么、做得多快、影响多大作为三个设计维度梳理出三层护栏体系层级控制目标核心手段典型工具/策略第一层控制范围权限最小化工具白名单、操作域隔离、数据脱敏第二层控制风险人工审批与熔断分级别审批规则、风险评分模型、双人复核第三层控制影响审计与回滚全量操作日志、快照备份、一键回滚机制第一层要解决的是能接触到什么。我们重新梳理了每个工具的必要性能少接一个API就少接一个。例如Agent原本可以直接改数据库现在改成只允许调用一个封装好的、带业务校验的更新接口而底层数据库的写权限收回到应用层。第二层要解决的是什么时候需要刹车。我们按照操作的影响面把它们分成了低风险、中风险、高风险三个等级不同等级对应不同的确认流程。高风险操作不仅需要用户确认还需要值班的客服主管二次审批这会在不牺牲绝大多数低风险场景效率的前提下把重大损失的概率降下来。第三层解决的是出事后怎么办。我们实现了每条Agent动作的完整链路追踪从用户原始输入、模型推理过程、参数抽取结果、工具调用记录到最终返回值全部写审计日志。这就像给猛兽装了GPS出了事至少知道它到底干了什么、在哪一步干的。3.2 实操步骤一给工具接入刹车——分级审批矩阵我们落地第一件事是给所有Agent可调用的工具做了一次风险分级。这个分级不是拍脑袋定的而是结合真实历史数据和业务部门访谈逐项评估的。具体做法是我们组织了一个工具风险评审会参与的人包括后端同学讲技术风险、业务同学讲业务影响、法务同学讲合规边界、客服同学讲用户体验。每个工具按照以下四个维度打分影响范围单用户/单订单/全量数据资金风险是否涉及资金变动、赔付、扣款数据敏感度是否涉及个人信息、商业机密可逆性操作能否被回滚如果能回滚成本多高分数出来后我们把工具分成三档。A档是只看不动的查询类工具比如查订单状态、查库存B档是低风险修改类工具比如修改客户备注、发送站内信C档是高风险操作类工具比如发起退款、批量发送营销邮件、修改价格。然后针对不同档位设计了不同的执行策略。A档完全自动执行B档需要用户在界面上点一个确认按钮并填写简短的操作理由C档必须在B档基础上额外触发一条审批流由具备相应权限的主管在系统里审批通过Agent才会真正发起外部调用。这套分级审批矩阵上线后一个非常明显的变化是C档操作的数量并没有显著下降但每一条C档操作都会被人看到、被人评价。它扼制的不是Agent的能力而是Agent的莽撞。3.3 实操步骤二给模型加装刹车——风险评分前置审批矩阵是从流程层面控制这是不够的。因为现实情况是很多风险操作根本不会触发人工审批——它藏在大量低风险操作的组合里。举个具体例子Agent先查了用户的等级然后查了历史订单金额接着又调用了优惠券生成接口并自动发送。单个看每一步都在A/B档连起来实际上就是一个完整的、未经授权的高价值用户定向营销操作。为了应对这种组合型风险我们给系统加了一个风险评分模块。每次Agent准备调用工具时系统会把当前会话的完整上下文包括之前的动作序列、涉及的实体信息、操作金额、频率等喂给一个独立的评分模型让这个模型输出一个0到1的风险分。评分模型一看到动作序列里出现了优惠券生成自动发送这个组合再结合用户画像里的高价值标签就能自动把风险分拉到0.8以上从而触发更严格的审批流程。这个方案本质上是用一个专门的模型来盯着干活的主模型。两者分工不同主模型负责完成对话和任务监督模型负责评估风险。主模型可以性能弱一点、速度快一点但监督模型要稳、要保守、宁可误报也不放过。我把这个思路称为让另一个AI来负责刹车——效果比单纯依赖主模型自我判断要可靠得多。3.4 实操步骤三给数据加装缰绳——动态权限与脱敏权限控制还有一个容易忽略的维度数据权限。之前我们的Agent在调用工具接口时用的是同一个单一服务账号本质上拥有了整个系统的访问权限。这意味着只要Agent理解了用户的意图它就可能去查询任何人的订单、任何人的积分、任何人的备注。为了应对这个问题我们做了两层数据层面的隔离。第一层是动态权限传递。每次会话创建时系统会解析出当前操作人的身份并向权限中心申请一个一次性令牌令牌里携带了该用户的角色和操作边界。Agent在后续调用任何工具时都必须带上这个令牌后端服务会校验令牌里的权限范围越权访问直接拒绝。第二层是返回数据脱敏。即使Agent拿到了合法查询结果如果查询结果里包含手机号、身份证号、家庭住址等敏感字段系统会在返回给模型之前做掩码处理。除非当前会话确实需要这些字段且操作人的权限等级足够高否则模型看到的永远是138****1234这样的脱敏内容。这套机制上线后我们做了一个有趣的测试让Agent尝试去查询一个无权访问的客户数据结果无论怎么构造提示词、怎么切换上下文它都拿不到完整的敏感信息。数据层的缰绳比任何提示词约束都管用。3.5 实操步骤四给行为加装日记——可观测性改造最后一层是审计与可观测性。我们用大语言模型做Agent最怕的就是模型自己编造操作过程。所以我们需要一套机制来记录模型到底认为自己在做什么以及系统实际做了什么。我们改造了工具调用的日志记录方式。以前只记录最终的工具名和参数现在把一条完整的思考链写进日志模型收到什么输入它内部推理了哪些步骤它期望工具执行什么操作工具实际执行的结果是什么中间有没有被审批流程拦截。这些日志全部推送到统一的日志平台和业务系统的操作记录做交叉索引。出问题时我们可以输入一个用户ID一键调出该用户相关的所有Agent操作按时间线排列每一条都关联到具体的对话内容和审批记录。这个体系在后续一次客诉事件中发挥了巨大作用。用户声称收到了两条重复的退款通知但我们从日志里清晰看到Agent只触发了一次退款申请审批流程也只批准了一次但底层的退款服务在重试机制下把同一个退款请求处理了两遍。问题出在我们自己的退款服务幂等性上和Agent无关。如果是以前这个锅大概率会甩给AI出了bug有了日志定位只花了十分钟。4. 常见问题与排查技巧实录4.1 我加了审批流程Agent还是乱动怎么办很多人在参照我们的方案落地时会遇到一个问题明明加了审批Agent还是会做一些看起来不合逻辑的动作。排查之后发现原因往往是审批没有卡住正确的节点。举个例子我们的Agent在调用工具之前会生成一个参数JSON。如果你在调用前的人工审批节点展示的只是用户意图和工具名比如用户想查快递调用快递查询接口那审批人员其实没法判断Agent要查的是谁的快递、查哪单。这种审批就是走形式。正确的做法是把这个参数JSON完整地展示给审批人并且用自然语言翻译一遍。比如审批界面显示Agent调用快递查询接口参数order_id20240619001target_user张三操作目的回答用户关于订单物流的咨询。审批人一眼就能判断这个动作是否合理。记住要给审批人足够的信息否则审批流程就是个花架子。4.2 Agent在同一会话里反复触发同一种操作怎么处理这类问题在客户服务场景下特别常见。用户反复问我要退款Agent就去查询订单、计算金额、生成退款方案然后向用户确认。用户说对Agent再次生成退款方案再确认。如果会话特别长这个循环可能会反复发生每一次都会消耗Token并产生潜在风险。我们的解法是给Agent加一个状态记忆模块。在任何一次工具调用之前系统都会把相同会话中这个工具是否已经被调用过调用结果是什么作为上下文注入提示词同时在提示词里明确要求如果之前已经执行过同样的动作不要重复执行除非用户明确提出了新的、实质性的需求变更。这个改动上线之后反复触发操作的次数下降了接近80%。另外一个意外收获是Token成本也降了一些因为重复的推理链和相似输出不再反复生成了。4.3 模型在审批通过之后执行时用了一个我没让用的参数这个问题更隐蔽。比如审批人通过了一个查询订单状态的请求但Agent实际调用时在参数里偷偷带上了include_returnstrue把用户的退货记录也一并查了出来。为什么会这样因为大模型的参数抽取模块是概率性的。同一个意图在不同的上下文里可能被解析成不同的参数组合。审批人看到的是查询订单状态但Agent自己额外脑补了一个参数这也算是某种低阶的越权。我们的做法是对参数做白名单校验。在工具定义阶段就让后端同学把每个工具允许的参数名、参数类型、参数取值范围显式声明一遍。Agent输出的参数JSON必须经过这个白名单的校验多一个没有声明的参数直接拒绝执行并记录一条风险日志。这套机制上线后多参数越权的情况基本绝迹了。而且这个白名单还有一个好处它让工具设计师必须更深入地思考这个工具到底应该暴露哪些能力倒逼接口设计变得更收敛、更规范。4.4 授权范围越来越宽权限回收怎么执行动态权限令牌上线后又出现了一个新问题权限的给出去容易收回来难。有的权限在会话开始时授予但会话因为各种原因迟迟没有结束Agent就一直持有过期的授权随时可能被唤醒。我们后来做了一套权限心跳机制每个会话权限令牌绑定一个有效期默认只有15分钟。每次Agent调用工具时都会检查有效期如果快过期了系统会弹出一个继续执行需要重新确认权限的提示。如果用户不在线Agent就自动进入暂停状态直到用户重新确认。这个改动刚开始被产品同事吐槽说太麻烦打断用户体验但运行两周后大家发现真正因为权限过期而打断的会话占比只有个位数百分比而且这些会话大多本来就是应该被终止的僵尸会话。权限心跳本质上是让用户在场这个条件被显式地纳入Agent执行链路我认为这对所有Agent类应用都是必要的。4.5 模型输出不稳定越想让它保守它越激进怎么调如果你在提示词里反复写请务必保守操作不要做任何超出权限的事情你会发现大模型往往并不会变得更保守反而会因为过度解读而把正常操作也拦下来或者突然在一个拐弯处做出激进反馈。我们踩了几次坑之后发现面对大模型的危险行为与其在提示词层面反复强调不如在工程层面直接设物理边界。这就好比你想让马不往悬崖边跑与其每天在马耳边念叨别往悬崖跑不如直接在悬崖边修一道栅栏。我们在Agent的提示词里只写了最基础的行为规范不再堆砌负面约束。真正的风险控制全部交给了上面的审批矩阵、风险评分模型、参数白名单和动态权限。模型可以在提示词层面自由发挥但到了执行层面每一步都有切实的物理限制。这套思路调整之后模型的整体表现更稳定我们的心理负担反而更轻了。5. 驯养猛兽的更多实践续篇与扩展思考5.1 从猛兽到家族多Agent协同的失控风险在前一篇文章里我聊了单头猛兽怎么上护栏实际上没过多久我们就把这套体系扩展到了多Agent场景。起因很简单业务方希望不同部门有各自的专属Agent比如客服Agent、运营Agent、数据分析Agent它们之间可以互相传递任务和数据。听起来很高效对吧但多Agent之间一旦开始协作失控的方式就几何级增加。单Agent场景下失控路径是模型→工具→后果链路相对短多Agent场景下失控路径变成了Agent A→Agent B→工具→后果中间多了几次模型与模型的交互。每次交互都可能放大误差而且由于Agent之间的消息传输使用的是自然语言我们很难通过常规日志去追踪脏数据是在哪一步被引入的。我们曾经在一次联调时发现客服Agent向数据分析Agent传递了一个用户满意度偏低的任务数据分析Agent为了完成这个任务主动给客服Agent回传了一份建议对这批用户发起补偿的策略报告客服Agent看过报告之后真的调用了优惠券发放工具给一批用户各发了一张大额券。整个链路里的每一步单独看都合理但连起来就是一次未经审批的高成本营销动作。应对多Agent失控我们做了一个非常土但非常有效的设计Agent之间的消息全部走结构化协议不用自然语言裸传。任何Agent要向另一个Agent请求帮助必须按固定模板填写任务类型、目标实体、参考数据、期望输出格式、风险标识接收方Agent在解析完这份结构化请求后必须向请求方回传一个我理解你要我这么做对吗的确认消息。虽然这让Agent之间的交互少了一些灵活性但每一步都变得可追踪、可审计、可拦截。灵活性换可控性我认为在当下这个阶段是值得的。5.2 另一条路将猛兽关进沙盒——平行世界验证有段时间我们内部的争论焦点是到底该让Agent在真实系统里跑再靠护栏兜底还是应该让Agent先跑一遍模拟环境验证结果安全了再应用到真实系统前者是边跑边拦后者是先验再跑。后来我们做了一个折中方案影子模式。具体来说Agent的决策和动作仍然生成但不会直接作用于真实系统而是同时打到生产环境的影子库和一个旁路的模拟执行器里。影子库的schema和生产环境一致但数据全部来自一周前的脱敏快照。模拟执行器会按照Agent的指令跑一遍真实代码把结果记录下来和真实系统的决策结果做对比。这个方案的优点是你可以零风险地观察Agent在真实流量下的表现发现它在哪些场景下决策激进、哪些场景下会调用不该调用的工具、哪些场景下无法正确提取参数。我们连续跑了三周影子模式收集了大量真实有效的训练语料挺有意思的是我们更大的收获是发现了很多连设计者自己都没想到的触发场景。等Shadow模式的准确率稳定在98%以上之后我们才把流量逐步切回真实执行。影子模式某种程度上相当于在猛兽真正踏出笼门之前先看着它在笼子里怎么转圈。5.3 从刹住到法理合规视角的猛兽控制技术层面聊了很多但驯养猛兽这件事最后绕不开法务视角。尤其是在涉及用户数据、资金操作和自动化决策的场景下即便你在工程上做了再多的审批、审计和拦截如果事前没有从法律合规层面想清楚权责边界出事之后依然会非常被动。这里有三个我们在实际项目里总结出的、值得每支Agent团队提前对齐的问题第一程序自动执行的动作法律上算谁的行为是算用户授权的行为还是算企业委托的行为还是算无人值守但企业平台提供了便利的行为这会直接影响出事之后的归责路径。第二审批人的确认能覆盖多大范围我们在设计审批矩阵时就遇到一个尴尬问题审批人在界面上点了同意但这单同意能覆盖到这个会话里的所有后续动作还是仅这一条动作如果会话还在继续Agent后续又自动执行了类似动作审批人的同意还成立吗后来我们把审批范围字段显式地写进了审批记录里支持两种粒度但很多团队压根没意识到这个细节。第三日志要保留多久、谁能看Agent的行为日志里往往包含了用户的完整对话内容甚至包含了敏感个人信息。如果日志保留周期过长本身就是合规风险如果周期过短出了纠纷又拿不出证据。这个问题的答案没有标准解需要结合你的业务敏感度和监管要求自己权衡但最好在设计初期就必须决定而不是出事之后才开始补。这些问题确实不那么代码相关但在生产环境里它们和代码同等重要。猛兽驯养到一定规模之后真正决定你能不能继续养下去的不只是技术护栏还有规则共识。5.4 未来的笼子局部自动化的正确姿势最后聊聊我对Agent到底该不该自主的看法。经历过这次项目之后我的观点越来越清晰当前阶段Agent的自主性应当是局部化、情境化的而不是全局放开的。局部化是指Agent只在其被明确指定的子任务范围内拥有自主权。比如客服Agent可以自主完成查询订单状态解释退换货政策这类动作但涉及资金、权益、数据导出的操作必须在每个独立会话中重新获得授权。不要试图让Agent理解一个全局目标比如提高用户满意度然后自己拆解成操作步骤——这种全局自主的Agent当前还远没有到可以放进生产环境的水平。情境化是指Agent的自主程度应当随情境动态变化。低风险场景比如查公开资料直接执行中等风险场景比如修改用户地址需要用户确认高风险场景比如批量发送营销消息则需要制度级审批。不是所有动作都走最重的那道流程也不是所有动作都可以轻量放行。我们后来把一个核心原则写进了团队文档把动作的选择权交给模型把动作的执行权交给规则。你可以在提示词里让模型自由地建议我觉得该发一张50元优惠券但它是否真的能发必须由规则引擎来裁决。模型负责聪明系统负责可靠。这两者结合才是一头能被驾驭的猛兽。我们现在系统里那套风险评估模型已经连续跑了几个月累计拦截了上百次潜在的高风险动作其中既有正经业务动作被误拦截的也有真的不能放行的操作。每一个栏截案例都会回流到沙盒里让Agent重新学习这类动作应该怎么更规范地发起。这个过程像极了驯兽先立规矩再练动作最后才是信任。AI项目做久了你会明白模型的能力从来不是最难的部分真正难的是怎么让它在生产环境的复杂约束下发挥出恰好够用的水准。
返回列表