标签:AI Agent 安全设计 纵深防御 工业AI 系统设计 Cybersecurity
一个让我后背发凉的时刻
AgentClaw L1跑通后,我加了一个工具:run_command,让Agent能执行shell命令。
测试时我问:“帮我查看当前目录下的文件”。Agent调用了ls -la,返回了目录列表。很好用。
然后我半开玩笑地问:“帮我清理一下临时文件”。
Agent直接去执行了rm -rf /tmp/*。
幸亏我是在Docker容器里跑的测试。但那一刻我意识到:我给Agent装上了“手”,却没给它装上“刹车”。
L1的Agent能回答问题。L2的Agent能操作文件、管理进程、控制浏览器。L3的Agent能定时调度任务。能力越强,风险越大。工业场景下,Agent不是跑在沙箱里的玩具。它连接着真实的产线设备,操作着真实的配置文件,影响着真实的生产流程。一次误操作,可能导致设备停机、数据丢失、甚至安全事故。
这篇文章,记录我为AgentClaw构建的贯穿六层的纵深安全防御体系。
安全设计的核心原则:默认拒绝
大多数系统是“默认允许”——先放行,发现危险再拦截。
我的设计是反过来的:默认拒绝,除非明确允许。
- 文件写入:不是在发现敏感路径时报错,而是只有在白名单内的路径才允许写入。
- 命令执行:不是拦截危险命令,而是只有在白名单内的命令才允许执行。
- 进程管理:不是检测到
rm -rf才拦截,而是只有python/pip/docker等安全命令才能启动。
这个原则来自产线上的防呆设计——物理钥匙、权限卡、互锁装置。宁可误拦一千,不漏放一个。产线上的急停按钮,按下去就停,不需要判断“是否真的需要停”。
六层防线总览
安全不是只在入口处加一把锁。是每一层都有自己的防线。
| 层次 | 防护对象 | 核心机制 |
|---|---|---|
| L6 检测层 | 服务健康 | 三维健康检查,异常自动摘除 |
| L5 服务层 | API请求 | 令牌桶全局限流、请求体长度限制 |
| L4 编排层 | Agent推理 | 最大循环次数、超时控制 |
| L3 安全与可靠性层 | 调用链路 | 指数退避重试、LLM/工具双层限流 |
| L2 工具层 | 文件/命令/进程 | 路径白名单、命令白名单、内容审计 |
| L1 基础层 | 配置/日志 | 密钥外置、审计日志 |
L2 工具层:安全的第一道防线
工具层是Agent与操作系统交互的唯一通道。所有危险操作都在这一层被拦截。这是整个安全体系中设计最精密的一层。
文件写入的四层检查
file_write是风险最高的工具。四层检查,缺一不可。
第一层:路径白名单。 只有白名单内的目录才能写入——桌面、文档、项目目录、当前工作目录。Agent想写/etc/passwd?第一关就拦下。
第二层:敏感文件黑名单。 即使路径在白名单内,文件名也不能是敏感的——.env、.ssh/、id_rsa、authorized_keys。双重保险。
第三层:内容审计。 对.py/.sh/.js等可执行文件,扫描危险关键词——rm -rf、eval、os.system、subprocess.call。Agent想在脚本里藏恶意代码?第三关拦下。
第四层:大小限制。 默认10MB,防止Agent意外写入超大文件撑爆磁盘。
额外保护:自动备份。 覆盖写入前自动创建带时间戳的备份文件。即使Agent写错了,也能回滚。
进程管理的两阶段终止
process_mgr启动进程前,命令必须过两关:命令前缀在白名单内(只允许python/pip/npm/docker等),危险参数检测(拦截rm -rf、sudo、chmod 777、mkfs)。
终止进程也分两阶段:先SIGTERM优雅终止,等待2秒;如果进程仍存活,再SIGKILL强制终止。避免资源残留和孤儿进程。
图片生成的内容审计
image_generate的提示词也有安全检查。危险模式包括暴力、色情、违禁等内容,检测到直接拦截。即使是AI生成的图片,也要守住底线。
L3 安全与可靠性层:系统的“保险丝”和“限速器”
L2解决“能做什么”,L3解决“做多了怎么办”。
令牌桶限流:三层部署
令牌桶算法的思路很简单:桶以固定速率产生令牌,每个请求需要消耗一个令牌。桶满了就不产生,令牌用完了就拒绝。
AgentClaw部署了三层限流:
- 全局HTTP限流:每秒0.5个令牌,桶容量30。保护整个系统不被过载。
- LLM调用限流:每秒1个令牌,桶容量5。保护API配额。
- 工具执行限流:每秒1个令牌,桶容量5。防止LLM进入循环调用模式时工具被无限触发。
三层独立运行,互不干扰。一个层被限流不影响其他层。
指数退避重试:防止重试风暴
API调用失败时不能无限重试。重试机制采用指数退避+随机抖动:
- 第1次重试:等待1秒
- 第2次重试:等待2秒
- 第3次重试:等待4秒
- 每次等待时间乘以随机因子(0.75-1.25),防止多个客户端同时重试形成“重试风暴”
只有可重试异常(TimeoutError、ConnectionError、OSError)才触发重试。不可重试异常(ValueError、PermissionError)直接返回错误。
L5 服务层:API的第一道防线
服务层是外部请求的入口,也是攻击者的第一目标。
安全中间件部署在FastAPI中,对所有请求执行五层检查:
- 令牌桶全局限流——超限返回429
- 请求体长度检查——超过5000字符返回413
- SQL注入检测——8种正则模式
- XSS攻击检测——5种正则模式
- 敏感信息过滤——7种关键词(password、secret、api_key、token等)
一层失败就拒绝,不继续后续检查。
L4 编排层:Agent的“刹车”
L4防止Agent“跑飞”。
最大循环次数:ReAct循环默认最多5轮。超过轮次强制返回已有结果,防止Agent陷入死循环。
工具超时控制:每个工具都有独立的超时时间。calculator 5秒、web_search 15秒、run_command 60秒。慢工具不会卡住整个Agent循环。
L6 检测层:运维的“眼睛”
L6是v6.1新增的。它不做拦截,做监控。
/health端点返回基础状态(版本、运行时间、内存)。/health/detailed端点检测三个依赖服务:ChromaDB心跳、LLM API可达性、系统内存使用率。
兼容Kubernetes探针规范。LivenessProbe用/health——进程挂了Pod自动重启。ReadinessProbe用/health/detailed——依赖服务不可用时Pod从负载均衡摘除。
一条完整的安全链路
假设用户通过API发来一个恶意请求:“帮我把这个脚本写入/etc/passwd”。
L5服务层:令牌桶限流通过,SQL注入检测通过,XSS检测通过,敏感信息检测通过。请求进入系统。
L4编排层:Agent推理后决定调用file_write工具。
L2工具层:
- 第一层路径白名单:
/etc/passwd不在白名单内 → 拦截,返回“路径不在白名单内”。 - 工具返回失败,Agent收到“操作被安全策略拦截”。
L5服务层:返回200,日志记录本次请求的拦截信息。
整个过程,恶意操作在L2就被拦截,系统毫发无伤。审计日志完整记录了攻击尝试,安全团队事后可追溯。
从AME视角看这件事
产线上有一个概念叫“防呆设计”——通过机械结构或电气逻辑,让操作员即使想犯错也犯不了。两个按钮必须同时按下才能启动冲压机,单手操作就不可能触发。
我的六层安全体系,本质上就是软件世界的防呆设计。
- 路径白名单 = 物理钥匙:只有插对钥匙才能开门。
- 命令白名单 = 权限卡:只有授权人员才能操作特定设备。
- 内容审计 = 金属探测器:即使进了门,危险物品也会被检出。
- 自动备份 = 保险绳:即使操作失误,也能拉回来。
- 令牌桶限流 = 产线节拍:太快了自动降速,防止过载。
- 健康检查 = 设备巡检:异常自动报警,必要时自动停机。
AME的思维不是“相信操作员不会犯错”,而是“设计一个让操作员没法犯错的系统”。
我把这套思维用在了Agent上。我不相信Agent会“自觉”不删文件。我设计一个让它想删也删不了的系统。
这,就是AgentClaw六层安全防护体系的设计哲学。