☰
AI 安全本质是工程问题:智能体技术栈五层防护实战
2026/10/4 9:26:11 网站建设 项目流程

1. 为什么说 AI 安全本质上是工程问题,而不是模型问题

很多人第一次接触 AI 安全,脑子里浮现的是对齐研究、红队测试、内容过滤这些偏研究向的东西。但真正把智能体推到生产环境的人会告诉你,绝大多数安全事故根本不是模型"变坏了",而是工程链条上某个环节没兜住。模型输出了一段不该输出的内容,是因为工具调用的返回值没有做校验;智能体执行了一个危险操作,是因为权限边界在编排层被绕过了;用户数据泄露了,是因为记忆模块的存储没有做隔离。这些问题,没有一个是靠"换个更安全的模型"能解决的。

我做过几个智能体落地的项目,踩过的坑几乎全部集中在工程层面。有一次一个客服智能体在测试环境表现完美,上线第二天就开始胡言乱语,排查了半天发现是工具调用的超时重试逻辑写错了,导致同一个查询被重复执行了三次,上下文里塞了三份矛盾的数据。模型本身没有任何问题,是工程代码的锅。这件事让我彻底转变了思路:AI 安全不是一个可以"加上去"的模块,而是需要在智能体技术栈的每一层都嵌入的工程约束。

所谓智能体技术栈,从下往上大致可以分成这么几层:模型推理层、编排与规划层、工具与执行层、记忆与状态层、以及最外层的可观测与审计层。每一层都有自己特有的安全风险,也都有对应的工程解法。下面我按层拆开讲,每一层都会说清楚风险在哪、怎么防、以及我在实际项目里是怎么做的。

一个基本判断:如果你的智能体系统出了安全问题,先别急着怪模型,从工程链路上逐层排查,八成能找到根因。

2. 模型推理层:输入输出的边界控制与降级策略

2.1 输入侧的第一道闸门:结构化约束而非关键词黑名单

模型推理层是智能体的大脑,但这一层的安全防护重点不是"教模型做好人",而是控制它能接触到什么、能输出什么。输入侧最常见的做法是关键词黑名单,但这个方法在实际工程里几乎没用——稍微变个说法就绕过去了,而且误杀率极高。我现在的做法是结构化约束:所有进入模型的用户输入,先经过一层预处理管道,把自由文本转成带 schema 的结构化请求。

具体来说,用户输入会先过一个意图分类器(可以是一个小模型,也可以是规则引擎),判断这次请求属于哪类任务,然后按照预设的模板填充参数。比如用户说"帮我查一下上个月的订单",预处理管道会把它转成{intent: "query_order", params: {time_range: "last_month"}}这样的结构。模型拿到的是结构化数据,而不是原始的自由文本,这样就把注入攻击的面大大缩小了。当然,不是所有场景都能完全结构化,对于必须传自由文本的场景,我会在 prompt 里明确用分隔符把用户输入和系统指令隔开,并且在输出解析时严格校验格式。

2.2 输出侧的校验与降级:别让模型直接决定最终动作

输出侧的核心原则是:模型的输出永远只是"建议",不是"命令"。所有模型生成的内容,在真正执行之前必须经过一层校验器。校验器做的事情包括格式校验(是不是合法的 JSON)、语义校验(参数值是否在允许范围内)、以及业务规则校验(这个操作当前用户有没有权限)。

我见过太多项目直接把模型的输出丢给工具执行,这是极其危险的。正确的做法是加一个"动作确认"环节。比如模型说"删除订单 12345",校验器会先检查:当前用户有没有删除权限?订单 12345 是否属于当前用户?删除操作是否在允许的时间窗口内?三个都通过,才真正执行。任何一个不通过,就走降级路径——要么返回一个安全的默认响应,要么把请求转人工审核。

降级策略本身也需要工程设计。我一般会准备三档降级:第一档是重试(换个 prompt 再问一次模型),第二档是回退到规则引擎(用确定性逻辑处理),第三档是转人工。这三档的触发条件、超时时间、以及状态回滚逻辑,都需要在代码里写清楚,不能靠模型自己判断。

