
做agent开发的人迟早会卡在同一个地方模型光有脑子不行得给它配手。这个“手”就是工具。但等你真去查资料、看文档、逛社区会发现市面上叫法乱七八糟——今天说function calling明天说MCP后天又冒出来一个“skill”。很多初学者直接把这三个词当成同义词混着用结果看代码一头雾水找资料也对不上号。这其实不是你的问题是整个生态发展太快术语还没收敛。但这篇文章得把这个事讲透。我基于自己在agent开发里的实践把skill、MCP、function calling这三类工具的本质、使用场景、选型逻辑和组合方式完整梳理一遍。适合正在做agent应用、或者准备入坑LLM应用开发的开发者参考。读完你至少能搞清楚它们分别解决什么问题什么情况下该用哪个以及为什么好的agent项目往往是三者的组合拳。1. 三者本质FDC是函数、MCP是标准化协议、Skill是自然语言流程先说结论function calling函数调用下文简称FDC、MCPModel Context Protocol、Skill这三样东西根本不是同一个维度的概念。它们之所以经常被放在一起讨论是因为它们都扮演了“让模型使用外部工具”的角色但抽象层级完全不一样。FDC是“函数调用”它的核心就是让模型输出一段结构化的JSON告诉你“我要调用这个函数参数是这些”。这是最底层、最直接的机制。比如你给模型一个天气查询函数get_weather(city)模型理解用户问题后会输出类似{name: get_weather, arguments: {city: 北京}}的JSON你的代码负责解析并真正执行函数。FDC本质上是模型与程序之间的一种“接口约定”它不关心函数内部怎么实现只关心模型能不能准确地把意图映射到函数签名上。MCP是“标准化协议”它的维度更高。MCP想解决的是“工具接入的碎片化问题”。早期做agent每个工具都要自己写一套接入逻辑对接不同的API、不同认证方式、不同的数据格式非常痛苦。MCP定义了统一的服务端MCP Server和客户端MCP Client通信协议工具提供方只需实现一个MCP Server任何支持MCP的agent客户端都能直接对接。类比一下FDC好比是“插座”MCP好比是“统一标准的插座形状和电压”它让所有厂商的电器都能插进同一个墙上。Skill是“技能包”它的抽象层级更高一点偏向于“流程与策略的封装”。一个Skill通常不只是单一函数而是一组精心编排的提示词、工具调用序列、甚至是子agent的集合。比如“写博客Skill”可能包含主题分析、大纲生成、素材检索、段落撰写、语法校对五个步骤内部调用多个不同的FDC或MCP工具。Skill的价值在于把“如何完成任务”的经验固化下来让agent面对同类任务时不需要从头推理直接按照Skill定义的路径执行稳定性和效率都更高。理解了这一层你再看社区里的争论——有人吹MCP有人唱衰MCP说function calling就够了——其实他们根本不在一个层面上对话。MCP和FDC是不同抽象层级的产物Skill又是另一种维度的组织方式。更准确地说它们是可以叠加使用的Skill内部可以调用MCP工具而MCP工具最终执行时底层还是要落到FDC或类似的机制上。2. 三类工具的适用场景不是替代关系是分工关系很多人问“我该用FDC还是MCP”这个问题本身就问错了。更合理的问法是“我当前项目里哪一层需要我投入精力”下面按场景拆开说帮你对号入座。2.1 什么时候FDC就够了FDC适合所有“单机、轻量、自包含”的工具场景。你的业务逻辑不复杂工具数量不超过十几个也不打算对外发布工具给别的agent使用那FDC就是最务实的选择。比如做一个内部知识库问答agent你需要让模型调用“查文档”“查工单”“查人员信息”三个工具。这三个工具都是内部服务数据格式固定调用方只有你一个agent应用。这种情况下引入MCP纯属增加复杂度——你得多维护一套Server进程多一层网络通信还要处理协议适配问题。直接写三个函数在调用LLM时把函数schema传给模型然后解析模型返回的function call结果20分钟就能跑通。FDC还有个很大的好处可调试性极强。因为一切都是内存中的函数调用你可以在本地断点调试打印每一步的输入输出确认是模型理解错意图还是参数映射出了问题。对于刚起步的项目这个优势太重要了。2.2 什么时候必须上MCPMCP的核心价值在“跨应用复用”和“动态发现”。当你的工具要被多个agent复用、或者工具数量多到难以静态配置、或者工具由不同团队甚至不同公司提供时MCP就体现出压倒性优势。举个实际场景某公司要做一个统一的agent中台上挂客服助手、数据分析助手、运维助手三个agent它们都要访问内部的知识库、监控系统和工单系统。如果用FDC你得在三套agent代码里各自实现一遍对接逻辑而如果用MCP知识库团队只需部署一个MCP Server三个agent客户端通过统一协议接入即可。后续知识库接口有变动也只需改Server端客户端完全无感。另外MCP还有一个FDC很难以低成本实现的能力动态工具发现。MCP Client可以随时向Server查询“你提供了哪些工具”新增工具不需要重新配置agent。这也是为什么很多agent开发框架如Claude的MCP生态、各类MCP路由器都在重点发力这个方向。2.3 Skill的价值把“会做一件事”沉淀为可复用资产Skill最典型的应用场景是“任务型agent”。这类agent不是单纯回答问题而是要完成一整套任务流。我做过一个自动化数据分析agent它的任务链路是接收需求→理解指标口径→写查询SQL→执行查询→解读结果→生成图表→输出报告。在没有Skill之前模型每次都要从头推理这些步骤经常在“解读结果”和“生成图表”之间逻辑断层或者漏掉口径确认环节执行质量很不稳定。后来我把整个流程封装成一个数据分析Skill把每个步骤的提示词、工具调用顺序、甚至质量检查规则都固化下来执行稳定率一下就上来了。所以Skill的定位很明确它是“经验与流程的固化层”。如果说FDC是让模型有工具可用MCP是让工具好接入那么Skill就是让工具用得对、用得稳。它最适合业务路径相对稳定、重复执行频率高的场景。3. 实战选型一张决策表解决你的工具选型纠结根据上面的分工逻辑我在实际项目里总结了一套选型决策表基本能覆盖绝大多数情况判断条件推荐方案核心原因工具数量少10、单应用调用、内部私有数据FDC实现简单可调试性强无额外架构负担工具要跨多个agent复用MCP一次接入处处复用接口变动对客户端无感工具由第三方/外部团队提供MCP标准化协议是协作的唯一可行方式工具随时会动态增删MCP动态发现能力是FDC结构很难实现的任务是固定流程、重复度高Skill内部可含FDC/MCP固化执行路径提升稳定性和效率任务开放性强、不可预判FDC/MCP裸用不要让Skill限制模型的自由推理空间模型上下文窗口紧张优先FDCMCP的Server返回信息可能更冗长需额外设计裁剪追求极低延迟300msFDC省去进程间通可谓性能最优这个表格不是我凭空想出来的是踩过不少坑之后总结的。之前有个项目工具数量明明只有五个但因为追了MCP的时髦强行上了MCP架构。结果是工具调用链路从“内存函数调用”变成“本地HTTP请求”每次调用多出几十毫秒延迟还要配置认证、处理连接池和超时——复杂度上了一个台阶收益几乎为零。后来冷静下来把所有MCP换回FDC整个agent轻了一倍。反过来说另一个项目要接入三个外部团队的八个工具每个团队都有自己的接口风格和鉴权方式。如果不用MCP统一协议客户端代码会变成一团乱麻于是果断上了MCP协作效率立竿见影。一句话总结我的选型心智FDC是起点MCP是通道Skill是策略。项目小从FDC起步没错项目要长大尽早规划MCP接入层项目跑通了、路径稳定了再考虑沉淀Skill。4. 组合打法生产级agent的典型架构是三者混合你可能以为选了FDC就不用碰MCP选了MCP就不用管FDC——真实的生产级agent根本不是这样它们是混着用的。拿我之前做的一个项目为例整体架构是这样的底层一个内部MCP Server封装了知识检索、数据库查询、工单状态查询三个工具。所有agent都通过MCP协议接入工具复用得很好。中间层特定agent内部用FDC做“私有工具”比如会话记忆组件、上下文裁剪组件、敏感词过滤组件。这些工具只给本agent自己用没有复用需求但要求低延迟、强可控所以走FDC。上层核心业务任务封装成Skill。比如上面说的数据分析Skill内部编排了“指标确认→SQL生成→查询执行→结果解读→报告输出”五步每一步调用MCP工具或FDC私有工具。你可以看到同一个项目里三层各司其职谁也不替代谁。这也是为什么我不认可“MCP会取代function calling”或者“Skill MCP就够用了”这类说法。它们是不同抽象层的组件组合起来才能覆盖生产环境的真实复杂度。4.1 一个值得参考的封装思路如果你在建自己的agent框架我建议你做一层“工具抽象层”把FDC和MCP统一封装成同一套接口。具体做法是定义一个统一的Tool抽象类属性和方法名称、描述、参数schemaJSON Schema格式、执行方法。MCP工具写一个MCPTool适配器从远端Server拉取工具定义转换成统一的schema格式执行时转发请求。FDC工具写一个LocalTool适配器直接把本地函数包成同样的接口。Skill工具把Skill包装成一组有序工具序列本质上也是一个Tool超集。这样做的好处是上层业务代码完全感受不到底层工具的来源差异。写agent逻辑的时候只需要从“工具注册表”里取一个工具然后执行即可。工具是本地函数还是MCP远端服务对上层透明。这套架构我在多个项目里验证过扩展性很好无论后续新增工具还是切换协议成本都可控。4.2 别踩的坑盲目叠加导致“工具溢出”三者混合虽然强大但有一个隐性风险工具一多模型的选择困难症就犯了。给模型10个工具它用得好给50个工具它就开始蒙圈——选错工具、漏选工具、参数乱填什么毛病都可能出来。解决办法是分层的工具可见性。不要让一个agent看到所有工具而是根据当前任务状态动态决定哪些工具对模型可见。比如数据分析agent第一步“指标确认”阶段只暴露三个工具查指标字典、问口径、确认日期范围确认完成、进入查询阶段后再暴露SQL执行工具。这样每个阶段模型面对的选项都很少准确率自然高。这套机制我们内部称之为“按阶段工具切换”对生产级agent的效果提升非常明显。5. FDC实战细节从模型输出到函数执行的关键链路很多讲FDC的文章只讲到“模型返回JSON你执行就行”但对真实开发里的坑避而不谈。这里把我实战中踩过的关键细节展开讲一下。5.1 函数Schema的编写决定模型理解的上限FDC的效果好不好七成取决于你写的函数schema。模型不是靠看你的函数实现来理解工具而是靠你提供的描述和参数定义。所以schema写得含糊、参数说明不清模型十有八九会填错。以下几点经验值得记下来函数名用动词 名词的清晰组合比如query_user_orders不要用do_stuff这种含糊命名。**description务必交代清楚在什么场景下使用、何时不该用、输出是什么。**比如query_user_orders的description可以写“查询用户的历史订单列表仅当用户明确要求查看订单时使用统计类需求请使用query_order_stats”。**每个参数字段的description要写清楚语义和取值范围。**模型对齐歧义参数时你表里的字段说明就是唯一的参考。**必要参数和可选参数要分清楚且都声明过。**很多模型在可选参数上容易“自由发挥”你在schema里标明default能减少不少乱填概率。5.2 处理多工具并行调用的细节现在主流模型都支持一个回复里包含多个function call并行调用。这个能力要小心使用因为并行调用会带来两个问题一是并发执行的资源竞争二是并行调用之间的逻辑依赖。我的习惯是**默认不并行除非工具之间明确无依赖。**比如“获取用户信息”和“获取用户订单”两个调用可以并行但“先查库存再根据库存创建订单”这种不能并行需要分两轮让模型推理。实现上我通常会在工具执行层加一个依赖声明字段声明为“依赖上一个调用的输出”时就让agent引擎自动降级为串行执行。5.3 工具调用的错误处理与重试机制模型给的函数调用参数不是永远正确的。最典型的问题是“幻觉函数”和“幻觉参数”——模型调了一个你根本没注册的函数或者给参数塞了一个不存在的枚举值。这时候FDC层的兜底逻辑就很重要注册一个unknown_function兜底模型调用未知函数时返回“工具不存在可参考以下可用工具列表”而不是直接报错崩溃。参数解析失败时不要直接异常逐字段校验后返回具体的字段错误信息下一轮模型能自己修正。工具内部异常要设计“结构化错误返回”让模型得以理解错误原因并继续推理而不是二段直接断掉。这一步做好agent的“抗幻觉能力”会有质的提升。6. MCP实战要点Server端设计和Client端最容易踩的坑MCP的入门门槛比FDC高不少很多新手照着文档跑通demo后一上生产就翻车。这里分别从Server端和Client端说几个关键点。6.1 Server端工具粒度设计要为“对话式调用”服务MCP Server暴露的每个工具本质上是一次函数调用但它要服务的是“模型的对话推理”。这意味着工具粒度不要太小也不要太大。粒度太小的典型例子把“读取用户表的第2到5行”“获取数据库连接”“关闭数据库连接”这种底层操作暴露给模型。模型陷入细节操作里反而做不好业务决策。粒度太大的典型例子把“完成整份周报”做成一个工具。模型失去了中间步骤的可控性一旦参数不对整个任务失败且不可调试。我实践下来的合理粒度是一个工具对应一个“业务原子操作”。比如“查询某产品线的本周销量”“获取客户行业的宏观指标”“生成指定数据的折线图”。这种粒度下模型能理解工具用途编排链条时也有足够的灵活性。6.2 资源列表Resources的取舍MCP协议里除了工具Tools还有资源Resources的概念用来暴露数据文件给模型读取。但实际项目里我很少直接用Resources。原因是资源数据往往很长直接塞进上下文很浪费token而且实时性差。我的做法是把“动态数据”一律做成工具而不是资源。模型需要数据时通过工具实时查询拿回精简后的结果。静态模板、说明文档这类内容才考虑用Resources方式挂载且要控制单文件长度。6.3 Client端连接管理和超时是重灾区MCP的Client端最常见的坑是**“长连接管理不当导致的内存泄漏和文件描述符耗尽”**。很多实现直接为每个agent会话新建一个Client进程会话结束不主动关闭时间一长服务就垮了。我的建议是批量请求共用一个Client长连接按关键字区分会话不要每次调用都重建连接。所有MCP工具调用必须设置超时且超时必须区分“网络超时”和“业务超时”。网络超时建议3-5秒业务超时根据工具性质单独设置比如查询工具给10秒、生成类工具给30秒。超时的兜底设计很重要MCP Client超时后返回一个“服务执行超时请稍后重试或缩小查询范围”可以避免模型因为拿不到结果而陷入死循环重试。6.4 MCP Server的鉴权模型MCP自带的安全机制比较基础生产环境必须自己加强。尤其要警惕“工具投毒”——如果某个MCP Server没人审核工具描述写得很误导模型可能被带偏。我的做法是每个接入的MCP Server都要过一套工具白名单审核确认安全后才能对agent开放。涉及敏感数据的工具在Server端做权限校验。MCP协议本身不解决这个问题你必须自己实现用户身份上下文传递。对Server的调用做全量审计日志目的是出问题时能追溯哪个agent、哪条会话、调了什么工具、拿了什么数据。7. Skill实战细节从“任务描述”到“可复用技能包”的完整过程最后把Skill的构建过程完整写一遍。很多人以为Skill只是“写几段提示词”真正落过地的人知道远没那么简单。7.1 Skill的构成要素我构建一个Skill一般包含四个部分触发条件描述什么情况下应该使用这个Skill。这是给模型决策用的写得清晰能有效避免Skill被滥用。执行流程图任务是单步还是多步每一步之间的依赖关系是什么哪些步骤可以并行工具调用编排每一步用到哪些工具、工具的输入输出如何流转。输出校验规则如何判断这一步的结果是“合格”的不合格时怎么回退或重试。这四个部分缺一个Skill就很容易在复杂任务里“翻车”。尤其是输出校验规则很多初版Skill都漏掉结果就是步骤错乱了模型自己都意识不到。7.2 如何调试和迭代SkillSkill不是一次写好的它是“长”出来的。我的迭代路径是用真实任务跑50条样本统计失败模式归类后修改Skill定义。反复做这个循环直到失败率降到可以接受的水平。统计下来最常见的失败模式不外乎这么几类漏步骤任务做到一半就提前输出结论。跳校验某个中间结果质量很差但模型直接拿着继续跑。工具选错任务走到后续步骤时模型选了不恰当的工具替代。每一类失败对应的修复动作也不同。漏步骤就在流程编排里加上“步骤完成标记”跳校验就把校验规则写进过程里的每一步提示词工具选错就检查工具描述是否足够消除歧义。7.3 Skill与FDC/MCP的分工边界最后强调一遍三者边界这一点理解了你的架构思路就清晰了FDC解决“能力”问题模型能调用什么。MCP解决“接入”问题工具怎么被高效、标准化地连接和复用。Skill解决“策略”问题任务流程怎么编排才能做得对、做得稳。所以不要再纠结“用哪个替代哪个”。成熟的agent架构里三者在不同层面上各司其职、缺一不可。你现在如果正在做一个刚起步的项目最优路径是先用最朴素的FDC赶紧跑通核心流程验证业务价值随着项目增长、工具和复用需求变多逐步引入MCP业务流程稳定后再把高频任务固化成Skill。每一步都在上一轮复杂度确有必要时才往前走。我做了这么多年agent开发最大的体会是工具层的设计不需要炫技只需要“匹配当下真实的复杂度”。很多项目死在过度设计上而不是死在工具不够多上。希望这篇文章能帮你把skill、MCP、FDC这三件事真正理顺少走点弯路。