
AI learned to act. I built the gate that makes it prove it should如果你过去一年一直在关注大模型开发大概已经发现一个肉眼可见的趋势AI 正在从“会聊天”走向“会动手”。半年前我们还在讨论怎么让大模型输出更准确的 JSON三个月前大家开始给模型接工具、连数据库、调接口现在已经有不少团队把 Agent 直接放到了生产环境里让它自己去查订单、改配置、发消息、调退款接口。这一步迈得很快快到我身边很多工程师还没来得及想清楚一个问题AI 行动了如果它做错了谁负责“AI 学会行动”和“AI 应该被允许行动”是两回事。模型在推理时产生的自信并不等于它在真实系统里应该拥有权限。我在实际项目中尝试过很多次之后逐渐形成一个判断在 AI Agent 飞奔向生产环境的过程中最缺的不是更强的基础模型也不是更长的上下文窗口而是一个介于“模型输出”和“系统执行”之间的门。这篇文章就是把这道门完整地拆给你看。1. 这篇文章真正要解决的问题先说一个我反复遇到的真实场景。假设你负责一个电商平台的 AI 客服系统。用户对客服说“我要退货”客服 Agent 查询到订单、确认了商品、判断符合退货条件然后直接调用了退货接口。这套流程看起来行云流水但仔细想一遍会发现几个让人后背发凉的可能性第一个是幻觉。模型可能把订单号记错了把 A 用户的订单填成了 B 用户的订单可能把“退货申请”推理成了“退款打款”可能在参数里填了一个超出运营规则允许的金额。第二个是提示注入攻击。用户在对话里塞入一段精心构造的指令诱导模型去调用一个本不该调用的工具。模型本身没有恶意但它被操控了系统却会因为“模型已经输出”而直接放行。第三个是不可逆操作的风险。查询一个订单的失败成本几乎为零但退款、删数据、发公告、改权限这些操作的失败成本很高。传统的 API 权限控制只能管住“谁有权限调”却管不住“一次调用该不该在这个场景下发生”。这三个问题指向同一个核心矛盾大模型已经把“意图理解”的成本降到很低但“行动授权”的机制几乎没有跟上。我们真正需要的不是让 AI 变得更小心那是模型训练侧的问题而是在模型输出之后、系统执行之前建立一道独立的闸门。这道闸门要做的事情很明确让 AI 在行动之前先“证明”它应该行动。这里的“证明”不是让模型多写几句解释而是用结构化、可校验、可审计的方式让系统检查它即将执行的每一个动作。2. 核心概念行动提案、策略校验、执行审批把这道门拆开它由三个核心部分组成。2.1 行动提案Action Proposal传统 API 调用的输入是参数输出是结果。但在 AI Agent 场景下模型输出的不应该只是“我要调用什么”的意图而应该是一个结构化的行动提案。行动提案至少包含以下字段字段含义为什么关键intent意图名称例如 query_order系统通过它找到对应的策略parameters执行参数例如订单号、金额策略校验的核心对象reasoning模型给出的行动理由用于人工复核和审计confidence模型对本次行动正确性的置信度可以作为风险计算的输入你可以把行动提案理解成一种“行动计划书”。AI 不能直接拉动扳机它先把扳机怎么扣、扣多重、为什么扣写成一份计划书交给系统审核。2.2 策略校验Policy Check策略校验是这道门最核心的闸点。它根据预设的策略对行动提案进行一系列检查。策略本质上是一组规则回答了这么几个问题这个意图是否在允许执行的清单里参数是否齐全、格式是否正确金额、次数、范围等关键约束是否在允许范围内这个行动的风险等级是低、中还是高2.3 执行审批Approval策略通过之后系统还需要根据风险等级决定最终是否放行。低风险操作可以自动执行高风险操作必须进入人工审批队列中风险操作可以根据置信度决定是自动执行还是需要二次确认。这套机制在业界有一个很形象的类比副驾驶可以协助驾驶但起飞和降落按钮必须由机长确认。结合起来这套门控机制解决了一个根本问题AI 的行动能力与系统允许的行动权限从此被严格分开。模型可以“想”做任何事但“能”做什么由策略层说了算。3. 一个具体的应用场景电商 AI 客服为了让后面的代码不是空中楼阁我们建立一个贯穿全文的具体场景。假设我们正在为一个电商平台开发 AI 客服系统。系统支持三种意图查询订单query_order用户询问订单物流状态。低风险自动放行。修改收货地址update_address用户要求修改配送地址。中风险需要校验“是否在发货前”必要时二次确认。发起退款refund_order用户申请退款。高风险金额超过阈值时必须进入人工审批。这个例子特别适合讲解门控因为它同时包含了一个不可逆操作退款、一个需要时效约束的操作改地址以及一个高频低成本操作查询。在实际项目里这套门控机制可以接在任何 Agent 框架之后。无论你用的是 LangChain、Spring AI、自研的 Agent 调度器还是直接用模型 API 写业务逻辑门控层都应该是独立于框架的一层。4. 环境准备与前置条件下面的示例使用 Python 3.10 和 FastAPI 构建。我选择 FastAPI 不是因为它是唯一的框架而是因为它的类型系统和 Pydantic 结合得很好特别适合做结构化校验。如果你公司的主技术栈是 Java也可以用 Spring Boot 实现同样的逻辑核心设计是相通的。你需要准备的环境如下Python 3.10 或更高版本pip 包管理器一个用于调试模型的 OpenAI 兼容 API 接口本文演示的核心是门控逻辑模型部分先用模拟数据代替不影响理解建议创建一个独立的虚拟环境python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate安装依赖pip install fastapi pydantic pyyaml uvicorn项目目录结构如下先搭建好ai-action-gate/ ├── gate/ │ ├── __init__.py │ ├── models.py │ ├── policy_checker.py │ ├── executor.py │ ├── api.py │ └── config/ │ └── policies.yaml ├── main.py └── requirements.txt版本不需要刻意追求最新FastAPI、Pydantic、PyYAML 的任何近一年内的稳定版本都能跑通这套代码。本文重点演示的是设计思路不是锁定某个特定版本。5. 核心代码实现三步构建行动门控5.1 定义行动提案模型首先用 Pydantic 定义行动提案的数据结构。# 文件路径gate/models.py from enum import Enum from typing import Any from pydantic import BaseModel, Field class RiskLevel(str, Enum): LOW low MEDIUM medium HIGH high class ActionProposal(BaseModel): AI 提出的行动提案必须通过门控校验才能执行。 intent: str Field(..., description意图名称例如 refund_order) parameters: dict[str, Any] Field(..., description执行参数) reasoning: str Field(..., description模型给出的行动理由) confidence: float Field( ..., ge0.0, le1.0, description模型对本次行动正确性的置信度 )这段代码定义了一个结构化的提案模型。Field里的description不只是注释FastAPI 会自动把它们变成 OpenAPI 文档的一部分对团队协作很有帮助。confidence用ge0.0, le1.0做了范围约束防止模型输出超范围的置信度。5.2 编写策略配置文件策略层和代码层分离的好处是改策略不需要改代码、不需要重新部署。我们把策略写进 YAML 文件。# 文件路径gate/config/policies.yaml policies: query_order: risk: low allowed: true required_params: - order_id update_address: risk: medium allowed: true required_params: - order_id - new_address constraints: max_delivery_days: 7 refund_order: risk: high allowed: true required_params: - order_id - amount constraints: max_amount: 1000 requires_approval: true这个配置文件表达了三层信息风险等级、参数要求、约束条件。其中requires_approval是高风险操作的“人工审批”标记。max_amount是金额上限超过上限直接拒绝。5.3 实现策略校验器策略校验器是整个门控的逻辑核心。它读取 YAML 配置对每一个行动提案做完整检查。# 文件路径gate/policy_checker.py from typing import Any import yaml from .models import ActionProposal, RiskLevel class PolicyChecker: 策略校验器检查行动提案是否满足系统策略。 def __init__(self, config_path: str): with open(config_path, r, encodingutf-8) as f: self._config yaml.safe_load(f)[policies] def check(self, proposal: ActionProposal) - dict: policy self._config.get(proposal.intent) # 1. 意图必须已注册 if not policy: return { allowed: False, reason: fintent{proposal.intent} 未在策略中注册, } # 2. 受限意图直接拒绝 if not policy.get(allowed, False): return { allowed: False, reason: fintent{proposal.intent} 已被策略禁用, } # 3. 必需参数检查 required_params policy.get(required_params, []) missing [ param for param in required_params if proposal.parameters.get(param) is None ] if missing: return { allowed: False, reason: f缺少必要参数: {missing}, } # 4. 约束条件检查 constraints policy.get(constraints, {}) # 金额上限检查适用于退款、转账等涉及金额的操作 max_amount constraints.get(max_amount) amount proposal.parameters.get(amount) if max_amount is not None and amount is not None: try: if float(amount) float(max_amount): return { allowed: False, reason: f金额 {amount} 超过上限 {max_amount}, } except (TypeError, ValueError): return { allowed: False, reason: famount 参数无法转换为数值: {amount}, } # 5. 汇总策略判定结果 risk RiskLevel(policy[risk]) return { allowed: True, risk: risk, requires_approval: policy.get(requires_approval, False), }这段实现有几个值得注意的设计。第一每个拒绝分支都返回了明确的原因。这个原因不只是给系统看的更是给后续审计和人工复核看的。当业务方问“为什么 AI 的退款申请被拦了”你可以直接给出一条可读的文本。第二约束检查是独立的步骤。未来如果要增加“每天最多退款 3 次”“同一订单 24 小时内只能改一次地址”这类计数约束只需要在约束检查里增加对应的判断逻辑不影响其他部分。第三返回值里包含了风险等级。策略层不仅回答“能不能做”还回答“风险有多大”这直接决定了后续的审批流程。5.4 实现执行器与审批流程执行器负责把策略校验的结果转换为最终的行动决策并对高风险操作标记“等待人工审批”。# 文件路径gate/executor.py from .models import ActionProposal from .policy_checker import PolicyChecker class ActionGate: 行动门控AI 的动作必须先经过这道门。 def __init__(self, checker: PolicyChecker): self._checker checker self._approval_queue [] # 简化版审批队列生产环境请用数据库 def request(self, proposal: ActionProposal) - dict: result self._checker.check(proposal) # 策略不允许直接拒绝 if not result[allowed]: return { status: denied, reason: result[reason], proposal_id: id(proposal), } # 高风险操作进入人工审批 if result[requires_approval]: task_id fapproval_{len(self._approval_queue) 1} self._approval_queue.append( { task_id: task_id, proposal: proposal.model_dump(), risk: result[risk].value, } ) return { status: pending_approval, task_id: task_id, risk: result[risk].value, } # 低中风险操作直接放行 return { status: approved, risk: result[risk].value, }在这个简化示例中审批队列用内存列表代替。真实生产环境应该使用数据库或专门的审批流引擎并且要保证审批记录不可篡改。5.5 暴露 HTTP 接口最后用 FastAPI 把门控能力暴露成一个接口。# 文件路径gate/api.py from fastapi import FastAPI from .models import ActionProposal from .policy_checker import PolicyChecker from .executor import ActionGate app FastAPI(titleAI Action Gate, version1.0.0) policy_checker PolicyChecker(gate/config/policies.yaml) action_gate ActionGate(policy_checker) app.post(/v1/propose-action) async def propose_action(proposal: ActionProposal): AI Agent 调用此接口提交行动提案并等待门控裁决。 return action_gate.request(proposal) app.get(/v1/approval-queue) async def get_approval_queue(): 查看待人工审批的高风险任务列表。 return {queue: action_gate._approval_queue}启动应用的入口# 文件路径main.py import uvicorn if __name__ __main__: uvicorn.run(gate.api:app, host0.0.0.0, port8000, reloadTrue)到这里门控系统的最小闭环已经完成模型提交行动提案 → 策略校验器检查 → 执行器裁决 → 返回结果。6. 运行结果与效果验证启动服务python main.py看到Uvicorn running on http://0.0.0.0:8000说明服务已经就绪。然后模拟三种真实场景。场景一查询订单低风险预期自动放行curl -X POST http://127.0.0.1:8000/v1/propose-action \ -H Content-Type: application/json \ -d { intent: query_order, parameters: {order_id: A1001}, reasoning: 用户咨询订单 A1001 的物流状态, confidence: 0.97 }预期返回{ status: approved, risk: low }场景二修改地址正常通过curl -X POST http://127.0.0.1:8000/v1/propose-action \ -H Content-Type: application/json \ -d { intent: update_address, parameters: {order_id: A1001, new_address: 北京市朝阳区示例路 88 号}, reasoning: 用户要求修改配送地址, confidence: 0.9 }预期返回{ status: approved, risk: medium }场景三退款金额超过阈值高风险预期进入人工审批curl -X POST http://127.0.0.1:8000/v1/propose-action \ -H Content-Type: application/json \ -d { intent: refund_order, parameters: {order_id: A1001, amount: 5000}, reasoning: 用户申请退款 5000 元, confidence: 0.85 }预期返回{ status: pending_approval, task_id: approval_1, risk: high }场景四缺少参数预期拒绝curl -X POST http://127.0.0.1:8000/v1/propose-action \ -H Content-Type: application/json \ -d { intent: refund_order, parameters: {order_id: A1001}, reasoning: 用户申请退款但没有填金额, confidence: 0.8 }预期返回{ status: denied, reason: 缺少必要参数: [amount] }验证这些场景时一个常见误区是只关注“放行”的情况。实际上对拒绝和降级的验证同样重要。你应该专门构造一批“恶意请求”或“残缺请求”确认门控能把它们拦截下来。这一步在测试中的优先级和正常流程是同等的。7. 常见问题与排查思路在实现和部署行动门控的过程中下面几个问题出现的概率最高。问题现象可能原因排查方式解决方案模型输出无法通过 Pydantic 校验模型返回的 JSON 字段不全或 confidence 超范围查看模型原始输出开启 Pydantic 的详细报错日志在模型提示词中加入 JSON Schema增加一层输出纠错逻辑明明配置了策略却提示未注册YAML 配置缩进错误或加载路径不对检查 policies.yaml 的缩进打印加载后的配置内容用yaml.safe_load单独调试检查路径是否正确高风险操作没有进入审批队列requires_approval 写在了错误层级检查 YAML 中该意图的配置层级确保 requires_approval 与 allowed 同级金额上限形同虚设模型把金额作为字符串传回在约束检查处打印参数类型在策略校验中显式做 float 转换并捕获异常生产环境重启后审批队列丢失使用了内存队列检查 executor 的存储实现替换为数据库或独立审批服务人工审批通过后没有执行结果通知审批流程与执行流程没有闭环检查审批完成后的回调逻辑在审批队列中补充状态流转和回调事件很多团队第一个版本会忽略一个问题门控本身的故障怎么办。如果门控服务挂了AI Agent 是直接放行所有请求还是拒绝所有请求我的建议是在门控不可用时默认拒绝。宁可让 AI 停下来也不能让它在没有防护的情况下行动。8. 最佳实践与工程建议概念和代码都跑通了最后聊几个我在实际项目中认为价值最大的工程实践。8.1 策略即代码变更要审计策略 YAML 文件应该像代码一样管理进入 Git、走评审流程、保留变更历史。一次误改策略的破坏力可能比一次线上 Bug 更大。建议在 CI 阶段增加策略校验测试确保每次策略变更都经过自动化检查。8.2 从“拒绝”到“解释”再到“建议”如果门控只返回一个deniedAI Agent 并不知道怎么修正。更成熟的方案是在拒绝原因基础上给模型提供修正建议。比如因为金额超限被拒时返回“最大退款金额是 1000 元”让模型重新生成一个合规的提案。这样既能守住边界又不会中断用户体验。8.3 审计日志要完整每次门控裁决无论通过、拒绝还是进入审批都要记录以下信息完整的行动提案命中的策略规则裁决结果和原因模型置信度请求到达的时间戳如果有一天用户投诉“AI 动了我账号里不该动的东西”这份日志就是你和合规团队坐下来排查问题的起点。8.4 对提示注入攻击保持敏感门控机制防不住恶意用户在对话中注入“假装系统指令”的攻击但门控能减少攻击造成的实际破坏。即使 prompt 被攻击了AI 生成的行动提案也必须经过策略校验。如果策略层不允许“转账”这个意图那么无论 prompt 怎么被注入AI 都调不了转账工具。这就是“AI 可以想但未必能做”的价值。8.5 用模拟工具先把大模型接入点埋好在这个演示里我刻意把门控设计成与模型无关。实际接入时你只需要在 Agent 调工具的地方把parameters交给策略校验器即可不需要关心底层用的是哪个模型。推荐先把整个链路用模拟数据跑通再接真实模型这样出问题时更容易定位是门控的问题还是模型的问题。9. 总结与后续学习方向这篇文章想表达的核心观点其实很简单大模型已经证明了它能“行动”我们作为工程师真正要做的是让它的每一次行动都先“自证清白”。行动门控不是一个复杂的架构它由三个明确的部分组成结构化的行动提案、可配置的策略校验、分级的执行审批。但恰恰是这样一个看似简单的中间层把 AI 的“意图能力”和系统的“行动权限”解耦了。这层解耦带来的收益非常大你可以在不完全信任模型的前提下逐步开放 Agent 的能力边界也可以在不改变模型的情况下快速调整业务的合规约束。如果你接下来打算在项目里落地这套思路我建议按下面的顺序推进第一步先梳理你项目里 Agent 可以执行的所有操作按照风险分成低、中、高三档。第二步为每个操作定义结构化的参数模型和策略规则用本文的代码作为起点跑通最小闭环。第三步接入真实的模型输出重点观察模型生成行动提案时的字段完整率和格式稳定率这往往是第一个瓶颈。第四步把审批队列、审计日志和生产环境的高可用补齐再逐步放开流量。后续值得深入的方向还有三个一是把模型的置信度纳入风险计算让低置信度的高风险操作自动降级二是建立一套针对门控本身的评测集专门测试恶意绕过和策略边界三是把门控做成公司内部的通用组件让不同业务线的 Agent 复用同一套审批和审计能力。AI Agent 的浪潮不会停下来但能够长期跑在生产环境里的 Agent一定不是那个“最聪明”的 Agent而是那个“想清楚后才行动、行动前先证明”的 Agent。这道门值得每一个正在做 AI 应用的团队认真对待。