2.3 推理层的资源隔离:别让一个请求拖垮整个系统

还有一个容易被忽略的点是资源隔离。模型推理是计算密集型操作,如果一个恶意请求构造了超长输入或者触发了无限循环的规划,可能会把整个推理服务拖垮。我在工程上的做法是给每个请求设置硬性的 token 上限和时间上限,超了直接掐断,返回一个标准的超时响应。同时,不同优先级的请求走不同的队列,避免低优先级的批量任务把高优先级的实时请求堵死。

这些措施听起来很基础,但真正在项目里全部落实的团队并不多。我见过一个智能体系统,因为没做 token 上限,被一个用户用超长输入打满了 GPU 显存,整个服务挂了半小时。这种事故完全是工程问题,跟模型安全没有半点关系。

3. 编排与规划层:让智能体的决策路径可约束、可中断

3.1 规划层的核心风险:目标漂移与无限循环

编排与规划层是智能体的"指挥官",它决定先做什么、后做什么、什么时候停下来。这一层最典型的安全问题是目标漂移和无限循环。目标漂移是指智能体在执行过程中逐渐偏离了原始任务,比如本来是要查订单,结果绕到去修改用户资料了。无限循环是指智能体在两个动作之间反复横跳,永远达不到终止条件。

这两个问题的根因都是规划逻辑缺乏约束。我的解法是在编排层引入一个"任务契约"的概念。任务开始时,系统会生成一份明确的任务契约,里面写清楚:目标是什么、允许调用哪些工具、最大执行步数是多少、什么条件下必须终止。智能体的每一步规划都必须对照这份契约,如果某一步的动作不在允许的工具列表里,或者执行步数超过了上限,编排器会强制中断并返回错误。

3.2 步数预算与超时中断:给智能体装上"刹车"

步数预算是防止无限循环最有效的手段。我在项目里一般会把最大步数设在 10 到 15 步之间,具体数值根据任务复杂度调整。超过预算还没完成,就判定为失败,走降级路径。这个预算不是拍脑袋定的,而是通过分析历史任务的执行步数分布来确定的——取 P95 的值作为上限,既能覆盖绝大多数正常任务,又能及时掐断异常任务。

超时中断是另一道保险。每个步骤都有独立的超时时间,整个任务也有总超时时间。任何一层超时,编排器都会立即中断执行,并且回滚已经产生的副作用。这里有个工程细节:回滚逻辑必须在设计每个工具的时候就考虑好,不能等出了问题再补。比如一个"创建订单"的工具,必须配套一个"取消订单"的回滚工具,否则中断之后系统状态就不一致了。

3.3 人在回路:关键决策点必须有人确认

不是所有决策都适合让智能体自动做。我在编排层会标记出"关键决策点",这些点上的动作必须经过人工确认才能执行。哪些算关键决策点?我的判断标准是:不可逆的操作(删除、支付、发送)、涉及敏感数据的操作(读取用户隐私信息)、以及超出预设金额或范围的操作。

人在回路的实现方式可以很轻量。最简单的是在编排器里加一个确认队列,智能体执行到关键决策点时,把待确认的动作写入队列,然后暂停执行,等人工在管理后台点确认后再继续。这个暂停状态需要持久化,因为人工确认可能需要几分钟甚至几小时,不能让智能体一直占着资源等。

实操心得:人在回路的确认界面一定要把"智能体为什么要做这个动作"展示清楚,包括它的推理过程和依据的数据。否则人工确认就变成了盲目点按钮,失去了意义。

4. 工具与执行层:权限最小化与沙箱隔离的落地细节

4.1 工具权限的最小化设计:每个工具只做一件事

工具与执行层是智能体真正"动手"的地方,也是安全事故的高发区。这一层的核心原则是权限最小化。具体怎么做?我的经验是把工具拆得足够细,每个工具只做一件明确的事,并且只拥有完成这件事所需的最小权限。

