Agent 小知识|让 Agent 调对工具:输入输出契约的设计

简介: 本文详解Agent工具调用的输入输出契约:输入契约规范工具名称、描述、参数Schema与使用边界,确保模型准确调用;输出契约定义结构化结果、状态码与错误反馈,支撑模型可靠决策。二者共同保障Agent“思考→行动→判断”闭环的稳定性与可解释性。

在上一期我们聊到每次 Agent 调用模型前,要根据当前的规则、任务状态、工具信息等上下文内容来动态组装本轮 Prompt。

工具信息虽然只占当中很小的一部分,但它决定了 Agent 能不能把思考变成行动。要让模型“动起来”,得先让模型知道有哪些可用的工具,这些工具又能做什么,以及如何使用这些工具(参数应该怎么填写)。等工具执行完任务后,系统会把执行结果送回上下文,方便模型进行下一步的判断。

而上面这套工具调用流程之所以能够顺利运行,是因为背后有一套明确的工程约定:模型应该以什么格式发起调用请求,工具又应该以什么格式返回执行结果。

这就是本文要讨论的工具调用的输入输出契约。

工具调用的双向契约

在传统软件开发中,API 请求一般会定义好请求参数、返回字段、错误码和权限要求。调用方依据接口文档发送请求,服务端再依照约定处理请求并返回结果,这样就完成了一次数据交互。

Agent 的工具调用逻辑和上面类似,只不过调用方从程序变成了大语言模型。一轮完整的工具调用包含以下过程:

工具定义进入上下文
      ↓
模型选择工具并生成参数
      ↓
Harness 校验并执行工具
      ↓
工具返回结果或错误
      ↓
结果进入上下文
      ↓
模型决定下一步

在上面这条链路中,输入契约作用于工具执行之前,约定了模型应该如何调用工具,包括但不限于工具名称、使用场景、参数类型、必填字段和限制条件。输出契约作用于工具执行之后,约定工具应该返回什么信息。其中,返回信息要有结果数据、执行状态、错误信息和必要的元数据。

简单来说,输入契约约束了模型该怎样去调用工具,输出契约让模型知道这次调用产生了什么结果。

这样,输入输出契约一起决定了模型与工具之间是如何沟通的。如果输入契约不清楚,模型可能会选错工具或传错参数。如果输出契约不清楚,模型拿到结果后,可能无法准确判断本次工具调用是否成功、当前任务是否要继续推进,以及发生错误时应该采取什么恢复措施。

目前,主流的 Agent 架构将工具定义、调用编排、实际执行和输出处理都归入 Harness 的职责范围:模型负责理解工具的结构化定义,再生成调用请求,而 Harness 负责执行工具调用请求并处理输出,并将结果送回循环。

输入契约的结构组成

一个工具的输入契约,最重要的是要告诉模型这个工具叫什么,以及它能完成什么任务。

例如,一个天气查询工具可以写成:

{
  "name": "get_weather",
  "description": "查询指定城市当前的天气情况",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称,例如 Beijing"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "温度单位"
      }
    },
    "required": ["city"]
  }
}

这个定义当中的关键部分有:

  • name,即工具名称。作为模型识别和调用工具的唯一标识,名称最好采用“动作 + 对象”的结构,让模型一眼看出这个工具要做什么、作用于什么对象。参考:search_webread_filesend_email。像 processhandle 这类宽泛的名称,会让模型难以判断它适合什么任务。

  • description,即工具描述。主要用来说明工具的能力、适用场景和使用边界。一个工具描述如果只写“搜索内容”是远远不够的,更清楚的表达是“这个工具是用于搜索公开网络上的实时信息,请不要用于查询公司内部资料。”当模型选择工具时,除了参考当前任务之外,会结合工具名称和工具描述进行判断。

  • input_schema,即参数 Schema。它定义了参数整体的数据结构,以及每个字段的类型、含义和约束。比如,上面示例的 properties 就定义了 cityunit 两个参数,enum 将温度单位限制在 celsiusfahrenheit 之间。

  • required,即必填字段列表。示例中的 "required": ["city"] 表示调用这个工具时必须提供属性(properties)中的 city,而 unit 可以不填。这里提醒一点,requiredinput_schema 的一部分。

