AI Agent工具能力深度解析:Function Calling、MCP与Skills的差异及应用

深入解析AI Agent工具能力:Function Calling是基础,MCP解决集成问题,Skills实现流程自定义。文章还讨论了MCP与Skills的竞争关系以及Lynxe的实践。

原文标题:AI Agent系列|深入解析Function Calling、MCP和Skills的本质差异与最佳实践

原文作者:阿里云开发者

冷月清谈:

本文深入探讨了AI Agent中Function Calling、MCP和Skills这三个核心概念。Function Calling是AI Agent调用外部工具的基础,它实现了LLM将非结构化指令转化为结构化函数调用的能力。 MCP(模型上下文协议)旨在解决Function Calling框架下工具集成成本高的问题,通过提供一套标准化的接驳协议,降低了LLM与既有系统集成的复杂度。而Skills则进一步发展,允许用户以文字而非代码的方式定义指令、脚本和资源,形成可复用的任务流程,从而更灵活地指导模型执行任务。文章还分析了MCP与Skills之间的竞争关系,并指出了当前Skills方案在需求精确描述和既有系统集成方面的不足。最后,文章引出Lynxe的Func-Agent思路,强调通过函数式接口暴露Agent能力,实现Agent与现有系统的更紧密集成,打破Agent仅限于对话框交互的局限。

怜星夜思:

1、Function Calling、MCP和Skills,你认为哪一个对于AI Agent的未来发展更重要?为什么?
2、文章中提到Skills的需求描述部分不够结构化,容易导致sub-agent无法获得充分的信息,你有什么解决这个问题的思路吗?
3、文章最后提到了Lynxe的Func-Agent思路,你觉得这种将Agent能力函数化的方式,在实际应用中会带来哪些好处和坏处?

原文内容

阿里妹导读


本系列文章基于 Lynxe 作者沈询的实战经验,深入浅出解析 ReAct Agent 的核心原理与工程价值,帮助开发者快速掌握从“写流程”到“造智能体”的关键跃迁。

关于这个系列

作为 Lynxe(原JManus)的作者,我花费了很多课余时间来完善这个Func-Agent框架,也因此对于什么是ReAct Based Agent 有了更深一些的理解。

所以想把这些内容总结出来,是因为这个项目本身核心目的就是探索Agent的前沿最佳实践,目前已经有所小成,Lynxe能解决我自己面对的80%以上的问题了,所以我觉得值得把我实验下来有效的东西写出来,方便大家快速入门。

你可以访问 Lynxe(菱科斯)阅读详细源码来学习agent的一些最佳实践。这是一个非常完善的产品级的 Func-Agent框架。

https://github.com/spring-ai-alibaba/Lynxe

系列计划

  • 深入解析Function Calling、MCP和Skills的本质差异与最佳实践 (本篇)

  • 上下文管理的一些实践

  • 并行执行的最佳实践与我走过的弯路

在前面的文章中,我们介绍了什么是 ReAct Agent,以及 Agent 与传统编程、Workflow 的本质区别。

现在我们来聊聊一个大家广为谈论的话题:AI Agent 的工具能力是什么?Function Calling、MCP 和 Skills 这三者有什么区别?它们背后的核心原理是什么?

一句话总结

  • Function Calling:AI Agent 调用工具的基础能力,也是后面两个能够存在的基础。

  • MCP (Model Context Protocol):由 Anthropic 推动的开放标准,为 LLM 应用提供标准化接口以连接和交互外部数据源和工具,现已捐赠给linux基金会。

  • Skills:Anthropic Claude的一个新的尝试,可以允许用户更细致的用文字定义指令、脚本和资源,跟MCP有竞合关系,我们后面会从不同角度来阐述这个竞合关系(虽然很多人认为是互补,但实际上,这两个是竞争关系更大一些)。

为什么需要这些技术:理解工具调用的基础

