智能体的工具边界:何时调用工具 + 如何设计工具 I/O(让你的系统不再猜测)

发布: (2026年1月8日 GMT+8 08:55)
10 min read
原文: Dev.to

Source: Dev.to

Anindya Obi

问题

如果你不定义 tool boundaries,你的代理在生产环境中会出现以下两种情况之一:

  1. Over‑call 工具,针对所有情况调用 → 速度慢、成本高、噪音大。
  2. Under‑call 工具 → 自信的幻觉。

“Tool calling is where ‘demo agents’ go to die.”

最近的失败

用户询问:“Why did my order fail to deliver?”

  • 代理没有订单数据,于是猜测 “weather delays.”
  • 然后它写了一段自信的道歉并继续进行。

结果:没有调用工具,没有验证,只有感觉。

解决方案

我把工具使用变成了一个 contract

下一次运行时,代理说:

“I can check your order status. What’s your order ID?”

它先询问缺失的前置条件,只有在准备好时才调用工具,并且能够干净利落地处理失败。这就是助理与生产系统之间的区别。

为什么在生产环境中会失败

工具行为因两个可预见的原因而中断:

IssueSymptom
Over‑calling每个问题都会触发工具 → 延迟、成本、混乱的追踪
Under‑calling代理在没有所需数据的情况下作答 → 带有自信的幻觉

在生产环境中,你需要的工具使用方式是:

  • Testable – 你可以为其编写评估。
  • Auditable – 你可以追踪并调试它。
  • Repeatable – 它在不同运行中表现一致。

这只有在你把工具使用视为 API 合约 而不是建议时才会实现。

定义 – “工具边界” 实际含义

工具边界是决定以下事项的规则:

  1. 触发 – 何时必须调用工具 vs 何时必须不调用工具。
  2. 前置条件 – 调用前所需的输入(order_id、query、file_id,…)。
  3. I/O 合约 – 对工具输入使用严格的 JSON + 对输出使用严格的 JSON。
  4. 失败策略 – 重试 vs 询问用户 vs 回退 vs 升级。
  5. 可审计性 – 记录的内容(trace_id、tool_name、latency、status、cost)。

如果你定义了这些,你的代理就不会在执行过程中自行编造工作流。

即插即用标准(复制/粘贴) – 工具边界合约

将其粘贴到您的系统提示或路由代理指令中。

TOOL BOUNDARY STANDARD (binding rules)

You may call tools only when the user's goal cannot be satisfied safely with internal reasoning alone.

1) MUST_CALL conditions:
   - The answer requires private/user‑specific data (account, orders, tickets, files, DB records).
   - The answer requires up‑to‑date or externally verifiable facts (news, prices, weather, availability).
   - The answer requires computation or transformation best done by a tool (calc, parsing, file ops).
   - The agent has insufficient inputs and the tool is the only way to obtain them.

2) MUST_NOT_CALL conditions:
   - The user is asking for explanation, brainstorming, writing, or strategy that does not depend on external data.
   - Tool prerequisites are missing (e.g., no order_id, no query, no file_id).
   - A tool result would not materially change the answer.

3) BEFORE_CALL checklist:
   - Identify required tool inputs.
   - If missing: ask ONE targeted question to obtain them.
   - Choose exactly ONE tool. Do not chain tools unless explicitly needed.

4) TOOL_IO:
   - Tool inputs MUST match the declared JSON schema.
   - Tool outputs MUST be treated as source of truth.
   - Never fabricate tool outputs.

5) ON_ERROR policy:
   - If retryable (timeout/429): retry up to 2 times with backoff.
   - If not retryable (4xx validation): ask for corrected input.
   - If tool unavailable: provide a safe fallback + explicit limitation + next step.

路由器决策模式(严格 JSON)

最小化的模式,使工具调用评估更加友好。

{
  "decision": "CALL_TOOL | ASK_USER | ANSWER_DIRECT | REFUSE",
  "reason": "string",
  "tool_name": "string | null",
  "tool_input": "object | null",
  "missing_inputs": ["string"],
  "success_criteria": ["string"],
  "fallback_plan": ["string"]
}

如果你不做其他任何操作,请强制执行此模式。它迫使代理 提交 一个决策,消除“工具氛围”。

工具 I/O 模板(每个工具)

每个工具都应该像这样发布需求(即使是自动生成的)。

{
  "tool_name": "string",
  "required_inputs": ["string"],
  "optional_inputs": ["string"],
  "input_example": {},
  "output_schema": {},
  "error_shapes": [
    { "type": "timeout", "retryable": true },
    { "type": "validation_error", "retryable": false }
  ]
}

