恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
agent-skills 实战:从工具调用到技能封装,让智能体真正会干活
首页
资讯中心
/
agent-skills 实战:从工具调用到技能封装,让智能体真正会干活
agent-skills 实战:从工具调用到技能封装,让智能体真正会干活
发布时间:2026/10/11 9:47:34
1. 从“会聊”到“会做”agent-skills 到底在解决什么问题第一次看到 agent-skills 这个词很多人会下意识把它理解成“给智能体加几个插件”。这个理解不算错但太浅了。真正做过智能体落地的人都知道一个能对话的模型和一个能稳定干活的智能体之间隔着的不是几个接口而是一整套能力封装、调度、校验和复用机制。agent-skills 要处理的正是这层机制。我先把话说直白一点大模型本身只会“生成文本”它不会读文件、不会调接口、不会记住上次任务做到哪一步、更不会在失败后自己换条路重试。你让它写一段代码它能写你让它把这段代码跑通、报错后自己修、修完再验证结果它就开始露怯了。agent-skills 的价值就是把这些“露怯”的环节变成一个个可被调用、可被组合、可被测试的标准化技能单元。打个比方模型是大脑agent-skills 是手和脚外加一套肌肉记忆。大脑再聪明没有手脚也搬不动箱子有了手脚但没有肌肉记忆搬两次就累趴下。skills 就是让智能体从“纸上谈兵”变成“真能干活”的那套基础设施。这套东西适合谁看三类人最该关注。第一类是正在做智能体应用的开发者你大概率已经踩过“工具调用不稳定、上下文爆炸、任务跑一半断了”的坑第二类是做自动化流程的产品和技术负责人你在评估智能体到底能不能替代一部分人工操作第三类是对 AI 应用感兴趣、想自己动手搭一个能干活的小助手的爱好者。不管你是哪一类只要你想让智能体从“会聊”进化到“会做”agent-skills 这套思路就绕不开。接下来我会从整体设计思路、核心细节、实操落地、问题排查四个层面把 agent-skills 拆开讲透。里面会穿插我自己踩过的坑和一些实测有效的做法尽量让你看完就能上手而不是看完只觉得“有道理但不知道从哪下手”。2. 整体设计与思路拆解为什么是“技能”而不是“工具”2.1 工具调用和技能封装差的不只是一个名字很多人会问现在模型不是已经支持 function calling 了吗直接定义几个工具让模型调不就行了为什么还要搞一层 skills这个问题问到点子上了我一开始也是这么想的直到我在一个真实项目里被工具调用坑到怀疑人生。工具调用的本质是“模型输出一个结构化请求外部执行后把结果塞回去”。它解决的是“模型能不能触发一个动作”的问题。但真实任务里一个动作往往不是一步而是一串先读数据、再清洗、再计算、再写回、最后校验。如果你把这一串全塞进一个工具里工具会变得又大又难维护如果你拆成五个工具让模型自己串模型很容易在中间某一步跑偏或者把参数传错。skills 的思路不一样。它把“完成一类任务所需的完整能力”打包成一个技能技能内部可以包含多个步骤、多个工具、甚至多轮自我校验对外只暴露一个清晰的调用入口。模型不需要知道技能内部怎么实现它只需要知道“我现在该用哪个技能、传什么参数”。我用一个生活化的类比来解释。工具调用像是给一个刚学做饭的人一堆厨具告诉他“这是刀、这是锅、这是盐”然后让他自己看着办。skills 像是给他一本菜谱菜谱里写清楚了“做番茄炒蛋需要先打蛋、再切番茄、热锅下油、先炒蛋盛出、再炒番茄、最后混合”。前者考验的是这个人的临场发挥后者考验的是菜谱写得好不好。显然后者更容易稳定复现。2.2 技能的三层结构描述层、执行层、校验层一个设计良好的 skill我习惯把它拆成三层来看。描述层是给模型看的。它用自然语言说清楚这个技能是干什么的、什么时候该用、需要哪些输入、会产出什么。这一层的关键是“边界清晰”不能让模型觉得“这个技能好像也能干那个活”。描述模糊是技能被误用的头号原因。执行层是真正干活的代码。它可以是几个函数调用、一段脚本、一次接口请求甚至是对另一个技能的编排。执行层要尽量做到“输入确定、输出确定、副作用可控”。什么叫副作用可控就是这个技能执行完除了它该改的东西别的地方不能被动。我见过一个技能在执行时顺手改了全局配置结果把后面所有任务都带偏了。校验层是最容易被忽略、但最重要的一层。它负责判断“这次执行到底成没成”。校验可以是格式检查、可以是结果比对、可以是异常捕获也可以是让模型自己对结果做一次复核。没有校验层的技能就像没有刹车的车平时看着能跑一出事就是大事。这三层结构的好处是职责分明。描述层出问题模型会选错技能执行层出问题任务会跑失败校验层出问题失败会被掩盖。排查问题时按这三层去定位效率会高很多。2.3 为什么技能要“可组合”而不是“大而全”设计技能时有个很常见的诱惑既然模型调用技能有开销那我干脆做一个超级技能把所有功能都塞进去一次调用全搞定。这个想法听起来很省事实际是个坑。超级技能的问题有三个。第一描述层会变得极其臃肿模型很难判断什么时候该用它误用率飙升。第二执行层内部逻辑复杂任何一个小改动都可能影响其他功能维护成本指数级上升。第三校验层没法做细粒度判断只能给一个笼统的“成功/失败”出问题时根本不知道是哪一步坏了。正确的做法是让技能保持“单一职责”然后通过组合来完成复杂任务。比如“读取数据”是一个技能“清洗数据”是一个技能“生成报告”是一个技能复杂任务由上层编排把它们串起来。这样每个技能都短小精悍容易测试、容易替换、容易复用。组合的方式有两种。一种是显式编排就是由代码或流程定义好先调哪个再调哪个模型只负责在关键节点做判断。另一种是隐式编排就是模型根据任务目标自己决定调用顺序。前者稳定但不够灵活后者灵活但容易跑偏。我的经验是核心流程用显式编排保底边缘判断用隐式编排增加灵活性两者结合最稳。2.4 技能注册与发现让模型知道“我有哪些本事”技能写好了还得让模型知道它们的存在。这就涉及技能注册与发现机制。最简单的做法是把所有技能描述塞进系统提示词里但技能一多提示词会爆炸模型反而记不住。更合理的做法是分层注册。把技能按领域分组每组有一个简短的组描述模型先选组再选组内的具体技能。这样提示词的长度可控模型的决策路径也更清晰。还有一种做法是“按需加载”就是根据当前任务动态检索相关技能只把最相关的几个塞给模型。这需要一套检索机制通常用向量匹配或者关键词匹配来实现。检索的好处是提示词极短坏处是检索不准时会漏掉关键技能。我一般会在检索之外保留一个“常用技能”白名单保证核心能力永远可见。提示技能描述里一定要写清楚“不适用场景”。只写“这个技能能干什么”模型容易过度使用补上“什么情况下不要用这个技能”误用率会明显下降。3. 核心细节解析与实操要点把技能写“稳”的关键3.1 技能描述怎么写才不会被误用技能描述是模型决策的唯一依据写得好不好直接决定调用准确率。我总结了一个描述模板实测下来比自由发挥稳定得多。描述应该包含四个部分能力声明、触发条件、输入说明、输出说明。能力声明用一句话说清楚这个技能干什么触发条件说明什么情况下该用输入说明列出参数和格式输出说明描述返回结果的结构。举个例子一个“读取表格数据”的技能描述可以这样写能力声明是“从指定路径读取表格文件并返回结构化数据”触发条件是“当任务需要获取表格内容且数据尚未加载时使用”输入说明是“需要文件路径支持常见表格格式”输出说明是“返回行列表每行是一个字段到值的映射”。这里有个细节很多人会忽略参数格式要写死。不要写“路径可以是相对或绝对”而要写“路径必须是绝对路径”。模型对模糊表述的处理很不稳定你给它留的模糊空间越大它传错参数的概率越高。还有一个技巧是给技能起名要“动词开头、语义明确”。叫“read_table”比叫“table_util”好叫“send_email”比叫“email_helper”好。名字本身就是模型判断用途的重要线索。3.2 参数校验别指望模型每次都传对即使描述写得再清楚模型传错参数也是常态。所以执行层的第一件事永远是参数校验而不是直接干活。参数校验要检查三样东西类型对不对、范围合不合理、必填项有没有缺。类型检查是基础比如路径应该是字符串、数量应该是数字。范围检查是防止模型给出离谱的值比如读取行数传了个负数。必填项检查是防止模型漏传关键参数。校验失败时怎么处理直接报错是一种方式但更好的方式是返回一个清晰的错误说明让模型有机会自我修正。比如返回“路径参数缺失请提供绝对路径”模型看到后往往会重新调用一次并补上参数。这比直接抛异常让整个任务中断要友好得多。我踩过的一个坑是早期我写的技能在参数错误时直接抛异常结果模型收到异常后不知道该怎么办要么重复调用同样的错误参数要么干脆放弃任务。后来改成返回结构化错误信息任务成功率明显提升。3.3 执行隔离一个技能崩了不能拖垮全局技能执行时一定要做隔离。什么叫隔离就是这个技能无论怎么失败都不能影响其他技能和主流程。隔离的手段有几个层面。超时控制是必须的任何技能都要设一个最大执行时间超时就中断不能让一个卡死的技能拖住整个任务。异常捕获也是必须的技能内部抛出的异常要在技能边界被捕获并转成结构化结果不能让它冒泡到主流程。资源限制在有条件时也要做比如限制内存占用、限制并发数。我见过一个真实案例一个技能在读取超大文件时把内存吃满导致整个进程崩溃前面所有任务的中间结果全丢了。后来加了文件大小上限和流式读取问题才解决。这个教训是技能不能假设输入永远合理防御性编程在技能层比在普通代码里更重要。3.4 结果校验怎么判断“真的成了”结果校验是技能可靠性的最后一道防线。校验方式取决于技能类型常见的有几种。格式校验适用于输出结构固定的技能检查返回结果是否符合预期结构。内容校验适用于有明确正确性标准的技能比如计算结果是否在合理范围内。交叉校验适用于关键操作用另一种方式验证结果比如写完文件后重新读一遍确认内容。模型复核适用于主观性较强的技能让模型自己判断结果是否满足要求。校验不通过时可以选择重试、降级或者上报。重试适合偶发失败降级适合有备选方案的情况上报适合必须人工介入的情况。我的经验是重试次数不要超过两次超过两次还失败说明不是偶发问题继续重试只是浪费资源。注意校验逻辑本身也可能有 bug。我遇到过校验函数写错导致所有结果都被判为失败的情况排查了半天才发现是校验的问题而不是技能的问题。所以校验逻辑也要测试不能想当然。3.5 上下文管理技能之间怎么传递信息多个技能协作时信息怎么传递是个大问题。全塞进上下文会让提示词爆炸不塞又会让后续技能拿不到需要的数据。我的做法是分层存储。技能之间传递的中间结果放在一个结构化的“工作区”里模型只看到工作区的摘要和索引需要具体数据时再按需读取。这样上下文里只保留关键信息具体数据放在外部存储。工作区的结构要设计好通常包含任务目标、已完成步骤、当前状态、待处理事项、关键数据引用。模型每次决策前先看工作区就能知道任务进行到哪了、下一步该干什么。这里有个容易忽略的点工作区要定期清理。任务跑久了工作区会积累大量过期信息反而干扰模型判断。我一般会在每个主要阶段结束时清理一次只保留对后续有用的内容。4. 实操过程与核心环节实现从零搭一个技能体系4.1 环境准备与基础框架选型动手之前先把基础框架定下来。技能体系的框架不需要多复杂核心就是三件事技能注册表、技能执行器、工作区管理。技能注册表负责存储所有技能的描述和实现引用。最简单的实现就是一个字典键是技能名值是描述和函数。复杂一点可以用配置文件或者数据库支持动态加载。技能执行器负责接收调用请求、校验参数、执行技能、校验结果、返回结构化响应。它是技能和主流程之间的中间层所有隔离和校验逻辑都在这里实现。工作区管理负责存储和检索任务中间状态。简单场景用内存字典就够需要持久化就用文件或者轻量数据库。语言选择上Python 是绝大多数人的首选生态成熟、上手快。如果你追求性能或者要和现有系统集成也可以用其他语言但核心思路是一样的。# 技能注册表的极简实现 SKILL_REGISTRY {} def register_skill(name, description, func): SKILL_REGISTRY[name] { description: description, func: func } def list_skills(): return [ {name: name, description: info[description]} for name, info in SKILL_REGISTRY.items() ]这段代码虽然简单但已经包含了技能体系的核心注册和发现。后面所有的复杂度都是在这个基础上叠加的。4.2 写第一个技能从“读取文件”开始第一个技能建议从最简单的开始比如读取文件。它的逻辑足够简单能让你把整个流程跑通又不会在细节上卡太久。技能实现要包含参数校验、执行逻辑、结果校验三部分。参数校验检查路径是否存在、是否是文件、大小是否超限。执行逻辑读取内容。结果校验检查内容是否为空、编码是否正确。import os def read_file_skill(path, max_size1024*1024): # 参数校验 if not isinstance(path, str): return {success: False, error: 路径必须是字符串} if not os.path.isabs(path): return {success: False, error: 路径必须是绝对路径} if not os.path.exists(path): return {success: False, error: 文件不存在} if os.path.getsize(path) max_size: return {success: False, error: 文件超过大小限制} # 执行逻辑 try: with open(path, r, encodingutf-8) as f: content f.read() except Exception as e: return {success: False, error: f读取失败: {str(e)}} # 结果校验 if not content: return {success: False, error: 文件内容为空} return {success: True, data: content}这个技能虽然简单但已经体现了前面说的所有原则参数校验、异常捕获、结果校验、结构化返回。你可以照着这个模板写其他技能。4.3 技能编排把多个技能串成一条流水线单个技能只能干一件事真正有价值的是把多个技能串起来完成复杂任务。编排有两种方式我先讲显式编排因为它更稳定。显式编排就是用一个流程定义把技能按顺序串起来每个技能的输出作为下一个技能的输入。流程定义可以是代码也可以是配置。代码方式灵活配置方式易改。def run_pipeline(steps, initial_input): workspace {input: initial_input, steps: []} for step in steps: skill_name step[skill] params step.get(params, {}) # 从工作区取参数 for key, ref in params.items(): if isinstance(ref, str) and ref.startswith($): params[key] workspace.get(ref[1:]) # 执行技能 result execute_skill(skill_name, params) workspace[steps].append({ skill: skill_name, result: result }) if not result[success]: return {success: False, workspace: workspace} # 把结果写回工作区 workspace[step[output_key]] result[data] return {success: True, workspace: workspace}这段编排代码的核心是工作区。每个技能从工作区取参数执行完把结果写回工作区。这样技能之间不需要直接耦合通过工作区间接传递数据。隐式编排则是让模型根据任务目标自己决定调用顺序。实现方式是给模型提供技能列表和当前工作区状态让模型输出下一步该调哪个技能、传什么参数。这种方式灵活但需要更强的校验和兜底。我的建议是核心流程用显式编排异常处理和边缘判断用隐式编排。比如数据处理的主流程是固定的就用显式编排但遇到数据格式异常时该重试还是该跳过可以交给模型判断。4.4 参数计算与选择几个关键数值怎么定技能体系里有几个关键参数需要根据实际情况调整我把我常用的取值和理由说一下。技能超时时间默认设 30 秒。读取类技能可以短一些10 秒足够计算类技能可以长一些60 秒。超过 60 秒的技能建议拆成异步任务不要让主流程干等。重试次数默认 2 次。第一次失败可能是偶发第二次失败基本可以判定是系统性问题继续重试意义不大。重试之间要有间隔我一般用指数退避第一次等 1 秒第二次等 2 秒。工作区保留条数默认保留最近 20 条记录。太少会丢失上下文太多会干扰模型判断。如果任务步骤特别多可以按阶段清理每个阶段只保留该阶段的关键记录。技能描述长度单个技能描述控制在 100 字以内。超过 100 字说明这个技能职责不够单一考虑拆分。所有技能描述加起来控制在 2000 字以内超过就要考虑分组或按需加载。这些数值不是绝对的你要根据自己的场景调整。但调整时要有依据不能凭感觉。比如超时时间你可以先统计技能的实际执行时间分布取 95 分位数的两倍作为超时时间这样既能覆盖绝大多数情况又不会让异常情况拖太久。4.5 一个完整的实操案例自动整理数据并生成报告我把前面讲的东西串起来走一个完整案例。任务目标是读取一个数据文件清洗数据计算统计指标生成报告。第一步是定义技能。需要四个技能读取文件、清洗数据、计算统计、生成报告。每个技能都按前面的模板写包含参数校验、执行逻辑、结果校验。第二步是定义流程。流程是读取文件 → 清洗数据 → 计算统计 → 生成报告。每个步骤指定技能名、参数来源、输出键名。第三步是执行流程。调用编排函数传入流程定义和初始输入。编排函数会依次执行每个技能把结果写回工作区遇到失败就中断并返回工作区状态。第四步是处理结果。如果成功从工作区取出报告内容如果失败从工作区取出失败步骤和错误信息决定是重试还是上报。这个案例看起来简单但包含了技能体系的全部核心环节。你把每个环节都跑通一遍再扩展到更复杂的场景就有底了。提示第一次跑流程时建议在每个技能里加详细日志记录输入参数、执行时间、输出摘要。这些日志在排查问题时非常有用等流程稳定后可以降低日志级别。5. 常见问题与排查技巧实录那些文档里不会写的坑5.1 技能调用准确率低模型总是选错技能这是最常见的问题表现是模型该调 A 技能时调了 B 技能或者该调技能时直接自己编答案。排查思路分三步。先看技能描述是不是有重叠两个技能描述如果都包含“处理数据”这种模糊词模型分不清很正常。再看技能数量是不是太多超过 15 个技能后模型的选择准确率会明显下降这时候要考虑分组或按需加载。最后看提示词里有没有给模型足够的决策依据比如当前任务状态、上一步结果这些信息能帮模型做出更准确的判断。解决技巧给每个技能加一个“反例说明”明确写出“这个技能不适用于什么情况”。比如“读取文件技能不适用于读取数据库数据库请用查询技能”。反例说明能显著降低误用率。5.2 任务跑一半断了中间结果全丢这个问题通常是两个原因导致的。一是技能执行时抛了未捕获的异常把主流程带崩了。二是工作区没有持久化进程重启后状态丢失。排查时先看日志里有没有未捕获异常有的话在技能边界加异常捕获。再看工作区是不是只在内存里如果是改成定期持久化到文件或数据库。解决技巧工作区持久化不需要每步都写可以每完成一个主要阶段写一次。这样既保证状态可恢复又不会因为频繁写盘拖慢速度。恢复时从最近的持久化点继续不用从头再来。5.3 技能执行越来越慢最后卡死技能执行变慢通常是资源泄漏导致的。常见的有文件句柄没关、网络连接没释放、内存没回收。排查时先看资源监控确认是哪种资源在涨。然后检查技能实现里有没有忘记关闭的资源。Python 里用 with 语句能自动关闭文件网络请求要用上下文管理器或者显式关闭。解决技巧给每个技能加资源使用上限超过上限就强制中断并记录。这样即使有泄漏也不会让整个系统卡死。另外定期重启执行进程也是个简单有效的兜底手段。5.4 模型传的参数格式总是不对参数格式问题很烦人模型有时候传字符串有时候传数字有时候传列表有时候传单个值。排查时先看技能描述里的参数说明是不是足够明确。如果只写“传入数量”模型可能传“5”也可能传 5。要写成“传入整数类型的数量”。解决技巧在参数校验层做类型转换和容错。比如模型传了字符串“5”校验层尝试转成整数 5转换成功就继续失败才报错。这样能兼容模型的格式波动减少不必要的失败。5.5 常见问题速查表问题现象可能原因排查方向解决技巧技能选错描述重叠或数量过多检查描述边界和技能总数加反例说明分组或按需加载任务中断异常未捕获或状态丢失查日志和工作区持久化技能边界加捕获定期持久化执行变慢资源泄漏监控资源使用加资源上限定期重启参数格式错描述不明确检查参数说明校验层做类型转换容错结果被误判校验逻辑有 bug单独测试校验函数校验逻辑也要写测试上下文爆炸中间结果全塞提示词检查工作区大小分层存储只传摘要和索引这张表是我自己排查问题时总结的基本覆盖了八成以上的常见问题。遇到新问题时先对照这张表看看是不是已知问题不是的话再按“描述层、执行层、校验层”三层去定位。5.6 几个独家避坑技巧第一个技巧是给技能加版本号。技能实现改了之后老任务可能还在用老版本直接替换会导致行为不一致。加版本号后新任务用新版本老任务继续用老版本平滑过渡。第二个技巧是技能执行前先做一次干跑。干跑就是只校验参数不真正执行确认参数没问题再执行。这样能把参数错误和执行错误分开排查时更清晰。第三个技巧是给关键技能加人工确认点。有些操作副作用很大比如删除数据、发送消息这种技能执行前应该暂停等人工确认后再继续。不要完全信任模型的判断。第四个技巧是定期回放历史任务。把过去失败的任务拿出来重新跑一遍看看在新版本技能下能不能成功。这能帮你发现技能的回归问题也能验证改进效果。6. 技能体系的扩展与长期维护6.1 技能库怎么从 10 个长到 100 个还不乱技能少的时候怎么放都行技能多了就必须有组织结构。我的做法是按“领域 动作”两个维度分类。领域比如“文件”“网络”“数据”“文本”动作比如“读取”“写入”“转换”“校验”。每个技能归属到一个领域和一个动作查找时先定位领域再定位动作。分类之外还要有命名规范。技能名统一用“领域_动作_对象”的格式比如“file_read_text”“data_clean_table”。命名规范的好处是看名字就知道技能干什么不用翻描述。还要有技能的生命周期管理。新技能先标记为“实验”稳定后标记为“正式”废弃的标记为“弃用”。模型只看到正式技能实验技能只在特定场景下开放。这样能避免不成熟的技能干扰主流程。6.2 技能测试怎么做才靠谱技能测试分三层。单元测试测单个技能输入各种参数看输出是否符合预期重点测边界情况和异常情况。集成测试测技能组合把几个技能串起来跑看数据传递是否正确。回归测试测历史任务把过去跑过的任务重新跑一遍看结果是否一致。测试用例要覆盖正常情况、边界情况、异常情况三类。正常情况验证基本功能边界情况验证极端输入异常情况验证错误处理。我一般要求每个技能至少有三个正常用例、两个边界用例、两个异常用例。测试数据要真实。用假数据测出来的结果参考价值有限尽量用脱敏后的真实数据。如果真实数据涉及隐私可以构造结构相同但内容替换的数据。6.3 技能性能怎么优化技能性能优化有几个方向。减少不必要的调用是最直接的能一次拿到的数据不要分两次拿。缓存重复结果也很有效同样的输入如果频繁出现缓存起来能省很多时间。并行执行独立技能能显著缩短总时间前提是技能之间没有依赖。优化的前提是测量。先用日志统计每个技能的执行时间和调用次数找出耗时最长和调用最频繁的技能优先优化这些。不要凭感觉优化感觉往往不准。优化的度也要把握。过度优化会让代码变复杂维护成本上升。我的原则是如果优化带来的收益小于维护成本的增加就不优化。技能体系的首要目标是稳定可靠性能是第二位的。6.4 技能体系的安全边界技能体系让智能体有了干活的能力也带来了风险。一个能读写文件、调用接口的智能体如果被恶意引导可能造成实际损害。所以安全边界必须提前划好。第一道边界是权限控制。每个技能明确自己能访问哪些资源不能越界。文件技能只能访问指定目录网络技能只能访问白名单地址。第二道边界是操作审计。所有技能调用都记录日志包括谁调的、调了什么、传了什么参数、结果是什么。出问题时能追溯。第三道边界是危险操作确认。删除、覆盖、发送这类不可逆操作执行前必须确认。确认可以是人工确认也可以是二次校验。第四道边界是速率限制。防止技能被高频调用导致资源耗尽每个技能设一个调用频率上限超过就拒绝。这四道边界不是可选项是必选项。我见过太多因为没做安全边界而出事的案例事后补救的成本远高于事前预防。6.5 我个人在实际操作中的体会搭技能体系这件事最难的从来不是写代码而是想清楚“边界在哪”。技能该拆多细、描述该写多长、校验该做多严这些都没有标准答案只能根据你的场景去试。我自己的经验是宁可先拆细一点用起来发现太碎再合并也不要一开始就做大而全的技能。拆细了合并容易大而全拆开难。还有一个体会是技能体系的稳定性是迭代出来的不是设计出来的。第一版能跑通就行别追求完美。跑起来之后你会遇到各种预料之外的问题根据这些问题去调整体系才会越来越稳。我第一版技能体系只有五个技能跑了一个月才扩展到二十个每个新技能都是被真实需求逼出来的不是拍脑袋加的。最后分享一个小技巧给技能体系加一个“健康检查”技能定期跑一遍所有技能确认它们都能正常工作。这个技能本身很简单但能帮你在问题影响主流程之前就发现它。我现在的习惯是每天早上跑一次健康检查有问题当天就修不让它过夜。