要讲明白为什么这几个概念是竞合关系,我们需要先简单了解一下AI Agent工具调用的基本原理。

AI Agent工具调用的基本流程

一个典型的AI Agent工具调用流程是这样的:

1、LLM接收用户请求和工具描述

  • 用户提出需求(比如"帮我查一下北京今天的天气")

  • 系统向LLM提供可用工具的列表和描述(比如"天气查询工具:可以查询指定城市的天气信息")

2、LLM决定是否需要调用工具

  • LLM根据用户需求和工具描述,判断是否需要调用工具

  • 如果需要,LLM会生成结构化的工具调用请求

这里的关键是LLM返回的是结构化的JSON格式,而不是自然语言。比如用户说"帮我查一下北京今天的天气",LLM可能会返回:

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"北京\", \"date\": \"today\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

这种结构化的输出格式,就是Function Calling的核心机制。它让系统能够稳定地解析LLM的意图,而不需要复杂的文本解析逻辑。注意关键字段:

  • tool_calls:当需要调用工具时,这里包含工具调用的信息;

  • function.name:要调用的工具名称;

  • function.arguments:工具的参数(JSON字符串格式);

3、系统解析并执行工具调用

  • 系统解析LLM生成的工具调用请求;

  • 执行对应的工具函数(比如调用天气API);

  • 获取工具执行结果 还是以上面的llm返回为例;

上面的JSON格式会被系统解析并转换为真正的函数调用。以JavaScript为例:

// 1. 从LLM响应中提取工具调用信息
const toolCall = response.choices[0].message.tool_calls[0];
const functionName = toolCall.function.name;  // "get_weather"
const functionArgs = JSON.parse(toolCall.function.arguments);  // {city: "北京", date: "today"}

// 2. 根据工具名称找到对应的函数
const tools = {
  get_weather: (city, date) => {
    // 执行天气查询逻辑
    return 北京今天天气:25°C,晴天;
  },
  // … 其他工具
};

// 3. 执行工具调用
const result = tools[functionName](functionArgs.city, functionArgs.date);
// 实际调用:tools"get_weather"

这个过程是自动的:系统根据function.name找到对应的函数,解析function.arguments获取参数,然后执行调用。这就是Function Calling让工具调用变得可预测和可靠的核心机制。

4、将结果返回给LLM

  • 工具执行结果被返回给LLM;

  • LLM根据结果决定下一步行动(继续调用工具,或者生成最终回答)。

小结:工具调用的本质

这个流程的核心在于:LLM需要把用户的非结构化需求(一段自然语言文本)转换为结构化的函数调用(函数名和参数),然后与其他应用程序交互,再将结构化结果返回给模型,让模型能够基于这些结果进行下一步决策。

问题的本质在于,历史上其他系统(数据库、API、文件系统等)只能处理结构化信息,而LLM擅长处理非结构化信息(文本)。因此,LLM必须想办法在两种信息形式之间架起桥梁:将非结构化的用户需求转换为结构化的函数调用,这样才能与外部系统交互。

这就是Function Calling的本质,也是后面MCP和Skills能够存在的前置条件。

既然有了工具调用,为什么又会有MCP和Skills呢?

Function Calling确实解决了核心问题:让LLM能够稳定地输出结构化的工具调用请求,实现了"非结构化→结构化"的转换。这是AI Agent工具能力的基础。

但在实际应用中,开发者很快发现了一个新的问题:工具集成成本太高。

Function calling会有工具集成成本高的问题

现实世界中,有大量的既有系统和数据:数据库里存储着业务数据,文件系统里有各种文档和代码,GitHub上有项目仓库和Issue,dingding里有团队沟通记录,还有各种API服务提供实时数据。这些既有系统里有着丰富的信息,如果能让LLM直接使用这些系统和数据,AI Agent的能力会大大增强。

但问题是:如何让LLM能够使用这些既有系统?