除了 JSON Schema 中的参数约束,工具定义还需要说明调用这个工具可能会产生的影响。例如,发送邮件(工具)会把内容发给真实收件人,执行工具调用之前要和用户进行确认;网页抓取(工具)可能耗时会比较久;删除文件(工具)会产生不可逆的结果。诸如此类的使用边界可以写进工具描述,也可以通过额外的工具元数据和 Harness 权限规则讲清楚。

讲清楚使用边界之后,还要进一步降低模型填写参数时的理解成本。可以通过工具定义加入真实的调用示例来降低理解成本。虽然 Schema 能说明字段类型,却难以说明时间戳的单位是使用秒还是毫秒、电话号码是否需要国家代码、嵌套过滤条件该如何组合。给出具体示例可以把这些隐含的约定直接展示给模型,减少它临时猜测参数格式的情况。

一般来说,工具描述还要覆盖使用时机、边界、参数示例、返回值和执行代价。一旦模型频繁选错工具,我们应该先检查工具是否定义清楚,再考虑模型能力。

参数语义与传递保真

输入契约除了要保证格式正确,还要保证参数从模型传到工具的过程中保持语义的一致。

在实际的工具调用链路中,模型生成 JSON 参数后,中间的 Agent 运行层通常还会经过多个处理步骤。例如,Harness 或 SDK 可能会进行序列化、类型转换、默认值补充、编码处理等操作。如果这些处理在模型不知情的情况下改变了参数内容,模型理解的状态就会和工具实际执行的状态产生偏差。

举个例子,一个文件替换工具要求模型提供 old_stringnew_string 两个参数。模型读取文件时发现原文使用的是中文弯引号,没做思考直接将这段文本原样传入 old_string。但这里有一个隐藏机制是,参数传递层会在执行前自动将中文弯引号转换成英文直引号,直传的话会导致工具无法匹配文件中的原始内容。

从模型视角来看,它已经根据读取到的信息生成了正确参数;但从工具视角来看,实际收到的参数已经发生了变化,因此工具会持续返回“未找到匹配”。这可苦了 Agent,要不断地重试工具调用,却难以察觉问题在于中间的参数转换。

类似的传递偏差情况还包括:

  • 将秒级时间戳自动转换为毫秒,却没有明确告知模型;

  • 自动清除查询字符串中的特殊字符;

  • 在 Shell 命令后追加模型没有生成的参数;

  • 自动修改文件编码或换行符;

  • 将空字符串、null 和字段缺失视为同一种情况。

这些“智能”的修正可能会让单次调用更加方便,但也会降低工具调用的可解释性和可调试性。如果确实要对参数进行规范化处理,转换规则应该明确写入工具描述;工具执行后,也应该返回实际采用的参数,让模型知道系统最终执行了什么。

因此,参数保真关注的不只是“字段有没有传过去”,还包括参数的值、编码、单位、顺序以及语义是否在整个调用链路中保持一致。

输出契约的结果表达

输入契约负责解决“工具怎么调用”,输出契约负责回答“工具做完后发生了什么”。

一个工具执行完只返回“成功”或“失败”信息,是无法为 Agent 的下一步决策提供足够信息进行判断的。比较合理的输出应该包含明确的状态、结构化数据和必要的执行细节。参考:

{
  "status": "success",
  "data": {
    "city": "Vancouver",
    "temperature": 13.2,
    "unit": "celsius",
    "conditions": "clear"
  }
}

当工具执行失败时,也应该返回稳定的错误结构:

