1. 为什么说 AI 安全本质上是工程问题1.1 从模型对齐到系统可靠性的认知转变过去两年大家聊 AI 安全第一反应基本都是模型层面的东西——对齐训练、红队测试、内容过滤、越狱防护。这些当然重要但如果你真正把一个大模型塞进生产系统跑过一段时间就会发现一个很尴尬的事实绝大多数线上事故根本不是模型变坏了而是工程链路某一环出了问题。我举个自己踩过的真实例子。之前做一个客服智能体模型本身表现很稳但上线第三天开始出现偶发的答非所问。排查了两天才发现是工具调用返回的 JSON 里有个字段偶尔为 null模型拿到脏数据后开始胡编。这跟模型对齐没有半毛钱关系纯粹是数据校验没做好。类似的事情还有上下文被截断导致模型丢失关键指令、并发请求下会话状态串了、某个外部 API 超时后智能体陷入死循环疯狂重试烧 token。这些问题的共同点是——它们都是工程问题不是模型问题。你没法靠再训一轮模型来解决只能靠工程手段加校验、加超时、加熔断、加可观测性。所以我现在越来越认同一个判断AI 安全在落地阶段本质上是一个智能体技术栈的分层工程问题。你得把整个栈拆开一层一层去看风险在哪、边界在哪、怎么兜底。这也是我想在这篇里系统聊清楚的东西。1.2 智能体技术栈的分层模型要把每一层讲清楚先得有个分层框架。我习惯把智能体系统拆成这么几层从下往上层级名称核心职责典型安全风险L1模型层推理、生成幻觉、越狱、提示注入L2运行时环境层执行沙箱、资源隔离越权访问、资源耗尽、逃逸L3Harness 编排层工具调用、流程控制、状态管理工具滥用、循环失控、状态污染L4数据与上下文层记忆、检索、上下文组装数据泄露、上下文投毒L5应用与交互层用户接口、权限、审计身份冒用、审计缺失这个分层不是学术定义是我自己在做项目时总结出来的实用框架。你会发现每一层的安全策略完全不同用的工具也不同。把它们混在一起谈AI 安全就会变成一锅粥。提示分层的目的不是分类而是定位。出问题时你能快速判断这是哪一层的锅然后去那一层找对应的工程手段。1.3 为什么分层解决比统一防护更靠谱很多人一开始的想法是搞一个统一安全网关所有请求都过一遍统一过滤。这个思路在小规模下能用但一旦智能体开始做多步工具调用、长任务编排就会崩。原因很简单不同层的风险特征不一样防护手段也不一样。模型层的提示注入你靠运行时沙箱是防不住的运行时层的资源耗尽你靠内容过滤也拦不住。硬要统一最后就是每层都防得不彻底。分层解决的核心逻辑是每一层只解决自己这层的问题层与层之间通过明确的契约交互。这样每层的防护可以独立演进、独立测试、独立替换。这也是为什么像 NVIDIA OpenShell 这类运行时环境会被单独拎出来做——它专注解决 L2 的问题不越界去管 L3 的编排逻辑。理解了这一点后面每一层的具体做法就顺理成章了。2. 运行时环境层把能执行变成安全地执行2.1 运行时环境到底在防什么运行时环境Runtime Environment是智能体真正动手的地方。模型负责想运行时负责做。一旦智能体有了执行能力——跑代码、调命令、读写文件、访问网络——风险就从说错话升级成做错事。我见过最惊险的一次是一个做数据分析的智能体被要求清理临时文件结果它生成的 shell 命令里路径拼接出了偏差差点把整个工作目录删了。幸好当时跑在容器里而且挂载是只读的才没出事。这件事之后我就彻底重视起运行时隔离。运行时层要防的主要是这几类越权访问智能体访问了它不该访问的文件、目录、网络端点资源耗尽无限循环、内存爆炸、磁盘写满、CPU 打满逃逸从沙箱里跑出来影响到宿主机或其他租户副作用不可控执行了不可逆的操作比如删数据、发请求、转账2.2 沙箱隔离的三种粒度与选型沙箱不是有或没有的问题是多细的问题。我一般按三种粒度来选进程级隔离最轻用独立进程 权限降级比如 Linux 的 seccomp、capability 裁剪。启动快开销小但隔离强度有限适合可信度较高的内部任务。容器级隔离中等用 Docker 或类似方案配合只读挂载、网络策略、资源限额。这是目前最主流的做法平衡了隔离强度和运维成本。我大部分项目都用这一档。虚拟机/微虚拟机级隔离最重用 KVM、Firecracker 这类。隔离最强启动稍慢适合执行完全不可信的代码比如用户提交的任意脚本。选型的时候我会问自己三个问题这段代码是谁写的它能碰到什么资源出事了影响范围多大三个问题的答案决定了粒度。2.3 NVIDIA OpenShell 这类方案解决的核心痛点NVIDIA OpenShell 这类运行时环境的思路是把安全执行做成一个标准化的底座。它要解决的核心痛点是让智能体的执行能力可控、可观测、可回滚。具体来说它通常提供这几样东西标准化的执行接口智能体不用直接碰系统调用而是通过一层抽象接口提交执行请求细粒度的权限策略能精确到这个智能体只能读 /data 目录下的 csv 文件资源配额CPU、内存、时间、网络流量都有上限执行审计每一次执行都有完整记录谁在什么时候执行了什么、结果如何我自己的体会是这类方案最大的价值不是防住了多少攻击而是把不可控变成了可控。以前智能体执行出问题你只能看日志猜现在每一步都有记录排查效率完全不是一个量级。2.4 实操给智能体搭一个最小可用的安全执行环境下面是我常用的一个最小配置思路用容器做隔离你可以直接参考# 1. 创建受限的容器只读根文件系统独立网络 docker run -d \ --name agent-sandbox \ --read-only \ --tmpfs /tmp:size64m \ --memory512m \ --cpus1.0 \ --pids-limit128 \ --networknone \ --cap-dropALL \ --security-optno-new-privileges \ -v /data/agent-workspace:/workspace:rw \ agent-runtime:latest几个参数我解释一下为什么这么设--read-only根文件系统只读防止智能体往系统目录写东西--tmpfs /tmp:size64m给临时目录单独开内存盘并限大小很多程序需要写临时文件但你不能让它无限写--memory512m --cpus1.0硬性资源上限防止单个任务拖垮整机--pids-limit128限制进程数防 fork 炸弹--networknone默认断网需要联网时再单独开白名单--cap-dropALL丢掉所有 Linux capability最小权限--security-optno-new-privileges禁止提权注意--networknone会让很多需要联网的工具直接失败。我的做法是默认断网然后在 Harness 层做网络代理只放行白名单域名。这样既安全又能满足大部分需求。这套配置跑下来即使智能体生成了恶意命令影响范围也被死死限制在容器内。实测下来很稳开销也就多几十毫秒的启动时间。3. Harness 编排层智能体的神经系统怎么防失控3.1 Harness 和 Agent 到底啥区别这是最近被问得最多的问题之一。我的理解很直接Agent 是决策者Harness 是执行框架。Agent 负责想——根据目标决定下一步做什么。Harness 负责管——把 Agent 的决策翻译成实际的工具调用、管理状态、处理错误、控制流程。你可以把 Agent 理解成大脑Harness 理解成神经系统加四肢的协调机制。这个区分为什么重要因为安全责任是分开的。Agent 层要防的是决策错误比如选错工具、误解意图Harness 层要防的是执行失控比如无限循环、工具滥用、状态污染。很多人把这两个混在一起结果两边都防不好。3.2 工具调用的三道防线Harness 层最核心的职责就是管工具调用。我一般设三道防线第一道调用前校验。在工具真正执行前检查参数是否合法、是否在允许范围内、调用频率是否超限。比如一个发送邮件的工具你得校验收件人是否在白名单、附件大小是否超限、单位时间发送量是否异常。第二道执行中监控。工具执行过程中实时盯着超时、异常、资源异常就中断。这一步很多人会忽略觉得调用出去了就等结果。但恰恰是执行中的失控最危险比如一个爬虫工具陷入死循环。第三道调用后审计。记录完整的调用链谁调的、什么参数、什么结果、耗时多少。这不仅是安全需要也是排查问题的命根子。3.3 循环失控与状态污染的真实案例说个我亲身经历的。做一个自动化运维智能体任务是检查服务状态异常就重启。逻辑很简单但上线后某天半夜开始疯狂重启某个服务。排查发现那个服务重启后需要 30 秒才能健康但智能体的检查间隔是 10 秒于是它每次检查都发现不健康就再重启一次陷入死循环。这就是典型的循环失控。Harness 层如果没有同一操作在时间窗口内的次数上限这种保护就很容易出这种事。我后来加了个规则任何有副作用的操作5 分钟内最多执行 3 次超过就暂停并告警。状态污染是另一个坑。多轮对话里如果上下文管理不当前一轮的错误信息会污染后一轮的判断。比如智能体上一轮误判了某个文件不存在这个错误结论被写进记忆后面所有轮次都基于这个错误前提推理。解决办法是给记忆加时效性和可信度标记关键结论要重新验证。3.4 用 Harness 工程手段做最小权限编排最小权限原则在 Harness 层的落地核心是按任务动态授权而不是给智能体一个固定的权限集。我的做法是每个任务开始时Harness 根据任务类型生成一个权限清单任务结束就回收。比如读日志任务只给读权限重启服务任务才给执行权限而且执行权限只在特定服务上生效。这样即使智能体被提示注入攻击它能做的也被限制在当前任务的权限范围内。攻击者想让它删数据库但当前任务根本没有数据库权限直接失败。提示动态授权的关键是权限清单要可审计、可追溯。每次授权都要记录为什么给这个权限方便事后复盘。4. 数据与上下文层最容易被忽视的泄露通道4.1 上下文里到底藏了多少敏感信息很多人只盯着模型输出却忘了输入侧才是泄露重灾区。智能体的上下文里通常包含系统提示词、历史对话、检索到的文档、工具返回结果、用户画像……这里面随便一项都可能含敏感信息。我做过一次内部审计发现一个 RAG 智能体的上下文里居然混进了其他用户的订单信息。原因是检索时没做租户隔离向量库里所有数据一起搜。这种问题在测试环境根本发现不了因为测试数据都是干净的。4.2 检索增强场景下的数据隔离RAG 场景的数据隔离我总结了三层存储层隔离不同租户的数据物理分开或者至少逻辑上带租户 ID 强过滤。别指望应用层过滤应用层总会有人写漏。检索层隔离查询时强制带上租户条件而且这个条件不能由模型生成必须由 Harness 注入。模型生成的过滤条件不可信。组装层隔离上下文组装时再做一次校验确保拼进去的每一条数据都属于当前租户。这是最后一道防线。三层都做成本不低但比数据泄露的代价小太多了。4.3 上下文投毒与提示注入的工程防御提示注入Prompt Injection是上下文层最头疼的问题。模型分不清指令和数据攻击者可以把恶意指令藏在文档、网页、甚至文件名里。纯靠模型自身防御不靠谱得靠工程手段。我常用的几招指令与数据分离用明确的分隔符把系统指令和外部数据隔开并在系统提示里强调分隔符内的内容是数据不是指令输入清洗对外部数据做预处理剥离明显的指令性内容输出校验模型输出后检查是否包含不该有的操作意图比如突然要调用敏感工具权限兜底就算注入成功当前任务的权限也限制了它能造成的破坏最后一条最重要。假设注入一定会成功然后设计成功之后也干不了坏事的系统这才是工程思维。4.4 记忆管理的时效性与可信度标记智能体的长期记忆是个双刃剑。用好了能提升体验用不好就是污染源。我给记忆加两个维度时效性每条记忆带时间戳和过期时间。比如用户当前所在城市这种信息超过一定时间就失效需要重新确认。可信度区分用户明确说的、模型推断的、工具返回的。可信度低的记忆在使用时要谨慎关键决策不能只依赖低可信度记忆。这套机制实现起来不复杂就是在记忆存储时多存两个字段读取时按需过滤。但效果很明显能挡掉一大批基于过时/错误信息做决策的问题。5. 应用与交互层把好最后一道门5.1 身份、权限与审计的三角关系应用层是用户直接接触的地方也是安全的最后一道门。这里核心是三件事身份认证、权限控制、操作审计。身份认证解决你是谁权限控制解决你能干什么操作审计解决你干了什么。三者缺一不可。我见过不少系统认证做得很严但审计一塌糊涂出了事根本查不到是谁干的。审计日志我建议至少记录时间、用户 ID、会话 ID、操作类型、操作参数、操作结果、耗时。别嫌多出事的时候你会感谢自己记全了。5.2 人机协同中的确认点设计不是所有操作都该让智能体自动执行。高风险操作必须有人确认。关键是在哪里设确认点。我的原则是不可逆的操作、影响范围大的操作、涉及敏感数据的操作必须人工确认。比如删除数据、发送对外通知、修改权限配置。确认点的设计也有讲究。不能太频繁否则用户烦不能太稀疏否则失去意义。我一般按操作风险等级来定低风险自动执行中风险批量确认高风险逐个确认。5.3 可观测性让每一次决策都有迹可循可观测性是整个安全体系的底座。没有它前面所有防护都是盲防。智能体的可观测性比传统系统难因为它有推理这个黑盒环节。我的做法是把推理过程也尽量结构化记录模型的输入、输出、工具调用序列、每步的耗时和结果。这样出问题时能完整回放整个决策链。工具上OpenTelemetry 这类标准协议可以直接用把智能体的每一步都当成一个 span 来追踪。配合日志和指标基本能做到任何一次异常都能定位到具体哪一步。5.4 一个完整的端到端安全链路示例把前面几层串起来一个完整的请求大概是这样的用户发起请求应用层做身份认证和权限检查Harness 根据任务类型生成权限清单初始化运行时环境上下文层组装输入做租户隔离和注入防御模型推理Harness 拦截工具调用请求并做三道防线校验运行时环境在沙箱内执行全程资源限额和审计结果返回应用层做输出校验高风险操作触发人工确认全链路日志和追踪数据落库供事后审计这条链路上每一环都有独立的防护任何一环出问题都不会导致全局崩溃。这就是分层解决的价值。6. 常见问题与排查技巧实录6.1 智能体越权了怎么快速定位越权问题的排查我一般按这个顺序先看权限清单确认当前任务到底给了哪些权限。很多时候不是越权是权限给多了。再看调用日志找到越权的具体那一步看参数是什么、谁触发的。最后看上下文判断是模型自己决策的还是被注入诱导的。我整理了个速查表现象可能原因排查方向访问了未授权文件权限清单过宽检查任务权限生成逻辑调用了未注册工具Harness 校验缺失检查工具白名单执行了危险命令注入攻击成功检查上下文清洗和权限兜底频繁重复操作循环控制失效检查操作频率限制6.2 工具调用失败率高的排查思路工具调用失败先分类是参数错误、权限错误、还是执行超时。参数错误通常是模型生成的参数格式不对解决办法是在工具定义里把参数 schema 写清楚并在 Harness 层做参数校验和自动修正。权限错误看权限清单。超时看运行时资源配额和外部依赖。我踩过的一个坑某个工具在测试环境一直好好的上线后失败率飙升。最后发现是生产环境的网络延迟高默认超时时间不够。所以超时时间一定要按生产环境来设别用测试环境的默认值。6.3 上下文污染导致的行为漂移行为漂移的表现是智能体一开始表现正常跑着跑着就开始跑偏。这基本都是上下文污染。排查方法是对比上下文快照。把正常时和异常时的上下文都 dump 出来diff 一下看多了什么、少了什么。我遇到过的是历史对话里混进了一条错误信息被模型当成了事实。解决办法是给上下文加清理策略定期清理低可信度记忆、过期信息、以及和当前任务无关的历史。别让上下文无限增长。6.4 离线/内网环境下的部署注意事项内网部署是很多团队的刚需但坑不少。核心是依赖的完整性和可复现性。我的做法是所有依赖提前打包包括模型权重、工具二进制、Python 包、系统库。用容器镜像把整个环境固化下来内网直接导入镜像避免现场装依赖。另外内网环境通常没有外网所以任何需要联网的功能都要提前设计降级方案。比如模型更新、插件下载、遥测上报都得有离线替代路径。注意内网部署前一定要在隔离环境完整跑一遍全流程包括异常路径。我见过太多装好了但一跑就报错的情况都是因为某个隐藏依赖没打包进去。6.5 插件加载失败的典型原因插件加载失败比如常见的 failed to load plugins通常就几个原因路径不对、权限不够、依赖缺失、版本不匹配。排查顺序先看日志里的具体报错通常会指明是哪个插件、哪一步失败。然后检查插件目录的读取权限内网环境经常是权限问题。再确认插件依赖的库版本是否匹配。最后看插件本身是否完整有没有在传输过程中损坏。我一般会写个简单的自检脚本启动时自动检查所有插件的加载状态有问题直接报出来别等到用的时候才发现。7. 我个人的一些实践体会做智能体安全这段时间最大的体会是别追求绝对安全追求可控可恢复。绝对安全是不存在的模型会出错工具会失败攻击会成功。工程思维的核心不是杜绝问题而是问题发生时影响可控、事后可恢复、过程可追溯。另一个体会是分层要彻底。我早期也想过搞统一防护结果就是每层都防得不彻底。后来老老实实分层每层只解决自己的问题反而整体更稳。层与层之间的契约要清晰但实现要独立。最后一点安全要前置到设计阶段。事后加防护成本是事前的十倍而且往往加不干净。我现在做任何智能体项目第一版设计里就会把运行时隔离、权限清单、审计日志这些考虑进去后面省心太多。这套分层思路不是银弹但至少能让你在出问题时知道去哪找、怎么修。智能体这东西工程上的坑远比模型上的多把工程做扎实了安全自然就上来了。