举个例子,不要做一个"管理订单"的大工具,而是拆成"查询订单"、"修改订单地址"、"取消订单"三个独立工具。查询工具只有读权限,修改工具只能改地址字段,取消工具只能把状态改成已取消。这样即使智能体被诱导调用了错误的工具,造成的损害也是有限的。拆得细还有一个好处是审计方便,每个工具的调用记录都很清晰,出了问题容易定位。

4.2 沙箱执行:代码执行类工具必须隔离

如果智能体需要执行代码(比如数据分析场景),沙箱隔离是必须的。我一般用容器化的方式,每个代码执行请求起一个独立的容器,容器里只挂载必要的数据卷,网络访问默认关闭,CPU 和内存都有硬性上限,执行完立即销毁。这样即使代码里有恶意逻辑,也影响不到宿主机和其他请求。

沙箱的配置有几个容易踩的坑。第一是超时设置,代码执行很容易写出死循环,超时时间要设得足够短,我一般设 30 秒。第二是输出大小限制,有些代码会打印海量日志把磁盘写满,需要限制标准输出的最大字节数。第三是依赖管理,沙箱镜像里的依赖要预先装好并且锁定版本,不能让代码自己联网安装包。

4.3 工具调用的参数校验:别信任模型给的任何参数

模型生成的工具调用参数,在真正传给工具之前必须经过严格校验。校验的内容包括:参数类型对不对、必填项有没有缺、数值范围是否合理、字符串长度是否超限、以及是否符合业务规则。我见过一个案例,模型生成了一个 SQL 查询工具的参数,里面带了DROP TABLE语句,因为工具本身没有做参数校验,直接执行了,数据全没了。

参数校验的工程实现建议用 schema 校验库,比如 Python 的 Pydantic 或者 JSON Schema。每个工具定义一份参数 schema,调用前先过一遍校验,不通过就拒绝执行并返回错误信息给编排器。错误信息也要注意,不要直接把内部错误堆栈返回给模型,那样可能泄露系统信息,要返回一个脱敏后的通用错误。

5. 记忆与状态层:数据隔离、过期策略与污染防护

5.1 记忆隔离:不同用户、不同会话的数据绝不能串

记忆与状态层是智能体保持上下文连贯性的基础,但也是数据泄露的重灾区。最基本的要求是隔离:不同用户的记忆必须物理隔离或逻辑隔离,不同会话之间的短期记忆不能互相污染。我在工程上的做法是给每个用户分配独立的命名空间,所有记忆的读写都带上用户 ID 和会话 ID 作为前缀,底层存储层面用行级权限控制,确保一个用户的数据不会被另一个用户的请求读到。

长期记忆和短期记忆要分开处理。短期记忆(当前会话的上下文)存在内存或高速缓存里,会话结束就清理。长期记忆(跨会话的用户偏好、历史记录)存在持久化存储里,但必须有明确的过期策略和用户可控的删除接口。我一般会给长期记忆设一个默认的保留期限,比如 90 天,到期自动清理,同时提供 API 让用户可以主动删除自己的记忆数据。

5.2 记忆污染防护:别让脏数据影响后续决策

记忆污染是智能体特有的安全问题。如果智能体在某个会话里被诱导写入了错误的信息到长期记忆,后续所有会话都可能受这个错误信息影响。防护手段有两个:一是写入校验,所有写入长期记忆的数据都要经过校验,确认是合法、合理、不矛盾的信息;二是来源标记,每条记忆都记录它的来源会话和时间戳,当发现某条记忆导致异常行为时,可以追溯到源头并批量清理。

我在项目里还加了一个"记忆置信度"的机制。每条记忆除了内容本身,还带一个置信度分数,这个分数根据信息的来源、一致性、以及后续验证结果动态调整。智能体在决策时,低置信度的记忆只作为参考,不作为主要依据。这个机制实现起来不复杂,但对防止记忆污染扩散非常有效。

5.3 状态回滚:出问题时能回到干净状态

