1. 从插件到技能:大模型能力扩展的底层逻辑变了
大模型能力扩展这件事,过去两年我一直在跟。从最早ChatGPT刚开放Plugin那会儿,到后来各种Agent框架满天飞,再到最近Claude-Skills这套东西出来,说实话,整个思路发生了好几次根本性的转向。如果你现在还在用“写个函数让模型调用”的思维去理解今天的能力扩展方案,那大概率会走不少弯路。
这篇文章我想把这条演进线彻底捋一遍。不是那种新闻通稿式的回顾,而是从一个实际做Agent开发的人的角度,讲清楚每个阶段到底解决了什么问题、又留下了什么坑,以及为什么Claude-Skills代表了一种完全不同的思路。如果你正在做Agent项目、正在选型能力扩展方案,或者单纯想搞明白“大模型能力扩展”这件事到底该怎么落地,这篇内容应该能帮你省下不少试错时间。
先说结论:ChatGPT-Plugin的核心是“让模型调用外部API”,Claude-Skills的核心是“让模型学会一套工作方法”。前者扩展的是模型的能力边界,后者扩展的是模型的行为模式。这个区别听起来很抽象,但落到实际开发里,影响的是你整个架构的设计方式。
2. ChatGPT-Plugin时代:第一次让模型“长出手脚”
2.1 Plugin到底解决了什么问题
2023年3月ChatGPT Plugin刚出来的时候,整个圈子都沸腾了。原因很简单:在此之前,大模型再聪明,它的知识也是冻结在训练数据里的。你问它今天天气怎么样,它只能告诉你“我的知识截止到某年某月”。Plugin的出现,相当于给模型开了一扇通往外界的窗户。
Plugin的技术本质其实不复杂。你写一个符合OpenAPI规范的接口描述文件,ChatGPT在对话过程中根据用户意图判断是否需要调用这个接口,如果需要,就生成对应的请求参数,由ChatGPT的服务器代为发起HTTP请求,拿到结果后再交回给模型组织成自然语言回复。整个链路是:用户输入 → 模型判断意图 → 生成API调用参数 → 平台执行调用 → 结果回传模型 → 模型生成回复。
这个流程今天看起来理所当然,但在当时是一个巨大的范式转变。它意味着大模型不再只是一个“文本生成器”,而开始变成一个“任务执行器”的调度中枢。
2.2 Plugin架构的先天局限
但Plugin这套东西用久了,问题就暴露出来了。我总结下来主要是三个层面的限制。
第一,调用链路太重。每次Plugin调用都要经过ChatGPT的服务器中转,这意味着你没办法在本地做任何缓存或预处理。而且Plugin的调用是串行的,一个请求没回来,下一个就没法发。我试过做一个需要连续调用三个API的任务,整个响应时间直接拉到十几秒,用户体验非常差。
第二,能力描述太薄。OpenAPI规范能描述接口的输入输出,但描述不了“什么时候该用这个接口”“用了之后下一步该干什么”。模型只能根据接口描述和用户输入做匹配,稍微复杂一点的场景就容易判断失误。比如你有一个“查询订单”的接口和一个“取消订单”的接口,用户说“我不想要这个订单了”,模型有时候会先去查订单再取消,有时候直接调取消接口然后因为缺少订单号而失败。
第三,生态封闭。Plugin只能在ChatGPT的体系里跑,你没办法把它拿到别的模型上用。而且Plugin的审核和上架流程很长,很多内部工具根本没法通过这个渠道来扩展模型能力。
这三个问题叠加在一起,导致Plugin在实际项目中的适用范围其实很窄。它适合做那种“单次调用、结果明确”的简单任务,比如查天气、查汇率、搜新闻。一旦任务链条变长、状态变多,Plugin就力不从心了。
2.3 从Plugin到Function Calling的过渡
Plugin之后,OpenAI很快推出了Function Calling。这个东西本质上把Plugin的能力下放到了API层面。你不再需要写OpenAPI规范文件,只需要在API请求里用JSON Schema描述你的函数,模型就会在需要的时候返回一个结构化的函数调用请求,由你自己的代码来执行。
Function Calling相比Plugin的最大进步是控制权回到了开发者手里。你可以在函数执行前后加任何逻辑,可以做缓存、可以做重试、可以做并行调用。而且Function Calling不绑定平台,你在自己的后端服务里想怎么用就怎么用。
但Function Calling也有它的问题。它解决的仍然是“模型如何调用一个函数”的问题,没有解决“模型如何完成一个多步骤任务”的问题。你可以在系统提示词里写“先调用A,再调用B,最后调用C”,但模型不一定会严格按这个顺序执行。而且当函数数量多起来之后,模型选择函数的准确率会明显下降。我实测过,当可用函数超过20个的时候,模型选错函数的概率大概在15%到20%之间,这个错误率在生产环境里是不可接受的。
3. Agent框架爆发期:编排层成为新的战场
3.1 为什么需要Agent框架
Function Calling解决了“调用”的问题,但没解决“编排”的问题。一个真实的业务任务往往需要多个步骤、多个工具、多个判断分支。比如“帮我分析一下最近三个月的销售数据并生成报告”这个任务,至少涉及:查询数据库、数据清洗、统计分析、图表生成、报告撰写五个环节。每个环节可能对应一个或多个函数调用,而且环节之间有依赖关系。
Agent框架就是在这个背景下火起来的。LangChain、AutoGPT、CrewAI、AutoGen,包括后来国内的一堆框架,本质上都在做同一件事:把多个函数调用组织成一个可执行的工作流。
3.2 主流Agent框架的架构差异
我实际用过比较深入的几个框架,它们的架构思路差别挺大的。
LangChain的思路是“链式编排”。你把每个步骤定义成一个Chain,然后把Chain串起来。每个Chain可以是一个LLM调用、一个函数调用、或者一个判断逻辑。LangChain的优势是生态丰富,几乎什么工具都有现成的集成。但它的抽象层太厚,调试起来很痛苦,而且版本迭代太快,经常升级一次就有一堆东西不能用了。
AutoGPT的思路是“自主规划”。你给它一个目标,它自己拆解任务、自己决定下一步做什么。这个思路很吸引人,但实际用下来,AutoGPT的自主性太强反而成了问题。它经常会陷入循环,或者做一些你完全没预期的操作。而且它的token消耗非常大,一个简单任务可能烧掉几十万token。
CrewAI的思路是“角色协作”。你定义几个不同的Agent角色,每个角色有自己的职责和工具,然后让它们协作完成任务。这个思路在模拟人类团队协作的场景下效果不错,但角色之间的通信开销很大,而且容易出现“互相等待”的死锁情况。
AutoGen的思路是“对话驱动”。多个Agent通过对话来协调任务,每个Agent可以是一个LLM、一个代码执行器、或者一个人工输入节点。AutoGen的灵活性很高,但配置复杂度也高,新手很难上手。
3.3 Agent框架的共性痛点
用了这么多框架之后,我发现它们有一些共同的痛点。
状态管理混乱。多步骤任务需要维护中间状态,但大多数框架对状态的管理都很粗糙。要么是全部塞在对话历史里,要么是让开发者自己维护一个全局字典。前者会导致上下文爆炸,后者容易出bug。
错误处理薄弱。当某个步骤失败时,框架通常只是简单地重试或者直接报错。但实际业务中,不同步骤的失败需要不同的处理策略。比如查询数据库失败可以重试,但数据校验失败重试多少次都没用。
可观测性差。一个任务跑了十几步,中间调了七八个工具,最后结果不对。你想知道是哪一步出了问题,但框架只给你一个最终的输出,中间的调用链路和参数都看不到。这个问题在调试阶段特别致命。
提示词工程复杂。每个Agent都需要一套精心设计的系统提示词,告诉它什么时候该用什么工具、怎么处理异常、输出格式是什么。这些提示词写起来很费劲,而且很难复用。
这些问题归根结底是因为Agent框架把太多的责任放在了“编排层”。它试图用一个通用的架构去解决所有任务编排问题,但不同任务的编排逻辑差异太大了,通用架构反而成了限制。
4. Claude-Skills:把“能力”变成“技能包”
4.1 Skills的设计哲学
Claude-Skills出来的时候,我第一反应是“这不就是Plugin吗”。但仔细看完文档之后,我发现完全不是一回事。
Claude-Skills的核心概念是:一个Skill就是一个包含指令、脚本和资源的文件夹。这个文件夹里可以有一个SKILL.md文件来描述这个Skill是干什么的、怎么用,可以有Python脚本、可以有模板文件、可以有参考数据。当用户的任务匹配到某个Skill时,Claude会加载这个文件夹里的内容,按照里面的指令来执行任务。
这个设计最巧妙的地方在于:它把“能力扩展”的问题转化成了“知识管理”的问题。你不需要写复杂的API描述,不需要设计函数签名,不需要考虑模型怎么选择工具。你只需要把完成某个任务所需的知识、步骤、脚本整理成一个结构化的文件夹,Claude自己会去读、去理解、去执行。
4.2 Skills与Plugin的本质区别
我用一个具体的例子来说明这个区别。
假设你要让模型帮你处理Excel文件。在Plugin/Function Calling的思路下,你需要:定义一个read_excel函数、定义一个write_excel函数、定义一个filter_data函数、定义一个create_chart函数,然后在系统提示词里告诉模型这些函数怎么用、什么时候用。模型每次处理Excel任务时,都要从这些函数里挑选合适的组合。
在Claude-Skills的思路下,你创建一个叫excel-toolkit的Skill文件夹,里面放一个SKILL.md写清楚“这个Skill用于处理Excel文件,支持读取、写入、筛选、生成图表”,再放几个Python脚本实现具体功能。当用户说“帮我分析这个Excel”时,Claude会自动加载这个Skill,阅读SKILL.md,然后按照里面的说明来调用脚本。
区别在哪里?Plugin模式下,模型是在“调用工具”;Skills模式下,模型是在“学习技能”。调用工具时,模型需要理解工具的接口;学习技能时,模型需要理解任务的方法论。前者是接口级别的扩展,后者是知识级别的扩展。
4.3 Skills的渐进式披露机制
Claude-Skills还有一个很聪明的设计叫“渐进式披露”。一个Skill文件夹里可以有很多内容,但Claude不会一次性全部加载。它先读SKILL.md的摘要,判断这个Skill是否相关;如果相关,再读详细指令;如果需要执行脚本,再加载脚本。这个机制的好处是:你可以把大量的领域知识塞进Skill里,而不用担心撑爆上下文窗口。
我实测过一个包含十几个参考文档和五六个脚本的Skill,Claude在回答简单问题时只会加载SKILL.md的前几行,只有在处理复杂任务时才会逐步加载更多内容。这个设计让Skills的扩展性比Plugin好很多。
5. 能力扩展方案选型:什么场景用什么方案
5.1 选型决策表
| 维度 | ChatGPT-Plugin | Function Calling | Agent框架 | Claude-Skills |
|---|---|---|---|---|
| 适用场景 | 简单单次调用 | 中等复杂度任务 | 复杂多步骤任务 | 领域知识密集型任务 |
| 开发成本 | 低 | 中 | 高 | 中 |
| 调试难度 | 低 | 中 | 高 | 低 |
| 上下文消耗 | 低 | 中 | 高 | 可控 |
| 跨平台性 | 无 | 好 | 好 | 目前仅Claude |
| 状态管理 | 无 | 开发者自管 | 框架管理 | 文件系统管理 |
| 适合团队 | 个人/小团队 | 中小团队 | 中大型团队 | 知识型团队 |
5.2 我的实际选型经验
做了这么多项目之后,我现在的选型逻辑是这样的。
如果任务非常简单,就是“查个数据然后告诉用户”,直接用Function Calling就够了,没必要上框架。如果任务涉及多个步骤但步骤是固定的,我会用Agent框架把流程编排好,但会把每个步骤的实现细节封装成独立的模块。如果任务需要大量的领域知识(比如法律文书处理、医疗报告分析),我会优先考虑Claude-Skills,因为它的知识管理能力确实比提示词工程要优雅得多。
还有一个很重要的考量因素是团队的技术栈。如果你的团队本来就是Python技术栈,那Agent框架的选择面会很广。如果你的团队更偏业务侧,没有太多工程能力,那Claude-Skills这种“写文档就能扩展能力”的方式会更友好。
5.3 混合方案的可行性
实际项目中,这几种方案并不是互斥的。我最近做的一个项目就是混合方案:用Function Calling处理实时数据查询,用Claude-Skills管理领域知识库,用轻量级的Agent编排层把两者串起来。关键是要想清楚每一层负责什么,不要让职责重叠。
6. 实操:从零搭建一个Claude-Skill
6.1 环境准备与目录结构
Claude-Skills目前主要是在Claude的桌面端和API中使用。如果你用的是Claude Desktop,Skills的存放路径通常在配置目录下的skills文件夹里。API方式的话,你需要通过特定的接口来注册和调用Skill。
一个标准的Skill目录结构是这样的:
my-skill/ ├── SKILL.md # 技能描述文件,必须 ├── scripts/ # 可执行脚本 │ ├── process.py │ └── utils.py ├── references/ # 参考文档 │ └── domain-knowledge.md └── assets/ # 模板、数据文件等 └── template.xlsxSKILL.md是整个Skill的入口,它的格式要求不算严格,但有几个关键部分需要写清楚。
6.2 SKILL.md的编写要点
我写SKILL.md的时候会遵循一个原则:假设读这个文件的人完全不了解这个领域。因为Claude在加载Skill时,确实对这个领域一无所知,它完全依赖SKILL.md来理解任务。
一个实用的SKILL.md模板大概长这样:
# Skill名称 ## 用途 一句话说明这个Skill是干什么的。 ## 触发条件 描述什么类型的用户请求应该使用这个Skill。 ## 使用步骤 1. 第一步做什么 2. 第二步做什么 3. ... ## 脚本说明 - `scripts/process.py`:处理输入数据,参数说明... - `scripts/utils.py`:辅助函数... ## 注意事项 - 什么情况下不要用这个Skill - 常见的错误用法我踩过的一个坑是:一开始我把SKILL.md写得太简略,只写了“这个Skill用于处理Excel”,结果Claude经常在不该用的时候加载它,或者加载了之后不知道具体该怎么做。后来我把触发条件写得很具体,比如“当用户提到.xlsx文件、需要做数据透视、需要生成图表时使用”,准确率就上来了。
6.3 脚本编写与调试
Skill里的脚本我用Python写得最多。有几个经验可以分享。
第一,脚本的输入输出要标准化。我习惯让所有脚本都接受JSON格式的输入,输出也是JSON。这样Claude在调用脚本时不容易出错,而且调试的时候也方便。
第二,脚本要能独立运行。不要依赖Claude传递的上下文,所有需要的信息都通过参数传进来。这样你可以在本地先测试脚本,确认没问题了再放进Skill里。
第三,错误信息要写清楚。脚本报错时,错误信息会返回给Claude,Claude会根据错误信息决定下一步怎么做。如果错误信息只是“Error”,Claude就懵了。如果错误信息是“输入文件格式不正确,期望.xlsx但收到了.csv”,Claude就知道该怎么处理了。
调试Skill的时候,我一般会先用Claude的对话界面手动触发几次,看看它加载Skill的逻辑对不对、执行步骤的顺序对不对。确认没问题了,再写自动化测试。
6.4 一个完整的Skill示例
我做一个“销售数据分析”的Skill来举例。
SKILL.md的内容:
# 销售数据分析 ## 用途 分析销售数据Excel文件,生成统计摘要和趋势图表。 ## 触发条件 用户提到销售数据、销售报表、业绩分析,并且提供了Excel文件或文件路径时使用。 ## 使用步骤 1. 确认输入文件路径和输出目录 2. 运行 scripts/analyze.py 进行数据读取和清洗 3. 运行 scripts/stats.py 计算统计指标 4. 运行 scripts/chart.py 生成趋势图 5. 汇总结果,生成分析报告 ## 脚本说明 - analyze.py: 输入 {"file_path": "路径", "sheet_name": "表名"},输出清洗后的数据摘要 - stats.py: 输入清洗后的数据,输出统计指标JSON - chart.py: 输入统计数据,输出图表文件路径 ## 注意事项 - 只支持.xlsx和.csv格式 - 如果数据量超过10万行,需要先做采样 - 图表默认保存为PNG格式这个Skill我实际用下来,处理一个中等规模的销售数据文件大概需要30秒到1分钟,比手动写pandas代码快很多,而且非技术同事也能用。
7. 常见问题与排查技巧实录
7.1 Skill加载失败怎么办
这是最常见的问题。Claude没有加载你期望的Skill,或者加载了错误的Skill。排查思路是这样的:
先检查SKILL.md的触发条件是否足够具体。如果触发条件写得太宽泛,Claude可能会在不该用的时候加载。如果写得太窄,又可能该用的时候不加载。我一般会写三到五个具体的触发场景,覆盖主要的用户表达方式。
然后检查文件编码。SKILL.md必须是UTF-8编码,如果有中文内容,编码不对会导致读取失败。这个问题很隐蔽,因为文件在编辑器里看起来是正常的,但Claude读出来就是乱码。
最后检查目录权限。如果Skill文件夹的权限设置不对,Claude可能没有读取权限。特别是在Linux环境下部署时,这个问题比较常见。
7.2 脚本执行报错的排查顺序
脚本报错时,按这个顺序排查:
- 先在本地终端手动运行脚本,确认脚本本身没问题
- 检查Claude传递的参数格式是否和脚本期望的一致
- 检查脚本依赖的库是否在运行环境中安装了
- 检查文件路径是绝对路径还是相对路径,Claude传递的路径可能和你的预期不一样
我遇到最多的问题是路径问题。Claude传递的路径有时候是相对于Skill目录的,有时候是相对于工作目录的,这个行为不太稳定。我的做法是在脚本里统一把路径转成绝对路径,避免歧义。
7.3 上下文窗口不够用的处理
虽然Skills有渐进式披露机制,但如果一个Skill的内容太多,还是可能撑爆上下文。我的处理方式是:
把大段的参考文档拆成多个小文件,在SKILL.md里只写摘要和索引。Claude需要详细信息时,再通过脚本去读取对应的文件。这样上下文里只保留摘要,详细信息按需加载。
另外,脚本的输出也要控制大小。如果脚本返回的数据量很大,不要直接全部返回给Claude,先在脚本里做聚合和摘要,只返回关键信息。
7.4 常见问题速查表
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| Skill不加载 | 触发条件不明确 | 细化触发条件描述 |
| Skill加载错误 | 多个Skill触发条件重叠 | 调整触发条件的边界 |
| 脚本执行超时 | 脚本处理数据量过大 | 增加采样或分页逻辑 |
| 输出格式不对 | SKILL.md未指定输出格式 | 在SKILL.md中明确输出格式要求 |
| 中文乱码 | 文件编码不是UTF-8 | 统一转换为UTF-8编码 |
| 路径找不到 | 相对路径解析不一致 | 脚本内统一转绝对路径 |
8. 能力扩展的未来走向
8.1 从“工具调用”到“技能学习”的范式转移
回头看这条演进线,其实是一个从“接口扩展”到“知识扩展”的过程。Plugin和Function Calling解决的是“模型能做什么”的问题,Agent框架解决的是“模型怎么组织多个动作”的问题,Claude-Skills解决的是“模型怎么掌握一套工作方法”的问题。
这个转移背后的驱动力是:大模型的基础能力越来越强,瓶颈从“模型不会做”变成了“模型不知道怎么做才对”。以前我们扩展模型能力,是因为模型连基本的工具调用都不会。现在我们扩展模型能力,是因为模型虽然会调用工具,但不知道怎么组合工具来解决一个复杂的业务问题。
8.2 对开发者的影响
这个变化对开发者的技能要求也产生了影响。以前做能力扩展,核心技能是API设计和提示词工程。现在做能力扩展,核心技能变成了领域知识梳理和流程设计。你需要能把一个业务问题拆解成清晰的步骤,把每个步骤的知识和工具整理成模型能理解的形式。
我觉得这是一个好的变化。它意味着不懂深度学习的人也能参与到AI应用的构建中来,只要你对自己的业务领域足够了解。同时,它也意味着纯技术背景的开发者需要补上业务理解的课。
8.3 我个人的一些判断
基于我自己的实践,我觉得接下来能力扩展方案会往两个方向走。
一个是更轻量的知识封装。Claude-Skills已经比Agent框架轻很多了,但我觉得还能更轻。未来可能会出现一种“知识卡片”的形式,你只需要写一段结构化的文字描述,模型就能理解并执行。不需要脚本,不需要文件夹,就是纯文本。
另一个是更强的自动化编排。现在的Agent框架还需要开发者手动设计工作流,未来模型可能会根据任务自动生成工作流。你只需要告诉它目标,它自己决定用什么工具、按什么顺序执行。这个方向已经有了一些早期探索,但离实用还有距离。
我在实际项目中的体会是:不要追新,要根据自己的业务场景选最合适的方案。Plugin虽然老,但在简单场景下依然好用。Agent框架虽然重,但在复杂流程编排上依然是首选。Claude-Skills虽然新,但在知识密集型任务上确实有独特优势。关键是想清楚你的核心需求是什么,然后选那个最能解决你问题的方案。