news 2026/7/15 22:36:48

Function Calling 工具描述优化:怎么写工具说明让模型更准确

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Function Calling 工具描述优化:怎么写工具说明让模型更准确

Function Calling 工具描述优化:怎么写工具说明让模型更准确

一、"模型总是选错函数"的背后是描述写得像猜谜

Agent 有query_orderquery_order_detail两个函数。用户说"帮我查一下订单",模型有 60% 的概率选错函数。原因很简单:两个函数的 description 分别是"查询订单"和"查询订单详情"——从人类角度看区别够明显,但对模型来说,这两个描述太像了。

工具描述的写法直接影响 Function Calling 的准确率。模型是根据描述来判断"什么时候该调用哪个函数"的。描述写得好,准确率可以从 60% 提升到 90% 以上。

二、工具描述的黄金结构

一个高质量的工具描述应该包含五个要素:

  1. 功能动词:一句话说清楚这个函数做什么
  2. 使用场景:什么情况下该用这个函数(帮助模型做选择)
  3. 输入说明:需要什么参数才能正确调用
  4. 输出说明:调用后会返回什么
  5. 反面示例:什么情况下不该用这个函数
flowchart LR A[工具描述] --> B[功能: 一句话总结] A --> C[场景: 何时使用/何时不用] A --> D[输入: 参数要求] A --> E[输出: 返回什么] A --> F[示例: 正确调用示范] B --> G[模型快速判断函数用途] C --> H[避免选错函数] D --> I[准确填充参数] E --> J[模型知道如何使用结果] F --> K[减少调用格式错误]

三、Python 实现:描述质量评估与自动优化

from dataclasses import dataclass from typing import Optional import re @dataclass class ToolDescription: """工具描述结构体""" name: str function_summary: str # 功能概述(1句话) use_cases: list[str] # 使用场景 not_use_cases: list[str] # 不应使用的情况 input_requirements: str # 输入参数说明 output_description: str # 输出说明 examples: list[str] # 调用示例 # ========== 坏 vs 好的描述对比 ========== bad_descriptions = { "query_order": { "description": "查询订单", # ❌ 太简短,无区分度 "parameters": { "order_id": {"type": "string", "description": "订单号"}, }, }, "query_order_detail": { "description": "查询订单详情", # ❌ 和上一个几乎一样 "parameters": { "order_id": {"type": "string", "description": "订单号"}, }, }, } good_descriptions = { "query_order": { "description": ( "查询用户的订单列表,支持按时间和状态筛选。" "当用户想查看「最近订单」「所有订单」或按条件筛选订单时使用。" "注意:如果用户要查看单个订单的详细信息(如物流、商品明细)," "请使用 query_order_detail。" "返回订单列表(ID、金额、状态、时间),不包含商品细节。" ), "parameters": { "status": { "type": "string", "enum": ["pending", "paid", "shipped", "completed"], "description": ( "订单状态筛选,可选。" "不提供时返回所有状态的订单。" "注意:'已完成'应使用'completed'而非'done'" ), }, "limit": { "type": "integer", "description": ( "返回条数,默认10,最大50。" "超过50会自动截断为50" ), "default": 10, }, }, }, "query_order_detail": { "description": ( "查询单个订单的完整详情,包括商品明细、物流状态、支付详情。" "仅在用户指定了具体订单号或明确说「查看订单详情」时使用。" "不要用于批量查询订单列表——批量查询请使用 query_order。" "返回完整的订单信息(商品、物流、支付、发票等)。" ), "parameters": { "order_id": { "type": "string", "description": ( "订单号,格式为 ORD-年月日-流水号。" "例如: ORD-20260715-0001。" "如果用户提供了不完整的订单号,请先向用户确认" ), }, }, }, } # ========== 描述质量评分器 ========== class DescriptionScorer: """工具描述质量评分""" @staticmethod def score(description: str, parameters: dict) -> dict: score = 0 details = [] # 1. 长度检查:要有足够信息量 if len(description) > 30: score += 20 details.append("描述长度充足 (+20)") elif len(description) > 10: score += 10 details.append("描述长度一般 (+10)") else: details.append("描述过短 (-0)") # 2. 区分度关键词:是否包含"注意/不要/请使用" if any(kw in description for kw in ["不要", "请使用", "注意"]): score += 15 details.append("包含区分度关键词 (+15)") else: details.append("缺少区分度关键词 (-0)") # 3. 场景说明:"当用户...时使用" if "当用户" in description or "用于" in description: score += 15 details.append("包含使用场景 (+15)") # 4. 输出说明:"返回..." if "返回" in description: score += 15 details.append("包含输出说明 (+15)") # 5. 参数描述质量 param_score = 0 for name, param in parameters.items(): param_desc = param.get("description", "") if len(param_desc) > 15: param_score += 5 if "例" in param_desc or "例如" in param_desc: param_score += 5 score += min(param_score, 25) details.append(f"参数描述质量 (+{min(param_score, 25)})") # 6. 检查是否有枚举约束 for param in parameters.values(): if "enum" in param: score += 5 details.append("参数使用 enum 约束 (+5)") break return {"score": min(score, 100), "details": details} # ========== 描述优化提示模板 ========== OPTIMIZATION_PROMPT = """ 你是一名 API 文档专家。优化以下 Function Calling 的工具描述。 当前描述: {current_description} 优化规则: 1. 功能概述:用一句话说清楚做什么 2. 使用场景:什么时候该用这个函数 3. 排除场景:什么情况下不该用(避免和相似函数混淆) 4. 输入说明:需要什么参数 5. 输出说明:返回什么 优化后的描述(只需返回描述文本): """

