关于 agent-guardrail
Guardrail 是为 AI Agent 工具调用设置的确定性策略防火墙,适用于需要限制命令执行、消息发送或资金操作的开发者。它按可审计的 YAML 规则作出允许、警告或阻止决定,并记录审计日志。
主要功能
- 01按 YAML 策略检查工具调用
- 02支持阻止、警告和允许决定
- 03提供规则与参数匹配、数值上限及速率限制
- 04记录 SQLite 审计日志
- 05通过装饰器或强制执行的 MCP 服务拦截操作
适用场景
- 01限制 Agent 的转账金额或调用频率
- 02在删除数据或发送外部消息前要求确认
- 03在 MCP 操作执行前实施策略检查
MCP 相关
提供咨询式 MCP 服务,公开检查、记录执行结果和查询 Agent 历史的工具;另有强制执行的 MCP 服务,将实际操作执行器置于策略检查之后。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| agent_id | string | 是 | 调用方 Agent 的标识符 |
| arguments | object | 否 | 调用此工具时将使用的参数 |
| tool_name | string | 是 | 拟议工具/操作的名称 |
详细介绍
Guardrail
📄 阅读白皮书
在 AI Agent 与每项不可逆操作之间设置策略防火墙。
你的 Agent 想要运行 shell 命令、发送电子邮件或转移资金。 Guardrail 会在请求执行前,根据你编写的规则进行检查, 然后允许操作、请求人工审核或阻止操作——每次都会给出 通俗易懂的理由。
60 秒快速入门
git clone <this repo> && cd agent-guardrail
pip install -r requirements.txt
python3 cli.py check --agent trading-agent-001 --tool wallet.transfer \
--args '{"amount": 9999, "to": "0xabc"}'
或者,运行 pip install guardrail-mcp 即可直接获得
guardrail 命令——输出相同,无需检出代码仓库(如果你没有将
--policy 指向自己的文件,则会使用软件包中附带的策略):
guardrail check --agent trading-agent-001 --tool wallet.transfer \
--args '{"amount": 9999, "to": "0xabc"}'
{
"decision": "BLOCK",
"matched_rules": [
{"rule": "numeric_cap_exceeded", "severity": "BLOCK",
"message": "amount=9999.0 exceeds cap 5 for 'wallet.transfer' (unknown agent)"}
]
}
就是这么简单——无需服务、账号或 API 密钥。policies/default.yaml 就是
作出这个决定的文件;打开它并修改数值,使其符合你自己的规则。
为什么选它,而不是另一个“AI 风险评分”工具
大多数“AI Agent 安全”项目(包括我之前的一个项目) 都依赖基于数据计算的统计风险评分,而这些数据在构建时无人能够 实际验证——钱包年龄、“声誉”、合约“风险”——这要么需要你尚未拥有的付费数据源, 要么悄悄变成伪装成真实数据的模拟数据。原型开发时没问题,但不该这样发布。
Guardrail 只作出有依据的判断。每项检查都是一条确定性 规则——黑名单条目、正则表达式匹配、数值上限、速率限制—— 根据你编写且可以自行审计的策略文件进行评估,并由真实、持久的审计日志(SQLite)支持, 你可以对其进行查询。这里的任何内容都不会假装知道自己并不知道的事。
它也不局限于区块链。执行 shell 命令、发送电子邮件、发起 HTTP 请求、删除文件、写入数据库、进行加密货币交易——使用相同的 引擎、相同的策略文件和相同的规则。
四种使用方式
1. CLI — 手动测试策略
如上所示。无需设置,编写规则时即可即时查看结果。
2. MCP 服务(mcp_server.py)— 简单入门,提供建议
将 guardrail_check、guardrail_record_outcome 和
guardrail_agent_history 暴露为 MCP 工具,任何兼容 MCP 的 Agent(Claude
Desktop、Claude Code、自定义 MCP 客户端)都可以调用。
{
"mcpServers": {
"guardrail": {
"command": "python3",
"args": ["/absolute/path/to/agent-guardrail/mcp_server.py"],
"env": { "GUARDRAIL_POLICY": "/absolute/path/to/agent-guardrail/policies/default.yaml" }
}
}
}
然后,在系统提示词中告诉你的 Agent:在花钱、删除数据、向外部人员发送消息
或运行代码之前,始终调用 guardrail_check。
请清醒认识它的局限: 和任何 MCP 工具一样,没有什么能阻止 调用模型直接不调用它。只有在指示 Agent 先进行检查时,这才有用——若要 确保它无法跳过,请参阅 #3。
3. guardrail.decorator.enforce — 真正的保障
包装实际执行工具副作用的 Python 函数。检查会在你的代码中运行, 且在该函数执行前完成——模型没有机会直接调用真正的函数。
from guardrail.decorator import enforce, BlockedActionError
@enforce(engine, tool_name="send_email")
def send_email(agent_id: str, to: str, subject: str, body: str):
... # only runs if the decision is ALLOW, or WARN-and-confirmed
如果你正在构建自己的 Agent 循环(LangChain、CrewAI、自定义 MCP 主机、带有工具访问权限的
Slack 机器人),请使用此方式。运行 python3 examples/example_agent_usage.py,查看它如何阻止真实的函数调用。
4. guardrail.mcp_enforced_server.EnforcedGuardrailMCPServer — 通过 MCP 实现真正的保障
上面 #2 中的 MCP 服务坦诚地说明了它只是提供建议:模型会获得一个 guardrail_check 工具,但没有任何机制能阻止它不先检查就调用实际工具(该工具由其他 MCP 服务提供,或模型通过自身直接访问),也没有机制能阻止它检查一件事却执行另一件事。如果模型只能通过 MCP 与你的基础设施交互——无法使用 Python 装饰器——那么这就是针对该场景的同等 #3 保障:操作人员将实际操作执行器(持有真实凭据并执行实际副作用的代码)注册为模型调用该操作的唯一途径。
from guardrail.mcp_enforced_server import EnforcedGuardrailMCPServer
def do_transfer(request):
wallet = get_wallet_for(request.agent_id) # real credentials, held here - never exposed to the model
tx_hash = wallet.transfer(to=request.arguments["to"], amount=request.arguments["amount"])
return {"tx_hash": tx_hash}
server = EnforcedGuardrailMCPServer(policy_path="policies/default.yaml")
server.register_action(
"wallet.transfer", "Transfer funds from the agent's wallet.",
input_schema={"type": "object", "properties": {"to": {"type": "string"}, "amount": {"type": "number"}}, "required": ["to", "amount"]},
executor=do_transfer,
)
server.serve_stdio()
模型只能获得一个名为 wallet.transfer 的 MCP 工具——无法通过此服务以其他不受保护的方式转移资金。若决策为 BLOCK,do_transfer 就绝不会运行。此方式和 enforce() 共用同一套“检查、必要时将 WARN 转交给人工处理、仅在未阻止时运行、报告实际结果”的实现(guardrail/enforcement.py)——而不是两份各自维护、实现相同保障的代码。
让人工真正确认 WARN
on_warn 是钩子——Guardrail 提供两种现成实现:
本地 Web UI(guardrail/confirmation/web_ui.py)——一个内置的小型服务(仅使用标准库,无需 Flask),带有 Approve/Reject 按钮。包装后的函数会一直阻塞,直到有人点击按钮或超时(默认拒绝——超时意味着拒绝,而不是“默认允许”)。
from guardrail.confirmation.web_ui import ConfirmationServer
confirmation = ConfirmationServer(port=8787, timeout_seconds=300)
confirmation.start(open_browser=True)
@enforce(engine, tool_name="wallet.transfer", on_warn=confirmation.request_confirmation)
def transfer(...): ...
试运行:python3 examples/example_web_confirmation.py,然后打开
http://localhost:8787。
终端提示(guardrail/confirmation/cli_ui.py)——适用于脚本和本地测试,无需大费周章地打开浏览器:
from guardrail.confirmation.cli_ui import cli_confirm
@enforce(engine, tool_name="wallet.transfer", on_warn=cli_confirm)
def transfer(...): ...
两者都不是必需的——on_warn 只是一个 (decision) -> bool 函数,因此 Slack 消息、工单或你已在使用的任何其他方式都可以。
编写策略
策略采用纯 YAML 格式——请参阅 policies/default.yaml,这是一个真实可用的起点(11 个需确认的工具、10 项破坏性模式检查、数值上限、域名规则、速率限制,均带注释)。
| 规则类型 | 检查内容 |
|---|---|
blocked_tools | 永远不允许使用的工具名称 |
confirmation_required_tools | 总是会产生 WARN 的工具名称 |
argument_patterns | 针对 JSON 序列化调用参数的正则表达式——无论使用这些参数的是哪个工具,都会检查破坏性 shell 命令、SQL、泄露的凭据、路径遍历、SSRF 和强制推送 |
numeric_caps | 每个工具的数值字段上限;对没有历史记录的 Agent 设置更严格的限制 |
aggregate_caps | 多个工具共用的上限,每个 Agent 追踪一个运行总额——见下文 |
domain_rules | 针对每个工具的 URL 或电子邮件收件人字段设置允许/拒绝列表 |
rate_limits | 每个(Agent、工具)的滑动窗口调用限制,由 SQLite 支持 |
numeric_caps 分别限制每个工具——若 wallet.transfer 和 wallet.approve 的上限都分别设为每天 1000,则同时使用这两个工具的 Agent 仍可合计转移 2000/天。aggregate_caps 可解决这个问题:同一组中列出的每个工具都会从同一个共享运行总额中扣减,例如:
aggregate_caps:
daily_money_movement:
tools:
wallet.transfer: amount
wallet.approve: amount
window_seconds: 86400
max_unknown_agent: 5
max_known_agent: 1000
只有已确认的支出才会计入总额:被 BLOCK 的请求不会增加总额;如果某个请求已暂时记账(因为它自身的检查已通过),但之后实际操作未能成功,则会退还这笔金额——当真实执行器抛出异常,或人工拒绝 WARN 后导致 BlockedActionError 时,enforce() 和强制执行型 MCP 服务都会自动调用 engine.record_outcome(request_id, "error")(两者共享 guardrail/enforcement.py 中的同一套实现)。因此,实际执行这一机制与所有依赖调用 record_outcome 的功能一样,都有相同的注意事项:在 enforce() 和强制执行型 MCP 服务中(见下文)可完整运行;而在仅提供建议的 MCP 服务中(上文的 #2),暂时记账的金额会一直保留,因为没有任何机制反馈实际操作是否发生。完整说明请参阅 guardrail/storage/aggregate_spend.py 的模块文档字符串。
调整这些设置无需修改代码——编辑 YAML,然后重启进程(或 MCP 服务)。
运行测试
pip install -r requirements.txt
PYTHONPATH=. python3 -m unittest discover -s tests -v
共 134 项测试:规则评估、完整引擎流水线(由真实 SQLite 支持的速率限制、总支出追踪和审计持久化)、enforce 装饰器和强制执行型 MCP 服务(两者都会验证 BLOCK 确实能阻止真实操作运行,并共享同一套保障实现)、仅提供建议的 MCP 服务的 JSON-RPC 处理、通过真实 HTTP 请求对运行中的服务测试确认 Web UI,以及一套专门的测试,用于检查随附的 policies/default.yaml(而非仅合成的测试策略)是否确实能拦截其声称可以拦截的内容。
坦诚地说,仍然缺少什么
- 默认使用单进程 SQLite。 对单个 Agent 进程来说没问题;如果多个副本要共享速率限制/审计历史记录,请让每个进程都指向共享存储上的同一个文件,或者换用真正的数据库(存储类很小,也很容易改为连接其他数据库)。
- 审计日志默认会对机密/个人身份信息进行脱敏。
AuditLog会对键名看起来敏感的值(password、api_key、authorization……)以及几种可信度较高的值格式(PEM 私钥块、JWT 格式的字符串)进行脱敏,不受键名影响;并会递归处理嵌套的字典/列表——具体能识别和不能识别哪些内容,以及为何刻意不采用通用熵启发式规则(普通 UUID/哈希会导致太多误报),请参阅guardrail/storage/redaction.py。传入AuditLog(redact=False)可按提交时的原样存储参数;传入extra_sensitive_keys={...}可对工具特有的其他字段名进行脱敏。 - 默认策略是合理的起点,并非完整的威胁模型。 它能识别常见的破坏性 Shell/SQL 模式和明显的凭据格式——请根据 Agent 实际会接触的内容扩展
argument_patterns。 - 确认网页 UI 没有身份验证。 按设计,它绑定到
127.0.0.1(不会暴露在网络上),但任何能在本地访问该端口的人都可以批准/拒绝。对于单个开发者的机器来说没问题;如果多人共用主机,请在它前面加上自己的身份验证。
这些都不是模拟或伪造的功能——只是尚未构建;如果你采用这个项目,这些就是坦诚列出的下一步。
发布本项目/让人们真正用起来
请参阅 PUBLISHING.md,了解具体的检查清单:要提交到哪些 MCP 目录、条目需要包含什么,以及怎样才算“完成”。
相关项目
同一作者将同一理念应用于其他领域:
- agentic-wallet-guardian-v3 — 为在链上交易的 AI Agent 提供安全决策层。MIT, 112 项测试。
- x402-attest — 为 Agent 间支付策略决策提供经过密码学签名(Ed25519)、可独立验证的 证明。早期概念验证。
- open-agent-attestation — 与供应商无关的开放规范(JWT+EdDSA),用于签署 Agent 策略 决策,任何人都可以验证。上面的 x402-attest 使用自定义格式; 这是通用化版本。草案 v0.1。
项目结构
guardrail/
__main__.py CLI implementation — also the `guardrail` console command
mcp_server.py MCP stdio server — also the `guardrail-mcp-server` console command
core/
models.py ActionRequest, RuleMatch, GuardrailDecision (stdlib only)
policy.py Policy loader (the one place PyYAML is used)
rules.py Deterministic rule evaluators
storage/
rate_limiter.py SQLite-backed sliding-window rate limiter
audit.py SQLite-backed persistent audit log
engine.py GuardrailEngine — orchestrates rules + rate limit + audit
decorator.py enforce() — the unbypassable integration point
confirmation/
web_ui.py Local web UI for human approve/reject (stdlib http.server)
cli_ui.py Terminal-prompt confirmation
policies/default.yaml Copy of the default policy bundled into the installed package
policies/default.yaml Canonical, editable default policy (git-clone workflow)
cli.py Thin shim -> guardrail/__main__.py (for `python3 cli.py`)
mcp_server.py Thin shim -> guardrail/mcp_server.py (for `python3 mcp_server.py`)
pyproject.toml Package metadata — `pip install .` gives you `guardrail` + `guardrail-mcp-server`
.github/workflows/ci.yml Runs the test suite + policy validation + package build on every push
examples/
example_agent_usage.py Decorator basics
example_web_confirmation.py Real browser-based approve/reject, live
tests/ 46 unit tests, all runnable with just PyYAML installed
CONTRIBUTING.md How to add a rule type, ground rules
CHANGELOG.md Version history
PUBLISHING.md How to actually get this in front of people
landing/index.html Static one-page site (open directly or host on GitHub Pages)
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。