恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Agent技能库设计实战:从提示词堆叠到结构化技能编排

  • 首页
  • 资讯中心
  • /
  • Agent技能库设计实战:从提示词堆叠到结构化技能编排

相关资讯

三菱FX3U-80MR/DS选型避坑指南:从型号解码到伺服定位与通信协议 2026/10/7 11:39:49
蓝桥杯while循环实战:从语法到死循环排查 2026/10/7 11:39:49
Agent-Reach:智能体的触达能力决定业务价值上限 2026/10/7 11:34:48

最新资讯

双向可控硅实现单相电机无级调速:原理、选型与实操
中小企业网络规划与设计:从需求摸底到交付验收的完整指南
OSATE2环境搭建深度指南:AADL建模与验证的工程化实践
网络驱动重装全指南:从原理到实操解决网卡失灵断网问题
Ponytail 日志尾随增强插件:多文件追踪、过滤告警与 logrotate 轮转实战
FPGA除法不再难:Vivado Divider Generator IP配置从入门到实战

今日推荐

SSD不认盘怎么修?金士顿SV300板级排查与短接ROM进工厂模式
Unity 3D RPG开发:C#状态机与物理更新时机实战指南
AIoT开发工程师岗位全景:从嵌入式Linux到边缘计算与端侧AI部署

本周热门

MR25H40CDF + PIC18F65K40:工业记录仪高可靠存储实战
基于STM32的数控恒压恒流电源设计:从硬件到PID调参全解析
LT9211 MIPI重定时器原理与双路扇出实战指南

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

Agent技能库设计实战:从提示词堆叠到结构化技能编排

