工具设定决定Agent上限

工具设定决定Agent上限

很多Agent不是模型不行,而是工具设计太差

工具设计,直接决定Agent的能力上限

你给它一个含糊的工具,它就只能猜

你给它一堆粒度混乱的工具,它就会乱选

你给它一个返回值全是自然语言的工具,它下一步就没法稳定判断

工具不是API列表,而是Agent的行动边界

很多人一开始做工具调用,思路是这样的

"后端已经有一堆接口了,我把这些接口都注册给大模型,不就完事了吗"

这也是很多Agent项目失控的开始

后端API是给程序员用的

Agent工具是给模型决策用的

程序员调用API时,脑子里面知道业务含义、调用时机、参数来源、异常处理

模型不知道

模型看到的只是工具名、工具描述、参数Schema和历史上下文

如果你把一堆内部接口原样丢给模型,比如:

  • queryData
  • getInfo
  • submit

那他只能猜,所以工具设计的第一条原则就是:

工具不是把API暴露给模型,而是把可控动作封装成模型能理解、能选择、能恢复的能力

一个好的工具,至少要回答四个问题:

  • 这个工具能做什么
  • 什么时候应该使用它
  • 什么时候不应该使用它
  • 调用完之后,Agent能不能根据结果继续判断

如果这四个问题没回答清楚,Agent就会开始自由发挥

自由发挥听起来很智能,但是放在生产里面,就是不稳定

工具描述:不要只写"查询订单信息"

很多工具描述写的特别随意,比如:

复制代码
{
	"name":"get_order",
	"description":查询订单信息
}

这样的描述太浅了,模型看完只能知道这个工具能查订单

但是它不知道:

  • 查的是订单基础信息,还是支付、物理、退款状态
  • 用户只提供手机号时能不能用
  • 订单不存在时会返回什么
  • 这个工具适合排查什么问题
  • 他能不能替代退款工具

对人来说,"查询订单信息"也许够了

对于Agent来说,不够

因为Agent要靠描述判断"下一步该不该用它"

更好的描述应该这样写:

复制代码
{
	"name":"get_order_detail",
	"description":"根据订单ID查询订单的基础状态、支付状态和退款状态,适用于用户询问订单进度、支付是否成功"
}

好的工具描述不只是说"能做什么",还要说清楚"适用边界"

尤其是三类信息:

第一,工具能解决什么问题

比如"查询订单状态""查询接口延迟""检索知识库文档"

不要写"处理用户请求"

第二,工具不能做什么

比如查询工具不能修改数据

草稿工具不能直接发送消息

库存查询工具不能代表最终可购买数量

这个"不做什么" 很重要

因为Agent最怕把相似工具混在一起

第三,什么时候优先使用它

工具描述不是注释

工具描述就是Agent的使用说明书

参数设计:别把脏活都丢给模型

工具描述决定模型会不会选对工具

参数设计决定模型能不能把工具用对

很多Agent工具的参数设计很重要:

复制代码
{
	"name":"search_logs",
	"parameters":{
	"query":"string"
	}
}

看起来很灵活,实际上很危险,因为你把所有的脏活都丢给模型,模型要自己决定:

  • 查哪个服务
  • 查哪个时间段
  • 查什么日志级别
  • 查哪些关键词
  • 返回多少条

这就很容易出问题,他可能把时间写成"昨天晚上"

它可能查了太宽的范围,导致工具超时

可能查了太窄的范围,什么都查不到

更好的方式,是把参数拆清楚:

复制代码
{
  "name": "search_service_logs",
  "description": "查询指定服务在固定时间范围内的日志,用于排查接口错误、超时和异常调用链。",
  "parameters": {
    "type": "object",
    "properties": {
      "service_name": {
        "type": "string",
        "description": "服务名称,例如 payment-service"
      },
      "start_time": {
        "type": "string",
        "description": "查询开始时间,格式为 YYYY-MM-DD HH:mm:ss"
      },
      "end_time": {
        "type": "string",
        "description": "查询结束时间,格式为 YYYY-MM-DD HH:mm:ss"
      },
      "level": {
        "type": "string",
        "enum": ["ERROR", "WARN", "INFO"],
        "description": "日志级别,排查故障时优先使用 ERROR 或 WARN"
      },
      "keyword": {
        "type": "string",
        "description": "可选关键词,例如接口路径、错误码或 traceId"
      }
    },
    "required": ["service_name", "start_time", "end_time", "level"]
  }
}

这样Agent就不会随便编一个大字符串

必须按照结构填参数

这就是参数Schema的价值

它不是为了让接口看起来高级

他是为了模型的自由度约束在合理范围内

参数设计有几个很实用的原则:

能枚举就枚举

比如日志级别、订单状态、排序方式、操作类型

能用enum,就不要让模型自由填字符串

自由字符串看似灵活,但很容易出现:

  • err
  • error
  • ERROR_LOG