在Function Calling的框架下,每个既有系统都需要单独集成到应用中。每个组织或公司都有自己的API、认证方式、数据格式,开发者需要为每个组织或公司编写对应的函数实现。这就是MCP产生的原因:提供一个服务,可以让既有系统快速集成到LLM中。

MCP的核心其实还是基于Function Calling的。它做的事情很简单:把Function Calling的调用,在客户端转换成一套JSON+HTTP的请求。然后提供一套Server来响应这个JSON+HTTP请求,这样就能实现各类应用都可以被LLM使用的效果。

LLM -> Function Calling -> MCP Client -> JSON+HTTP请求 -> MCP Server -> 既有系统(GitHub/Slack/数据库等)
                                                                    ↓
LLM <- Function Calling结果 <- MCP Client <- JSON响应 <- MCP Server <- 既有系统返回结果

但MCP解决了工具集成的问题后,又出现了另一个问题。

Function Calling和MCP都会有任务流程定义困难的问题

在实际使用中,用户经常需要让AI Agent按照特定的方式执行任务。比如,格式化Excel表格要按照公司的品牌指南,法律审查要遵循特定的合规性要求,数据分析要按照组织的工作流程。这些任务往往需要复杂的提示词和多个步骤的组合。

但在Function Calling和MCP的框架下,用户面临一个两难的问题:当前的大模型很难仅仅依托自己的模型能力就做出最优的工具调用步骤。很多任务需要特定的执行顺序、规则和约束,但把这些步骤全部写成代码又不太现实。就像我们在第一篇文章里讲的,模型的核心优势是面对不确定性时可以走一步看一步,动态调整策略。如果全部落成程序,就会丧失模型的核心优势。

举个例子,我们以Lynxe实际在跑的一个new_branch流程定义为例,我这个流程用文字写到一个markdown里面,每次都让模型遵照执行:

1) 确认本地的 VERSION 与 pom.xml 与 本地branch 中的版本一致,不一致的话以pom.xml为准
2) mvn package 
3) 进入 ui-vue3 运行pnpm lint 
4) 退回项目目录, git merge upstream/main
5) 项目目录,运行 make ui-deploy
6) git 提交 branch到origin
7) git 打包 tag名字与pom的版本号一致,先删除远程tag(如果存在):git push upstream :refs/tags/v{版本号},然后上传tag到 upstream (上传之前请先用git remote 看一下upstream是哪里,确认是spring-ai-alibaba/JManus)

这个流程有7个步骤,每个步骤都有特定的顺序、条件和规则。如果完全写成代码,每一步都要处理各种异常情况(比如版本不一致、tag已存在、upstream地址不对等),代码会变得非常复杂。但如果只给模型一个简单的提示词"帮我创建新分支",模型可能无法按照这个精确的流程执行,或者执行顺序不对。 而用文字表达,非常直接简单,而且实际跑的过程中只有很小的概率会出错,非常爽。

而这就是这个问题的本质:如何在尽可能的准确的前提下,能让用户能用文字(而非代码)指导模型按照特定的流程和规则执行任务?

这就是Skills产生的原因(其实也是Lynxe的Func-Agent产生的核心原因):提供一个方式,让用户可以用文字定义指令、脚本和资源,形成可复用的任务流程。

Skills的核心其实也是基于Function Calling的。它做的事情很巧妙:通过一个固化的函数和参数,让模型去查找和加载固定的skills文档。

这里的关键是,Skills完全依赖于Function Calling这个基础能力。 如果没有Function Calling,Skills就无法工作。Skills只是在Function Calling之上的一个巧妙应用:把"加载文档"这个操作封装成一个函数,然后让Claude在需要时自动调用。

