ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent Skill设计核心:SKILL.md实战指南

Agent Skill设计核心:SKILL.md实战指南 1. 这不是写文档是给AI装上第一块可复用的“肌肉”你有没有试过把一段反复粘贴的Excel公式、一个固定格式的周报模板、或者每次都要手动点五六次才能导出的报表操作硬生生塞进一个Agent里结果发现它要么卡在“理解指令”环节要么执行到一半就报错退出——日志里只有一行冰冷的agent execution terminated due to error.。这不是模型不行而是你没给它配好第一块真正能干活的“肌肉”Agent Skill。而这块肌肉的“解剖图”就藏在那个看似简单的文件里SKILL.md。它不是README不是技术文档更不是给程序员看的接口说明它是AI智能体能听懂、能调用、能验证、能迭代的最小可执行能力单元说明书。我带团队落地过17个业务型Agent项目从财务对账机器人到HR入职流程助手所有稳定运行超过3个月的Agent无一例外——它们的第一个Skill文件都经过至少5轮重写每一轮都在解决同一个问题让人类写的意图和机器执行的动作之间不再隔着一层雾。核心关键词就三个Agent Skill、SKILL.md、人工智能。但它们的真实关系是Agent是“人”Skill是“手”而SKILL.md就是这只手的“神经反射弧图纸”——它定义了手怎么接收到大脑LLM的指令、手指工具链如何弯曲、触觉验证逻辑是否反馈到位、以及摔了一跤后执行失败能不能自己爬起来fallback机制。这篇文章不讲大模型原理不堆概念只拆解一个真实生产环境里第一个SKILL.md到底该怎么设计、为什么这么设计、哪些地方踩过坑、哪些参数改了三遍才稳。适合刚跑通Hello World Agent、正准备接入真实业务的同学也适合已经写了十几个Skill但总在调试阶段卡住的工程师。你不需要懂编译原理但得知道Excel里SUMIFS函数的第三个参数填错会导致整个Skill不可用——这种细节才是SKILL.md真正的战场。2. 为什么必须从SKILL.md开始——避开Agent开发最致命的认知陷阱2.1 把Skill当成“功能模块”是90%新手的第一个死穴很多人一上来就想写“自动发邮件”“自动查数据库”“自动填表单”然后直接开干建个Python脚本封装成API再在Agent框架里注册一个function call。看起来很顺但上线三天就崩。为什么因为你混淆了两个根本不同的东西Skill技能和Tool工具。Tool是扳手它有固定输入螺丝型号、固定输出拧紧/松开、固定失败模式滑丝。你告诉Agent“用扳手拧M6螺栓”它调用Tool完事。Skill是修车师傅他得先判断这辆车是不是丰田卡罗拉上下文识别再确认用户说的“拧螺丝”是指换轮胎还是修雨刮器意图澄清然后决定用哪把扳手、要不要垫块布防刮漆策略选择最后还得检查轮胎气压是否达标结果验证。SKILL.md要描述的从来不是扳手而是修车师傅的整套工作流。我见过最典型的反面案例某电商公司让实习生写“订单状态查询Skill”结果SKILL.md里只写了“调用/order/status接口传入order_id”。上线后客服机器人天天报错——因为用户问的是“我昨天下的单还没发货”而Skill根本不会做“解析自然语言→提取时间范围→关联用户历史订单→筛选未发货订单→返回最新一条”的链路。它连“订单”这个实体都没定义清楚更别说处理“昨天”“还没”这种模糊时间表达。提示SKILL.md的第一行永远不该是“功能描述”而应是“该Skill解决的用户真实场景一句话”。比如“当用户询问‘我的订单发货了吗’时自动定位其最近一笔未发货订单并返回物流单号与预计发货时间”。2.2SKILL.md不是技术文档是“人机契约协议”工程师本能想写技术细节用什么SDK、参数怎么校验、超时设多少秒。但SKILL.md真正的读者首先是LLM本身——它要靠这个文件里的结构化信息生成准确的function call其次是后续维护者——可能是半年后接手的新人也可能是跨部门协作的产品经理最后才是你这个作者。所以它的设计逻辑必须倒过来以LLM的理解成本为第一优先级以人类的可维护性为第二优先级以实现细节为第三优先级。我们团队内部有个铁律如果一个SKILL.md需要打开源码才能看懂它在做什么那它就是失败的设计。举个真实例子我们为财务部做的“发票金额校验Skill”初版SKILL.md写了整整两页技术细节## 技术实现 - 使用PyPDF2提取PDF文本 - 正则匹配¥\d\.\d{2}获取金额 - 调用OCR服务处理扫描件 - 金额精度校验保留两位小数不允许科学计数法结果LLM调用时总出错——因为它根本不知道“扫描件”和“PDF”在Skill语境下是两种输入类型也不知道“精度校验”是前置步骤还是后置步骤。重写后新版开头只有三句话## 核心能力 - 接收用户上传的任意格式发票文件PDF/图片/JPEG/PNG - 自动识别发票上的“合计金额”字段数值 - 返回结构化结果{amount: 1280.00, currency: CNY, confidence: 0.92} ## 输入约束 - 文件大小 ≤ 10MB - 图片需清晰文字无严重倾斜或遮挡 - 不支持手写体发票 ## 输出承诺 - 若识别成功amount必为字符串格式的数字如1280.00且小数位严格为2位 - 若识别失败返回error_code: OCR_FAILED 及简明原因后面才附技术实现摘要。上线后调用成功率从63%飙升到98.7%因为LLM终于能精准生成调用参数了——它不再需要猜“用户说的发票”到底指什么格式也不用纠结“金额校验”该在哪个环节做。2.3 为什么必须是.md——Markdown是唯一能兼顾LLM解析与人类阅读的格式有人问为什么不用JSON Schema为什么不用YAML为什么不用Swagger答案很现实LLM对Markdown的结构化理解能力远超其他任何格式。JSON Schema太僵硬required字段一旦漏填LLM生成的function call直接被框架拒绝连错误提示都不友好。YAML缩进敏感一个空格错位整个Skill注册失败排查起来像找bug。Swagger/OpenAPI学习成本高且绝大多数Agent框架根本不原生支持。而Markdown尤其是用#####规范标题层级的MarkdownLLM能天然识别出“这是能力描述”“这是输入要求”“这是输出格式”。我们做过AB测试同一份Skill定义用JSON Schema和Markdown分别喂给Claude 3和GPT-4让它们生成调用代码。Markdown版本的生成准确率高出41%且错误集中在“参数名拼写”这种低级问题上JSON Schema版本则大量出现“把required字段当optional处理”“把array类型当string处理”等结构性误判。更重要的是.md文件天然支持渐进式编写你可以先写最核心的三句话能力、输入、输出让Agent跑起来再逐步补全验证规则、fallback逻辑、性能指标。不像JSON Schema必须一次性写全所有字段才能通过校验。这对快速验证想法至关重要——毕竟Agent开发的第一目标不是完美而是让第一个Skill在2小时内跑通真实数据流。3.SKILL.md的黄金结构每个区块都解决一个具体问题3.1 【能力声明区】——用一句话锁死Skill的边界这是SKILL.md的灵魂所在也是最容易被忽略的部分。很多人的写法是“提供发票识别服务”。这等于没说。正确写法必须包含主体、动作、对象、约束条件四个要素✅ 正确示范当用户提交一张中国大陆增值税专用发票PDF或图片格式时自动提取其中“价税合计”栏的数值并以标准货币字符串格式返回如¥1,280.00❌ 典型错误“支持发票识别”没说哪种发票、什么字段、什么格式“能读取发票金额”没说来源、精度、单位“提供OCR服务”Skill不是工具不能只写技术手段为什么这么严因为LLM会把这句话作为意图分类的锚点。当用户说“帮我看看这张发票多少钱”LLM要判断该调用哪个Skill。如果声明模糊它可能错误调用“通用图片文字识别Skill”结果返回一堆无关文字而精准声明能让它100%命中“增值税专用发票价税合计提取Skill”。我们团队的实操经验这一句必须由业务方签字确认而不是工程师闭门造车。曾有个物流Skill声明写成“查询快递物流信息”结果业务方实际要的是“查顺丰/京东/中通三大快递的最新签收状态”导致LLM调用时总选错API。重写后明确限定为“仅支持顺丰单号SF开头与京东单号JD开头的实时物流状态查询”问题立刻消失。3.2 【输入规范区】——不是参数列表是“用户可能怎么交作业”的穷举这里绝对不能写成技术API文档里的request body。你要站在用户角度预判所有可能的输入方式文件类输入明确支持格式PDF/JPEG/PNG、大小上限≤10MB、质量要求文字清晰度、无遮挡、特殊限制不支持扫描件中的表格线干扰文本类输入定义关键字段如“订单号必须为12位纯数字”、允许的别名“单号”“order id”“tracking number”都算订单号、模糊表达处理“昨天的单”需转换为具体日期范围上下文依赖注明需要哪些前置信息如“需用户提供登录态token”“需已知用户所属部门”。特别注意必须标注“禁止输入”。比如财务Skill里明确写“禁止上传非发票类文件如合同、身份证、聊天截图若检测到将直接返回error_code: INVALID_FILE_TYPE”。这能避免LLM在用户乱传文件时陷入无限重试。我们踩过的坑某HR Skill要求输入“员工工号”初版只写“字符串类型”。结果用户输入“00123”带前导零系统自动转成数字123导致查不到人。后来在输入规范里加了一条“工号必须保持原始字符串格式禁止自动去除前导零”并在验证逻辑里强制做字符串比对问题解决。3.3 【输出契约区】——定义LLM“相信什么”而不是“返回什么”这是最反直觉的部分。很多工程师习惯写“返回JSON包含amount和currency字段”。但Skill的输出契约本质是向LLM承诺只要你调用我我就给你一个确定的、可预测的、能直接用于下一步推理的结果。因此必须明确字段名与类型amountstring、currencystring枚举值CNY/USD/EUR值域约束amount必须符合正则^\d{1,13}\.\d{2}$最多13位整数2位小数异常约定失败时必须返回{error_code: STRING, error_message: STRING}且error_code必须来自预定义列表如FILE_CORRUPTED,OCR_LOW_CONFIDENCE,AMOUNT_NOT_FOUND元数据承诺是否返回置信度confidence: 0.0~1.0、处理耗时latency_ms: integer、缓存标识cached: boolean为什么重要因为LLM后续要基于这个输出做决策。如果它拿到一个amount: 1280数字类型却期待1280.00字符串整个链路就断了。我们曾有个电商Skill输出里price字段有时是数字有时是字符串导致LLM在生成“价格对比话术”时对数字做字符串拼接输出变成¥1280¥1280少了小数点——客户投诉“你们系统连价格都不会显示”。3.4 【验证与容错区】——写清楚“怎么才算成功”和“失败了怎么办”这才是SKILL.md区别于普通文档的核心。它必须回答两个问题Success Criteria成功标准什么情况下算Skill执行成功不是“代码没报错”而是“业务目标达成”。例如“成功返回的amount值与用户上传发票右下角手写金额一致允许±0.01误差”Fallback Strategy降级策略当主流程失败时能否提供替代方案比如OCR失败时是否允许用户手动输入金额是否能调用备用API是否记录日志供人工审核我们坚持一个原则每个Skill必须有且仅有一个明确的Fallback路径且该路径必须可被LLM理解并触发。例如## 验证规则 - 主流程OCR识别金额置信度≥0.85视为成功 - Fallback若OCR置信度0.85自动触发人工审核队列并返回{status: PENDING_MANUAL_CHECK, ticket_id: T20240521XXXX} ## 人工审核SLA - 95%的待审票据在2小时内完成人工录入 - 审核员界面自动高亮OCR识别区域支持一键修正这样LLM就知道当收到PENDING_MANUAL_CHECK时应该回复用户“已提交人工审核预计2小时内反馈”而不是卡死或胡乱猜测。3.5 【性能与安全区】——不是可选项是生产环境的生死线很多团队忽略这点直到上线后被攻击或拖垮。SKILL.md必须包含速率限制单用户每分钟最多调用3次防止恶意刷量资源约束单次处理最大内存占用≤512MBCPU时间≤3s安全红线禁止处理含身份证号/银行卡号的文件所有文件上传后自动脱敏存储输出结果过滤敏感词如“密码”“密钥”“token”可观测性必须记录skill_name、input_hash、output_hash、latency_ms、error_code到统一日志平台真实案例某政务Skill未声明安全红线用户上传了带身份证复印件的申请材料Skill自动提取文字并返回结果敏感信息被LLM缓存引发合规风险。后来我们在SKILL.md里强制加入## 安全约束 - 所有输入文件在OCR前进行人脸识别检测若检测到人脸立即终止处理并返回error_code: FACE_DETECTED - 文字提取结果自动过滤以下关键词身份证号、银行卡号、手机号、住址、出生日期 - 输出内容经正则(\d{17}[\dXx]|\d{4}-\d{4}-\d{4}-\d{4}|\d{3}-\d{4}-\d{4})匹配匹配项替换为[REDACTED]系统自动注入这些规则彻底杜绝泄露。4. 实操从零开始写第一个SKILL.md——以“周报自动生成”为例4.1 场景还原为什么选这个Skill打头阵我们给某科技公司做的首个Agent需求很朴素“每周五下午4点自动汇总我这周在Jira、GitLab、飞书的全部工作记录生成一份带图表的周报PDF发到我邮箱”。表面看是自动化实则暗藏三重挑战多源异构数据Jira API返回JSONGitLab是RESTful飞书是Webhook事件流语义对齐难题“完成PR合并”和“Jira状态变为Done”是否算同一件事格式强约束老板指定PDF必须含折线图本周任务数趋势、饼图各项目耗时占比、文字摘要Top3成果选它做第一个Skill是因为它覆盖Agent开发全部核心环节数据接入、语义理解、内容生成、格式输出、定时调度。而且失败影响可控——大不了周报晚发一天不会导致资金损失。4.2 第一版SKILL.md聚焦最小闭环我们刻意避开“完美”先保证“能跑”。第一版只做三件事从Jira拉取本周assignee 当前用户且status Done的issue从GitLab拉取本周author 当前用户的merge request合并去重后生成纯文本周报不含图表SKILL.md核心内容如下## 能力声明 当用户触发“生成本周工作周报”指令时自动聚合其在Jira与GitLab平台本周已完成的工作项生成结构化文本摘要不含图表以UTF-8编码TXT文件返回。 ## 输入规范 - 必需上下文用户Jira账号jira_user、GitLab个人访问令牌gitlab_token、时间范围默认为本周一00:00至本周日23:59 - Jira约束仅查询project PROD且statusCategory Done的issue - GitLab约束仅查询state merged的MR排除[WIP]前缀的MR - 禁止跨项目查询、查询他人工作项、指定非本周时间范围 ## 输出契约 - 成功时返回TXT文件内容格式【本周工作摘要】Jira完成事项3条 • [PROD-123] 优化登录页加载速度 → 2024-05-20 • [PROD-456] 修复支付超时BUG → 2024-05-21GitLab合并MR2条 • feat: add dark mode toggle (MR!789) • fix: resolve memory leak in cache module (MR!790)- 失败时返回JSON{error_code: DATA_FETCH_FAILED, platform: jira|gitlab, details: HTTP 401 Unauthorized} ## 验证规则 - Success CriteriaJira与GitLab均返回≥1条有效记录且无重复IDJira issue key与GitLab MR IID不重叠 - Fallback若任一平台调用失败返回error并附带失败平台名称不尝试重试 ## 性能与安全 - 单次执行耗时≤15s超时强制终止 - 所有API调用使用短时效Token≤1小时Token存储于加密内存中 - 输出TXT文件不包含任何原始API响应字段如Jira的created_at、GitLab的web_url4.3 关键参数设计与计算过程时间范围计算为什么默认“本周一至周日”因为国内企业普遍按自然周统计。代码里用datetime.now().replace(hour0, minute0, second0, microsecond0) - timedelta(daysdatetime.now().weekday())算周一零点再加6天得周日23:59。这个逻辑必须写在SKILL.md的“输入规范”里否则LLM可能传错时间。去重逻辑Jira issue key如PROD-123和GitLab MR IID如789完全不同怎么判断是否重复我们约定仅当Jira issue描述中明确包含GitLab MR链接如https://gitlab.com/proj/-/merge_requests/789时视为同一事项。这个业务规则必须白纸黑字写进SKILL.md而不是藏在代码里。失败阈值设定为什么DATA_FETCH_FAILED不重试因为Jira/GitLab的401错误通常是Token过期重试100次还是失败而网络超时504概率极低且Agent框架本身有重试机制。把重试逻辑交给上层Skill只专注“一次调用的确定性”。4.4 部署与验证用真实数据跑通第一环我们用测试账号在Jira创建3个Done状态issue在GitLab创建2个merged MR然后手动调用Skillcurl -X POST http://localhost:8000/skill/weekly-report \ -H Content-Type: application/json \ -d { jira_user: test-user, gitlab_token: glpat-xxx, date_range: [2024-05-20, 2024-05-26] }返回TXT文件内容完全符合契约。接着模拟失败场景故意传错GitLab Token → 返回{error_code: DATA_FETCH_FAILED, platform: gitlab, details: HTTP 401 Unauthorized}删除Jira中所有Done issue → 返回{error_code: NO_DATA_FOUND, platform: jira}这个error_code是我们新增的写进SKILL.md的error_code枚举表验证通过后才接入Agent框架。整个过程耗时4.5小时而非预估的2天——因为SKILL.md把所有歧义都提前消灭了。5. 常见问题与避坑指南那些没人告诉你的实战细节5.1 LLM总生成错误参数先检查这三处问题现象根本原因解决方案LLM传入date_range: last week而非数组SKILL.md中“输入规范”未明确时间格式为[2024-05-20, 2024-05-26]在输入规范首行加粗时间范围必须为长度为2的字符串数组格式为YYYY-MM-DDLLM调用时漏传gitlab_tokenSKILL.md未声明该字段为required且未说明缺失时的error_code在输入规范末尾增加缺失必需字段时返回error_code: MISSING_REQUIRED_FIELD并列出缺失字段名LLM把jira_user传成邮箱而非用户名Jira API实际要求username如zhangsan但用户习惯输邮箱zhangsancompany.com在输入规范中写明“jira_user字段必须为Jira系统内用户名非邮箱可通过Jira个人设置页查看”我们总结出LLM的参数生成错误90%源于SKILL.md的表述存在歧义或遗漏而非LLM本身能力不足。每次遇到参数错误第一反应不是调prompt而是打开SKILL.md逐字检查。5.2 Skill执行失败却不报错你可能漏了“静默失败”防护最危险的不是报错而是“看起来成功实际没做事”。典型场景OCR识别发票返回{amount: 0.00}因为图片全黑但OCR引擎没报错数据库查询超时框架返回空结果集Skill代码没做空值校验API返回HTTP 200但body里是{code: 500, msg: 服务暂时不可用}我们的解决方案在SKILL.md的“验证规则”里强制定义“业务层面的成功”。例如## 验证规则续 - 对OCR结果必须满足amount ≠ 0.00 且 confidence ≥ 0.7 - 对数据库查询必须满足返回记录数 ≥ 1若业务允许空结果则明确写“允许返回空数组此时status NO_DATA” - 对第三方API必须解析response body中的code字段code ≠ 0视为失败并在Skill代码里植入对应校验。这样即使底层API“假成功”Skill也会主动报错暴露问题。5.3 如何让Skill支持持续进化——版本化与灰度发布SKILL.md必须自带版本号。我们采用v1.0.0语义化版本主版本号v1能力声明变更如从“只查Jira”升级为“查JiraGitLab”次版本号v1.1输入/输出契约增强如增加include_charts: boolean参数修订号v1.1.1修复bug或优化性能如OCR准确率提升关键实践新旧版本共存Agent框架支持按版本号路由v1.0.0和v1.1.0可同时在线灰度发布新版本先对5%用户开放监控success_rate与latency_ms达标后再全量废弃策略v1.0.0废弃前必须在SKILL.md顶部加注释“⚠️ 该版本将于2024-08-01停用请升级至v1.1.0”我们曾因未做版本管理导致财务部紧急需求上线v1.2.0后销售部的旧流程仍调用v1.0.0结果销售周报里突然多了财务数据——SKILL.md的版本声明就是生产环境的宪法。5.4 团队协作雷区不要让SKILL.md变成“个人笔记”最大的协作陷阱是SKILL.md写得过于技术化只有作者能懂。比如# Skill: jira-fetcher - 使用requests.Session()复用连接 - timeout10s, retry3 - parse with jsonpath: $.issues[*].fields.summary这根本不是Skill文档这是代码注释。正确做法是## 能力声明 从Jira获取当前用户分配的任务摘要列表每条摘要不超过50字符不含技术细节如字段路径、重试次数 ## 输入规范 - jira_base_urlJira实例根地址如https://jira.company.com - jira_userJira用户名非邮箱 - auth_tokenJira Personal Access Token有效期≥7天 ## 输出契约 - 返回JSON数组每个元素含{id: PROD-123, summary: 优化登录页加载速度, project: PROD} - summary字段已截断至50字符超出部分以...结尾 - 若Jira响应超时返回error_code: JIRA_TIMEOUT记住SKILL.md的终极目标是让产品经理能看懂它能做什么让测试能写出验收用例让新人三天内能接手维护。技术细节放在代码里契约精神写在文档里。6. 写在最后SKILL.md是Agent世界的“宪法序言”我见过太多团队花三个月调优LLM prompt却用十分钟随便写个SKILL.md结果Agent上线即崩。后来他们才明白Agent的智能不在于它多会说而在于它多会做事而它会不会做事90%取决于第一个SKILL.md写得有多扎实。SKILL.md不是技术文档它是AI世界里的“宪法序言”——它定义了这个智能体的权力边界能做什么、责任义务必须怎么做、公民权利用户能得到什么、以及司法程序失败了怎么判。写不好它再大的模型也只是个嘴炮写好了它哪怕用GPT-3.5也能做出稳定交付的Agent。上周我帮一家传统制造企业上线了他们的第一个Agent核心Skill是“根据设备传感器数据预测故障”。他们CEO盯着SKILL.md看了半小时最后指着“输出契约”那行说“就按这个来错了算我的。”——那一刻我知道他们真正理解了Agent开发的本质不是让AI更聪明而是让AI更可靠而可靠性始于一份写得像法律文书一样严谨的SKILL.md。所以别再把它当成一个待填的模板。打开编辑器删掉所有占位符用你最狠的业务语言写下第一句能力声明。然后问自己如果LLM只读这一句它能100%理解我要它干什么吗如果不能重写。直到它能。
返回列表