一句话结论: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 至少要满足:

  1. 可发现:模型从名字和描述就知道什么时候用。
  2. 可区分:和其他 tool 没有模糊重叠。
  3. 可填写:参数少、强类型、无歧义,缺参数时能让模型知道该问用户还是用默认策略。
  4. 可执行:有 timeout、retry、idempotency、权限校验和错误处理。
  5. 可恢复:失败返回结构化、可行动的错误,而不是 raw exception。
  6. 可评测:能用 trace 判断是否选对 tool、参数是否正确、结果是否达成任务。
  7. 可治理:有版本、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 应该回答三个问题:

  1. 它操作哪个领域?
  2. 它做什么动作?
  3. 它和相邻 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)

这个设计的好处是:

  1. 模型可以换。
  2. tool backend 可以换。
  3. MCP / HTTP / SDK 可以换。
  4. session 和 memory 可以独立演进。
  5. 权限、安全和审计不绑死在 prompt 里。
  6. 评测可以跨模型、跨 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 的本质:给非确定性智能体使用的、可治理的确定性能力接口。