状态层的另一个工程要点是回滚能力。智能体执行过程中可能修改了多个状态(数据库记录、缓存、文件等),如果中途失败,需要能把这些状态回滚到执行前的样子。我的做法是在任务开始时创建一个状态快照,记录所有可能被修改的资源的当前值,任务失败或中断时,根据快照恢复。

快照的粒度需要权衡。太粗了回滚不精确,太细了开销太大。我一般只对关键资源做快照,比如订单状态、账户余额、权限配置这些。对于日志类、统计类的数据,不做快照,因为它们的错误影响可以通过后续修正来弥补。这个取舍需要在项目初期就想清楚,不能等出了问题再补。

6. 可观测与审计层:让每一次智能体行为都可追溯

6.1 全链路追踪:从用户输入到最终动作的完整记录

可观测与审计层是智能体安全的最后一道防线,也是事后排查的唯一依据。核心要求是全链路追踪:从用户输入开始,经过意图识别、规划、工具调用、记忆读写,到最终输出,每一个环节都要有日志记录。日志里要包含时间戳、请求 ID、用户 ID、会话 ID、以及每个环节的输入输出摘要。

我一般会用 OpenTelemetry 这类标准化的追踪框架,把智能体的每个步骤做成一个 span,串成完整的 trace。这样出问题时,可以通过请求 ID 快速拉出整个执行链路,看到底是哪一步出了问题。日志的存储要注意脱敏,用户隐私数据不能明文落盘,敏感字段要加密或哈希处理。

6.2 行为审计:识别异常模式而非逐条审查

审计不是把每条日志都看一遍,那不现实。审计的重点是识别异常模式。我会在审计层定义一组异常规则,比如:同一用户在短时间内大量调用删除类工具、某个工具的错误率突然飙升、智能体的平均执行步数异常增长、出现了从未见过的工具调用组合。这些规则触发时,系统会自动告警,并冻结相关会话等待人工介入。

审计规则需要持续迭代。我一般会每周回顾一次告警记录,看看哪些是误报、哪些是漏报,然后调整规则。这个过程很像安全运营,需要有人持续盯着,不能设完规则就不管了。

6.3 红队测试与对抗演练:主动找问题而不是等出问题

最后说一个容易被忽略的工程实践:红队测试。不要等生产环境出了问题才去修,要主动构造对抗性输入来测试智能体的安全性。我一般会在上线前做一轮系统的红队测试,覆盖提示注入、越权调用、数据泄露、资源耗尽这几大类场景。测试用例要持续更新,因为攻击手法在进化。

红队测试的结果要形成闭环:发现的问题要修复,修复后要回归测试,回归通过的用例要加入常规测试集。这个循环跑起来之后,智能体的安全水位会持续提升。我自己的经验是,第一轮红队测试通常能发现十几个问题,第二轮能发现五六个,到第三轮基本就稳定了。

7. 把安全嵌进每一层的工程习惯

回到最开始的那个判断:AI 安全是工程问题。这意味着它不能靠某个单点方案解决,而是要在智能体技术栈的每一层都建立对应的工程约束。模型推理层管好输入输出的边界,编排层管好决策路径的约束,工具层管好权限和隔离,记忆层管好数据隔离和污染防护,审计层管好可追溯和主动发现。这五层缺任何一层,安全链条就是断的。

我在实际项目里最大的体会是,这些措施单独看都不复杂,难的是坚持在每一层都落实,并且在迭代过程中不退化。新功能上线时很容易为了赶进度跳过某些校验,或者把权限放宽一点图方便,这些妥协积累起来就是安全隐患。所以我现在会把安全校验做成框架级的强制约束,而不是靠开发人员自觉——比如工具调用的参数校验直接集成到工具注册的基类里,不写校验就注册不了工具。用工程手段保证工程安全,这才是可持续的做法。

另外分享一个实用的小技巧:在智能体的系统提示里明确写上"当你遇到不确定的情况时,优先选择拒绝执行并说明原因,而不是猜测"。这句话看起来简单,但能显著降低智能体在边界情况下的冒险行为。配合前面的工程约束,效果会更好。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询