深入浅出:拆解实现skill

📅 发布时间:2026/10/15 7:38:31
深入浅出:拆解实现skill
深入浅出揭开 AI Agent 中 Skill 的神秘面纱随着大语言模型LLM的火热AI Agent智能体的概念也越来越普及几乎每家公司都在尝试打造自己的“超级助理”。但在实际开发和使用 Agent 的过程中我们经常会碰到几个让人头晕的专业名词Tool工具、MCP模型上下文协议以及今天我们要重点拆解的主角——Skill技能。很多小伙伴可能会疑惑既然我们已经有了一个无所不知的大模型并且也给它配备了各种可以调用的 API 工具为什么还要在中间搞出一个“Skill”的概念呢它到底是个啥它和单纯的 Tool 有什么本质区别今天咱们就用最接地气的大白话结合一些具体的代码示例把 Skill 这个概念掰开揉碎了好好聊一聊。1. 什么是 Skill如果把大模型LLM比作一个拥有超强记忆力和逻辑推理能力的“超级大脑”那么我们要明白一点大脑本身是与物理世界隔离的。为了让它干活我们需要给它装备和指导。如果不装载任何 Skill大模型就像一个“刚毕业的顶级学霸”。你让他造火箭他能给你默写出火箭的理论公式但你让他去车间拧螺丝他可能连扳手在哪都找不到。Tool工具就像是车间里的扳手、螺丝刀是基础的执行单元。Skill技能则像是“修车这门手艺的SOP标准作业程序”。简单来说Skill 是针对特定业务场景或复杂任务的高阶能力封装。它不仅仅包含了一组工具给你一把扳手更重要的是它包含了完成这项任务的领域知识Domain Knowledge、标准操作流程Prompt 指导、异常处理逻辑以及工作流Workflow。举个例子当你对 Agent 说“帮我给这段代码写个单测”时。如果只是普通的 Tool 堆砌大模型可能会胡乱调用搜索工具然后给出一个通用但不一定能跑通的代码。但如果 Agent 加载了“单元测试 Skill”它就瞬间从一个“通才”变成了一个“资深测试工程师”。它知道第一步该用什么工具去读取当前代码上下文第二步该用什么框架Jest/JUnit第三步如果运行失败了该如何读取报错日志并自我修复Self-Correction。Skill就是赋予 Agent “职业灵魂”的插件。2. Skill 与 Tool、MCP 的区别这三个概念在开发 Agent 时总是形影不离但它们的定位完全不同。咱们来打个生动的比方假设我们要开一家智能餐厅Agent Tool工具切菜刀、炒锅、煤气灶。定位原子的、单一功能的执行单元。特点比如read_file读文件、web_search网络搜索。它没有任何业务逻辑它不管你是要做鱼香肉丝还是宫保鸡丁它只负责执行“切”或者“烧”这个具体的动作。 MCPModel Context Protocol模型上下文协议厨房电器的通用插座与标准化接口。定位一种标准化的通信协议比如 Anthropic 牵头推出的那个。特点过去每个大模型调用工具的格式都不一样接入新工具要写一堆适配代码。有了 MCP它就像统一了厨房的插座标准国标。只要你的数据源或工具符合 MCP 标准不管是哪家的大模型Agent插上就能用。它解决的是“连接”和“标准化”的问题。 Skill技能《米其林三星主厨的独家菜谱》 主厨的经验。定位带着知识和工具的场景化解决方案。特点Skill 决定了什么时候去拿切菜刀Tool通过什么标准接口MCP去获取本地的食材数据以及遇到火候不对时该怎么补救最终怎么把这些食材炒成一盘好菜。它是一套端到端End-to-End的逻辑闭环。一句话总结Tool 是肢体动作MCP 是神经连接协议而 Skill 则是特定领域的肌肉记忆和专家思维。3. 如何实现一个 Skill把理论化为实践要实现一个真正好用的 Skill可不是随便写两句 Prompt 就完事了。本质上我们需要把“大模型的角色设定”、“相关的 Tools”以及“特定的执行逻辑”打包成一个高内聚的模块。一般来说开发一个完整的 Skill 需要定义以下几个核心部分触发意图Intent / Trigger用户说了什么话或者在 IDE 里做了什么操作比如选中了一段代码右键需要唤醒这个 Skill通常会通过向量检索或小模型来做意图匹配。专家身份与上下文System Prompt给 LLM 注入特定领域的知识和 SOP。比如“你现在是一个有着 10 年经验的 Node.js 性能优化专家你需要严格按照以下三步来排查内存泄漏问题…”专属工具集Toolchains这个 Skill 需要用到哪些具体的 Tool 或 MCP Server。为了避免大模型“分心”或触发幻觉通常只在加载该 Skill 时才把这部分特定的工具暴露给它。生命周期与工作流Lifecycle WorkflowOnLoad加载时初始化一些前置条件比如检查用户的 Git 状态。OnExecute执行中可能包含多轮的思考-执行循环ReAct 模式。OnError错误恢复如果调工具失败了Skill 内部应该怎么引导大模型重试。OnUnload卸载时清理上下文把控制权交还给主 Agent。4. 当前 Skill 的架构在一个成熟的 Agent 框架比如 IDE 里的智能助手中Skill 的架构通常是高度插件化Pluggable的。你可以把它想象成手机里的 App StoreAgent 就是操作系统iOS/Android而 Skill 就是一个个可以下载安装的 App。 进阶理解Skill 架构与多智能体Multi-Agent架构的异曲同工之妙如果你仔细观察我们当前的设计会发现Skill 架构本质上就是一种多智能体Multi-Agent架构的落地实现。在我们的代码中Main Agent主智能体扮演着“路由节点”或“项目经理Manager Agent”的角色。它负责理解用户的总目标然后将具体的子任务分发给不同的 Skill。Skill子智能体每一个装载了特定 System Prompt 和工具集的 Skill其实就是一个独立的“专家智能体Worker Agent”。当主 Agent 发现需要进行复杂计算时它不是自己拿着计算器工具去硬算而是把整个任务Task作为参数调用了特殊的 Skill Tool。此时控制权交给了“计算专家”子 Agent计算专家在一个独立的“沙箱”里思考、调用工具、得出结论后再把结果返回给主 Agent。这种**“Agent 嵌套 Agent”、“把 Agent 封装成 Tool”**的模式正是目前业界处理复杂任务时最推崇的 Multi-Agent 协作范式它的流转过程和架构大概是这样的[ 用户输入 User Input / 上下文动作 ] | v [ 意图路由层 Intent Router ] |-- 负责理解用户想要干什么。 |-- 比如识别出用户想要 Code Review代码审查。 | v [ 动态加载器 Skill Loader ] |-- 从技能市场或本地仓库加载对应的 CodeReviewSkill。 |-- 这一步会进行“上下文隔离”防止上一个“写文档”的技能干扰当前任务。 | v [ ⚡️ Skill 沙箱运行环境 (Skill Execution Engine) ] |-- 1. 注入专家 Prompt (System Message) |-- 2. 挂载专属工具 (git_diff, inline_comment 等) |-- 3. [核心执行循环]: 观察(Observation) - 思考(Thought) - 动作(Action) |-- 4. 自我纠错机制 (如果有报错在沙箱内尝试解决) | v [ 技能卸载 输出给用户 Output ]这种架构的巨大优势在于高内聚低耦合。你可以随时给 Agent 安装新的 Skill比如“画图技能”、“数据库 SQL 诊断技能”而不需要去改动 Agent 的核心底层代码。这使得 Agent 的能力可以无限水平扩展。5. Skill 的实现案例光说不练假把式。为了让大家有更直观的体感咱们来看一下本项目 (src目录下) 是如何用 TypeScript 真正落地这套架构的。- 步骤 1定义基础 Tool 工具 (src/tool.ts)工具 (Tool) 是最底层的原子能力。我们需要将其封装成大模型能够理解的格式比如 JSON Schema。// src/tool.ts 核心代码片段exportclassTool{name:string;description:string;parameters:object;private_execute:(params:any)any|Promiseany;constructor({name,description,parameters,execute}:ToolConfig){this.namename;this.descriptiondescription;this.parametersparameters??{type:object,properties:{}};this._executeexecute;}// 真正执行工具动作asyncrun(params:any):Promisestring{constrawaitthis._execute(params);returntypeofrstring?r:JSON.stringify(r);}// 转换为大模型标准 function calling 格式 (Schema)toSchema():ToolSchema{return{type:function,function:{name:this.name,description:this.description,parameters:this.parameters},};}}- 步骤 2封装 Skill 技能 (src/skill.ts)Skill 不仅仅是一组 Tool 的集合它自身也相当于一个“领域专家”。在我们的架构中Skill 甚至可以作为一个特殊的 Tool 注册给主 Agent即 Agent 嵌套。// src/skill.ts 核心代码片段exportclassSkill{name:string;description:string;systemPrompt:string;// 注入领域专家知识tools:Tool[];// 技能专属的工具集privateagent?:Agent;// 生命周期钩子onLoad?:()void;onExecute?:(task:string)void;onError?:(error:any)void;onUnload?:()void;// 初始化技能内部的 Agent 沙箱initAgent(baseConfig:PartialAgentConfig){this.agentnewAgent({...baseConfig,systemPrompt:this.systemPrompt,tools:this.tools,});this.onLoad?.();// 触发加载生命周期}// 运行该技能asyncrun(task:string):Promisestring{if(!this.agent)thrownewError(Skill ${this.name} not initialized.);try{this.onExecute?.(task);// 触发执行中生命周期returnawaitthis.agent.invoke(task);// 调用 LLM 解决任务}catch(error){this.onError?.(error);// 触发错误恢复生命周期throwerror;}}// 卸载技能unload(){this.onUnload?.();// 触发清理生命周期this.agentundefined;}// 核心亮点把整个 Skill 包装成一个供外部 Agent 调用的 ToolasTool():Tool{returnnewTool({name:this.name,description:this.description,parameters:{type:object,properties:{task:{type:string}},required:[task]},execute:async({task}:{task:string}){console.log(\n[Skill 委派] 将任务转交给技能 ${this.name}:${task});returnawaitthis.run(task);// 转交给专属专家处理},});}}- 步骤 3Agent 的调度与调用 (src/agent.ts src/index.ts)最后主 Agent 作为“大脑”统筹调度所有的 Skill 和基础 Tool。// src/agent.ts 核心调度逻辑片段exportclassAgent{// ...省略构造逻辑...asyncinvoke(input:string):Promisestring{this.messages.push({role:user,content:input});// 获取所有可用工具/技能的 SchemaconstschemasArray.from(this.tools.values()).map((t)t.toSchema());letrounds0;// 核心 ReAct 循环大模型思考 - 调用工具 - 获取结果 - 继续思考while(rounds10){constmsgawaitthis._chat(schemas);// 调用大模型 APIthis.messages.push(msg);// 如果大模型不要求调用工具说明任务完成直接返回if(!msg.tool_calls?.length){returnmsg.content??;}// 执行大模型指定的工具调用for(consttcofmsg.tool_calls){consttoolthis.tools.get(tc.function.name);constparamsJSON.parse(tc.function.arguments||{});constresulttool?awaittool.run(params):Tool ${tc.function.name} not found;this.messages.push({role:tool,tool_call_id:tc.id,content:result});}}return[超出最大调用次数];}}来看看实际应用场景 (src/index.ts)我们给 Agent 装载了“数学专家”和“日常助手”两个 Skill。当遇到复杂问题时主 Agent 会像项目经理一样把子任务委派给对应的专家// 1. 定义一个日常助手 SkillconstgeneralSkillnewSkill({name:general_assistant,description:日常信息查询工具,systemPrompt:你是一个贴心的日常助手可以帮助用户查询时间和天气。,tools:[newTool({name:get_time,execute:()({time:newDate().toISOString()}),}),newTool({name:get_weather,parameters:{type:object,properties:{city:{type:string}},required:[city]},execute:({city})({city,weather:晴朗 ☀️,temperature:25°C}),}),],});// 2. 实例化主 Agent挂载各种 SkillconstagentnewAgent({apiKey:YOUR_API_KEY,// 替换为真实的 API Keymodel:gpt-4o,skills:[calculationSkill,generalSkill],// 装载技能systemPrompt:你是一个全能超级智能体根据用户需求委派给合适的技能专家。,});// 测试调度agent.invoke(现在几点了并帮我计算1000*99等于多少).then(console.log);在这个真实的项目架构中你可以清晰地看到职责的划分Tool负责封装底层的 API 接口能力。Skill负责将特定的System Prompt与其专属的Tool结合并且可以向上暴露为一个高阶 Tool供外部调度。Agent负责驱动 LLM 大模型进行意图识别、ReAct 循环以及任务的路由委派。6. 总结Skill 的本质看到这里相信你对 Skill 已经有了一个立体、直观的认识。Skill 的本质其实就是“特定场景下Agent 能力的标准化、插件化打包”。我们可以从三个维度来总结它的核心价值Prompt Engineering提示词工程的沉淀与复用把人类专家在某个领域的最佳实践SOP固化成了系统提示词和流程代码。你不需要每次都教大模型怎么写单测加载对应的 Skill 就行了。工具上下文的隔离与收敛避免一次性把成百上千个 Tool 扔给大模型导致它“眼花缭乱”超出 Context Window 且极易产生幻觉而是按需精准分配工具提高执行的成功率和稳定性。Agent 进化的基石正如智能手机因为有了 App Store 才变得无所不能Skill 就是 AI 时代的 App。它让 Agent 的能力可以被解耦、被无限扩展、被分发甚至被交易。未来的 AI 助手一定是一个搭载了无数精良 Skill 的“操作系统”。以后再遇到复杂的任务别急着让大模型硬上也别指望只塞给它几个裸露的 Tool 它就能干好。先想一想我是不是可以为它开发一个专属的 Skill 呢完整案例https://github.com/CatiiHuang/SkillAndAgent