工具调用是AI智能体从“能聊天”走向“能干活”的关键一步。但很多团队在搭建Agent系统时会发现一个扎心的现象:模型明明选对了工具,参数却填错了——该填数字的地方填了字符串,该留空的可选参数被模型自己编了个值出来,日期格式五花八门,枚举值压根不在候选列表里。这些问题表面上看是模型能力不行,本质上大多是提示词没有把参数约束讲清楚。本文就来聊聊如何围绕“精确参数提取”这一目标,设计一套结构化的提示词方案。

为什么工具参数提取总是出错
要解决问题,先得理解问题的来源。参数提取出错的根源通常有三个。第一,工具描述信息残缺。很多开发者写工具描述时只写了一句“查询订单信息”,参数说明全是空的,模型只能靠猜。大模型对参数的理解完全来自提示词中的描述文本,描述越模糊,模型自由发挥的空间就越大。
第二,参数约束没有形式化表达。比如一个参数要求格式为 YYYY-MM-DD,如果只在描述里轻描淡写地提一句,模型可能会输出“2024年1月5日”或者“01/05/2024”。约束必须用明确、可执行的规则写出来,而不是自然语言的模糊表达。
第三,缺少输出结构的强约束。如果提示词没有规定模型必须输出JSON且字段固定,模型就会倾向于输出一段自然语言,后端解析自然就失败了。参数提取的本质是一次结构化信息抽取任务,提示词必须把这个定位传递给模型。
参数提取提示词的核心结构设计
一份合格的参数提取提示词,通常包含四个部分:任务定位、工具定义、提取规则和输出格式。任务定位部分要明确告诉模型它的职责是提取参数,而不是回答问题,这一点能有效抑制模型“顺手回答用户”的冲动。
工具定义部分建议采用统一的Schema描述方式,把每个参数的名称、类型、是否必填、取值范围、格式要求、默认值都写全。下面是一个典型的工具定义提示词片段:
你是一个参数提取引擎,任务是从用户输入中提取工具调用所需的参数。 可用工具定义如下: 工具名称:query_order 工具描述:根据订单号查询订单的物流状态 参数列表: - order_id(必填,string) 说明:订单编号,格式为字母O开头加10位数字,如 O1234567890 - phone_suffix(可选,string) 说明:手机号后4位,用于身份校验,4位纯数字 - query_scope(可选,string,枚举值) 说明:查询范围,只能是以下值之一:logistics(物流)、payment(支付)、all(全部) 默认值:all
提取规则部分是最能体现功力的地方。建议把规则写成逐条列举的硬性约束,例如:参数值只能来自用户原话或明确的时间信息,禁止推测或编造;可选参数若用户未提及则不输出该字段;日期统一转换为YYYY-MM-DD格式;数字一律不加千分位。这些规则看起来琐碎,但每一条都对应着一种真实的错误场景。
输出格式部分则要求模型以固定结构的JSON返回,并明确“提取不到的必填参数对应字段填null”。这一点很重要,因为后续流程需要区分“用户没说”和“参数恰好是空字符串”这两种情况。
用Few-shot示例提升提取稳定性
光有规则还不够,模型对规则的理解往往需要示例来锚定。Few-shot示例的价值在于把抽象规则翻译成具体的输入输出对,尤其是要覆盖那些容易出错的边界场景。示例的选择很有讲究,建议至少包含四类:标准完整输入、参数缺失输入、带干扰信息的输入、格式需要归一化的输入。
下面这套示例直接放在提示词末尾,效果通常立竿见影:
示例1(完整输入):
用户输入:帮我查一下订单O9876543210的物流,手机尾号是5678
输出:{"order_id":"O9876543210","phone_suffix":"5678","query_scope":"logistics"}
示例2(可选参数缺失):
用户输入:查订单O1111222233
输出:{"order_id":"O1111222233","phone_suffix":null,"query_scope":null}
注意:可选参数未提及时不猜测,直接填null。
示例3(带干扰信息):
用户输入:昨天下午我在你们小程序下了个单,单号是O5566778899,顺便问下退货政策
输出:{"order_id":"O5566778899","phone_suffix":null,"query_scope":null}
注意:只提取工具所需参数,忽略无关问题。
示例4(格式归一化):
用户输入:查一下1月5号下的那个订单O1234000011的手机尾号后四位2333
输出:{"order_id":"O1234000011","phone_suffix":"2333","query_scope":null}这里有个实用技巧:在示例后面追加一句简短的“注意”说明,解释这个示例想强调什么。这相当于在教模型“这道题的考点是什么”,比单纯堆示例的效果好不少。实践中两到四个高质量示例通常就够了,示例太多反而会稀释关键规则的权重,还会占用宝贵的上下文窗口。
常见提取失败的排查与迭代方法
提示词不是写完就万事大吉,需要基于真实 badcase 持续迭代。排查时建议建立一个简单的分类习惯:先判断错误属于哪一类,再针对性修改。类型错乱(数字输出成字符串)通常是输出格式约束不够硬,可以在提示词里强调“JSON中所有字段类型必须与工具定义一致”;幻觉参数(编造用户没说的值)多半是缺少“禁止推测”的规则,或者few-shot里没覆盖参数缺失的场景。
枚举值越界是另一类高频问题,比如用户说“查支付信息”,模型却输出了"payment_status"这种自造词。解决办法是在枚举参数的描述里补充同义词映射,明确写出“用户说支付、付款相关时,填payment”。日期格式混乱则可以通过固定的转换规则加一个对应示例来解决。
还有一点容易被忽略:参数提取提示词应该与工具选择提示词解耦。让模型先决定调用哪个工具,再在第二步做纯参数提取,两步各自的任务更单一,准确率普遍比一步到位的混合提示词更高,排查问题时也更容易定位责任环节。如果条件允许,在提取结果送入工具执行前加一层程序化校验,用正则或JSON Schema验证参数合法性,校验不通过就把错误信息回传给模型重新提取,形成一个轻量的自我修正闭环。
总的来说,Agent工具参数填充的提示词设计没有玄学,核心就是把参数的约束条件写清楚、把容易错的场景做成示例、把输出格式钉死,再配合程序校验兜底。把这几件事做扎实,工具调用的成功率会有非常明显的提升。