后端还要做一堆兼容

枚举能减少很多不必要的不稳定

时间、数量、范围要明确

Agent很喜欢写模糊表达

  • 最近
  • 做完
  • 前几天

这些对人能理解,对工具不稳定:

工具参数里最好要求明确格式:

  • start_time
  • end_time
  • limit
  • sort_by

同时加上默认上限,这些限制不是小题大做,而是防止Agent一次调用把系统拖垮

不要让一个参数承担多个含义

比如:

复制代码
{
	"user_input":"帮我查一下张三昨天的订单"
}

这个参数就太混乱,里面混了用户、时间、对象和意图

工具端还要再做一次理解,如果工具本身还要靠大模型再解析,那你就把不确定性叠了两层

更好的方式是拆开:

  • user_name
  • data
  • query_type

参数越清楚,Agent越稳定

缺关键参数时,不要让模型硬编

缺少必要参数时,先向用户询问

返回值设计:别只返回一段自然语言

很多人只重视工具入参,不重视工具返回值

这也很容易出现问题

比如一个订单查询工具返回:

复制代码
{
	"result":"订单已经支付,目前正在仓库处理中,预计明天发货"
}

人看当然没问题,但是Agent下一步要怎么判断?

工具返回值的设计,至少要包含三类信息

第一,状态字段

比如:

  • success
  • status
  • error_code
  • order_status
  • risk_level

状态字段让Agent能做分支判断

第二,证据字段

比如:

  • 数据来源
  • 命中文档
  • 查询时间范围
  • 监控指标
  • 日志片段ID

证据字段让Agent的最终回答不只是猜,他能说:"我根据什么得出这个结论"

第三,下一步提示

比如:

复制代码
{
  "suggested_next_actions": [
    "如果用户询问物流单号,可以调用 get_shipping_detail",
    "如果用户要求取消订单,可以先调用 check_cancel_policy"
  ]
}

这个字段不是必须的,但是在复杂的Agent里面很有用

他不是替代Agent做决定,而是给Agent一个可靠的行动提示

尤其是业务系统里面,不同状态对应不同后续动作

把这些动作提示词写在工具返回里面,比让模型凭空猜稳定很多

工具粒度:太细会跑断,太粗会失控

工具粒度,是Agent设计里面最容易纠结的问题

工具应该设计的细一点,还是粗一点

答案是:都不能太极端

工具太细,Agent会被迫做大量低级决策

比如你给Agent这些工具:

  • get_user_id_by_phone
  • get_order_ids_by_user_id
  • get_order_base_info

这些工具单看都没问题

但是如果用户只是问:"我买的东西为啥还没发货"

Agent可能需要连续调用五六次,中间任何一步参数错了、结果空了、状态没记录好,后面就断了

工具太细,会让Agent变成一个脆弱的流程编排器

模型需要做太多机械步骤

这不是它擅长的

工具太粗,Agent又看不见过程

另一种极端是:

  • handle_order_problem
  • solve_user_issue
  • process_after_sales

这种工具太粗,Agent调用之后,里面到底在做什么,他不知道,返回一个"处理成功",它也不知道成功在哪里,出错了,也不知道是订单不存在、支付失败、库存不足

工具太细,Agent表面上很省事但是系统会变成黑盒,不可解释,也不好调试

合理粒度:围绕一个业务动作封装

一个工具完成一个清晰的业务动作,并返回可判断的结构化结果

工具粒度是要介于底层API和完整业务流程之间的,太细会增加多步调用失败库,太粗会降低可控性和可解释性。

有副作用的工具,必须单独设计边界

Agent工具大致可以分为两类

查询类工具和动作类工具

查询类工具只读数据,比如查订单、查日志、查监控、查知识库

动作类工具会改变外部世界

比如发邮件、提交退款、修改配置

这两类工具绝对不能混在一起设计

因为风险完全不一样,查询错了,最多答案不准

动作错了,就可能直接造成业务事故

所以有副作用的工具,至少要加三层保护

读写工具分开

不要设计这种工具:

复制代码
{
	"name":"handle_refuse",
	"description":"处理退款问题"
}

它太模糊了,处理退款到底是查规则还是直接提交退款

更好的设计是拆开:

  • get_order_detail
  • check_refund_policy
  • create_refund_draft
  • submit_refund_after_user_confirm

读是读,写是写,草稿是草稿

边界越清楚,越不容易出事故

高风险动作必须二次确认

凡是会影响钱、权限、数据、通知、生产环境的操作,都不要让Agent单独决定

比如:

  • 退款
  • 扣费
  • 删除数据
  • 发送正式邮件
  • 改生产配置

这些操作之前,应该让Agent生成草稿或者执行计划

然后让用户确认,再调用真正的执行工具

这不是智不智能,这是工程安全

一个成熟的Agent系统,必须知道什么时候停下来让人确认

工具返回要记录审计信息