具体工作流程是这样的:

  • 初始化阶段:用户用文字定义指令、脚本和资源,打包成Skills(包含SKILL.md和可选的脚本、参考资料等)。Claude在启动时会读取所有Skills的元数据(名称和描述),这些元数据被加载到模型的上下文中(每个约100 token)。

  • 发现阶段:当用户发起请求时,Claude会根据请求内容,对比已加载的Skills元数据,判断是否需要使用某个Skill。这个判断过程本质上就是LLM根据上下文做决策,跟Function Calling中判断是否需要调用工具是一样的。

  • 加载阶段(Function Calling):如果Claude判断需要某个Skill,它会通过Function Calling机制调用一个专门的加载函数(类似load_skill(skill_name)),将对应的SKILL.md文档内容读取并加载到当前上下文中。这一步完全依赖Function Calling的能力。

  • 执行阶段(继续使用Function Calling):SKILL.md的内容(包含指令、流程、示例等)被加入到上下文后,Claude按照文档中定义的指令执行任务。如果SKILL.md中定义了需要执行脚本(比如scripts/rotate_pdf.py),Claude还是会通过Function Calling调用执行脚本的函数。如果需要加载参考资料,同样是通过Function Calling调用读取文件的函数。

可以看到,整个Skills的运行过程,从加载文档、执行脚本到读取资源,每一步都离不开Function Calling。Skills并没有创造新的能力,它只是把Function Calling这个基础能力组织成了一个更易用的形式:让用户可以用文字定义流程,让Claude自动发现和加载相关知识。 从本质来说,他替代的是mcp 调用的函数里面,过去可能会用代码写的一套串接各种API的逻辑流程,用这种方式,可以增强流程的适应性,其实也是呼应了我们第二篇文章的核心观点:Agent将决策权完全下放给了 Agent 和 Prompt,能够解决原有写程序不能解决的问题——比如处理不确定性、动态调整策略、理解自然语言意图等。

Claude 判断是否需调用某 Skill(基于请求内容匹配已加载的 skill_name 与 description)
↓
若需要,则通过 Function Calling 调用 load_skill(skill_name)
↓
将对应 SKILL.md 的内容注入当前上下文,作为执行指令依据
↓
Claude 依照 SKILL.md 中定义的流程执行任务
↓
在执行过程中,按需通过 Function Calling:
  • 调用 bash 执行附带脚本
  • 调用 read_file 读取所需资源文件
↓
整合执行结果

Function Calling、MCP、Skills的核心定位

通过前面的分析,我们可以看到Function Calling、MCP和Skills三者之间的本质关系:MCP和Skills都是基于Function Calling的,它们只是在Function Calling这个基础能力之上的不同应用方式。

MCP的核心是解决与既有系统的接驳问题 : 实际上,与外部系统接驳的方法并不只有MCP这一种——我们完全可以用curl、bash等传统方式来与程序接驳。MCP的价值在于它提供了一套标准化的接驳协议,让不同的工具和数据源能够以统一的方式被LLM使用。通过JSON-RPC协议和标准化的工具描述格式,MCP降低了工具集成的成本,让开发者不需要为每个系统单独编写集成代码。但本质上,MCP更偏重是一套接驳标准,而不是唯一的接驳方式。

Skills则实际上是一个sub-agent的包装 : 它让用户可以用文字来写流程,替代了过去在MCP调用的函数里用代码写的一套串接各种API的逻辑流程。这种方式可以增强流程的环境适应性——因为模型可以根据实际情况动态调整策略,处理不确定性,理解自然语言意图。这正是我们第二篇文章提到的核心观点:Agent将决策权完全下放给了模型和Prompt,能够解决原有写程序不能解决的问题。但代价就是不可能100%准确,因为模型的行为存在不确定性,无法像传统代码那样保证完全可预测的执行结果。

MCP与Skills的竞争关系

虽然很多人认为MCP和Skills是互补关系,但实际上,这两者更多是竞争关系。这种竞争主要体现在它们解决的是同一个问题:如何整合多个既有系统,实现复杂的多步骤任务

