给 AI Agent 写一份 Action Manifest:让工具调用从“能跑”变成“可控”
很多团队第一次做 AI Agent工具调用都是这样开始的pythontools {send_email: send_email,query_db: query_db,create_ticket: create_ticket}然后把工具列表交给模型让 Agent 自己决定调用哪个。Demo 阶段这样没问题。但一旦进入真实业务很快会出现几个问题工具用途描述不清。参数格式不稳定。必填字段缺失。高风险动作没有声明。重复执行导致副作用。失败后不知道能不能重试。不同工具返回格式不一致。所以AI Agent 要接入业务系统不能只给它一个函数列表而应该给每个工具写一份 Action Manifest。Action Manifest 是什么简单说就是一个工具动作声明文件。它告诉 Agent 和系统这个工具能做什么需要什么参数哪些参数必填动作风险等级是什么是否允许自动执行是否幂等失败后能否重试返回结构是什么。Google I/O 2026 之后Agent 调用工具这件事会越来越常见。Google 官方把 I/O 2026 称为 agentic Gemini eraThe Verge 也报道 Gemini Spark 将通过 MCP 扩展到第三方平台连接更多外部服务。这意味着工具调用会从“内部 Demo”变成“真实产品能力”。越是这样Action Manifest 越重要。一个简单的 Manifest 可以这样设计json{name: send_email,description: Send an email to a specified recipient.,risk_level: high,auto_execute: false,idempotent: false,retryable: false,required_permissions: [email:send],parameters: {type: object,required: [to, subject, body],properties: {to: {type: string,description: Recipient email address},subject: {type: string,maxLength: 120},body: {type: string,maxLength: 5000}}},returns: {type: object,properties: {message_id: {type: string},status: {type: string}}}}这个声明比一句“send_email 可以发邮件”清楚很多。它明确告诉系统这是高风险动作。不能自动执行。不可幂等。失败后不建议自动重试。需要 email:send 权限。必须有 to、subject、body。subject 和 body 有长度限制。接下来我们可以用 Python 定义 Manifest 数据结构。pythonfrom dataclasses import dataclassfrom typing import Dict, Any, Listfrom enum import Enumclass RiskLevel(str, Enum):LOW lowMEDIUM mediumHIGH highCRITICAL criticaldataclassclass ActionManifest:name: strdescription: strrisk_level: RiskLevelauto_execute: boolidempotent: boolretryable: boolrequired_permissions: List[str]parameters_schema: Dict[str, Any]returns_schema: Dict[str, Any]然后写一个参数校验函数pythondef validate_required_fields(arguments: Dict[str, Any], schema: Dict[str, Any]) - List[str]:missing []required schema.get(required, [])for field in required:if field not in arguments or arguments[field] in [None, ]:missing.append(field)return missing再写一个执行前检查pythondef validate_action_call(manifest: ActionManifest,arguments: Dict[str, Any],user_permissions: set) - Dict[str, Any]:missing_fields validate_required_fields(arguments, manifest.parameters_schema)if missing_fields:return {valid: False,reason: missing_required_fields,fields: missing_fields}for permission in manifest.required_permissions:if permission not in user_permissions:return {valid: False,reason: permission_denied,permission: permission}if manifest.risk_level in [RiskLevel.HIGH, RiskLevel.CRITICAL] and manifest.auto_execute:return {valid: False,reason: high_risk_action_cannot_auto_execute}return {valid: True,reason: validated}注意这里不是在写完整权限系统而是在确保工具调用前有明确声明和参数约束。Action Manifest 还应该声明幂等性。为什么因为 AI Agent 很容易出现重复调用。网络抖动后重试一次。模型以为上次没执行成功又调用一次。用户刷新页面导致任务重新触发。多个 Agent 同时处理同一任务。如果工具不是幂等的就会出问题。比如发送两封邮件。创建两张工单。重复扣款。重复修改状态。重复提交表单。所以 Manifest 里一定要有 idempotent 字段。对于非幂等动作系统应该要求 idempotency_key。pythondef require_idempotency_key(manifest: ActionManifest, arguments: Dict[str, Any]) - bool:if manifest.idempotent:return Falsereturn idempotency_key not in arguments执行前检查可以补上pythondef preflight_check(manifest: ActionManifest, arguments: Dict[str, Any], user_permissions: set):base_result validate_action_call(manifest, arguments, user_permissions)if not base_result[valid]:return base_resultif require_idempotency_key(manifest, arguments):return {valid: False,reason: idempotency_key_required}return {valid: True,reason: ready_to_execute}这样Agent 即使想重复调用也会被系统要求提供幂等控制。最后还要统一返回结构。不要让每个工具随便返回不同格式否则 Agent 后续处理会很麻烦。建议统一成json{ok: true,action: send_email,result: {message_id: msg_123,status: queued},error: null}失败时json{ok: false,action: send_email,result: null,error: {code: permission_denied,message: User does not have email:send permission}}对应 Python 封装pythondef action_success(action_name: str, result: Dict[str, Any]) - Dict[str, Any]:return {ok: True,action: action_name,result: result,error: None}def action_error(action_name: str, code: str, message: str) - Dict[str, Any]:return {ok: False,action: action_name,result: None,error: {code: code,message: message}}Action Manifest 的价值在于它把“模型想调用工具”这件事变成了工程系统可控的动作。如果你只是做个人 Demo可以直接写函数。如果你要做团队系统至少要有参数 schema。如果你要接入真实业务必须声明风险、权限、幂等和返回结构。如果你要支持多 Agent 并行执行幂等和审计更不能少。前期测试不同模型的工具调用规划能力时可以通过 gpt0424.com 这类综合入口比较 ChatGPT、Claude、Gemini、Grok 在结构化输出、工具选择、参数生成方面的表现。但进入工程落地后不能只相信模型要把工具动作写成 Manifest。Agent 不是不能调用工具。问题是你有没有告诉它每个动作的边界在哪里。