动作类工具返回值里面,最好包含:

  • 操作人
  • 操作对象
  • 操作时间
  • 操作前的状态
  • 操作后的状态
  • 审计ID
  • 是否需要人工复核

这样的Agent后续回答就不会说:我已经退款

而应该说:我已经创建退款申请草稿,需要你确认后才会正式提交

这就是工具边界带来的稳定性

错误信息要能让Agent恢复

很多工具失败时,返回值只有一句:

复制代码
{
  "success": false,
  "message": "系统异常"
}

这对Agent没什么帮助

他不知道接下来该重试、换参数、换工具,还是告诉用户稍后重试

好的错误返回,应该能帮助Agent恢复

Agent可以根据错误类型决定下一步:

  • 缺参数,就追问用户
  • 时间范围太大,就缩小范围
  • 权限不足,就说明无法执行
  • 工具超时,可以有限重试

错误信息不要只给人看,也要给Agent看,如果工具失败后,Agent无法恢复,它就很容易乱编一个答案

很多幻觉不是从模型生成开始的,而是从工具返回值太差开始的

不要一次性把所有工具都塞给Agent

工具越多,Agent越强,不一定

工具越多,选择空间越大,选错概率也就越高

如果你把订单、物流、退款、财务、监控等等全部塞给Agent,它每一步都要在几十个工具里面选择

这对模型不是增强,这是干扰

更好的方式是按照任务动态收敛工具集

比如客服Agent处理订单问题时,只给它:

  • 订单查询

  • 物流查询

  • 退款规则查询

  • 退款草稿创建

  • 用户追问工具

排查故障时,只给它:

  • 监控查询
  • 日志查询
  • 发布记录查询
  • 链路追踪查询

写代码可以告诉它:

  • 文件读取
  • 代码搜索
  • 测试执行
  • 补丁编辑

工具集不是越大越好

工具集要和当前任务相关

这点和Agent vs Workflow是连接的

Workflow 可以先判断任务类型,再给Agent分配对应工具箱

外层流程负责收口,内部Agent负责开放搜索

工具设计不好,Agent会出现哪些症状

判断工具设计有没有问题,不用玄学

看Agent的行为就知道

如果经常出现下面这些情况,大概率是工具设计有问题

经常选错工具

比如用户问退款规则,agent却直接查物流

这通常是工具描述太像,边界不清晰

解决方式是把每一个工具的使用场景和不适用场景写清楚

参数经常填错

比如时间格式错误、枚举填错、ID类型错误

这些通常是参数Schema太松

解决办法是收紧类型、枚举、必填项和格式说明

调用后不知道下一步

工具返回一大段自然语言,Agent看完继续猜

这通常是返回值没有状态字段和证据字段

解决方式是返回结构化结果

一直重复调用同一个工具

比如知识库没搜到,还连续搜索好几次

这通常是缺少失败语义和停止条件

解决方式是在返回值里面标记无结果原因,并提示下一步应该追问用户或换策略

做了不该做的动作

比如用户只是咨询退款,agent却直接提交退款

这通常是读写边界不清,没有二次确认

解决方式是拆分查询、草稿和正式执行工具

这些问题表面是Agent不稳定,底层经常是工具契约没设计好

相关推荐
每天都要写算法(努力版)2 小时前
【行业前沿报告】SCoRe:为什么会改答案,还需要专门训练
agent·agent 轨迹
for_ever_love__2 小时前
概率与统计——分布、期望与贝叶斯,语言模型的建模基础
python·机器学习·大模型·概率论
zmsup2 小时前
从运维需求到产品能力:OpsArk Agent 的运维智能平台架构设计思路
运维·系统架构·agent·智能体·运维智能平台
智码看视界2 小时前
开源大模型每日追踪:小米 MiMo-V2.6-Pro,登顶开放权重第一(超过 GLM-5.3 、Kimi K3)
agent·vllm·moe·全模态·小米大模型·mimo-v2.6
Together_CZ2 小时前
UFO : A UI-Focused Agent for Windows OS Interaction——面向Windows操作系统的UI聚焦智能体
agent·ufo·面向windows操作系统·ui聚焦智能体·agentos·ui-focused·os interaction
艾莉丝努力练剑3 小时前
【AI大模型接入SDK】C++ ChatSDK使用手册
开发语言·网络·c++·人工智能·学习·大模型
寻道码路11 小时前
大模型工程化实战(十六):政企国产化避坑——合规/信创名录/私有化运维/国产硬件适配/原厂支持这五道关怎么过
大模型·agent·信创·rag·ai工程化·国产化替代·政企ai落地
OxYGC13 小时前
玩转大模型(一):参数、token、FLOPs 怎么算,提示词/RAG/微调/续训/Agent 怎么选
大模型·模型微调·rag·智能体·提示词工程
张忠琳14 小时前
【hermes-agent】Hermes Agent 自我进化原理之一
ai·agent·hermes