要理解它们的竞争关系,我们需要回到Function Calling的本质:LLM要实现工具调用,实际上最需要的内容只有:函数名、参数要求,以及一个description。基于这个前提,我们来看看MCP和Skills的不同解决思路:

MCP的解决思路通过标准化的协议和Server架构,引入了一个新的协议转换Server(这个Server可以用Node.js、Python或其他语言来实现)。但这个协议转换层往往也只是先做了函数调用的协议转换,然后再增加一个description,打包,发布。这个流程是非常薄的——它本质上只是在Function Calling的基础上,增加了一层JSON-RPC协议转换。

Skills的解决思路选择了更简单的办法,可以不需要这层协议转发Server,直接用bash以参数形式调用,结果其实是一样的,还更省事。换句话说,MCP的JSON-RPC可以被直接替换为命令行脚本或curl远程调用,在本地直接调用。这样甚至都不需要额外做MCP封装了。而且在这个基础上,Skills还能支持更复杂的流程定义——通过SKILL.md文档告知LLM如何组合多个接口调用,所以长流程任务的成功率会更高。

这就是为什么说它们是竞争关系当用户选择使用Skills时,他们就不需要在MCP Server的函数中编写复杂的串接代码了;反之,如果选择在MCP Server中实现完整逻辑,Skills的价值就会降低。它们解决的是同一个问题(如何整合多个既有系统),但采用了不同的方法(协议转换Server+代码型流程定义 vs 直接命令行调用+文字化流程定义)。

三者的总结性对比表

Lynxe的实践与总结

首先,我们也认为Agent这种将决策委托给LLM的方式,是一种更有潜力的、能够提供完全不同体验的、面向未来的方案。通过Function Calling、MCP和Skills这些技术,我们看到了AI Agent工具能力的完整体系正在形成。

但我们也并不认为Skills就是终局。在Lynxe的开发实践中,我们发现Skills仍然有两个核心问题没有解决:

1. Skills的需求描述部分不够结构化

Skills仅仅通过description字段来描述sub-agent的要求,这会导致模型生成的信息非常容易不准确,从而导致sub-agent(也就是Skill)无法获得充分的信息,最终导致sub-agent无法达成用户期望。当任务复杂度增加时,纯文本描述的不确定性会放大,模型可能误解需求,或者遗漏关键信息。

2. Agent无法与既有的系统接驳

Agent仅仅只能通过聊天的方式与既有系统接驳,这种方式最后无论怎么做,都只能是个对话框。但真实的系统,远远不止有对话框这一种输入的方式。我们的大量表单都不是只有一个textarea的。现有的Agent方案很难集成到复杂的业务系统中,比如需要多步骤表单、需要实时数据展示、需要与现有UI组件交互的场景。

这就是Lynxe这套Func-Agent思路的原因。如果一句话来表达,就是:一切都是函数,函数才是第一公民。

在Lynxe的设计中,我们让每个Agent能力都通过函数的方式暴露,这样就能更好地把Agent集成到既有的系统中,让他不再仅仅是一个对话框。通过函数化的接口,Lynxe的Func-Agent可以:

  • 接受结构化的参数输入,而不是依赖纯文本描述;

  • 返回结构化的结果,方便与现有系统集成;

  • 支持多种调用方式,不仅仅是聊天界面;

  • 与现有的业务逻辑、表单、API无缝对接;

这种方式既保留了Agent处理不确定性的核心优势,又解决了结构化输入输出和系统集成的问题,为Agent在实际业务场景中的应用提供了更可行的路径。

这个问题很有意思!Function Calling更像是底层能力,啥都能用,比如你想让AI帮你订机票酒店,或者查询数据库,都离不开它。MCP适合那种需要大规模集成现有系统的场景,像公司内部有很多老旧系统,用MCP可以简化集成过程。Skills的话,适合需要定制化流程的场景,比如特定行业的合规审查,或者复杂的excel表格处理。