{
  "status": "error",
  "error": {
    "code": "RATE_LIMIT",
    "message": "请求频率超过服务限制",
    "retryable": true
  }
}

这样的输出结果让 Harness 和模型能够做出更明确的判断:当前调用是否成功、数据放在哪里、错误属于临时故障还是永久失败、是否值得重试。

输出契约还要区分工具执行成功任务结果正确。例如,write_file 返回成功,只能说明文件写入动作完成。至于写入的代码是否能编译通过、是否符合项目规范,这是需要进一步验证的。因此,文件编辑工具除了完成写入操作外,还可以在执行后主动运行语法检查,并返回结构化的错误信息,帮助 Agent 在下一轮调用中快速定位问题并完成修复。

对于文件读取、网页抓取、数据库查询和命令执行等工具,返回结果可能包含大量内容。为了避免过长的输出占用上下文空间,工具可以对结果进行截断或压缩,但截断过程必须明确告知模型。例如:

已返回第 1—200 行,共 5000 行。
剩余内容可通过 offset=200 继续读取。

静默截断会让模型误以为自己获得了完整信息,从而基于不完整的结果做判断。因此,工具在截断返回内容时,要明确告知模型当前结果是否完整,并提供继续获取剩余内容的方式。对于信息获取类和任务执行类工具,合理的做法还包括保留完整结果、进行自动验证,以及在结果进入上下文前完成解析、Schema 校验、长输出压缩和错误标准化。

错误反馈与恢复信号

工具执行失败是 Agent 运行中的常见问题。毕竟网络会超时,接口会限流,文件可能不存在,参数也可能无法通过校验,这些意外情况都会导致工具执行失败。

一个良好的输出契约不会把所有失败都压缩成一句“调用失败”,而是会提供足够的恢复信号:

  • 这个错误发生在哪个阶段;

  • 使用了哪些实际参数;

  • 错误类型和错误码是什么;

  • 该错误是否需要重试工具调用;

  • 本次调用是否已经产生部分结果;

  • 下一步可以采取什么措施。

举个例子,文件不存在和权限不足这两种情况都表现为读取失败,但 Agent 的处理方式完全不同。如果是文件不存在,Agent 可以搜索正确路径。如果是权限不足,Agent 可能要请求用户授权。如果是网络超时,Harness 就可以尝试先自动重试。如果是参数不合法,这时候应该让模型重新生成参数。

不同服务商 / 不同模型服务商返回的错误格式并不统一,因此 Harness 可以负责将这些错误转换成统一结构,并完成指数退避、备用工具调用和优雅降级等基础设施恢复。这样,模型接收到的是稳定、可理解的错误信息,就不需要在每次任务中重新推断某个底层 API 的错误含义。

除了错误处理,工具结果还需要和原始调用建立明确关联。当模型在同一轮中并行查询天气和时间时,两个返回结果必须分别绑定对应的调用 ID。否则,模型可能无法判断某个结果对应的是哪个工具调用,尤其是在并行工具调用或多 Agent 协作场景中。

ReAct 循环中的契约闭环

工具调用的输入输出契约,最终会嵌入 Agent 的 ReAct 循环。

模型会先根据工具定义生成结构化调用请求,等 Harness 校验完参数后会执行工具,再把调用工具的执行返回结果作为新的消息追加到上下文。这样,下一轮模型能看到自己此前发出的请求和工具返回的结果,并根据结果判断:是否继续调用工具?是否要修改参数重新调用工具?还是切换其他工具,生成最终回答?

Harness 层的校验职责

虽然结构化的 Schema 能帮模型生成调用工具的正确参数,但它不能代替运行时校验格式。模型生成的参数仍然存在越界、缺失或包含危险内容这些情况,所以在真正执行工具调用之前,Harness 需要再次检查参数是否合法、安全。