这可以防止经典的失败:“工具只收到一半输入 → 垃圾输出 → 下游混乱。”

示例

1️⃣ RAG 还是直接回答?

用户: “解释一下 embeddings 和 rerankers 的区别。”

OutcomeVerdictWhy
ANSWER_DIRECT不需要外部/用户特定数据,只需给出解释。
CALL_TOOL“让我搜索一下…” 增加延迟且没有价值。边界: MUST_NOT_CALL 用于概念性解释。

2️⃣ 用户特定数据 → 必须使用工具

用户: “为什么我的订单没有送达?”

OutcomeVerdictWhy
ASK_USER → CALL_TOOL请求 order_id,调用 get_order_status(order_id),根据结果解释;按策略处理失败。
ANSWER_DIRECT“可能是天气延误” → 幻觉。边界: MUST_CALL 当答案依赖私有数据时。

3️⃣ 缺少前提条件(不要猜测)

用户: “检查日志”

OutcomeVerdictWhy
ASK_USER提示所需的日志标识符,然后调用相应的日志获取工具。
ANSWER_DIRECT猜测会导致无意义输出。

TL;DR

将工具使用视为合同。

  1. 定义何时必须调用工具以及何时该调用。
  2. 在调用前要求提供所有输入;如果缺少任何内容,向用户询问。
  3. 强制严格的 JSON 输入/输出以及明确的错误处理策略。
  4. 记录所有内容以便审计。

Tool Boundary ContractRouter decision schema 复制到系统提示中,您的代理将不再猜测,开始表现得像可靠的软件。

Tool‑Usage Guidelines

✅ Good (ASK_USER)

  • “Paste the log excerpt or share the trace_id.”
  • Then route to the right tool/analysis path.

❌ Bad (CALL_TOOL)

  • Calls a “log tool” with empty input.
  • Or invents a plausible stack trace.
  • Boundary hit: MUST_NOT_CALL when prerequisites are missing.

示例 4 – 处理工具错误

工具返回:

{
  "status": "error",
  "error_type": "timeout",
  "message": "upstream timed out"
}

✅ 好的做法

  • 重试最多 2 次
  • 如果仍然失败:解释限制并给出下一步。
  • 提供面向用户的备选方案(手动检查、稍后重试、替代来源)。

❌ 错误做法

  • 假装成功。
  • “您的订单已送达”(灾难性错误)。

边界触发: 永不伪造工具输出;强制执行 ON_ERROR

什么可以安全自动化(不失正确性)

一旦边界明确,自动化就变得安全:

  • 工具注册表生成:从代码中提取必需输入、输出模式、错误形状。
  • 工具调用检查(lint):在缺少必需输入时阻止调用。
  • 基于边界的路由:路由代理仅输出严格的 JSON。
  • 结构化追踪trace_idtool_name、延迟、状态、成本)。
  • 评估框架:用于 MUST_CALLMUST_NOT_CALL 决策的评估。
  • 回退模板:处理超时 / 429 / 验证错误的模板。

这正是团队停止“调试提示”,开始调试系统的地方。

HuTouch + Work2.0(全新构建方式)

我正在构建 HuTouch,以自动化 AI‑engineer 路由器、范围、模式和评估集的提示设计中枯燥的部分,从而让你的代理默认带有安全护栏。

工作原理:
Instructions & Prompt Design

Work2.0 原则

  • 停止把努力误认为价值。
  • 自动化不需要深层技能的可重复步骤。
  • 夺回时间,用于真正重要的工作(以及生活)。

抢先体验申请:
Early Access Form Link

快速检查清单(打印此页)

  • 我们是否有明确的 MUST_CALLMUST_NOT_CALL 规则?
  • 每个工具是否声明了 required_inputsoutput_schema
  • 路由器是否返回严格的 JSON(CALL_TOOL / ASK_USER / ANSWER_DIRECT / REFUSE)?
  • 当前置条件缺失时,我们是否阻止工具调用?
  • 我们是否有错误策略(重试 / 询问用户 / 回退 / 升级)?
  • 工具调用是否可审计(trace_id、延迟、状态、成本)?
  • 我们是否使用评估提示测试边界,以尝试强迫不良行为?
Back to Blog

相关文章

阅读更多 »

TOON for LLMs:基准性能分析

每一次使用 JSON 的 API 调用,花费都比你想象的要高。我使用 Gemini 2.5 Flash 进行真实场景的提取,结果令人震惊:JSON……