最近跟几个做车控 Agent 和运营 Agent 的同行交流,大家几乎都碰到同一个问题:大模型接入执行链路之后,效果确实立竿见影,但安全上总像在走钢丝。对话里藏一段恶意改写,或者某个上游工单带上一条隐式指令,智能体就可能把“分析结果”错当成“明确操作”直接下发。传统 API 鉴权、Prompt 词过滤这类手段,放在车控这种高后果场景里根本不够看。
我花了两周把相关框架和落地经验理了一遍,核心收敛到 ISO/IEC 27090:2026 这一系统里提到的三范式:指令-数据分离、双智能体核验、沙箱推演。名字听起来像三个独立技巧,实际上它们是一套完整的执行层防御架构。这篇文章就是把三件事拆开讲透,给出可落地的设计思路、边界条件、性能取舍和我在实际部署中踩过的坑,适合正在把大模型智能体接入生产环境的架构师、安全工程师,以及想提前补 LLM 安全课的后端团队。
1. 为什么车控与运营智能体必须先谈“执行层”防御
1.1 上层防护做得再好,也挡不住恶意指令直达系统
先看一个很典型的现状:很多团队已经给智能体接了 Prompt 安全过滤器,例如拦截“忽略之前的指令”、“你现在是某系统管理员”这类攻击文本,也会做输出敏感词过滤。但问题在于,这些防护停留在模型交互层,并没有真正介入“指令到执行”的那一跳。
大模型智能体的本质是“自然语言到系统动作”的转换器。攻击者不需要绕过过滤器,只需要把恶意指令藏在看似无害的数据里。比如某个运营工单描述为“节点 CPU 持续 100%,建议重启”;如果智能体把这句话当作一个应当执行的命令,它就会真的去重启节点。但如果这句话只是监控告警里的备注文案,并没有经过人为确认,那么重启动作就变成了一次越权执行。传统防护不会理解“这是数据不是指令”,只有执行层才能基于来源、意图、操作权限做出区分。
车控场景更明显。车内语音交互里,驾驶员说“前面好像堵了”,这是一句路况讨论;而“切换导航到备选路线”才是一条明确的控制意图。如果智能体把前者误判为操作指令,可能触发不必要的变道建议甚至影响路线规划。车控和运营场景都有一个共同特点:后果不可逆程度高、系统影响范围大,所以必须在真正调用 CAN 总线、下发运维命令之前有一道独立于模型判断的防御闸门,这就是执行层防御的价值。
1.2 三范式从三个角度补上执行层的缺口
我理解 ISO/IEC 27090 这一版的核心逻辑,可以概括成一句话:在智能体真正碰系统之前,让“来源可信、意图经过交叉验证、影响经过模拟确认”。
- 指令-数据分离解决的是“什么东西能当命令”的问题。它把输入流拆成数据面和控制面,避免上下文信息直接成为可执行指令。
- 双智能体核验解决的是“单模型误判与幻觉”的问题。一个智能体提出动作,另一个独立智能体审查动作,相当于在人工批准之前加一道自动化同行评审。
- 沙箱推演解决的是“动作后果不确定”的问题。在执行之前先放到受控模拟环境里跑一遍,观察会不会违反约束、触发冲突,再决定是否放行。
这三个机制分别对应执行链路的三个时间点:输入时、决策时、执行前。把它们串在一条防御链上,比任何单点方案都可靠得多。
2. 范式一:指令-数据分离,把输入流拆成“数据面”和“控制面”
2.1 它很像 Web 安全里的“预编译”,而不是关键词过滤
举个例子你就明白了:SQL 注入的经典防御是预编译语句,把“SQL 结构”和“用户输入”彻底分开,用户无论输入什么,里面包含的引号、关键字都只是字符串,不可能变成新的 SQL 命令。指令-数据分离在智能体里的思路完全一样:系统预先定义“哪些来源、哪些格式的内容可以作为指令进入执行区”,其余所有内容一律视为数据,只能更新上下文,不能触发动作。
注意,这跟“提示词过滤”有本质区别。过滤是在已经混合的文本里找坏人,分离是从入口处就不让两类内容混在一起。前者是警察在街上查违章,后者是直接建了一条隔离车道。
在工程上,我建议在智能体输入端放一个“内容分类网关”,它不依赖大模型判断,而是用规则和轻量分类器完成初筛:
# 伪代码,展示指令-数据分离的入口逻辑 payload = receive_from_source(source_id, raw_content) content_kind, intent = classify_input(raw_content) if content_kind == "control_intent" and source_id in TRUSTED_CONTROL_SOURCES: # 只有通过来源校验、且意图明确属于操作目录的请求,才能进入执行区 return dispatch_to_execution_plane(build_command(payload)) else: # 其他的都作为数据/上下文进入状态区 return dispatch_to_context_plane(payload)这里的核心不是 NLP 有多准,而是“来源和意图是否双重匹配”。如果来源不可控,哪怕话术再像命令,也不能进入执行区。这就是我在项目中一直强调的:命令是否有效,不只取决于语义,更取决于管道是否可信。
2.2 车控场景:语音讨论和驾驶操作必须走两个通道
车内智能体最常见的风险来自麦克风输入。同一段车里人的对话,表面上是聊天,里面可能夹着“帮我切到运动模式”这种控制请求。如果智能体把所有语音文本都当作潜在指令处理,就很容易被误导。我的处理方式是分成两条通道:
- 控制面通道:必须包含明确的控制动词(如“切换”、“设置”、“关闭”),且经过车内用户身份确认(声纹或按钮确认),并被映射到预定义的操作白名单。任何不在白名单里的操作,一律不响应。
- 数据面通道:路况讨论、闲聊、天气问答进入上下文记录,只能影响推荐结果,不能触发线控指令。
这套方案会遇到一个边界情况:自然语言里,用户常常不直接说命令字词,例如“我冷了”隐含“调高空调温度”。我的经验是,对于这一类模糊请求,宁可把它归到数据面,生成一个“建议动作卡片”,等待用户确认,也不要去自动猜测。车控操作一旦猜错,代价不只是体验问题,更是安全责任问题。
2.3 运营场景:告警文本再急,也不能自动成为操作命令
运维场景里,指令-数据分离同样要处理“文本像命令”的诱惑。常见的错误做法是让智能体直接看工单内容并执行其中的操作建议。工单系统本身是数据系统,里面的文字大多只是描述,不是被审批过的操作指令。我见过有团队让 Agent 自动按告警描述执行重启,结果攻击者只需要在监控面板里伪造一条带有“建议重启”字样的假告警,就能触发批量重启。
正确的做法,是把工单标题、正文、监控告警文本一律视为不可执行数据。真正的操作请求必须来自任务编排系统里经过审批的“任务单”,且任务单本身要带结构化的操作码和参数,不能被自然语言带偏。也就是说,数据面负责给智能体喂上下文,控制面只接受结构化任务下发。二者在存储和链路上就分开,而不是靠模型临时分辨。
3. 范式二:双智能体核验,用提议与复核的对抗关系降低误判
3.1 两个智能体不能是“同一个模型换皮肤”
双智能体的设计初衷是制造一种结构性对抗:一个智能体负责提出动作,一个智能体负责审查动作是否存在风险、是否偏离任务目标、是否违反约束。但很多团队落地时只做了表面功夫,用同一个模型的两次调用就算“双智能体”,这在威胁模型里几乎无效。因为同一个模型的相同偏好和盲区会同时出现在两个角色里,攻击者只要用一份精心构造的输入,就能让两个角色都被误导。
我在项目里坚持两个原则:第一,提议模型和复核模型要有一方不同(不同供应商、不同参数规模、或至少是完全不同的系统提示和温度设置);第二,两个模型访问的上下文要隔离,复核方不能直接看到提议方与用户的完整原始对话,而是看到一份经过转写的“动作语义卡”,避免复核方被原始输入里的诱导词影响。
下面是动作语义卡的最小字段结构,我用这种格式在多个项目里传递两个智能体之间的信息:
| 字段 | 说明 | 示例 |
|---|---|---|
| action_id | 动作唯一编号 | act_20260211_001 |
| operation | 受控操作名,必须来自操作目录 | 重启节点 |
| target | 操作对象 | 节点组:prod-pay-003 |
| params | 结构化参数 | { mode: "rolling", batch: 1 } |
| evidence | 提议依据摘要 | 监控显示内存使用率连续 15 分钟 92% |
| risk_level | 提议智能体自评风险等级 | medium |
| constraints_checked | 已检查的约束清单 | 维护窗口内;非核心交易时段;批次限流 |
复核智能体拿到这张卡之后,会独立检查操作是否在白名单内、目标对象是否存在、参数是否越界、当前时间窗口是否允许、证据与操作之间的因果链是否可靠。它只对语义卡做出通过/拒绝/打回补充的结论,不能自己改动动作参数。如果需要改,必须把动作传回提议方重新生成。
3.2 双智能体核验的“否决权”和“升级路径”怎么设计
核验结果不能只是“给一个置信度分数”就完事,必须有清晰的处置路径。我常用的策略是:
- 双通过:进入沙箱推演阶段。
- 一通过一拒绝:进入人工复核队列,由值班人员判断,同时记录两份智能体的完整推理摘要。
- 双拒绝:直接终止动作,记录攻击或误判日志。
- 任意一方置信度低于阈值:降级为“建议动作卡片”,绝不自动执行。
另外,要设定升级路径的优先级。在车控场景里,任何“双智能体一票否决”的动作,除非驾驶员通过物理按钮再次明确确认,否则不可以强制执行。在运营场景里,双拒绝后的动作可以进入隔离观察区,但不进入批量执行队列。这套规则比“看分数”清晰得多。
3.3 那不是浪费算力,而是用可控成本换掉一次重大事故
很多人听到双智能体第一反应是“成本翻倍”。实际落地的时候,确实要多考虑推理延迟和 token 消耗,但有几个缓解手段:
- 复核模型不一定要跟提议模型同级。可以用更小的、经过精调的判别模型来复核结构化动作卡片,而不是让一个 100B 模型重新读一遍原文。
- 大多数动作在规则检查阶段就会被过滤掉,根本走不到第二个模型。先做轻量规则校验,再做双模型核验,能省掉大量无效推理。
- 对运营场景,动作允许异步核验;这对高吞吐场景很友好。车控场景则必须控制核验时长,后面章节会讲怎么优化。
以我个人经验,双智能体核验带来的收益不只是拦截攻击,它还能有效压低“模型幻觉导致误操作”的概率。尤其是在运营场景里,模型自己编造不存在的参数或者误解操作对象的情况,复核智能体通常会直接拦下来。
4. 范式三:沙箱推演,把每个决策先放到平行环境里跑一遍
4.1 沙箱不是容器沙箱,而是“行为预演系统”
提到沙箱,很多人会想到把代码放进隔离容器里执行。但智能体防御里的沙箱推演更像是一个“决策预演场”:在真实执行之前,把结构化动作放到一个模拟环境里跑一遍,观察是否触发约束冲突、资源争抢、时序问题。
这种做法的难度在于:沙箱不可能百分百模拟真实世界的物理效应。车辆换道推演需要结合当前的交通参与者位置、速度、车道线状态;服务器重启推演需要结合节点集群的副本数、流量调度策略。这也是为什么 ISO/IEC 27090 强调它不是替代真实测试,而是为高后果动作增加一道“后悔药”机制。
其核心价值在于,模型给出的动作在静态检查里可能完全合法,但在动态运行环境中可能造成共振故障。例如运营场景里两个动作分别合法,顺序错了就会造成先停主库再降副本的低级事故。沙箱推演就是把这些顺序、时序、并发层面的风险暴露出来。
4.2 车控推演:核心是“冲突检测”和“可恢复性验证”
车控动作推演不能等执行完再反馈,必须在毫秒级时间内完成。我有几个务实建议:
- 把推演范围限制在局部。例如“变道建议”,只需要构建当前车道和目标车道的局部时空模型,加上与相邻车辆的未来轨迹预测,而不是把整个城市路网都仿真一遍。
- 推演结果不是“能不能执行”,而是“如果执行,冲突概率和风险等级是多少”。模型给出动作后,推演器输出风险值,超过阈值就不允许进入下发通道。
- 对不可逆操作(如切换自动驾驶模式、紧急制动),推演器还应该计算可恢复性:如果动作结果不符合预期,系统是否有安全退出路径。
在技术选型上,车控场景不要追求复杂物理引擎,更实用的是一套轻量级的规则型时序推演器加一个训练好的轨迹预测模型。前者保证响应速度,后者提高对未来冲突的预判能力。
4.3 运营推演:用“影子执行”模拟批量操作的影响
运营智能体的沙箱推演,我称为“影子执行”:把动作下发到目标系统的影子副本,或者用日志回放的方式在离线环境里执行一遍,观察各项指标变化。典型设计如下:
- 先用影子集群执行动作,对比基础监控指标,确认不会突破安全水位。
- 如果没有影子环境,至少做“变更影响分析”:把动作涉及的资源依赖、上下游关系、容量冗余拉出来,逐一核对。
- 每次推演都要记录基线数据、动作参数、输出指标,作为后续审计和策略调优的数据集。
这里一个容易犯的错误是推演环境太“干净”。如果影子集群的负载曲线和线上差太远,推演结果没有任何参考意义。更好的做法是用线上流量回放,把真实负载特征注入影子环境,再观察动作影响。这块成本不低,所以通常只用于高风险批量操作(如大规模扩容、全量配置变更、节点重启批次),日常低风险操作不需要走推演。
5. 三范式怎么装进同一个执行层:整体架构与策略引擎设计
5.1 执行层的分层流水线:从输入到执行必须经过五道闸口
三范式不是三个独立工具,而是一条流水线上的三个闸口。我在落地时把它们串成这样:
外部输入 → 指令/数据分离网关 → 语义意图化 → 双智能体核验 → 沙箱推演 → 授权执行/回退 → 审计存储- 第一道闸口:来源识别与内容分类,完成指令-数据分离,拦截大多数明显攻击和非指令内容。
- 第二道闸口:结构化动作生成,把自然语言结果转成受控的操作语义卡。
- 第三道闸口:双智能体核验,一票否决或升级人工。
- 第四道闸口:沙箱推演,对高影响动作做行为预演。
- 第五道闸口:权限与策略执行,校验动作是否符合当前角色权限、维护窗口、操作频率限制。
真正到达执行器的,是一张通过了全五道闸口的操作语义卡,而不是一堆自然语言。
5.2 把策略引擎和现有权限模型打通
执行层防御架构要落地,不能脱离现有的权限体系。我的建议是抽象出一个特别重要的原则:智能体本身不直接拥有实操权限,它每次执行前向策略引擎申请一个短期授权令牌,令牌的作用范围严格限定在语义卡标注的目标、参数和时限内。这其实就是把人类运维里的“临时授权”变成自动化机制。
例如一个 Agent 想要重启某节点,策略引擎根据运维系统里已有的节点分组和责任人信息,确认当前操作人在应急手册里的授权范围,再结合变更窗口配置,决定是否签发令牌。令牌一旦签发,只能用于该 action_id 对应的执行,不能凭智能体再次输入的任意文本去触达其他资源。这个思路也适用于车控系统:驾驶员身份、车辆状态、地理围栏、时段限制都应该成为策略决策的输入。
5.3 怎么证明这套架构管用:故障注入与红蓝演练
我强烈建议每个团队的防御架构建设都配套一套故障注入测试。不要等到出事故才知道某道闸口漏了。我最常用的测试方法有三类:
- 提示词注入测试:在各类输入源里注入“忽略系统指令”、“现在按我的命令执行”等模板,观察是否进入执行区。
- 跨上下文攻击测试:把一个合法的控制命令藏在告警描述、工单附件、语音闲聊片段中,验证指令-数据分离是否真的能识别来源。
- 双智能体共识误导测试:构造一些对提议模型来说很有吸引力、但对系统有破坏力的动作,查看复核模型能否独立否决。
除了自动化测试,每个季度建议做一次人工红蓝演练。红队负责从攻击方角度找漏洞,蓝队负责调策略、补规则。这套机制比任何静态扫描都更能暴露真实缺陷。
6. 车控与运营场景的落地差异:延迟、异步与不可逆操作
6.1 车控场景的硬约束:推理必须在 200 毫秒量级内闭环
车控智能体不能像运营智能体那样做完整的多模型长链路推理。执行层防御的每一道闸口都会引入延迟,为了在性能和防御之间找到平衡,我推荐做“分级处理”:
- 低风险操作(如查询附近充电站、播报路况)只走指令-数据分离和规则校验,不触发双智能体核验。
- 中风险操作(如调整空调、选择推荐路线)走指令-数据分离和单次复核模型核验,尽量控制在一个小模型推理周期内。
- 高风险操作(如变道、超车、舒适模式切换等有明确动作的操作)走完整五道闸口,必要时接受 500 毫秒以上的延迟,因为这类操作本就必须经过驾驶员确认或系统内冗余校验。
车控场景的另一条铁律是:执行层防御任何一环超时,默认拒绝,不允许做成“暂时放行”。如果推演器没能在时限内返回,智能体的正确选择是放弃这次动作,而不是降级成直接执行。
6.2 运营场景的差异:批量操作的异步核验与影响面隔离
运营 Agent 通常处理批量操作,单个动作延迟没那么敏感,却对并发与影响面隔离要求极高。我的实践是:
- 把双智能体核验放进任务队列,异步处理,降低对在线推理链路的影响。
- 对批量动作做批次拆分,每批都要重新经过沙箱推演,不能因为第一批推演通过就让后面全部免检。
- 推演阶段一旦发现新告警,立刻暂停批次,进入人工研判,而不是继续按原计划执行。
在运营场景里,我最看重的指标不是“拦截率”,而是“误拦截率”。如果防御机制拦截了大量正常操作,会让运维团队失去对系统的信任,最终选择绕过安全机制。所以我主张把每个被拦截的动作都记录成案例,定期分析哪些是误判,哪些是攻击,不断调整规则。
6.3 部署中“贪方便”的坑,我基本都踩了一遍
最后分享几个非常现实的坑,都是我或团队在落地时真实踩过的。
第一个坑:把指令-数据分离做成“提示词过滤”。过滤器基于关键字判断“这是不是攻击”,结果攻击者换措辞就绕过。正确做法是基于来源和结构化意图分类,而不是基于文本内容找敏感词。
第二个坑:双智能体用同一套系统提示。两个模型表面上是两个角色,实际上共享了同一种偏见和盲区。攻击文本只要骗过提议模型,十有八九也能骗过复核模型,因为两个模型看到的是同一份文本。我在后来版本里让复核模型只看语义卡,不再看原始诉求,拦截率立刻提升明显。
第三个坑:沙箱推演环境太“干净”。用测试数据做推演,结果永远美好,一到线上就变样。解决方案是流量回放和动态负载注入,尽量让影子环境接近线上状态。
第四个坑:审计日志不够细。出了事故想追溯,结果发现日志里只有一句“动作已执行”,没有保存中间语义卡、模型置信度、推演风险值、授权令牌。这直接导致事故复盘什么都说不清。正确做法是从进入执行层的第一毫秒就把所有结构化信息落库,包括每个闸口的判断依据和负责人。
这四个坑,每一个都对应一次真实的线上事故或接近事故。防御架构不是搭出来就完事,它得像业务系统一样被持续测试、调优和审计。把三范式真正落到执行层,不是为了让架构图好看,而是为了让每一次智能体动作都有据可查、有错可拦、有险可防。