Harness 常见的校验工作包括:

  • 检查字段类型、必填项和枚举值;

  • 文件路径、SQL 和 Shell 参数的安全过滤;

  • 检查工具权限和副作用;

  • 请求用户确认高风险操作;

  • 确定执行时长、内存和调用次数限制;

  • 校验返回结果的 Schema;

  • 错误归一化与自动重试;

  • 工具调用参数、结果和时间戳的审计记录。

Harness 的校验并不是简单检查参数格式,而是在模型和真实环境之间增加一道安全边界。

在真正执行工具之前,Harness 和工具服务都要根据声明的 JSON Schema 对输入进行校验,并防范路径穿越、SQL 注入、命令注入、内部网络请求等风险。同时,工具还可以附带只读、破坏性、幂等性等属性注解,帮助 Harness 判断一次调用是否可以自动执行、是否支持安全重试,以及是否需要人工确认。

模型负责提出行动,Harness 负责保证这个行动符合工具契约。两者共同决定了一次工具调用能否从“参数格式正确”,进一步变成“执行过程安全可靠”。

结语

工具调用的输入输出契约,决定了 Agent 如何理解工具、调用工具以及根据结果继续行动。它不只约束参数格式,还需要明确工具能力、使用边界、执行结果和错误反馈。

对 Agent 来说,工具设计最终要回答三个问题:什么时候应该使用这个工具,调用时需要提供什么信息,执行后的结果应该如何理解。只有这些约定清晰,工具才能成为 Agent 可以稳定使用的能力。

#

相关文章
|
8天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2281 12
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
8天前
|
云安全 人工智能 安全
|
9天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1025 2
|
8天前
|
人工智能 自然语言处理 数据挖掘
最新版通义千问(Qwen3.8-Max-Preview)功能介绍
2026年,通义千问正式推出全新旗舰级大模型 **Qwen3.8-Max-Preview 预览版**,作为首款突破万亿参数规格的新一代基座模型,该模型总参数量达到**2.4万亿**,采用全新迭代的MoE混合专家架构,综合推理性能、长文本处理、多模态理解、复杂任务规划能力全面超越前代Qwen3.7-Max版本,整体实力跻身全球第一梯队,可对标海外顶级旗舰模型,是当前面向复杂工程开发、多智能体协同、超长文档解析、专业办公自动化场景的最优国产基座模型。
1062 0
|
10天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1027 44
|
7天前
|
自然语言处理 测试技术 API
通义千问Qwen3.8-Max-Preview全功能解析:2.4万亿参数旗舰模型深度使用指南
在大模型技术持续迭代的当下,通义千问推出的Qwen3.8-Max-Preview作为新一代旗舰预览版模型,凭借2.4万亿参数的超大规模、多模态融合能力与全场景适配特性,成为开发者与企业用户探索AI应用的核心工具。该模型采用稀疏混合专家(MoE)架构,是通义千问首个突破万亿参数的多模态模型,可同时处理文本、图像、视频与文档等多种数据形态,在全栈代码开发、复杂逻辑推理、长文档分析与多智能体协作等场景实现跨越式升级。本文将全面拆解Qwen3.8-Max-Preview的核心功能,详解API调用流程与配置方法,覆盖多场景实战技巧,帮助用户快速掌握这款旗舰模型的使用方法,充分释放其性能潜力。
510 1
|
7天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
576 0
|
10天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max 预览版全解析:2.4 万亿参数旗舰模型,Token Plan 限时优惠指南
Qwen3.8-Max-Preview是通义千问Qwen3系列旗舰MoE大模型,参数达2.4万亿,综合推理能力居行业第一梯队。支持思考/快速双模式,擅长大模型五大高难场景。现于阿里云百炼Token Plan、Qoder及QoderWork上线体验,个人版低至39元/月。在阿里云百炼官网:https://t.aliyun.com/U/fPVHqY 免费领取千万Tokens
705 1
Qwen3.8-Max 预览版全解析:2.4 万亿参数旗舰模型,Token Plan 限时优惠指南