你的AI Agent是在“自律”还是在“被铐着”?聊聊Gliding Horse的硬核门禁

当AI Agent的"安全"不再依赖LLM的自觉,而是靠代码级强制执行——这就是Gliding Horse(流马)的硬核门禁哲学。本文深入对比软性限制(Prompt引导)与硬性限制(系统调用门+数字签名+角色白名单)的本质差异,揭示为何企业级AI Agent需要"被铐着"才能跑得稳。不讲空话,只聊代码层面的安全架构。

在开始之前,咱们先做一道选择题。

你训你家狗子“不准偷吃桌上的肉”。你把肉放在桌上,然后出门了。你猜狗子会偷吃吗?

  • 选项A:会。狗子听不懂人话,它只看到肉。
  • 选项B:不会。你把肉放进了带锁的保险箱,狗子压根碰不到。

这题傻子都知道选B。但回到我们天天打交道的AI Agent,很多人却天真地选了A。

最近看到一个挺有意思的项目叫Superpowers,它搞了个“HARD-GATE”门禁机制。名字听着很硬核,我仔细研究了一下代码……然后发现它本质上就是选项A——它在给AI做思想教育,让AI“自觉”遵守规则。

而我们做的Gliding Horse(流马),选了选项B——我们根本不信任AI,所以用系统代码给它铐上了手铐和脚镣。

下面这张流程图直观展示了Gliding Horse硬核门禁的完整工作流程——从Agent发起操作请求,到系统调用门的三道硬拦截,再到阶段门禁的质量关卡:

🚪 阶段门禁(Stage Gate)

🚪 系统调用门(Syscall Gate)

参数格式/类型/必填项

❌ 驳回 + 错误码

✅ 通过

技能包完整性

❌ 拒绝加载

✅ 通过

PA/DA/CA/AA 权限

❌ 拒绝执行

✅ 通过

❌ 缺失项

✅ 通过

🤖 Agent 发起操作请求

🔒 第一道锁
JSON Schema 校验

校验通过?

返回 Agent 修正

🔒 第二道锁
Ed25519 签名验证

签名有效?

标记为篡改,告警

🔒 第三道锁
角色白名单检查

白名单匹配?

返回权限不足

✅ 放行执行

Agent 执行工具/生成产出

📋 SHACL 契约检查

质量标准达标?

打回重做 + 附缺失清单

✅ 流转至下一阶段

🎯 最终交付物

流程说明: Agent的每一步操作都必须先经过系统调用门的三道硬锁——参数校验、签名验证、角色白名单,任何一道不通过都会被硬性驳回。通过后执行工具并产出结果,再进入阶段门禁接受SHACL契约的质量检查,不合格则打回重做,合格才能流转到下一阶段。整个流程没有“AI自觉”的余地,全是代码级的强制执行。

一、Superpowers的“硬门禁”到底长啥样?

先客观还原一下它的工作原理:

  1. 每次新对话开始时,session-start这个hook脚本被执行。
  2. 这个脚本只做一件事:把 using-superpowers 这个“元技能”的Markdown内容,完整地注入到会话的上下文里。
  3. 这个“元技能”里写满了各种规矩。比如某个技能的 SKILL.md 里写着 HARD-GATE: 在用户批准设计前,不得编写任何代码

看见没,它所谓的“门禁”,就是一串文本。它没有执行任何代码来锁门,只是把“行为守则”塞给了LLM。

这相当于你在狗子耳边说:“肉在桌上,但你不能吃哦,吃了我生气。”然后你走了。 这就是典型的软性限制——规则写在纸上,执行全靠自觉。

二、Gliding Horse的“硬性门禁”:不信AI,只信代码

流马的门禁哲学非常冷酷:能执行代码的AI,本质上是一个潜在的罪犯。 我们不是在赌它遵不遵守规矩,而是让它在物理上(系统层面)根本做不了违规的事。

在流马里,Agent(不管是PA/DA/CA/AA)的任何一步操作,都必须经过一个铁面无私的裁判——系统调用门(Syscall Gate)