四、描述优化的边界与经验法则

不要让描述太长。150-300 字是最佳范围。太短模型无法区分函数,太长模型会"忘记"前面的约束。超过 300 字的描述,模型对后半部分的注意力权重会显著下降。

参数描述比函数描述更重要。模型看到函数描述后有 30% 的可能选对函数,但参数描述的质量直接决定能否正确填充。参数描述应该包含:类型说明 + 格式示例 + 默认行为 + 边界说明。

反面示例比正面示例更有效。在描述中说"不要用于..."比"用于..."更能帮助模型区分相似函数。这利用的是模型对否定信息的注意力偏差。

描述需要迭代优化。写完描述后端到端测试 100 个真实查询,统计错误调用率。针对错误率高的函数,分析是什么原因导致模型选错或填错,针对性修改描述。

五、总结

Function Calling 工具描述的核心法则是"让模型在不确定时能做出正确判断"。五要素结构(功能/场景/输入/输出/反例)是底线。参数描述要带格式示例,函数描述要含排除场景。描述的质量不是"写出来就觉得好",而是"测 100 条查询,错误率低于 5% 才算通过"。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 22:32:09

LangChain Agent 执行图可视化:用 Mermaid 自动生成 Agent 的运行时流程图

LangChain Agent 执行图可视化:用 Mermaid 自动生成 Agent 的运行时流程图 一、深度引言与场景痛点 调试 LangChain Agent 最让人头疼的事,不是它报错,而是它不报错却给了错误答案。你看不到它在每一步调用了什么工具、传了什么参数、工具返回…

作者头像 李华
网站建设 2026/7/15 22:31:58

企业级AI开发框架选型参考

当下不少团队在搭建自身AI能力体系时,往往会陷入零散拼接各类开源组件的误区,不仅适配成本高,后续迭代维护也很难跟上业务的实际需求。向量空间JBoltAI作为完全基于Java生态构建的企业级AI开发框架,围绕企业AI应用落地的核心痛点&…

作者头像 李华
网站建设 2026/7/15 22:31:41

用A4纸识别偏见:最简可行的决策校准法

1. 项目概述:这不是“讲概念”,而是带你看清偏见如何在你眼皮底下悄悄运作“Understanding Bias in the Simplest Plausible Way”——这个标题乍看像一句教学口号,但在我过去十年带团队做用户研究、设计AI产品、培训一线业务人员的过程中&am…

作者头像 李华
网站建设 2026/7/15 22:28:30

卷积核如何提取图像特征:从数学定义到PyTorch底层实现

1. 这不是数学考试,是让卷积“活”起来的实操课你打开一篇讲卷积神经网络的教程,第一页就看到积分符号、星号运算符、翻转滑动求和——瞬间头皮发紧。我试过三次:第一次硬啃公式,卡在“为什么非要翻转核”,第二次看动画…

作者头像 李华