一句话结论:Agent tool 不是"把后端 API 暴露给模型",而是给一个非确定性决策者使用的确定性能力接口。 好 tool 的目标不是"功能多",而是让 Agent 选得对、填得准、跑得稳、错了能恢复、全程可观测、权限可控、长期可评测。
Anthropic 把 tool 称为"确定性系统和非确定性 agent 之间的契约",并明确提醒:不要照着给人类开发者用的 API 设计 tool,要按 agent 的使用方式来设计;他们总结的重点包括选择正确的 tool、命名空间、上下文质量、token 效率、tool 描述和 eval 驱动迭代。(Anthropic) OpenAI 的函数调用文档也把 tool call 描述成一个多步闭环:模型提出 tool call,应用侧执行,应用再把结果返回给模型,模型继续推理或产出最终答案。(OpenAI 平台)
1. 各大厂观点汇总
Anthropic:少而精,面向 Agent 重新设计,不要做 API wrapper
Anthropic 的观点非常鲜明:tool 越多不一定越好。他们建议优先构建少量高影响力、任务导向的 tool,而不是把每个后端 endpoint 都包装成 tool;例如与其暴露一串 calendar API,不如设计一个 schedule_event 这样的任务级 tool。Anthropic 还强调 tool 返回内容要"高信号",避免把无关字段、UUID、冗长 JSON 全塞回上下文;返回格式、分页、过滤、错误信息都要为 agent 的下一步决策服务。(Anthropic)
Anthropic 在 agent 架构上也偏保守:先用最简单的模式解决问题,单个 LLM + 检索 + 少量 tool 经常已经足够;复杂框架可能遮蔽 prompt、response 和 tool 调用细节,导致系统难调试。(Anthropic)
我的提炼:Anthropic 的核心是"agent usability"。 Tool 不是工程师觉得完整,而是模型真的能理解、能选择、能恢复。
OpenAI:严格 schema、清晰函数、可控 tool choice、guardrails 和 tracing
OpenAI 的函数调用最佳实践非常工程化:函数名、参数名和描述要清晰;无效状态要尽量在 schema 里消除,例如使用 enum,而不是让模型自由填字符串;不要让模型填写应用已经知道的参数;总是一起调用的函数可以合并;初始可见 tool 数量要控制,OpenAI 文档给出的软建议是少于 20 个。(OpenAI 平台)
OpenAI 还强调 strict: true 的结构化输出,要求 schema 使用 additionalProperties: false,并让字段明确 required;可选字段可以通过允许 null 来表达。它也支持 tool_choice、强制调用、禁止调用、限制可用 tool、并行调用等控制手段。(OpenAI 平台)
在 Agents SDK 中,OpenAI 把 tool 分成 hosted tools、本地 function tools、agent-as-tool、MCP tool、code interpreter、web/file search 等多类;同时提供 tool timeout、tool error handler、tool guardrails、tracing,追踪 LLM generation、tool call、handoff、guardrail 和自定义事件。(OpenAI)
我的提炼:OpenAI 的核心是"contract + control + observability"。 Tool 要像强类型接口一样设计,还要能被运行时约束和追踪。
AWS / Amazon Bedrock:生产级 AgentOps,工具目录、网关、权限、评测、观测
AWS 的文章更偏企业生产落地。它强调从一开始就定义 agent 范围、语气、tool、参数、数据源和 ground truth dataset;上线前就要有 eval;上线后要持续 tracing、dashboard、A/B、drift detection、rollback。(Amazon Web Services, Inc.)
AWS 对 tool 的治理也很明确:tool 文档要包括名称、参数、返回格式、错误、使用示例;不要把所有工具都加载进上下文,可以用 Gateway / catalog / semantic search 做工具发现;安全上要先认证再执行 tool,用户 claims 要流入 tool 层,策略系统要验证"这个用户是否能用这个 tool、带这些参数调用"。(Amazon Web Services, Inc.) Bedrock Agents 的 action group 文档也支持 OpenAPI schema 或 function details,并支持对关键动作要求用户确认;AWS 同时强调最小权限 IAM、sessionAttributes、knowledge base metadata filtering 和 guardrails。(AWS 文档)
AWS 近期的 AgentOps 文章把 agent、tool、memory 都视为版本化、可 CI/CD 的工件,并要求跟踪每次交互中的决策、tool 调用、成本、延迟、错误和 memory 行为。(Amazon Web Services, Inc.)
我的提炼:AWS 的核心是"enterprise governance"。 在企业里,tool 不只是函数,而是权限、审计、目录、评测、回滚和责任边界。
Microsoft:最低复杂度原则,tool 输出不可信,重视决策规则和运行 trace
Microsoft 的 Azure AI Foundry 文档建议:Agent instructions 里要说明每个 tool 用来做什么、什么时候用、失败时如何处理;如果 tool 功能重叠,要写清决策规则。它也支持 tool_choice 控制 auto、required、none 等行为,并建议查看 run trace 来确认模型是否正确调用 tool、输入输出是否符合预期。(微软学习)
安全方面,Microsoft 明确提醒:tool 输出要视为不可信输入,关键值要验证,只传必要信息,不要把 secret 放进 prompt 或 tool 输出里,也要避免日志泄露 secret。(微软学习) 在 agent orchestration 上,Microsoft 官方架构建议使用能满足需求的最低复杂度:直接模型调用、单 agent + tools、多 agent 编排逐级升级;多 agent 适用于跨领域、安全边界或并行专业化场景,但要处理上下文、状态、可靠性、超时、重试、降级、成本和 HITL。(微软学习)
我的提炼:Microsoft 的核心是"pragmatic orchestration"。 不要为了 agent 而 agent;先单 agent,必要时再多 agent。
Google:函数签名、docstring、返回结构和长任务工具
Google ADK 的 tool 设计很强调代码层契约:框架会从函数名、docstring、参数、类型提示和默认值生成 tool schema;函数签名必须清楚,必填参数不要藏在模糊字符串里;不要滥用 *args / **kwargs 这种模型难理解的参数。Google 还建议返回结构化对象,包含状态、上下文和描述性字段;docstring 会成为发给 LLM 的 tool 描述,所以要写清目的、参数和返回值。(Google GitHub)
我的提炼:Google 的核心是"代码即契约"。 写函数不是只给运行时看,也是给模型看;签名和 docstring 都是 prompt surface。
MCP 社区:标准化 tool 协议,但 annotation 只是提示,不是安全边界
MCP 的 tool 定义包含 name、title、description、inputSchema、outputSchema 和 annotations;annotations 可以表达 readOnly、destructive、idempotent、openWorld 等风险提示。MCP 对 tool name 也有约束,例如大小写敏感、长度限制、字符集限制,并提醒多个 server 聚合时可能发生命名冲突,需要客户端做 disambiguation 或 prefix。(Model Context Protocol)
但 MCP 社区也特别提醒:annotations 是风险词汇,不是安全机制。恶意或不可信 server 可以撒谎,所以不能把安全决策建立在 annotation 本身上;真正的安全要靠 deterministic controls、权限、确认、隔离和审计。(Model Context Protocol Blog)
我的提炼:MCP 的核心是"interoperability, not trust"。 MCP 解决互联互通,不替你解决权限和安全。
2. 一套长期不过时的方法论
总原则:Tool 设计要同时满足 7 个目标
一个好 agent tool 至少要满足:
- 可发现:模型从名字和描述就知道什么时候用。
- 可区分:和其他 tool 没有模糊重叠。
- 可填写:参数少、强类型、无歧义,缺参数时能让模型知道该问用户还是用默认策略。
- 可执行:有 timeout、retry、idempotency、权限校验和错误处理。
- 可恢复:失败返回结构化、可行动的错误,而不是 raw exception。
- 可评测:能用 trace 判断是否选对 tool、参数是否正确、结果是否达成任务。
- 可治理:有版本、owner、权限、审计、下线策略和兼容策略。
这七个目标比任何一家 SDK 的语法更稳定。
3. Tool 粒度:什么时候做 tool,做多大?
不该做成 tool 的东西
| 场景 | 更好的做法 |
|---|---|
| 当前日期、用户 ID、租户 ID、locale | 作为 runtime context 注入,不要让模型调用 tool 查询 |
| 精确数学、税费、权限判断、合规规则 | deterministic code |
| 固定格式转换 | 普通代码 |
| 应用已经知道的信息 | 由系统填充,不要让模型猜参数 |
| 高风险授权判断 | policy engine / IAM / ACL,不靠 prompt |
AWS 也明确建议:计算、验证、业务规则等确定性逻辑应该用代码,agent 负责 orchestrate,而不是让模型执行所有步骤。(Amazon Web Services, Inc.)
应该做成 tool 的东西
| 类型 | 例子 | 设计建议 |
|---|---|---|
| 查询型 | 搜索客户、查订单、读文档、查日志 | read-only、可分页、可过滤、返回高信号摘要 |
| 动作型 | 创建工单、发邮件、改状态、退款 | 必须权限校验、幂等、确认、审计 |
| 复合任务型 | 安排会议、生成报价、诊断告警 | 把常见 API 链路压成一个任务级 tool |
Anthropic 的建议是:不要机械暴露每个 API endpoint,而要围绕真实任务设计高影响力 tool。(Anthropic)
粒度判断公式
如果模型每次都必须按固定顺序调用 A → B → C,那就合并成一个 tool。
如果不同任务会用不同顺序探索 A、B、C,那就保留为多个低层 tool。
如果某个能力本身需要独立推理、独立权限、独立上下文,就做成 agent-as-tool。
OpenAI Agents SDK 和 Google ADK 都支持 agent-as-tool 这种模式;它适合把复杂领域能力封装成一个上层 agent,而不是把几十个内部工具全部暴露给主 agent。(OpenAI)
4. Tool 命名和命名空间
命名要让模型"看名字就懂"。
推荐格式
domain.resource_action
service.resource.action
verb_noun
例子:
calendar.schedule_event
crm.search_customers
crm.get_customer_profile
billing.create_refund_request
github.search_issues
logs.search_error_events
避免的名字
get_data
process
handle
query
execute
call_api
update
run
这些名字对模型没有决策信息。
命名规则
每个 tool name 应该回答三个问题:
- 它操作哪个领域?
- 它做什么动作?
- 它和相邻 tool 的差别是什么?
Anthropic 建议用 namespace 按服务或资源组织 tool,减少混淆;MCP 也提醒工具聚合时可能命名冲突,所以大型系统要提前设计 prefix / namespace。(Anthropic)
5. Tool 描述:像给新人写交接文档
Tool description 不是注释,是模型的操作手册。Anthropic 说 tool spec 会被加载进 agent context,应该像 onboarding 新员工一样写清楚。(Anthropic)
一个优秀 description 应包含:
Purpose:
这个 tool 解决什么问题。
Use when:
哪些用户意图应该调用它。
Do not use when:
哪些情况不要调用它,应该改用哪个 tool 或直接回答。
Inputs:
每个参数的含义、格式、单位、约束、来源。
Outputs:
返回字段含义,哪些字段可用于下一步。
Failure behavior:
失败码、可恢复错误、是否应该询问用户、是否可以重试。
Safety:
是否只读、是否有副作用、是否需要确认、是否会访问外部世界。
示例:差描述 vs 好描述
差:
Search customers.
好:
Search CRM customer records by name, email, company, or account ID.
Use this when the user asks to find a customer or identify which customer record they mean.
Do not use this to fetch full account history; after finding the customer_id, use crm.get_customer_profile.
Return at most 10 candidates. If multiple candidates match, ask the user to disambiguate before taking any write action.
这类描述能显著减少"选错 tool"和"参数乱填"。
6. 参数 schema:让错误状态不可表达
参数设计要偏"强类型、少参数、低自由度"。
OpenAI 明确建议使用 enum、对象结构和清晰参数,尽量让 invalid states unrepresentable;不要让模型填写系统已知参数;一起调用的函数可以合并;初始可见函数数量控制在较小范围。(OpenAI 平台) Google ADK 也强调函数签名、类型提示、默认值和 docstring 会进入 schema,明确参数比 *args / **kwargs 更适合模型使用。(Google GitHub)
推荐 schema 习惯
1. 用 enum 替代自由字符串
不好:
{
"priority": {
"type": "string",
"description": "Priority"
}
}
好:
{
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "urgent"],
"description": "Ticket priority. Use urgent only when production is down or money movement is blocked."
}
}
2. 参数名不要模糊
不好:
{
"user": { "type": "string" }
}
好:
{
"user_id": {
"type": "string",
"description": "Internal immutable user ID, not email or display name."
}
}
3. 应用知道的参数不要让模型填
不要让模型填写:
{
"tenant_id": "...",
"current_user_id": "...",
"current_date": "...",
"locale": "..."
}
这些应该由 runtime 注入。让模型猜这些值,就是制造权限和数据污染风险。
4. 可选字段要明确
在 strict schema 里,OpenAI 建议所有字段 required;逻辑上的可选可以通过 ["string", "null"] 表示。(OpenAI 平台)
{
"type": "object",
"additionalProperties": false,
"required": ["customer_id", "date_range", "status_filter"],
"properties": {
"customer_id": {
"type": "string",
"description": "Internal customer ID."
},
"date_range": {
"type": "object",
"additionalProperties": false,
"required": ["start_date", "end_date"],
"properties": {
"start_date": { "type": "string", "description": "YYYY-MM-DD" },
"end_date": { "type": "string", "description": "YYYY-MM-DD" }
}
},
"status_filter": {
"type": ["string", "null"],
"enum": ["open", "closed", "pending", null],
"description": "Optional status filter. Use null when the user did not specify a status."
}
}
}
7. 返回值设计:高信号、低 token、可继续行动
Tool 输出不是给人类日志系统看的,而是给 agent 下一步推理用的。
推荐返回结构
{
"status": "success",
"summary": "Found 3 matching customers.",
"data": [
{
"customer_id": "cus_123",
"display_name": "Acme Japan",
"email": "[email protected]",
"match_reason": "Company name exact match"
}
],
"next_actions": [
"If the user wants account details, call crm.get_customer_profile with customer_id."
]
}
高质量输出的原则
| 原则 | 说明 |
|---|---|
| 返回状态 | success / not_found / partial / needs_clarification / error |
| 返回摘要 | 先给 agent 一个短 summary |
| 返回必要字段 | 不要把数据库整行都返回 |
| 返回可读 ID | 能用业务 ID、名称、URL 时,不要只给 UUID |
| 返回下一步建议 | 帮模型决定下一步该问用户还是调用另一个 tool |
| 支持格式切换 | response_format: concise / detailed |
| 支持分页 | limit, cursor, has_more |
| 错误可行动 | 不要只返回 stack trace |
Anthropic 特别强调返回高相关上下文、减少 token 浪费、使用分页/过滤/截断,并让错误信息能引导 agent 修复下一步。(Anthropic)
8. 错误处理:不要让 Agent 猜错在哪里
Tool 错误应该分层:
{
"status": "error",
"error": {
"code": "MISSING_REQUIRED_USER_INPUT",
"message": "The refund reason is required before creating a refund request.",
"recoverable": true,
"suggested_agent_action": "Ask the user for the refund reason."
}
}
常见错误码:
| 错误 | Agent 应该怎么做 |
|---|---|
MISSING_REQUIRED_USER_INPUT |
问用户 |
AMBIGUOUS_MATCH |
展示候选项,让用户确认 |
NOT_FOUND |
说明没找到,询问是否换条件 |
PERMISSION_DENIED |
不要重试;说明权限不足 |
RATE_LIMITED |
可等待或降级 |
TEMPORARY_FAILURE |
可有限重试 |
VALIDATION_FAILED |
修正参数后重试 |
DESTRUCTIVE_ACTION_REQUIRES_CONFIRMATION |
请求用户确认 |
OpenAI Agents SDK 支持 tool timeout 和 tool error handler;错误可以返回给 LLM 作为结果,也可以抛出异常交给应用处理。(OpenAI)
9. 安全设计:权限不能靠 prompt
这是最容易出事故的部分。Agent 可以建议调用 tool,但是否允许执行,必须由 deterministic policy 决定。
必须做的安全控制
| 控制 | 说明 |
|---|---|
| 最小权限 | tool 凭证只给必要 scope |
| 用户身份透传 | tool 执行时知道当前用户是谁 |
| 参数级鉴权 | 不只是"能不能调用 tool",还要判断"能不能用这个参数调用" |
| 写操作确认 | 退款、删除、发邮件、改权限等要确认 |
| 幂等性 | 写操作带 idempotency key |
| 审计日志 | 记录用户、agent、tool、参数、结果、时间 |
| secret 隔离 | 不把 token、key、cookie 暴露给模型 |
| 输出净化 | tool 输出视为不可信输入 |
| prompt injection 防护 | 外部文档、网页、邮件、ticket 内容不能直接当系统指令 |
| sandbox | 文件、代码、浏览器、终端类 tool 要隔离 |
AWS 要求在 tool 执行前做认证和策略校验,并把用户 claims 流入工具层;Bedrock 文档还支持对关键 action 要求确认,并强调 IAM 最小权限、session attributes 和 guardrails。(Amazon Web Services, Inc.) Microsoft 也明确指出 tool 输出是不可信输入,关键值要验证,不要把 secret 放进 prompt、tool 输出或日志。(微软学习)
MCP annotation 的正确用法
可以标注:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
但要记住:annotation 只能帮助 UI、模型和客户端理解风险,不能当成安全保证。 MCP 社区明确说 annotation 不是 enforcement,不防 prompt injection,也不能替代 deterministic controls。(Model Context Protocol)
10. Tool 运行时:别只设计 schema,还要设计执行环境
一个生产级 tool runtime 至少需要:
allowlist / denylist
tool_choice 控制
parallel call 控制
timeout
retry policy
idempotency
rate limit
circuit breaker
human approval
structured logging
trace id
redaction
policy check
sandbox
version routing
fallback
OpenAI 支持 tool_choice、required、none、allowed tools、并行调用等控制;OpenAI Agents SDK 也提供 tracing、guardrails 和 tool timeout。(OpenAI 平台) Microsoft 也建议用 tool_choice 增强确定性,并通过 trace 检查 tool 调用、输入和输出。(微软学习)
一个实用执行流程
User request
↓
Intent / risk classification
↓
Select available tool set
↓
LLM proposes tool call
↓
Schema validation
↓
Policy check: user + tool + params
↓
Optional human confirmation
↓
Execute with timeout / retry / idempotency
↓
Normalize output
↓
Redact sensitive fields
↓
Return structured result to agent
↓
Trace + eval sample + audit log
关键点:LLM 只负责提出"想调用什么";系统负责决定"是否允许、如何执行、如何记录"。
11. 评测:Tool 没有 eval,就等于靠感觉上线
Anthropic 对 agent eval 的定义比较完整:一个 eval 通常包括 task、trial、grader、trace/transcript、outcome、eval harness 和 agent harness;没有 eval,团队会进入"改 prompt → 看几个例子 → 又坏了"的盲飞循环。(Anthropic) AWS 也建议从一开始就建设 eval dataset,并覆盖不同表达、边界情况、模糊请求,度量 tool selection、参数抽取、拒绝准确率、延迟和成本。(Amazon Web Services, Inc.)
Tool eval 指标
| 维度 | 指标 |
|---|---|
| Tool selection | 该调用时调用,不该调用时不调用,多个 tool 选对 |
| 参数抽取 | 必填参数正确率、格式正确率、enum 正确率 |
| 权限行为 | 越权是否被拒、写操作是否确认 |
| 任务完成 | 最终 outcome 是否正确 |
| 恢复能力 | not_found、ambiguous、permission denied 后是否正确处理 |
| 成本 | token、tool call 次数、运行时间 |
| 稳定性 | 多次 trial 是否一致 |
| 安全 | prompt injection、数据泄露、越权调用 |
| 回归 | 新 prompt / 新模型 / 新 tool 是否破坏旧任务 |
Anthropic 建议同时使用 code-based、model-based 和 human graders;code grader 客观、便宜、可复现但脆弱,model grader 灵活但有成本和不确定性,需要人类校准。(Anthropic)
Eval 数据集应该长什么样
每个 tool 至少准备这些 case:
1. 标准成功路径
2. 用户表达很口语
3. 缺少必要参数
4. 多个候选结果
5. 没有结果
6. 用户要求越权
7. 用户要求危险动作
8. 外部内容包含 prompt injection
9. tool 暂时失败
10. 多 tool 顺序调用
11. 不该调用 tool 的问题
12. 同义意图:换说法仍然选同一个 tool
12. 多 Agent 与 Tool Catalog:不要把复杂度一股脑塞进主 Agent
当 tool 数量很多时,不要把 100 个 tool 全塞进一个 agent 的上下文。更好的方式:
组织级 tool catalog
↓
按任务 / 用户 / 权限 / 风险 动态选择
↓
当前 agent 只看到少量候选 tool
↓
必要时通过 Gateway / MCP / semantic tool search 发现更多 tool
AWS 建议用 centralized catalog 和 Gateway 管理 tool,并避免把所有 tool 都加载进上下文;OpenAI Agents SDK 也有 tool search,用来在运行时从大工具面里延迟发现 tool。(Amazon Web Services, Inc.)
什么时候上多 Agent?
| 信号 | 说明 |
|---|---|
| 单 agent prompt 太长 | 规则、领域知识、工具说明塞爆上下文 |
| tool 过多 | 模型频繁选错 |
| 权限边界不同 | 财务、人事、代码、客服需要不同权限 |
| 任务天然分工 | research、planning、execution、review |
| 需要并行 | 多来源调研、多候选方案评估 |
| 需要独立审查 | 一个 agent 执行,另一个 agent 审核 |
但 Anthropic 和 Microsoft 都提醒:先用最简单结构,复杂度只在必要时增加。(Anthropic)
13. 架构:Brain / Hands / Session 解耦
长期不过时的 agent tool 架构,最好拆成三层:
Brain: LLM / planner / policy-aware orchestrator
Hands: tool execution interface
Session: durable state / memory / files / trace
Anthropic 的 Managed Agents 架构文章明确提出把 brain、hands、session 解耦:稳定接口比具体实现更长寿;hands 可以抽象为 execute(name, input) -> string,背后可以接自定义 tool、MCP server、sandbox、container 等。(Anthropic)
这个设计的好处是:
- 模型可以换。
- tool backend 可以换。
- MCP / HTTP / SDK 可以换。
- session 和 memory 可以独立演进。
- 权限、安全和审计不绑死在 prompt 里。
- 评测可以跨模型、跨 runtime 复用。
14. 一份标准 Tool Spec 模板
可以把每个 tool 都按这个模板设计:
name: billing.create_refund_request
title: Create refund request
owner: billing-platform
version: 1.2.0
purpose: >
Create a refund request for an existing paid invoice.
This tool does not directly send money; it creates a pending request for approval.
use_when:
- The user asks to refund a paid invoice.
- The invoice_id is known or can be resolved from prior context.
do_not_use_when:
- The user only asks about refund policy.
- The invoice is unpaid or already refunded.
- The user has not confirmed the amount and reason.
risk:
read_only: false
destructive: false
idempotent: true
open_world: false
requires_confirmation: true
human_approval_required_above_amount: 50000
input_schema:
type: object
additionalProperties: false
required:
- invoice_id
- amount_cents
- currency
- reason
- idempotency_key
properties:
invoice_id:
type: string
description: "Internal invoice ID. Must start with inv_."
amount_cents:
type: integer
minimum: 1
description: "Refund amount in minor currency units."
currency:
type: string
enum: ["USD", "JPY", "EUR"]
reason:
type: string
description: "User-provided refund reason."
idempotency_key:
type: string
description: "Unique key generated by the application runtime."
auth:
principal: end_user
required_scopes:
- billing.refund_request.create
policy_checks:
- user_can_access_invoice
- amount_within_user_limit
- tenant_matches_session
execution:
timeout_ms: 8000
retry:
max_attempts: 1
retry_on:
- TEMPORARY_FAILURE
audit_log: true
redact_fields:
- internal_notes
output_schema:
type: object
required:
- status
- refund_request_id
- summary
- next_actions
properties:
status:
enum: ["success", "needs_approval", "error"]
refund_request_id:
type: ["string", "null"]
summary:
type: string
next_actions:
type: array
items:
type: string
errors:
INVOICE_NOT_FOUND:
recoverable: true
agent_action: "Ask the user for the correct invoice."
PERMISSION_DENIED:
recoverable: false
agent_action: "Explain that the user does not have permission."
CONFIRMATION_REQUIRED:
recoverable: true
agent_action: "Ask the user to confirm amount, invoice, and reason."
15. 一套落地流程
Phase 1:任务建模
先不要写 tool。先写清楚:
用户是谁?
他要完成什么任务?
成功结果是什么?
哪些情况必须拒绝?
哪些动作有副作用?
哪些数据源可信?
哪些参数来自用户,哪些来自系统?
哪些步骤必须 deterministic?
AWS 建议从小范围用例开始,明确 scope、tone、tools、参数和数据源,并建立 ground truth dataset。(Amazon Web Services, Inc.)
Phase 2:API → Tool 压缩
把后端 API 列出来,然后合并成 agent-friendly tool:
后端 API:
GET /customers
GET /customers/{id}
GET /invoices
POST /refunds
POST /refunds/{id}/approve
Agent tools:
crm.search_customers
billing.get_invoice_summary
billing.create_refund_request
不要一比一暴露 endpoint。模型不需要知道内部 API 拆分,它需要完成任务。
Phase 3:设计契约
每个 tool 设计:
name
description
use_when
do_not_use_when
input_schema
output_schema
errors
risk annotation
auth policy
timeout
retry
idempotency
audit
eval cases
Phase 4:运行时约束
运行时根据上下文动态决定:
当前用户能看到哪些 tool?
当前任务风险等级是多少?
是否允许写操作?
是否需要用户确认?
是否允许 parallel calls?
是否需要限制最大 tool call 次数?
是否需要人工审批?
Phase 5:评测和上线
上线前至少跑:
golden path eval
ambiguous input eval
missing parameter eval
permission eval
prompt injection eval
tool failure eval
regression eval
cost / latency eval
上线后持续看:
tool selection accuracy
argument accuracy
tool error rate
task success rate
human correction rate
latency
cost
permission denial
unexpected tool use
prompt injection attempts
AWS 的 AgentOps 文章也把 agent、tool、memory 当成 CI/CD 管理对象,强调生产 telemetry、trace、成本、错误、memory 和反馈闭环。(Amazon Web Services, Inc.)
16. 常见反模式
反模式 1:一个 endpoint 一个 tool
问题:tool 太多、语义重叠、模型选错。
改法:按任务合并。
❌ list_calendar_events + create_calendar_event + update_calendar_event + invite_user
✅ calendar.schedule_event
反模式 2:tool 描述只有一句话
问题:模型不知道什么时候用、不知道什么时候不用。
改法:写 use_when / do_not_use_when / failure behavior。
反模式 3:返回原始数据库行
问题:token 浪费、泄露字段、模型抓错重点。
改法:返回摘要 + 必要字段 + next_actions。
反模式 4:靠 prompt 做权限
问题:模型可以被 prompt injection、上下文污染或误调用诱导。
改法:policy engine + 参数级鉴权 + audit。
反模式 5:写操作没有幂等和确认
问题:重复退款、重复发邮件、重复删数据。
改法:idempotency_key + confirmation + approval。
反模式 6:没有 trace
问题:失败后不知道是模型选错、参数错、tool 错、权限错还是数据错。
改法:每次记录 tool call、参数、结果、latency、token、trace id。
反模式 7:没有 eval,只靠人工试
问题:prompt、模型、tool 一变就回归。
改法:建立 tool-level eval 和 task-level eval。
17. 不同观点之间的综合判断
少量 tool vs 大规模 tool catalog
Anthropic 和 OpenAI 更强调"当前上下文里 tool 要少而清晰";AWS 和企业架构更强调"组织级 catalog / gateway / MCP"。这两者并不矛盾。
正确做法:组织级可以有很多 tool,但单次 agent 可见 tool 要少。
Many tools in catalog
Few tools in context
Even fewer tools executable under current user permissions
高层任务 tool vs 低层原子 tool
高层 tool 更稳定、少出错;低层 tool 更灵活。
正确做法:
业务流程稳定 → 高层任务 tool
探索路径不确定 → 低层 read-only tool
高风险写操作 → 高层受控 tool
代码/浏览器/文件系统 → sandboxed low-level tool
Prompt 约束 vs deterministic 约束
所有厂商都建议写清 tool 描述,但安全不能靠描述。
正确做法:
描述用于引导模型
schema 用于限制参数形状
runtime 用于控制执行
policy 用于权限判断
audit 用于追责
eval 用于持续验证
单 Agent vs 多 Agent
单 agent 简单、低延迟、好调试;多 agent 可分工、隔离权限、降低单个 prompt/tool 面复杂度。
正确做法:先单 agent。只有当 tool 数量、领域复杂度、权限边界或并行需求真的压不住时,再多 agent。
18. 最终检查清单
设计一个 tool 前,逐项问:
1. 这个 tool 对应真实用户任务吗?
2. 是否只是后端 API wrapper?
3. 名字是否一眼看懂?
4. 和其他 tool 是否重叠?
5. description 是否写清 use_when / do_not_use_when?
6. 参数是否强类型、少歧义?
7. 是否避免让模型填写系统已知参数?
8. 是否使用 enum / object / required / null 限制无效输入?
9. 输出是否高信号、低 token?
10. 错误是否结构化、可恢复?
11. 是否有 timeout / retry / idempotency?
12. 写操作是否需要确认?
13. 权限是否在 tool 执行前 deterministic 校验?
14. tool 输出是否按不可信输入处理?
15. secret 是否不会进入 prompt、输出和日志?
16. 是否有 trace、audit、metrics?
17. 是否有 golden eval 和 edge eval?
18. 是否有版本、owner、回滚策略?
19. 是否能被动态加载,而不是永远塞进上下文?
20. 模型升级后是否能重新跑 eval?
19. 最压缩的方法论
可以记成一句话:
先从任务出发,设计少量高信号 tool;用严格 schema 和清晰描述让模型选对、填对;用 runtime、policy、confirmation 和 sandbox 保证安全执行;用 trace、eval、版本和 catalog 保证长期演进。
这套方法不会随着某个 SDK 过时,因为它抓的是 agent tool 的本质:给非确定性智能体使用的、可治理的确定性能力接口。