举个例子,一个电商网站可以用Function Calling来调用商品搜索API,用MCP来集成旧的库存管理系统,用Skills来定制促销活动的规则和流程。

楼上说得很到位!我补充一些,Function Calling可以看作是基石,没有它,后面两个都玩不转。MCP就像一个万能转换器,把各种奇奇怪怪的接口都统一成LLM能懂的语言。Skills则是把任务拆解成一个个小步骤,让AI像流水线一样完成工作。

我想到一个例子,比如智能客服。Function Calling可以用来查询知识库,MCP可以对接不同的业务系统(订单、物流、售后),Skills可以定义解决问题的标准流程,比如先确认问题,再查找解决方案,最后给出答复。

好文章,解析的很清楚;

在使用skill的过程中发现一个问题:在写description的过程中,换一种说法,大模型就不匹配了,必须大部分匹配我给出的提问示例才能匹配成功;

感谢你的反馈!你说的这个问题在使用Skills的过程中确实比较常见。因为目前大模型对文本的理解仍然依赖于pattern matching,description写得稍微不一样,模型就可能无法正确识别。可以尝试以下方法来优化:

  1. 增加Description的多样性:在description中,多提供几种不同的表达方式,覆盖用户可能使用的query。
  2. 使用更通用的描述词:避免使用过于specific的词汇,尽量用更general的词来描述skill的功能。
  3. 结合Few-shot示例:在description中,提供一些query示例,帮助模型更好地理解skill的用途。
  4. 调整模型的temperature参数:适当调高temperature,可以让模型在匹配时更具创造性,但也要注意避免引入过多噪声。

另外,也可以考虑使用一些更高级的匹配算法,比如向量相似度匹配,来提高skill匹配的准确率。

感谢回复!

除此之外我想了解下贵团队在使用 skill 通过 bash curl 等方式获取到原有系统的数据,再扔回给大模型处理时的两个细节

  1. 当获取的数据很大,已经超过了 bash 处理的长度限制时应该怎么处理;当前我是存储到/tmp文件中,再调用read去读
  2. 当 skill 是一个 聚合数据处理;例如。skill-A 中提供服务元信息;一个服务的元信息由多个来源聚合而成,如 机器,环境,owner,gc,vm 等信息;不同数据来源于不同的接口;是在 skill 聚合好给到大模型还是 直接拼接给到大模型呢?我发现这两种方式 大模型给出的结果差异比较大

关于你提到的两个细节问题,我来分享一下我们的经验: 1. 数据量过大问题:你目前使用/tmp文件存储的方案是可行的,但需要注意清理,避免磁盘空间占用过多。此外,还可以考虑以下方案: * 分块处理:将大数据分割成小块,逐块传递给大模型处理。大模型需要具备处理上下文信息的能力,将各分块的结果进行整合。 * 流式处理:使用管道将curl的输出直接传递给read命令,避免将所有数据加载到内存中。例如: bash curl 'your_url' | while IFS= read -r line; do # 处理每一行数据 echo "$line" | your_agent_process done * 使用数据库或键值存储:将数据存储到数据库(如Redis、MySQL)中,然后将数据库查询语句传递给大模型,让它根据查询结果进行推理。这样可以避免直接传递大量数据,并且可以利用数据库的查询优化能力。 2. 数据聚合问题:这确实会影响大模型的效果。我们的建议是,在Skill中尽可能做预处理和聚合,原因如下: * 减少大模型的token消耗:将多个来源的信息聚合后再传递给大模型,可以减少token数量,降低成本。 * 提升信息密度:在Skill中进行初步的整合和清洗,可以提高信息的信噪比,让大模型更容易抓住关键信息。 * 解耦数据来源:Skill相当于一个适配器,将不同的数据源适配成大模型可以理解的格式。这样,即使数据源发生变化,也不需要修改大模型的prompt。 但是,具体的聚合策略需要根据你的业务场景来决定。以下是一些建议: * 如果不同来源的数据有很强的关联性,可以在Skill中进行深度聚合,提取关键特征,然后再传递给大模型。 * 如果不同来源的数据相对独立,可以直接拼接,但需要注意使用清晰的分隔符,并为每个部分添加明确的标签,方便大模型理解。 * 可以尝试不同的聚合方式,然后通过实验来评估哪种方式效果更好。 总的来说,数据处理的原则是:尽可能在Skill中进行预处理,减少大模型的负担,提高信息密度。同时,要根据实际情况选择合适的聚合策略,并通过实验来验证效果。

