
1. 从会写Prompt到能造Skill为什么单次对话解决不了的问题需要新范式很多人第一次接触AI能力封装时脑子里想的都是我写一段提示词不就行了。我刚开始也是这么想的直到有一次需要让模型连续处理三十多份格式各异的表格每份都要先清洗字段、再按不同维度聚合、最后输出统一口径的结论。我写了一段自认为很完善的提示词前五份跑得挺好到第六份开始字段识别就飘了第十份之后连输出格式都开始自由发挥。那次经历让我彻底明白一个道理提示词解决的是这一次怎么说而Skill解决的是这一类事怎么做。所谓Skill你可以把它理解成给AI装的一个专业操作手册加工具箱。它不是一段话而是一套有输入约定、有处理流程、有输出标准、有边界说明的完整能力单元。打个生活化的比方提示词像是你临时打电话教朋友做一道菜说一句他做一步而Skill像是你直接给他一本菜谱里面写清楚了食材怎么挑、火候怎么控、哪一步容易翻车、做出来应该是什么样。前者依赖你每次都在场盯着后者他拿着就能独立复现。这个区别在数据分析场景里尤其致命。数据分析的活儿有个特点流程长、环节多、对一致性要求极高。你让模型做一次同比环比计算它可能算对但你让它对二十个不同来源的表都做同样的口径处理中间只要有一个环节的理解出现偏差最后汇总出来的数就是错的而且错得很隐蔽。所以设计一个好的Skill本质上是在解决如何让AI在重复性专业任务上保持稳定输出这个问题。这篇文章适合三类人看一是已经在用AI做数据处理、但被每次结果都不一样折磨过的从业者二是想把团队里某套成熟分析方法固化下来、让AI照着执行的负责人三是对AI能力封装感兴趣、想搞清楚Skill和普通提示词到底差在哪里的学习者。我会从需求拆解、结构设计、参数约定、边界处理、实测迭代几个角度把设计一个好Skill的完整思路讲透中间会穿插我自己踩过的坑和总结出来的判断标准。先说一个反直觉的结论设计Skill最难的部分不是写内容而是定义边界。大多数人把精力花在我要让AI做什么上却很少想我要让AI不做什么。而实际跑下来你会发现一个Skill好不好用八成取决于边界定得清不清楚。这个观点我会在后面的章节里反复用具体例子来印证。2. 拆解一个数据分析Skill的骨架输入、流程、输出、异常四层结构2.1 为什么是这四层而不是任务描述加示例我见过很多人的Skill初稿结构就是你是一个数据分析专家请帮我做以下事情示例……。这种写法在简单任务上能跑但一旦任务复杂度上来就会崩。原因在于它缺少了契约。什么叫契约就是调用方和被调用方之间对你给我什么、我还你什么、中间出问题怎么办的明确约定。一个能稳定复用的数据分析Skill我总结下来必须包含四层输入层、流程层、输出层、异常层。这四层缺一不可而且顺序不能乱。输入层定义我接受什么样的数据流程层定义我按什么步骤处理输出层定义我交付什么格式的结果异常层定义遇到意外情况我怎么反应。为什么输入层要放在最前面因为数据分析的输入质量直接决定输出质量。你如果不提前约定字段名必须是什么格式缺失值用什么符号表示日期是哪种写法模型就会在运行时自己猜。它猜对了是运气猜错了就是事故。我吃过这个亏有一次让模型处理一批销售数据有的表里金额带货币符号有的不带有的用千分位逗号有的用空格分隔。模型在处理带逗号的数值时把1,234理解成了两个数。后来我在输入层明确写了金额字段统一为纯数字字符串不含任何分隔符和货币符号如有不符请先报错这个问题就再没出现过。2.2 输入层把数据长什么样说死输入层的设计要点是穷举你能想到的所有格式变体然后规定一个唯一标准。具体来说要写清楚四件事字段清单、字段类型、取值范围、缺失表示。字段清单就是告诉模型你会收到哪些列。这一步看起来简单但很多人漏掉了可选字段和必填字段的区分。比如一个销售分析Skill订单号、金额、日期是必填的客户备注是选填的。如果不区分模型可能会因为某个可选字段缺失就拒绝处理整批数据这就过度敏感了。字段类型要精确到字符串还是数值还是日期。这里有个坑日期类型一定要规定格式。是2024-01-15还是2024/01/15还是15-Jan-2024不规定清楚模型在跨表关联时就会因为日期格式不一致而匹配失败。我的做法是统一要求ISO格式并在输入层加一句如日期格式不符先转换为ISO格式再进入流程。取值范围是很多人忽略的一层。比如折扣率字段正常范围是0到1之间如果出现大于1的值要么是数据错误要么是口径不同比如有人用百分比表示。提前规定范围模型就能在流程开始前做一次校验把脏数据挡在门外。缺失表示要统一。是空字符串、是NULL、是N/A、还是-1不同来源的数据缺失表示五花八门。我一般规定用空字符串表示缺失并在流程层说明遇到缺失值时的处理策略是跳过、是填充默认值、还是标记出来让调用方决定。2.3 流程层把怎么做拆成可验证的步骤流程层是Skill的核心但也是最容易写成一锅粥的地方。我的经验是每一步都要有明确的输入和输出且每一步的结果都可以被单独验证。换句话说如果最后结果不对你能通过检查中间步骤快速定位是哪一环出了问题。举个例子一个月度销售汇总Skill的流程可以拆成第一步校验数据完整性第二步按日期字段筛选目标月份第三步按产品类别分组求和第四步计算环比同比第五步生成汇总表。每一步的输出都是下一步的输入链条清晰。这里有个关键技巧在流程层加入自检点。比如第三步分组求和之后加一句检查分组后的总金额是否等于筛选后原始数据的总金额如不等则报错并停止。这个自检点能拦住大部分因为字段识别错误导致的计算偏差。我实测下来加了自检点的Skill输出错误率能降一大半。流程层还要注意步骤的粒度。太粗了模型容易自由发挥太细了又显得啰嗦且容易在细节上卡住。我的判断标准是一个步骤如果可以用一句话说清楚输入什么、做什么、输出什么那粒度就合适。如果一句话说不清就拆成两步。2.4 输出层与异常层交付标准和兜底策略输出层要规定三件事格式、精度、口径说明。格式是表格还是JSON还是纯文本精度是保留两位小数还是四位口径说明是很多人漏掉的——数据分析结果如果不带口径说明换个人看就可能理解错。比如平均客单价这个指标是总金额除以订单数还是总金额除以客户数必须在输出层写清楚。异常层是区分新手和老手的分水岭。新手写的Skill遇到意外就崩老手写的Skill遇到意外会分级响应。我一般把异常分成三级一级是致命错误比如必填字段全缺失直接停止并返回错误码二级是可修复问题比如个别缺失值按预设策略处理后继续但在输出里标注三级是警告比如数据量异常小正常处理但提醒调用方注意。提示异常层的设计原则是宁可多报不可漏报。一个被标注出来的小问题比一个被悄悄吞掉的大问题安全得多。3. 参数与口径数据分析Skill里最容易被忽视的隐形杀手3.1 为什么同一个Skill换个参数结果就天差地别数据分析有个特点同样的数据口径不同结论可能完全相反。举个简单例子活跃用户数这个指标按当天登录过算和按当天有任意操作行为算数字能差出三成。如果Skill里不把口径参数化、不把默认值写死那不同人调用同一个Skill就会得到不同结果这个Skill就失去了复用价值。我的做法是把所有会影响结果的口径都提取成显式参数并给每个参数设定明确的默认值和可选值。比如一个用户行为分析Skill我会定义这几个参数活跃定义默认有登录行为可选有操作行为、统计周期默认自然日可选滚动24小时、去重维度默认按用户ID可选按设备ID。调用方不传就用默认值传了就必须按传的来。这样做的好处是结果可追溯。当有人质疑为什么这个月的活跃用户数比上个月高这么多时你能明确回答因为这次调用把活跃定义从登录改成了操作行为。如果口径藏在流程的某个角落里你连解释都解释不清。3.2 时间窗口与聚合粒度两个必须显式声明的参数时间窗口和聚合粒度是数据分析里最容易出问题的两个参数因为它们经常被默认掉。什么叫被默认掉就是Skill设计者心里有一个默认理解但没有写出来结果调用方的理解和设计者的理解不一致。时间窗口要写清楚三件事起点、终点、是否包含边界。比如最近7天是包含今天还是不包含今天是从00:00:00开始还是从当前时刻往前推168小时这些不写清楚跨天调用就会出偏差。我一般规定时间窗口用左闭右开区间并在Skill里写明起点包含、终点不包含。聚合粒度要写清楚是按天、按周、按月还是按自定义周期。这里有个坑按周聚合时一周的起始日是周一还是周日不同系统默认不一样。如果不声明模型可能这次按周一算、下次按周日算。我的做法是强制声明周起始日为周一并在输出里标注。3.3 数值精度与舍入规则别让小数位毁掉一份报告数值精度这个问题平时不起眼但在财务和统计场景里能要命。我遇到过一次一个汇总Skill在中间步骤把金额四舍五入到整数最后汇总时和原始数据差了十几块。查了半天才发现是中间步骤的精度丢失累积导致的。我的经验是中间计算过程保持全精度只在最终输出时按约定精度舍入。并在Skill里明确写中间步骤不做舍入最终输出保留两位小数采用四舍五入规则。如果涉及百分比还要说明百分比保留一位小数且基于未舍入的原始值计算。另外除零问题要提前处理。计算增长率时如果基期值为零是返回空、返回无穷大、还是返回一个特殊标记不规定的话模型可能直接报错或者给出一个无意义的大数。我一般规定基期为零时增长率返回空值并在输出中标注基期为零无法计算。3.4 一个参数设计的反面案例说个我早期踩的坑。当时设计一个客户分层Skill我定义了三层高价值、中价值、低价值。但我没有把分层阈值参数化而是写死在流程里。结果业务方说我们这次想按不同的消费金额标准来分我只好把Skill复制一份改阈值。后来调用方越来越多阈值需求五花八门我手里攒了七八个几乎一样的Skill维护起来苦不堪言。后来我改成把阈值做成参数默认值给一套通用标准调用方可以覆盖。一个Skill就搞定了所有场景。这个教训让我明白凡是业务方可能想调整的数值都不要写死在流程里要提取成参数。判断标准很简单如果这个数值变了流程逻辑不变那它就该是参数。4. 边界与异常好Skill和能用Skill的分水岭4.1 明确不做什么比明确做什么更重要前面我提过一个观点设计Skill最难的是定义边界。这里展开说。一个Skill如果只写我要做什么那它在遇到边界情况时就会自由发挥。而自由发挥在数据分析场景里往往意味着灾难。举个例子一个数据清洗Skill如果你只写清洗数据那模型可能会把看起来像异常值的正常数据也删掉。但如果你写清楚本Skill只处理缺失值填充和格式统一不做异常值剔除异常值仅标记不删除模型的行为就收敛了。我一般会在Skill开头写一段能力边界声明包含三部分本Skill能处理什么、本Skill不处理什么、遇到不处理的情况怎么办。比如本Skill能处理结构化表格数据不处理非结构化文本和图像遇到非表格输入直接返回错误码E001。4.2 异常分级让Skill在意外面前有章可循异常分级我在前面提过这里给一个更具体的分级表是我自己在用的级别典型场景处理策略输出表现致命必填字段全缺失、数据为空立即停止返回错误码和原因可修复个别缺失值、格式不一致按策略处理后继续正常输出加标注警告数据量异常小、分布异常正常处理正常输出加提醒这个分级表的好处是把怎么办提前想清楚了。模型不需要在运行时临场判断它只需要按表执行。我实测下来有分级表的Skill输出稳定性明显高于没有的。4.3 空值与异常值的处理策略要写死空值和异常值是数据分析里绕不开的两个问题。我的原则是空值处理策略必须显式声明异常值只标记不擅自处理。空值处理有几种常见策略删除含空值的行、用均值或中位数填充、用前一个有效值填充、保留空值但标注。每种策略适用场景不同没有绝对的好坏。关键是在Skill里写清楚用哪种以及为什么用这种。比如金额字段的空值用0填充因为空值代表无交易评分字段的空值保留因为空值代表未评分填充会引入偏差。异常值我坚持只标记不删除。原因很简单你无法确定一个看起来异常的值是真的错误还是真实的极端情况。比如一个销售额字段出现了比平均值高一百倍的值可能是录入错误也可能是某个大客户的真实订单。擅自删除可能丢掉重要信息。所以我的做法是标记出来让调用方决定。4.4 边界测试上线前必须做的三组验证Skill写完之后不能直接上线必须做边界测试。我一般做三组空数据测试、脏数据测试、极端值测试。空数据测试就是给一个空表看Skill是否优雅地返回错误而不是崩溃。脏数据测试是给一批格式混乱的数据看Skill是否能按预设策略处理并标注。极端值测试是给一些边界数值比如零、负数、超大数看Skill的反应是否符合预期。这三组测试能拦住大部分上线后才会暴露的问题。我吃过亏一个Skill在正常数据上跑得很好结果上线第一天遇到一个全空表直接卡死调用方等了半天没响应。后来补了空数据测试这类问题就再没出现过。5. 从草稿到稳定一个数据分析Skill的迭代实录5.1 第一版功能齐全但脆弱我拿一个真实的迭代过程来说。需求是做一个多源销售数据合并汇总Skill输入是若干张格式不同的销售表输出是一张统一口径的汇总表。第一版我写得很全字段映射、单位换算、去重、汇总、排序一股脑全塞进去。结果跑起来问题百出。最典型的是字段映射环节不同来源的表里销售额这个字段有的叫金额有的叫销售金额有的叫total。我在第一版里写了一个映射表但没考虑大小写和空格差异导致金额 带空格没被识别。第一版的教训是功能齐全不等于健壮。一个环节的脆弱会拖垮整个Skill。5.2 第二版加了校验但流程变慢第二版我在每个环节都加了校验字段映射前先做标准化去空格、转小写汇总前先做总额校验。结果健壮性是上去了但处理速度明显变慢。因为每一步校验都要遍历一遍数据数据量大的时候耗时翻倍。这让我意识到一个平衡问题校验不是越多越好要放在关键节点上。后来我把校验精简到三个关键点输入校验、汇总前校验、输出前校验。中间的字段映射和单位换算环节用标准化规则代替逐条校验。速度回来了健壮性也没丢。5.3 第三版参数化与分级异常第三版做了两件大事把口径参数化把异常分级。口径参数化让同一个Skill能适配不同业务方的需求不用再复制多份。异常分级让Skill在遇到问题时有了明确的处理路径不再动不动就崩。这一版上线后调用方的反馈明显好了。以前经常有人问为什么这次结果和上次不一样现在因为口径都显式声明了这种问题少了很多。偶尔遇到异常Skill会返回明确的错误码和原因调用方自己就能判断怎么处理。5.4 迭代中总结出的三条经验第一先跑通再优化。不要一开始就追求完美先让Skill能跑出一个结果哪怕粗糙。有了结果你才知道哪里需要改。第二每次只改一个地方。我试过一次改好几个地方结果出了问题不知道是哪个改动导致的。后来改成每次只动一处改完测一遍问题定位快很多。第三保留版本记录。每个版本的Skill都存一份注明改了什么、为什么改。这样万一新版本出问题能快速回退到旧版本。我吃过没留版本的亏改崩了想回退都回不去。6. 让Skill真正被用起来文档、命名与协作习惯6.1 Skill文档要写给人看不是写给机器看很多人写Skill文档写的是机器能读懂的指令但忽略了人能不能看懂。结果Skill是能跑但没人敢用因为不知道它到底会做什么、不会做什么。我的做法是Skill文档分两部分一部分是给调用方看的说明一部分是给模型看的指令。给调用方看的说明用大白话写清楚这个Skill做什么、需要什么输入、输出什么、有什么限制。给模型看的指令才是那些结构化的流程和规则。两部分分开各司其职。6.2 命名要让人一眼看懂用途和版本Skill的命名我踩过坑。早期我用data_process_v1analysis_skill这种名字结果过了一个月自己都忘了哪个是哪个。后来改成销售数据月度汇总_口径A_v2这种一看就知道用途、口径和版本。命名建议包含三要素业务对象、操作类型、版本。比如用户行为_活跃统计_v3订单数据_异常检测_v1。这样在列表里一眼就能找到想要的。6.3 协作中的两个习惯第一个习惯是变更通知。Skill改了之后要通知所有调用方说明改了什么、影响是什么。我见过因为Skill悄悄改了默认口径导致下游报告全部出错的案例。第二个习惯是调用日志。每次调用记录下输入参数、输出摘要、异常情况。这样出问题时能快速定位是哪个环节、哪次调用出的问题。日志不用很复杂关键信息记下来就行。7. 我判断一个Skill好坏的五个标准跑了这么多Skill之后我总结出五个判断标准用来评估一个Skill是不是好Skill。第一可复现。同样的输入跑十次结果应该一致。如果结果飘忽说明流程里有不确定的地方。第二可解释。结果出来之后能说清楚是怎么算出来的。如果连设计者都解释不清中间步骤这个Skill就有问题。第三可容错。遇到意外数据不崩溃能按预设策略处理或明确报错。第四可配置。关键口径和阈值是参数不是写死的。这样能适配不同场景不用复制多份。第五可维护。改了之后能快速测试、快速回退有版本记录和变更说明。这五个标准里我觉得最重要的是可复现。因为数据分析的信任基础就是同样的条件得到同样的结果。一个不可复现的Skill哪怕功能再强大也没人敢在正式场景里用。最后分享一个我自己的小习惯每次设计一个新Skill之前我会先手动画一遍流程图把输入、每一步处理、输出、可能的异常都画出来。画的过程中经常能发现逻辑漏洞比直接写指令高效得多。画完再写思路清晰很多。这个习惯帮我省了不少返工的时间。