发布时间:2026/10/7 11:39:49
Agent技能库设计实战:从提示词堆叠到结构化技能编排 前阵子做AI Agent落地项目又遇到了一个典型问题底层模型已经换到目前能用的最强版本还是频繁在处理多步任务时断片。一会儿把昨天的日期算错一会儿对着一个需要登录的后台页面反复尝试无效操作。团队成员都开始怀疑模型能力不够。后来我把这几个月反复试错的经验总结了一下问题根源不在模型的智力而在我们根本没给Agent一套可复用的agent-skills体系。模型再聪明没有一个结构化的技能库它也只能靠现场编去应对真实任务出错是必然的。这篇文章想把我在技能定义、路由调度、执行链路、失败恢复这几个方向上的实战经验完整摊开来聊。适合正在做Agent应用、被多步任务稳定性搞得头疼的开发者也适合想从单点Demo走向真实业务的团队参考。1. 为什么提示词堆叠撑不起Agent的能力天花板1.1 一个真实任务让System Prompt全面失控团队原来接需求的方式很原始把业务流程描述直接塞进System Prompt。比如客户提了个需求每天定时检查所有未完结工单超过48小时没有新进展的给相关负责人发一封催促邮件同时更新到项目看板里。看起来不难Prompt也是这么写的。真跑起来全乱套Agent把所有工单一次性捞了出来几十个请求打到接口导致超时邮件的措辞像是一个模板套出来的每个客户收到的内容几乎一样更新看板这个动作时Agent又在犹豫该用哪个字段把状态值改错了。后来统计了一下单次任务里光理解业务规则就消耗了将近一半的上下文窗口留给真正判断和决策的空间所剩无几。加大模型上下文没用。问题在于Prompt是描述性的不是可执行的结构。它的值是提供一个总体方向但没法约束每一步动作的边界、参数和行为规范。Agent面对开放性指令时每次都会重新即兴发挥同样的任务跑十次过程十次不同结果自然时好时坏。1.2 技能的本质策略与工具之间的中间层我最后的落地方案借鉴了PC操作系统里快捷键和现代IDE里的代码片段思路把高频、可复用的原子动作固化成一个个命名清晰、边界明确的技能Skill。每个技能自带一份完整说明——什么时候该用、输入什么、输出什么、内部走什么流程、哪些情况要拒绝执行。这样一改Agent的职责从从头到尾编流程变成了从技能库里选技能、排顺序、填参数。我常跟同事用一个比喻解释这个变化把Agent当成一个乐手底层模型是指法和视奏能力技能库则是提前练好的乐谱片段。临场发挥偶尔能出一两个华彩但稳定撑起整场演出的一定是反复排练过的乐段。周围常见的做法是把这些逻辑做成工具函数或者工作流节点各有各的问题。裸工具函数只暴露一个个接口没有使用场景的语义约束重工作流把执行顺序写死等于把判断权全部收回Agent灵活度尽失。Skill取向刚好在两者之间保有判断空间同时用结构化的说明把自由度框在安全边界里。1.3 技能、function calling和MCP的边界如何划分再往细了说工程上还有个绕不开的问题Agent技能和OpenAI的function calling、Anthropic的tool use、以及现在很火的MCPModel Context Protocol到底什么关系。以我在实际项目里的感受这些不是同一个层次的东西可以共存但分工不一样。MCP解决的是Agent怎么连接到外部数据源和系统类似于给Agent接上了USB-C接口什么设备插上都能通讯function calling解决的是模型怎么按结构输出参数调用本地函数属于一次对话内的短链路交互。而Skill是更高层的编排单元——一个Skill内部可能调用多个MCP连接的资源也可能组合若干次function calling甚至嵌套其他Skill。打个比方MCP是水管网function calling是阀门Agent Skills才是整套供水方案。只通水管不设计方案水压再大也浇不对地方。这个理解直接影响了我们后面的技术选型在技能内部我们保留了function calling的GPU级效率在外部连接数据源才走MCP中间层则完全由Skills接管。把这三者的边界划清了架构才不会越用越乱。2. 技能仓库的目录结构与Schema设计动手之前先把边界想清楚2.1 一套可用的技能目录长什么样Skill的大致实现形式业内已有一些共识每个技能就是一个独立的目录里面包含说明文件和可执行文件。我的目录结构是基于实践反复调整过的现在基本稳定成这样agent-skills/ registry/ calendar/ SKILL.md dependencies/ requirements.txt scripts/ get_datetime.py get_weekday.py web_search/ SKILL.md dependencies/ scripts/ search_and_extract.py customer_followup/ SKILL.md dependencies/ scripts/ list_overdue_tickets.py send_reminder_email.py update_kanban.py shared/ logger.py http_client.py validators.py这里有个容易忽略的关键设计每个技能目录里必须有一个统一格式的SKILL.md它会成为Agent决定要不要调用这个技能的主要依据。不要把说明散落在代码注释里Agent读注释成本太高还容易漏。SKILL.md我一般固定为这几个段落技能目标、触发条件、输入参数、输出格式、使用边界、失败处理、示例。触发条件和使用边界这两段通常是团队最不爱写的却是排错时的救命稻草。2.2 技能描述里的触发条件是路由成败的关键我在实际踩坑中发现Agent选错技能八成是触发条件写得不够可判定。一开始我们写触发条件喜欢用自然语言比如当用户想了解某个领域的信息时这种描述等于没写。模型怎么理解想了解边界太模糊于是它经常在应该调搜索技能的时候调了网页解析技能或者在需要做定时提醒的时候调了日历查询。后来我把触发条件改成可枚举、可判定的清单形式明确动词列表查询、获取、设置、创建、删除、提醒、汇总……技能只对明确动词响应。实体/对象约束涉及哪些类型的对象工单、邮件、日历、网页URL与对象无关绝不响应。否定条件哪些情况明确不处理比如仅查询不修改不涉及发送邮件仅处理当前登录账号的数据。示例语句放2到3个真实用户输入示例帮助模型做类比判断。这样改动之后技能选型准确率肉眼可见地上升。因为模型做意图判断时本质是在有限选项里做匹配而不是开放式理解你给的匹配条件越具体它匹配得就越准。2.3 技能命名与粒度从日期查询到营销流程的拆解技能粒度是个要反复拿捏的事情。粒度太粗一个技能内部什么都要做出错时你根本不知道是哪个环节的问题粒度太细技能数量爆炸Agent选技能的时间比干活时间还长。我们内部有一个不成文的判断标准一个技能应该只完成一个不可再拆的业务目标它的内部步骤确实可以多但对外的目标必须单一。拿邮件相关功能举例我把它拆成了三个独立的技能技能名称职责范围不做什么工单逾期检测从系统拉取所有未完结工单计算停滞时长返回逾期列表不发邮件、不改工单状态邮件内容生成基于工单信息和沟通记录生成个性化催办邮件正文不调用邮箱API发送邮件发送与状态回写把生成的邮件发出并把发送状态和日期回写到工单记录不负责内容创作而完整催办流程这个粗粒度目标我放在上层编排层去串联这三个技能而不是把它们揉成一个营销流程大技能。一个技能一个目标一个目标一个入口这是技能库不失控的基础。3. 把技能组装进Agent路由、注册与执行链路3.1 注册表决定了Agent能看到哪些技能技能定义好了下一步是让Agent在运行时看得到它们。这里不是简单地给模型塞一堆文档而是要建一个注册表Registry把技能元数据集中管理。注册表我设计成了这样的数据结构{ skills: [ { name: 工单逾期检测, version: 1.2.0, description: 扫描未完结工单并计算停滞时长, triggers: [扫描工单, 检查逾期, 停滞), input_schema: { type: object, properties: { max_days: {type: integer, minimum: 1}, assignee: {type: string, description: 按负责人过滤可选} }, required: [max_days] }, output_schema: { type: array, items: {$ref: #/definitions/ticket} }, entrypoint: skill://工单逾期检测, dependencies: [shared:http_client, shared:logger], tags: [工单, 通知, 业务] } ] }把schema直接暴露给模型比自己写一段描述有效得多。模型对输入输出的结构理解是强类型的有清晰定义时它填参数很少再出现类型错乱。注册表还负责版本管理和依赖解析这个后面4.4会细讲。3.2 意图路由不能只靠大模型的感觉路由层的设计我踩过两次坑第一次想完全靠大模型做意图判断结果技能库超过30个之后模型开始频繁在相似技能之间犹豫响应延迟变高触发选择也开始左摇右摆第二次想走极端把所有路由逻辑写成硬判断效果倒是稳定了但新场景一来代码就要跟着改维护成本直线上升。现在采用的是**规则预筛 模型精排的双层路由**规则预筛第一层用关键词、正则和实体识别先把匹配范围收窄到3到5个候选技能。这一步不花LLM的token开销极小响应快。模型精排第二层把候选技能的SKILL.md精简版目标、触发条件、输入输出交给模型让它从中选出最合适的或者给出无可匹配。这套双层的核心逻辑很简单让规则做它擅长的事快速收窄让模型做模型擅长的事在模糊语境下做语义判断。目前我们的生产环境里第一层能杀掉70%的错误匹配第二层的准确率在90%以上整体路由准确率比纯模型方案高出不少调用成本也下了几个点。3.3 执行链路预检、执行、验证与回滚技能被选中后不能直接开跑。我在执行环节加了三道关卡每一道都拦过实际事故预检Pre-check在技能真的动手之前先校验参数是否完整、依赖的第三方服务是否可达、当前账号有没有权限。比如发送邮件技能预检阶段就会检查SMTP服务是否健康、发件人邮箱是否认证通过。预检没过直接返回错误说明不要等到邮件发一半才发现认证过期。执行与验证Execute Verify技能执行完毕后不是立刻告诉Agent成功了而是按SKILL.md里的验证规则做一致性检查。比如更新工单状态后重新查一遍这个工单确认status和owner字段确实变了。验证规则要和业务强相关宁可多查一次接口也不要带着错误结果继续往下走。回滚事务性操作Rollback如果技能链中间某一步失败而之前几步已经产生了写操作比如邮件已发出、状态已改必须有对应的补偿机制。我们在每个技能描述里都加了一个undo_mode字段标明这项操作可不可逆、能不能补偿。可补偿的自动做逆向操作不可补偿的至少要在日志里明确标记出来避免后面流程做出错误假设。执行链路完整下来一个技能调用大致是这个状态机技能被选中 - 参数校验 - 预检通过 - 执行 - 内部验证 |- 验证通过 - 完成 |- 验证失败 - 补偿/回滚 - 标记错误 - 预检失败 - 返回错误修复建议4. 三个典型技能的完整落地过程这里挑三个我在项目中实际落地过的技能走完整流程覆盖了三种典型类型纯计算型、外部数据获取型、多步骤操作型。4.1 技能一日期时间计算典型的需求场景用户问下周三下午三点是哪一天或者这个月最后一天是几号看似简单但直接让模型心算极容易出错。SKILL.md关键部分## skill: 日期时间计算 ### 目标 把自然语言里的日期时间表达解析并转换成具体的日期/时间对象。 ### 触发条件 - 用户输入包含下周三本周五月底三天后等相对时间表达 - 用户输入包含几号周几什么时间等查询词 ### 输入参数 - text: 用户的原始自然语言表达 ### 输出 - iso_datetime: 标准ISO格式的时间戳 - weekday: 星期几 - timezone: 时区 ### 使用边界 - 仅负责时间计算不负责设置提醒 - 遇到去年某月等需要额外上下文的情况返回错误并说明需要哪个基准日期 ### 失败处理 - 解析失败时返回已知的时间参照点当天零点和未能解析的片段便于上层追问核心脚本片段Pythonimport datetime from dateutil import parser import re def parse_relative_time(text: str, reference: datetime.datetime None): if reference is None: reference datetime.datetime.now() # 先处理绝对时间 try: return parser.parse(text, fuzzyTrue) except: pass # 处理下周三本周五这类相对表达 weekdays {周一: 0, 周二: 1, 周三: 2, 周四: 3, 周五: 4, 周六: 5, 周日: 6} m re.search(r([下上这])(周|星期|礼拜)([一二三四五六日天]), text) if m: direction m.group(1) weekday weekdays[m.group(3)] days_ahead (weekday - reference.weekday()) % 7 if direction 这: date reference datetime.timedelta(daysdays_ahead) elif direction 下: date reference datetime.timedelta(daysdays_ahead 7) elif direction 上: date reference - datetime.timedelta(days7 - days_ahead) return date.replace(hour0, minute0, second0, microsecond0) raise ValueError(f无法解析的时间表达: {text})这个技能的踩坑点出现在时区和基准时间上。一开始我没强制要求外部传入reference时间结果Agent在运行时会用当前时间的语义去猜部署到不同时区的服务器后出现了几小时的偏差。后来改成基准时间必须由调用方显式传入并且统一转成UTC8才算彻底稳定。4.2 技能二搜索结果结构化提取这个技能解决的是上网查资料但结果杂乱的问题。Agent不能自己去翻几十个网页它需要一个技能能搜索、抓取指定网页内容并按Schema返回结构化结果。设计思路输入查询关键词或URL列表、提取规则要哪些字段输出JSON数组每项包含来源URL、标题、正文摘要、字段值边界不访问需要登录的站点对疑似敏感内容直接报无法访问实际代码里我用了异步HTTP客户端并发抓取多个URL超时控制在5秒提取规则用XPath CSS选择器混合。这块有一个很实用的经验不要指望通用爬虫拿到什么有用内容。真实输入是五花八门的页面结构所以我在技能内部做了一个通用提取 规则覆盖机制——先用通用算法抽取正文如果调用方提供了具体字段规则就按规则重新抽取并覆盖。一个具体的调用示例比如要求整理这三家公司的创始人、成立年份、总部所在城市输出会是[ { company: 示例科技, url: https://example.com/about, extracted: { founder: 王某, founded_year: 2018, headquarters: 杭州 }, confidence: 0.92 } ]每个字段带置信度是个隐藏的好设计。后续决策可以优先采用高置信度的数据低置信度的让Agent给人看原始片段而不是直接当作事实用。4.3 技能三工单逾期检测与催办执行这个技能串起了前面的拆分思想再说说它内部的完整执行流程。它被设计为三个独立技能的上层调用链但实际SKILL.md里只暴露一个聚合入口方便Agent看到的是一件事。执行链路工单逾期检测技能扫描所有未完结工单查询条件status ! completed且updated_at早于当前时间-48小时每个工单计算停滞时长按剩余响应时间排序返回逾期列表工单ID、客户、负责人、停滞时长、最后动态邮件内容生成技能逐个工单生成催办正文获取工单的最近3条沟通记录按不同停滞时长匹配语气模板24小时/48小时/超过5天生成结果同时包含人类可读的HTML正文和纯文本备选邮件发送与状态回写技能负责发送并把结果登记回工单发送前再次检查收件人邮箱格式避免无效地址发送成功后在工单的last_followup_at字段写入时间戳如果发送失败把失败原因和工单ID写到一个专门的失败队列整个链路的成功关键在于第二和第三技能的彻底解耦内容生成不管发不发得出去发送技能也不管内容怎么写的。这样出错定位清晰——第三技能报错必然是发送环节的问题绝不可能因为邮件文案写得不好而怪到发送技能头上。5. 实测踩坑技能切割粒度、描述歧义与失败路径调试5.1 什么都能干的技能最容易翻车我们最早也图省事把日期、日历、提醒、日程安排全做进一个time_manager技能。结果Agent只要一提时间相关字眼就全往这个技能上靠。它内部有十几个不同的入口函数每天的分发逻辑越来越复杂更新一个入口就要动整个技能测试用例翻了倍最后还是出问题。拆完之后我的体会是技能粒度宁小勿大拆错了可以合并做成大杂烩再拆分则伤筋动骨。判据还是那个你能否用一句话说清楚这个技能不可再拆的唯一目标能说清楚就继续看说不清楚就是该拆的信号。5.2 描述里的模糊动词让Agent在边缘反复试探前面提到触发条件要可判定这里展开说一个具体例子。我们在网页内容提取技能描述里写过分析这个词Agent就会把总结这篇文章提取文中的观点这类语义模糊的任务也路由过来。实际技能只能做HTML抽取根本做不了语义总结于是返回一堆原样HTML用户体验极差。修复办法是把描述动词全部收敛成操作性的词抓取、解析、校验、格式化、提取、生成、发送、更新。描述里出现任何分析、理解、判断、评估这类认知动词先反思是不是把不该封装的能力封装进来了。这背后的原因很直接技能系统不是给Agent发展思维能力用的而是给确定性任务提供确定性的执行路径。5.3 失败路径比成功路径更值得先测这是我们团队踩得最深的一个坑。最开始所有技能的验收标准都是正常输入跑通就算完成对失败路径想得少。上了生产环境一周真实用户开始输入各种边界内容问题集中爆发工单列表为空时邮件内容生成技能还在傻乎乎地遍历空结果集搜索技能遇到目标站点403直接抛异常让整个任务中断日期解析遇到明天如果是周末就顺延到下周一这种条件表达时底层库解析失败后来我定了一条死规矩每个技能在验收时必须有专门的失败路径测试矩阵。至少覆盖空输入、非法参数、目标服务不可用、权限不足、超时、部分成功。每个技能必须在SKILL.md的失败处理段说明这几种情况下的行为Agent拿到错误提示才知道是重试还是放弃。def run_with_failure_handling(skill_name, params, ctx): try: result execute_skill(skill_name, params, ctx) except ServiceUnavailable as e: # 明确是第三方服务挂了与技能本身无关 return {status: retryable_error, retry_after_seconds: 15, message: f服务暂不可用建议稍后重试: {e}} except PermissionDenied as e: # 权限问题不能重试直接让Agent向用户请求新授权 return {status: fatal_error, action: request_permission, message: f缺少权限请先完成授权: {e}} except PartialSuccess as e: # 部分成功需要补偿逻辑 ctx.compensate(e.completed_items) return {status: partial_success_rolled_back, message: e.message}5.4 技能版本的兼容问题技能库大到一定程度会面临A技能依赖B技能的2.0版行为但注册表里B已经升级到3.0的问题。Agent在运行时如果拿到的是新版本行为却按照旧版SKILL.md的理解去编排参数很容易传错参数。我的解决办法是在注册表里引入依赖锁定每个技能声明自己依赖哪些共享模块和其他技能的哪个版本范围升级时强制走语义化版本检查。同时每个技能的SKILL.md文件头加一段metadata包含依赖清单name: 工单逾期检测 version: 1.2.0 requires: shared/http_client: 2.1.0, 3.0.0 shared/logger: 1.0.0这样做的效果是升级依赖库时能提前发现哪些技能不兼容而不是等Agent运行时才报错。团队里新来的同事改共享模块时也能通过冲突提示少踩很多坑。6. 从单体技能到技能生态复用、共享与扩展方向6.1 把技能库做成团队共享的工具包技能库一旦成形它就不再只是单个Agent的配置而变成了团队内的资产。我现在鼓励组里的同学把日常处理任务的确定性动作沉淀成技能放进一个统一仓库管理类似npm私服的概念。技能写出来之后别人拉下来就能用但必须遵循同一套SKILL.md规范和目录结构。这种共享模式带来的好处是隐性的能力复用一个同学写好的PDF表格提取技能其他Agent也都能直接调用不用每个项目都从头写一遍。对一个团队而言技能库的厚度比单次任务的成功率更值得关注——你积累的不是代码而是被验证过的行为模式。6.2 不同模型与技能之间的适配还有一个现实问题需要提醒技能描述和触发条件写得好不好跟底层模型的能力是强相关的。同一个技能库在Claude下的表现和在某轻量模型下的表现差距可以拉得很大。轻量模型在依赖语义判断的场景里更容易翻车解决办法是给不同模型配不同的路由策略——能力强的模型可以直接喂完整SKILL.md让它选技能能力弱的模型需要更多的规则预筛兜底甚至在候选技能只有2到3个时直接匹配关键词。另一个实用适配方法简化技能描述。技能描述写得再华丽对弱小模型的帮助也有限反而挤占上下文。对轻量模型我只保留触发词列表和输入输出schema把冗长的使用边界换成一个精简的禁忌列表实测效果比原封不动喂全量描述好很多。6.3 我接下来的扩展计划当前这套技能系统还有一个有意思的方向没有深入技能自动生成。现在写技能基本靠我们手工维护成本还是偏高。我在尝试让Agent基于一段失败的对话记录自动抽取出这里缺一个技能的结论然后生成技能骨架再由人来验证修改。把这个流程跑通技能库的进化速度会比现在快一个量级。另一个方向是把技能的验证规则做成可插拔的断言库。现在每个技能内部都写了一套验证逻辑很多是重复的如果能把字段是否变更列表是否为空调用是否超时这些常见断言抽成公共模块技能的代码量会显著下降维护起来也更轻松。最后说句实在话。Agent开发走到今天模型的选择固然重要但真正让产品能用起来、让用户愿意长期信任的是那些被反复打磨、边界清楚、失败可控的技能模块。每次模型能力提升一个台阶技能库都能无缝地跟着受益而不用推翻重来——这就是我认为现阶段最值得投入的资产。如果你也在做Agent方向建议从自己业务里最痛、最高频的那几个动作开始先沉淀出五个像样的技能很快你就能体会到这套思路和塞Prompt之间的天壤之别。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号