做 AI 应用必懂:Function Call 和 Skills,到底差在哪?
<h2 id="前言">前言</h2><p>今天来详细讨论一下,function call 和 skills。function call 到底是什么,skills 到底是什么,它们分别解决什么问题,最本质的区别在哪,以及在 Agent 系统里该怎么配合</p>
<h2 id="function-call">function call</h2>
<p><img alt="illustration-01" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260414101130163-30467701.png" class="lazyload"></p>
<p>function call 的本质,是让模型以工程化的方式调用某个具体工具或函数</p>
<p>以前模型想调用外部能力,通常只能口头表达——比如它输出一句:“请帮我查询北京天气”。对机器来说器,不知道这是普通文本,还是一个真正的调用指令</p>
<p>而 function call 出现之后,事情就不一样了。开发者会提前告诉模型:</p>
<ul>
<li>这里有一个函数,叫 <code>get_weather</code></li>
<li>它需要参数,比如 <code>city</code></li>
<li>参数类型是什么</li>
<li>返回结果可能是什么结构</li>
</ul>
<p>于是模型在需要时,就不再输出一大段自然语言,而是输出一份结构化调用意图,比如:</p>
<pre><code class="language-json">{
"name": "get_weather",
"arguments": {
"city": "Beijing"
}
}
</code></pre>
<p>这时候,模型就知道:不是聊天,是要真调用工具了</p>
<h4 id="function-call-解决什么问题">function call 解决什么问题</h4>
<p>它主要解决的是:</p>
<p>1)模型如何准确发起一次工具调用,明确告诉系统:调用哪个函数、传哪些参数</p>
<p>2)模型输出如何变成机器可执行的动作,自然语言适合人看,不适合程序稳定处理,结构化调用才方便程序使用</p>
<p>3)减少非结构化输出带来的歧义,参数格式统一了,系统更容易校验、重试、记录日志</p>
<h4 id="function-call-的典型特征">function call 的典型特征</h4>
<p>1)粒度小,通常代表一个具体动作,比如搜网页、读文件、查天气、写数据库</p>
<p>2)接口清晰,强调参数 schema、字段类型、必填项、返回值结构</p>
<p>3)偏执行层,关注的是怎么把这个动作调用出来</p>
<p>说白了,function call 更像是给模型装上一个标准化插口。模型通过这个插口,去调用外部世界的具体能力</p>
<h2 id="skills">skills</h2>
<p><img alt="illustration-02" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260414101138254-1949376756.png" class="lazyload"></p>
<p>我们之前讨论过skills,如果说 function call 解决的是怎么调用一个工具,那 skills 则是解决问题的方法、标准做法、固定流程和能力包</p>
<p>它本质上是在告诉模型:</p>
<ul>
<li>什么时候该接这个活</li>
<li>接到这个活之后先干什么</li>
<li>先查哪些资料</li>
<li>哪些步骤不能省</li>
<li>哪些坑不要踩</li>
<li>最终产出应该长什么样</li>
</ul>
<h4 id="skills-解决什么问题">skills 解决什么问题</h4>
<p>它主要解决的是:</p>
<p>1)面对复杂任务时,模型怎么少走弯路,不是让模型临场 freestyle,而是给它一套更稳的执行章法</p>
<p>2)一个任务做多了,总会形成套路。skills 的意义,就是把这些套路变成可复用的说明书</p>
<p>3)让结果更稳定,同样一个任务,有经验的人做出来通常更靠谱。skills 就是在给模型补这个经验层</p>
<h4 id="skills-的典型特征">Skills 的典型特征</h4>
<p>1)粒度更大,它通常对应一类任务,而不是单个动作</p>
<p>2)包含方法论,它不只调用什么工具,还会遵循步骤:先后顺序是什么、质量标准是什么</p>
<h2 id="核心区别">核心区别</h2>
<p><img alt="illustration-03" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260414101147412-1529216484.png" class="lazyload"></p>
<ul>
<li>
<p>粒度不同</p>
<ul>
<li>
<p>function call 往往对应一次具体能力调用,比如</p>
<ul>
<li><code>read_file</code></li>
<li><code>search_web</code></li>
<li><code>write_doc</code></li>
<li><code>send_message</code></li>
<li>function call 是原子动作</li>
</ul>
</li>
<li>
<p>skills:对应一类任务的完整做法,比如:</p>
<ul>
<li>检查线上事故</li>
<li>总结 URL</li>
<li>诊断 node 配对失败</li>
<li>skills 是复合能力</li>
</ul>
</li>
</ul>
</li>
<li>
<p>关注点不同</p>
<ul>
<li>
<p>function call:调哪个函数、传什么参数、参数是否合法、返回值怎么接,它更像接口设计问题</p>
</li>
<li>
<p>skills:任务开始需要干什么、哪些信息必须先拿到、中间怎么组织步骤、最终结果怎样,它更像经验与流程设计问题</p>
</li>
</ul>
</li>
<li>
<p>表达形式不同</p>
<ul>
<li>
<p>function call:function call 通常表现为一份结构化接口定义。比如:</p>
<pre><code class="language-json">{
"name": "web_search",
"description": "Search the web using DuckDuckGo",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"},
"count": {"type": "integer"}
},
"required": ["query", "count"]
}
}
</code></pre>
<ul>
<li>做技术的看到这个应该是非常亲切的,一看就懂:就是告诉模型怎么按格式调用</li>
</ul>
</li>
<li>
<p>skills:现在常见的形式为使用markdown格式,通常包含自然语言、结构化接口、执行层部分,自然语言层通常用于与llm交流,结构化接口通常用来 获取固定格式的数据,执行层通常用来决定该skill是用来干嘛的</p>
<pre><code>my-skill/
├── skill.md # 描述 & 参数定义
├── handler.py # 执行逻辑
└── requirements.txt# 依赖(可选)
</code></pre>
</li>
</ul>
</li>
</ul>
<h2 id="实际场景">实际场景</h2>
<p><img alt="illustration-04" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202604/1416773-20260414101157693-895633432.png" class="lazyload"></p>
<p>在排查线上故障这件事里,function call 可以提供很多底层能力,比如:</p>
<ul>
<li>读应用日志、网关日志、容器日志、服务配置文件</li>
<li>查 CPU、内存、RT、QPS、错误率、线程数等监控数据</li>
<li>查历史故障记录、排障文档、变更说明、已知问题列表</li>
<li>调用诊断接口、查看发布记录、触发一次有限范围的健康检查</li>
</ul>
<p>而 skills 在这个场景里负责的,就不是看哪份日志了,而是:</p>
<ul>
<li>先确认故障范围,到底是单机异常、单服务异常,还是整条链路出了问题</li>
<li>优先排查高概率路径,比如先看是否有发布、依赖超时、流量突增、资源打满等常见问题</li>
<li>把监控、日志、变更记录等多维数据一起排查</li>
<li>根据现象、日志、监控记录等诸多客观数据确定原因</li>
<li>下一步止损方案、建议动作等</li>
</ul>
<p>所以将两者一起工作,对互相擅长的东西进行互补,大大提高效率</p>
<h2 id="总结">总结</h2>
<p>function call 和 skills,看起来都在帮助模型干活,但它们解决的不是同一个问题</p>
<p>function call 解决的是:调用哪个工具、传什么参数、怎么把动作结构化执行出来<br>
skills 解决的是:这类任务应该怎么做更稳、步骤怎么组织、哪些经验和约束需要提前沉淀</p>
<p>让 function call 和 skills 各司其职。该提供工具的时候提供工具,该沉淀经验的时候沉淀经验</p>
<h2 id="联系我">联系我</h2>
<ul>
<li>联系我,做深入的交流</li>
</ul>
<p><img alt="" width="500" height="200" loading="lazy" src="https://img2024.cnblogs.com/blog/1416773/202411/1416773-20241121135740959-1907948957.png#" class="lazyload"></p>
<p>至此,本文结束</p>
<p>在下才疏学浅,有撒汤漏水的,请各位不吝赐教...</p>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自博客园,作者:it排球君,转载请注明原文链接:https://www.cnblogs.com/MrVolleyball/p/19865649</p>
<div>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。 </div><br><br>
来源:https://www.cnblogs.com/MrVolleyball/p/19865649
頁:
[1]