欢迎光临
我们一直在努力

工程实践——手把手教你设计高质量的Skills

工程实践——手把手教你设计高质量的Skills

引言:写"好"的Skill是一门艺术

在大模型应用中,Skill的设计质量直接影响Agent的成功率。写得好的函数描述,模型一次就能正确调用;写得差的,模型可能永远选错工具,或者生成错误的参数。

本章将从实战角度,分享设计高质量Skills的原则、技巧和常见陷阱。

一、Skill定义的核心要素

无论你使用OpenAI的Function Calling、Claude的Tool Use,还是开源的模型,Skill定义都包含几个核心字段。以OpenAI格式为例:

{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的实时天气信息,包括温度、湿度、风速和天气状况",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'、'上海',请使用标准中文名称"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,celsius为摄氏度,fahrenheit为华氏度",
"default": "celsius"
}
},
"required": ["city"]
}
}
}

每个字段都有其作用:

  • name: 函数名称,应简短、清晰、符合语义
  • description: 最重要的字段,用自然语言描述函数的功能
  • parameters: 参数定义,使用JSON Schema格式
  • required: 必填参数列表

二、黄金原则:如何写出让模型"一次看懂"的函数描述

原则1:描述要详细,但不要啰嗦

不好的描述:

  • "获取天气"——太简单,模型可能不清楚它是否包含湿度、风力
  • "这是一个获取天气信息的函数,你可以调用它来查询任何城市的天气,包括温度、湿度、降水概率、风速、风向、日出日落时间等等,非常全面"——太啰嗦,关键信息淹没在文字中

好的描述:
"获取指定城市的实时天气信息,包括温度、湿度、风速和天气状况"

要点:用一句话清晰概括功能,并列举关键输出。这相当于给模型一个"函数能做什么"的心理模型。

原则2:参数描述要包含示例和约束

对于参数,模型需要知道两件事:这个参数是什么?应该填什么?

"city": {
"type": "string",
"description": "城市名称,如'北京'、'上海'、'New York',请使用标准城市名,不要使用缩写"
}

"如’北京’"给了模型示例,“不要使用缩写"给了模型约束。这能显著减少"B”、"BJ"这类无效输入。

原则3:善用枚举和默认值

当参数只有有限选项时,使用enum明确告诉模型可选值:

"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位",
"default": "celsius"
}

枚举值让模型不会生成"celcius"(拼写错误)或"摄氏度"(中文)等无效输入。默认值则告诉模型:如果用户没说,就用这个。

三、常见陷阱与解决方案

陷阱1:函数命名冲突

当你有多个函数时,避免名称过于相似。比如:

  • get_weather_by_city
  • get_weather_by_coordinates

如果命名不够区分,模型可能混淆。解决方案是在description中明确区分使用场景。

陷阱2:参数依赖关系

有些函数参数之间有依赖:比如需要start_date和end_date,或者city和country。JSON Schema本身支持有限的条件约束,但更好的做法是在description中说明:

"description": "查询指定日期范围的天气,如果只提供start_date,则默认查询当天"

陷阱3:返回结果过大

如果Skill返回大量数据(比如查询整个数据库),可能超出模型的上下文窗口。解决方案:

  • 在Skill设计时限制返回数量(如最多10条)
  • 设计分页参数(如page和page_size)
  • 让Skill返回摘要,而非全部详情

四、构建多Skill协作系统

当你的Agent拥有多个Skills时,如何让它们协同工作?以下是几种常见的架构模式:

模式1:平行调用 (Parallel Calls)

用户的一个请求可能需要多个工具。例如"帮我查北京天气,然后发邮件告诉小王"。

OpenAI支持同时调用多个函数(parallel_tool_calls)。模型可以一次输出:

[
{
"name": "get_weather",
"arguments": {"city": "北京"}
},
{
"name": "send_email",
"arguments": {"to": "小王", "content": "北京天气是…"}
}
]

系统并行执行这两个调用,然后将结果合并返回给模型。

模式2:链式调用 (Chained Calls)

有些任务有先后依赖。例如"北京明天适合户外活动吗?"需要:

  • 调用get_weather获取天气
  • 模型分析天气数据
  • 如果需要,再调用get_air_quality获取空气质量
  • 最后生成结论
  • 这种场景需要循环调用:模型根据前一个工具的结果,决定是否调用下一个工具。

    模式3:路由模式 (Router Pattern)

    当有几十个甚至上百个Skills时,让模型每次都在所有工具中选,效果会变差(选择的熵太高)。

    解决方案是设计一个路由Skill:先让模型在一个小集合(如10个类别)中选择,然后再进入对应的子Agent。这类似于客服电话先按1、2、3选择业务类型,再具体办理。

    五、调试与评估:如何衡量Skill的质量?

    最后,如何知道你的Skill设计得好不好?以下是一些评估指标:

    • 调用准确率:需要调用时,模型是否调用了?(召回率)
    • 参数正确率:调用时,参数是否完整、格式正确?
    • 选择错误率:本应用A工具,却选了B工具的频率?
    • 无效调用率:模型在不需要调用时却调用了的频率?

    你可以通过构建测试集(如100个典型用户问题),手动或自动标注每个问题应该调用哪些工具,然后运行Agent统计以上指标。

    下一章我们将追溯Skills概念的演变历史——从早期的Toolformer、ReAct,到OpenAI Function Calling的里程碑,再到今天Agent生态的百花齐放。这是一段激动人心的技术演进史。

    赞(0)
    未经允许不得转载:171主机测评 » 工程实践——手把手教你设计高质量的Skills
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址