这不是一段Prompt,这是几百行Rust代码,它挡在Agent和外部世界之间,执行三层硬拦截:

  1. 第一道锁:JSON Schema校验。 Agent说我要调这个工具。行,你的参数合不合规?格式对不对?类型对不对?任何一个字段不合Schema,直接驳回,连日志带错误码甩回给Agent,让它自己改。
  2. 第二道锁:Ed25519数字签名验证。 参数对了就行?万一这个Skill被人篡改过,里面藏了恶意指令怎么办?每执行一个Skill,Gate都会验它的Ed25519签名。签名对不上,直接拒绝加载。
  3. 第三道锁:角色白名单检查。 你是PA(计划者)?对不起,你的身份只能读文件、查知识图谱。想写文件?想执行shell命令?白名单里没有你,直接拒绝。 哪怕LLM自己产生了“我要删库”的幻觉,Gate也会把它摁回去。

这还没完。当一个DA(执行者)好不容易干完了活,想把产出(比如一份PRD文档)传给下游的CA(检查者)时,它会触发流马的第二道硬门禁——阶段门禁(Stage Gate)。这个Gate会自动加载我们预设的SHACL契约(一种结构化质量标准),去图谱里检查这份PRD:

  • “有没有定义功能模块?”→ 没有。流转被硬性阻断。
  • “有没有列出系统参与者?”→ 没有。打回给DA,附上所有缺失项,让它重做。

这套循环,完全没有依赖“AI你自觉点”这种鬼话。不合格就是不合格,系统代码不给你过,你喊破喉咙也没用。

下面用一段简化的Rust伪代码,展示Syscall Gate如何执行JSON Schema校验和角色白名单检查的核心逻辑:

// ============================================================
// 简化版 Syscall Gate 核心逻辑(Rust 伪代码)
// ============================================================

/// 系统调用门:Agent 的每一步操作都必须经过此门
async fn syscall_gate(
    agent_id: &str,
    role: &str,           // 当前 Agent 角色:PA / DA / CA / AA
    tool_name: &str,      // 要调用的工具名
    params: &Value,       // 工具参数(JSON)
    skill_signature: &str,// 技能包的 Ed25519 签名
) -> Result<Output, GateError> {

    // ---- 第一道锁:JSON Schema 校验 ----
    let schema = load_tool_schema(tool_name).await?;
    if let Err(errors) = validate_json(&schema, params) {
        return Err(GateError::SchemaRejected {
            tool: tool_name.into(),
            reason: format!("参数校验失败: {:?}", errors),
        });
    }
    info!("✅ [Gate] Schema 校验通过: {}", tool_name);

    // ---- 第二道锁:Ed25519 数字签名验证 ----
    let skill_pubkey = lookup_skill_publisher(tool_name).await?;
    if !verify_ed25519(skill_signature, &skill_pubkey, params) {
        return Err(GateError::SignatureMismatch {
            tool: tool_name.into(),
            reason: "技能包签名无效,可能已被篡改".into(),
        });
    }
    info!("✅ [Gate] 签名验证通过: {}", tool_name);

    // ---- 第三道锁:角色白名单检查 ----
    let whitelist = load_role_whitelist(role).await?;
    if !whitelist.contains(tool_name) {
        return Err(GateError::RoleForbidden {
            agent: agent_id.into(),
            role: role.into(),
            tool: tool_name.into(),
            reason: format!("角色「{}」无权调用「{}」", role, tool_name),
        });
    }
    info!("✅ [Gate] 角色权限通过: {} -> {}", role, tool_name);

    // 三道锁全部通过,放行
    execute_tool(tool_name, params).await
}

这段代码清晰地展示了流马门禁的冷酷逻辑:参数不对 → 驳回;签名不对 → 驳回;角色没权限 → 驳回。 没有任何“商量”的余地,每一
下面是一个具体的 SHACL 契约 示例,用 Turtle 格式定义了对 PRD 文档的结构化质量约束——要求 PRD 必须包含"功能模块"和"系统参与者"两个属性,且每个属性至少有一个值:

# ============================================================
# SHACL 契约:PRD 文档质量标准(Turtle 格式)
# ============================================================
@prefix sh:   <http://www.w3.org/ns/shacl#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix prd:  <http://glidinghorse.dev/ontology/prd#> .