可以考虑引入强化学习。让Agent在实际环境中不断试错,学习最优的执行策略。通过强化学习,Agent可以更好地适应各种不确定性,提高任务完成的成功率。

当然,强化学习也需要大量的训练数据和计算资源。而且,如何设计合适的奖励函数也是一个挑战。

我想做一个智能文档助手,可以用 Skills 来提取文档的关键信息、自动生成摘要、自动翻译文档。比如,可以用一个 Skill 来提取合同的关键条款,用另一个 Skill 来生成会议纪要,用第三个 Skill 来翻译外文文献。这样就能大大提高阅读效率和信息获取能力。

我会做一个智能编程助手,可以用 Skills 来定义各种代码审查、代码生成、代码重构的流程。比如,可以用一个 Skill 来检查代码风格是否符合规范,用另一个 Skill 来自动生成单元测试,用第三个 Skill 来重构代码。这样就能大大提高开发效率和代码质量。

从长远来看,我觉得 Skills 更有潜力。虽然现在 MCP 在标准化集成方面有优势,但 Skills 允许用自然语言定义流程,更符合 AI Agent 的发展趋势,也更灵活。而且,现在 Skills 也在不断进化,比如可以通过更结构化的方式描述需求,提升准确性。

我有一个更“野路子”的想法!既然现在的大模型理解自然语言的能力这么强,能不能让它自己从Skills的代码和文档中提取Schema信息?比如,让模型分析Skill的函数签名、注释、示例代码等等,自动生成一个Skills的元数据描述。这样就省去了手动编写Schema的麻烦,而且还能保证Schema和代码的同步。当然,这种方法可能会有一些误差,需要人工进行校对。

与其纠结于MCP和Skills,不如跳出这个框架,思考Agent工具能力构建的本质。我觉得未来的Agent应该具备更强的自主学习能力,能够自动发现和利用各种资源,而不是依赖于预定义的工具和流程。这可能需要引入强化学习、迁移学习等技术,让Agent在实践中不断进化。

我觉得可以引入更严格的 schema 定义,让用户在编写 Skill 描述时,必须按照指定的格式填写关键信息,比如输入参数、输出结果、前置条件、后置条件等等。这样能减少自然语言描述带来的歧义,让模型更容易理解。可以参考JSON Schema的设计思想,定义Skill Schema。

嘿嘿,我有个大胆的想法!既然Agent现在还不够聪明,那不如让它先做一些简单的“体力活”。比如,自动填写表单、自动生成报告等等。从简单的任务入手,逐步提升Agent的能力。

在我看来,Function Calling最大的局限性在于对工具描述的准确性和完整性要求非常高。如果工具描述不够清晰,LLM可能无法正确判断是否需要调用该工具,或者无法生成正确的参数。弥补的方法是,一方面,要不断优化工具描述,使其更易于理解;另一方面,可以引入一些机制,例如用户反馈,让用户参与到工具选择和参数调整的过程中。

这个问题问得好!我觉得不存在谁主导的问题,而是融合。未来一定是三者结合,Function Calling提供基础能力,MCP解决标准化连接,Skills提供灵活的任务编排。就像乐高积木一样,基础砖块是Function Calling,标准接口是MCP,而Skills就是用这些积木搭建的各种模型。