# PRD 文档的形状定义
prd:PRDShape
    a sh:NodeShape ;
    sh:targetClass prd:PRDDocument ;   # 作用于所有 PRDDocument 类型的节点
    sh:property [
        sh:path prd:hasFunctionalModule ;   # 属性:功能模块
        sh:minCount 1 ;                      # 至少 1 个
        sh:severity sh:Violation ;           # 缺失即违规
        sh:message "PRD 必须至少定义一个功能模块" ;
    ] ;
    sh:property [
        sh:path prd:hasSystemActor ;         # 属性:系统参与者
        sh:minCount 1 ;                      # 至少 1 个
        sh:severity sh:Violation ;           # 缺失即违规
        sh:message "PRD 必须至少列出一个系统参与者" ;
    ] .

工作原理: 阶段门禁(Stage Gate)在收到 DA 产出的 PRD 后,会将其加载到知识图谱中,然后运行 SHACL 验证引擎(如 Oxigraph 或 Apache Jena)对 prd:PRDShape 进行校验。如果 PRD 节点缺少 prd:hasFunctionalModuleprd:hasSystemActor 属性(或属性值为空),引擎就会抛出 sh:Violation 级别的验证错误,并附上 sh:message 中的提示文本。Gate 捕获这些错误后,将 PRD 打回给 DA 重做,同时附上所有缺失项的清单——整个过程完全自动化,没有任何"AI 自觉"的余地。

行都是硬性拦截。

三、硬性限制 vs 软性限制,一张表看懂

类型 本质 实现方式 在 AI Agent 中的表现
软性限制 行为建议与引导 Prompt / Markdown / Mermaid 图 Superpowers 的 HARD-GATE:把规则注入上下文,要求 AI “自律”。
硬性限制 代码级强制拦截 Hook 脚本 / 系统调用门 / 数字签名 / 角色白名单 Gliding Horse 的 Gate:在代码层物理阻止 Agent 执行违规操作。

四、这套硬核门禁带来的架构收益

1. 确定性

把校验逻辑从“LLM的良心”变成了“Rust的函数”。同样的输入永远得到同样的拦截结果,不存在“今天心情好放你一马”。这对于企业级应用是必需品——审计、合规需要的就是确定无疑的结果。

2. 角色隔离

PA只能读,DA可以读写但必须签名,CA可以查一切并标记问题。通过Gate强制执行最小权限原则,一个Agent被“策反”不会导致系统崩盘。

3. 质量前置

以前软件工程的质量靠最后的测试兜底,测试来不及就“先上线再说”。流马通过阶段Gate把质量卡在每个阶段的出口——需求不合格别进设计,设计不合格别进编码。上线即灾难的概率直线下降。

4. 安全防篡改

即使外部MCP工具或社区Skill被恶意修改,Ed25519签名校验会直接拒绝加载。整个工具生态是“保税区”模式——开放,但每件货都过安检。

五、不便(如果有的话)

坦白说,硬性门禁确实有一个代价:初期配置成本更高。 你需要为每种交付物定义SHACL契约(PRD要包含什么、设计文档要包含什么),需要为每个角色配置工具白名单。这不是开箱即用的“聊天机器人”,而是一套需要定制的“工程流水线”。

但我们认为这不是劣势,而是分工——软性限制适合轻量级个人工具,硬性限制是企业级生产环境的基本要求。流马选择后者,是因为我们相信,真正能替代程序员的不是最强的AI,而是最可靠的AI。

六、最后说句人话

Superpowers的“门禁”是在给AI念《员工手册》,希望它做个好员工。流马的门禁是在办公室门口装了个安检门,身上有违禁品?门都进不来。

这两种思路没有绝对的对错,但如果你像我一样,不相信AI的“自律性”,只相信代码的“强制执行”,那你大概会喜欢流马的这套设计。

我这套系统叫 Gliding Horse(流马),所有代码都在 GitHub 上:https://github.com/doiito/gliding_horse

这个系列写了十多篇了,从 JSON-LD 到 CPU 缓存记忆,从 Oxigraph 到丰田安灯绳,从技能图谱到硬核门禁。下次可能是真正的总结篇——把这些拼在一起,聊聊流马到底能做什么。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