ARTICLE DETAIL

资讯详情

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

Agent Skills技能体系设计:从概念到工程实践,构建可复用的AI Agent技能库

Agent Skills技能体系设计:从概念到工程实践,构建可复用的AI Agent技能库 “agent-skills”这个短语最近在圈子里出现的频率越来越高。如果你正在折腾AI Agent大概率已经感觉到了单靠一个能聊天的模型远远不够真正让Agent“干活”的是一套可复用、可组合、可维护的技能体系。说白了Agent的智商是模型给的但它的“动手能力”全靠skill——同样的LLM配上不同的技能库能做出完全不同的产品。这篇文章我就从实际开发的角度聊聊我对agent-skills的理解、设计思路以及我踩过的那些坑。适合正在做Agent应用开发、或者准备给自己的AI助手扩充能力的同学参考。1. 先搞明白agent-skills到底在解决什么问题1.1 技能不是工具也不是插件很多人会把skill理解成“工具调用”或者“插件”这个理解不够准确。工具tool通常是一个独立的函数或者API比如“查天气”“发邮件”它是一次性的、无状态的。而技能skill是围绕某个能力域组织起来的一组行为模式它可能包含多个工具、多步推理逻辑、甚至私有的提示词模板和上下文记忆。举个例子“会议安排”是一个技能它内部需要调用日历工具、通讯录工具、会议室查询工具还要处理“冲突时怎么办”“对方没有回复怎么跟进”这类决策逻辑。如果把它拆成一个个独立的工具Agent在复杂场景下就很难自己把流程串起来。我的核心观点是技能是工具逻辑经验的三合一封装。它不仅仅告诉Agent“你能做什么”还告诉Agent“你该怎么做”。这有点像把菜谱和食材打包在一起给厨师而不是只甩给他一堆食材。1.2 技能的边界与粒度技能的设计最怕两个极端一种是把所有能力揉成一个巨大的万能技能另一种是把每个操作都拆成极其细碎的小技能。前者会让Agent在决策时非常困惑因为它无法判断该用技能的哪个子逻辑后者会让调度链路变得异常复杂Agent需要在几十个技能之间来回跳转效率和准确率都急剧下降。我自己的经验是技能粒度的判断标准只有一条看这个技能是否对应一个完整的用户意图。如果用户的请求是“帮我安排下周的团队周会”那就应该是一个独立的“会议安排”技能如果内部还牵扯到“查询空闲会议室”“发送会议邀请”这些子动作那这些动作可以作为技能内部步骤而不是独立暴露给Agent的skill。这个原则听起来简单但实际操作中非常容易犯迷糊尤其是当一个技能可以复用另一个技能的结果时很多人就开始纠结要不要拆分了。我的建议是先保持完整再考虑复用不要为了复用牺牲用户体验。2. 技能体系的设计思路与选型考量2.1 分层设计基础技能、复合技能、元技能一套成熟技能库不应该是一堆skill的平面堆积。我倾向于把它分成三层基础技能、复合技能和元技能。基础技能是最底层的原子能力比如“发送HTTP请求”“读写文件”“执行代码”“搜索本地文档”。这些技能通常无需依赖其他技能只和外部系统打交道。复合技能是基础技能的组装比如“分析日志文件”这个技能内部可能是“读文件”“执行Python脚本”“输出报告”的组合。元技能则是关于技能本身的技能——比如“技能选择”“技能编排”“技能自检”它们负责让Agent更聪明地使用其他技能。分层带来的直接好处是基础技能可以复用复合技能可以灵活组合元技能可以让体系自我进化。我在实际项目中基础技能数量通常控制在10-15个复合技能根据业务场景扩展元技能保持在2-3个就够用了。一旦某个层级膨胀整个体系的维护成本会指数级上升。2.2 技能描述的语言设计少写术语多写场景技能描述是给谁看的给LLM看的。这是很多开发者的认知但不够准确——技能描述不只是让LLM“看懂”更是让LLM在每一步决策时都能快、准、稳地做出判断。所以描述的语言风格非常重要。我踩过的一个典型坑是早期写技能描述使用的都是偏技术化的语言比如“在指定的文件路径下执行异步读取操作返回字节流”结果Agent经常在用户询问“帮我看看桌面的文档里有没有联系方式”时死活调用不到这个技能因为它的表述和用户意图差得太远。后来我把描述改成了用户视角技能名称“读取文件内容”技能描述“当用户需要查看某个文件的内容时使用支持txt、md、json等常见格式如果用户提到的文件有特定路径请优先使用该路径”。改完之后命中率明显上升。那之后我总结了一套描述模板技能名称不超过12字动词开头、一句话功能概述、适用场景举例至少3个典型请求、不适用于哪些场景防止误调用、输入参数的详细说明。这套模板看起来简单但每一条都有用。尤其是“不适用场景”这一条很多人会忽略但它能显著降低Agent的错误调用概率。2.3 输入输出Schema给参数加上“使用说明”技能的参数定义是所有环节里最容易被低估的部分。用Pydantic或JSON Schema定义参数类型只是第一步真正的关键在于每个参数都要给LLM提供足够充分的语义说明。举个我实际处理过的例子。有个“发送待办提醒”技能它有两个参数receiver和message。如果Schema只写类型Agent在判断“receiver”该填邮箱还是手机号时就会犹豫但如果我在字段描述里写明“receiver支持邮箱或手机号如果用户未明确提供接收人信息请先向用户确认”Agent就能正确处理模糊场景。另外参数的默认值也要慎重不要让Agent默默使用默认值除非这个默认值在绝大多数情况下都是用户想要的。还有一个容易被忽略的点参数之间的依赖关系。有些参数是可选的但它们的取值会影响技能内部的执行路径。这些信息必须在Schema里写清楚。比如“生成图表”技能output_format字段如果设为“png”那分辨率参数就有关联如果设为“html”那分辨率参数无意义Agent就应该忽略它。类似这种细节都会直接影响到执行结果的正确率。2.4 为什么用“技能”而不是直接写死在系统提示词里你会问既然技能描述最终都是给LLM看的为什么不直接把这些内容都写进系统提示词我最开始也是这么干的结果发现有两个严重问题。第一提示词的长度有限一旦技能数量超过5个塞进上下文中会挤占对话历史的空间还会分散注意力让LLM在关键任务上的表现下降。第二所有技能塞在一起修改任何一个技能都要重新调整整个提示词这显然没法工程化。技能体系的本质是“把决策空间缩小”。LLM每次行动前只需要从可用的技能列表里选择一个而不是从一段冗长的文字里猜测自己能做什么。这就像你给员工一本操作手册和给员工一张“遇到问题找对应人”的分工表后者明显更高效。工程上技能还可以独立版本化管理、按需加载、动态禁用这都是提示词做不到的。3. 从零搭一套技能库具体步骤与核心实现3.1 环境准备与基础框架选择我用Python实现过一套轻量级的技能库整体代码量不大但设计上非常讲究。先说环境Python 3.10及以上版本依赖只需要两个——pydantic和pydantic-settings前者做参数校验后者做配置管理。LLM部分我自己用的是OpenAI兼容接口但你完全可以用任何支持function calling的模型或者干脆用ReAct模式的提示词来调度。技能库的核心我用一个Skill基类来统一所有技能的结构。不要把它看得太复杂本质上它就是一个“带元数据的可调用对象”。每个技能实例包含名称、描述、输入Schema、执行函数这几个要素。下面是我实际使用的一个精简版本from pydantic import BaseModel, create_model from typing import Dict, Any, Callable, Optional from enum import Enum class SkillStatus(str, Enum): ACTIVE active DISABLED disabled DEPRECATED deprecated class Skill: def __init__( self, name: str, description: str, input_schema: Dict[str, Any], handler: Callable, status: SkillStatus SkillStatus.ACTIVE, tags: Optional[list] None, ): self.name name self.description description self.input_schema input_schema self.handler handler self.status status self.tags tags or [] # 动态生成pydantic模型用于参数校验 self._input_model create_model( f{name}Input, **{key: (value[type], value.get(default, ...)) for key, value in input_schema.items()} ) def validate_input(self, raw_input: Dict[str, Any]) - Dict[str, Any]: 校验输入参数返回规范化后的参数失败时抛出异常 validated self._input_model(**raw_input) return validated.model_dump() async def execute(self, **kwargs) - Dict[str, Any]: 执行技能统一做一次输入校验 validated self.validate_input(kwargs) return await self.handler(**validated)这个类虽然简单但它把“技能定义”和“技能执行”两个关注点分开了。你在定义技能时只需要关注Schema和handler不用关心调度层面的逻辑。create_model动态创建Pydantic模型这个技巧比较实用它可以让你用纯字典的方式定义Schema免去为每个技能单独写一个类的重复劳动。3.2 搭建技能注册中心有了Skill基类之后下一步是技能注册中心。它负责任务调度维护一个技能列表支持按名称、标签查询支持按状态过滤。最关键的是它要向LLM提供一个“技能清单”视图——每个技能的名称、描述、参数摘要这个清单将被传进LLM的函数调用上下文里。我实现了一个SkillRegistry类它维护一个内部字典并提供注册、发现、执行三个核心能力class SkillRegistry: def __init__(self): self._skills: Dict[str, Skill] {} def register(self, skill: Skill) - None: if skill.name in self._skills: raise ValueError(f技能 {skill.name} 已存在请勿重复注册) self._skills[skill.name] skill def unregister(self, name: str) - None: if name not in self._skills: raise KeyError(f技能 {name} 不存在) del self._skills[name] def list_skills(self, include_disabled: bool False) - list[Skill]: 列出当前全部技能可指定是否包含被禁用的 if include_disabled: return list(self._skills.values()) return [skill for skill in self._skills.values() if skill.status SkillStatus.ACTIVE] def get_skill(self, name: str) - Skill: 根据名称获取技能注意这里返回的是技能对象本身 if name not in self._skills: raise KeyError(f技能 {name} 不存在) if self._skills[name].status SkillStatus.DISABLED: raise RuntimeError(f技能 {name} 当前已禁用) return self._skills[name] async def execute(self, name: str, **kwargs) - Dict[str, Any]: 执行技能隔离异常返回结构化结果 try: skill self.get_skill(name) return { success: True, skill: name, result: await skill.execute(**kwargs), } except Exception as exc: return { success: False, skill: name, error: str(exc), error_type: type(exc).__name__, }这里有个值得强调的设计点execute方法不直接抛异常而是返回一个统一的结果结构。这样做的原因是Agent的下一步决策需要看到“技能是否成功”的信息如果把异常直接抛到LLM调度层要么导致整个对话中断要么LLM拿到一堆堆栈信息不知所措。统一返回success和error字段LLM就能根据失败原因自行判断下一步——比如重试、换一个技能或者直接如实告诉用户出错了。这个设计后来在很多项目里都发挥了作用。3.3 实现几个真正能跑的基础技能基类和注册中心都有了接下来实现几个技能。我先选三个典型场景来说明一个简单技能获取当前时间、一个带参数校验的技能数值计算、一个涉及外部I/O的技能读取文件内容。先看最简单的async def get_current_time(): from datetime import datetime return {now: datetime.now().strftime(%Y-%m-%d %H:%M:%S)} time_skill Skill( nameget_current_time, description获取当前时间当用户询问现在几点、今天日期时使用, input_schema{}, handlerget_current_time, )这里有几个细节。虽然这个技能不接收任何参数但input_schema仍然是空字典。我在Skill.__init__里用create_model处理了这个情况它会生成一个不接受任何字段的Pydantic模型。后面Agent调用时如果误传了参数校验会直接报错这反倒是个好事——可以尽早暴露出LLM幻觉参数的问题。再看带参数校验的数值计算技能async def calculate(expression: str): # 安全执行仅允许数字、运算符、括号和简单函数 import ast, math, operator safe_operators { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.Pow: operator.pow, ast.USub: operator.neg, } def _safe_eval(node): if isinstance(node, ast.Expression): return _safe_eval(node.body) if isinstance(node, ast.Constant): return node.value if isinstance(node, ast.BinOp): left _safe_eval(node.left) right _safe_eval(node.right) if isinstance(node.op, (ast.Div, ast.Pow)) and right 0: raise ZeroDivisionError(除数不能为0) return safe_operators[type(node.op)](left, right) if isinstance(node, ast.UnaryOp): operand _safe_eval(node.operand) return safe_operators[type(node.op)](operand) raise ValueError(f不支持的表达式语法: {type(node).__name__}) try: result _safe_eval(ast.parse(expression, modeeval)) except Exception as exc: return {error: str(exc)} return {result: result} calculate_skill Skill( namecalculate, description执行数学计算支持加减乘除、幂运算和括号如 (12)*3^2, input_schema{ expression: { type: (str, ...), description: 需要计算的数学表达式必须是纯数字和运算符, } }, handlercalculate, )这个技能使用了ast模块做安全的表达式解析而不是直接调用eval()。原因很简单eval()会把任何Python代码都执行一遍如果LLM生成的表达式里混入了恶意的系统调用后果不堪设想。写技能时凡是涉及执行用户输入或LLM生成内容的地方都必须做白名单校验。这是我在实际开发中一条铁律。再来看文件读取技能async def read_file(path: str, line_limit: int 200): import os if not os.path.exists(path): return {error: f文件 {path} 不存在请确认路径后重试} if os.path.isdir(path): return {error: f{path} 是一个目录不能作为文件直接读取} with open(path, r, encodingutf-8) as f: lines f.readlines() truncated len(lines) line_limit return { content: .join(lines[:line_limit]), total_lines: len(lines), truncated: truncated, read_limit: line_limit, } file_skill Skill( nameread_file, description读取指定文本文件的内容当用户需要查看文件里的信息时使用, input_schema{ path: { type: (str, ...), description: 文件的完整路径或相对路径, }, line_limit: { type: (int, 200), description: 最多读取多少行防止一次性加载超大文件默认200行, }, }, handlerread_file, )我特意加了line_limit这个参数默认200行。这是被现实教育出来的教训。有一次我在一个项目里让Agent去分析日志文件它拿到了一个几万行的日志直接把上下文撑爆了之后的回答质量一落千丈。后来我养成了习惯任何可能读取外部数据的技能都必须有显式的体量限制并且在返回结果中注明是否被截断。LLM看到truncated: true之后会主动提出“文件太长要不要我分段读取”或者“我先看看最后500行”。这样一来技能本身反而成了一个引导流程的工具。注册这些技能就更简单了就是把它们塞进注册中心registry SkillRegistry() registry.register(time_skill) registry.register(calculate_skill) registry.register(file_skill)3.4 让LLM学会使用技能两大调度模式对比技能库建好了需要接上LLM才能真正发挥作用。目前主流的方式有两种我分别实测过说说我的感受。第一种是Function Calling模式。这种模式适用于支持原生函数调用的模型比如OpenAI的tools参数。你把技能清单转成OpenAI的function schemaLLM会在回答时自动返回一个tool_calls字段里面标明它要调用哪个函数、参数是什么。代码侧只需要执行调用然后把结果再传回给LLM。这个模式的好处是准确率极高模型在训练阶段已经大量学习过这类交互方式基本上不会乱来。第二种是ReAct模式。这种模式不依赖模型的原生能力而是把技能列表放在提示词里让LLM的每一轮输出都包含“思考”和“行动”两个部分比如“我需要调用read_file技能参数是path/tmp/log.txt”。我再用正则表达式解析文本提取技能名和参数然后执行。这个模式的好处是适配所有文本生成模型坏处是输出格式不稳定稍微复杂一点的技能就容易解析失败而且消耗的token比Function Calling多不少。我现在的项目里优先用Function Calling只有在模型不支持的情况下才退回ReAct。还有一个折中方案如果模型的function calling能力偏弱可以在ReAct的基础上加一层JSON强制输出用response_format{type: json_object}来约束格式效果会有明显提升。3.5 技能编排从单技能到多技能协作单个技能只能解决单点问题真正复杂的任务需要多个技能协作。我在早期项目里发现一个常见现象Agent确实调用了多个技能但调用顺序经常是混乱的。比如处理“分析这个表格并给我画一张趋势图”Agent有时候先画图再分析数据结果图出来时没有数据支撑。后来我意识到这不是模型笨而是我没有给它足够的引导。我的解决方案是在复合技能内部嵌入一个“执行计划”字段。这个计划是一段标准化的文本描述技能内部的执行顺序和依赖关系。当Agent调用复合技能时它会先读取计划文本再逐项执行子技能。比如“数据分析与可视化”这个复合技能执行计划是这样的第一步检查输入文件是否存在 第二步用read_file读取文件的前200行判断数据结构 第三步用execute_python在代码中加载完整数据如果文件超过200行先截断到1000行再用 第四步根据用户的图表偏好生成图表 第五步把图表文件路径和简要数据结论汇总返回给用户。这段计划文字看着不起眼但它让Agent不再需要自己从头规划步骤节省了大量的推理时间和token消耗。而且计划还可以根据不同类型的请求动态调整——比如用户要求“只要趋势图不要数据明细”Agent就会跳过第二步和第五步中的明细部分。这个机制的底层逻辑是把成熟的流程沉淀成技能让Agent在流程框架内发挥灵活性而不是每一次都从零开始推理。还有一个细节复合技能调用子技能时需要把子技能的调用结果暂时存在内存里而不是直接展示给用户。我通常用一个执行上下文对象ExecutionContext来承载这些中间结果它本质上就是一个字典记录每个步骤的输出。这样设计的好处是后续步骤可以直接引用前面的结果不需要重复调用技能也方便调试时回溯。4. 技能库实战场上那些必须提前避开的坑4.1 参数校验的“太严”与“太松”都是问题参数校验是技能开发中最矛盾的地方。校验太严LLM生成的参数稍微格式不符就会被拒导致整个任务失败校验太松一些微妙的错误参数会悄悄混进handler执行出完全不符合用户预期甚至有害的结果。我经历过一次典型的“太严”事故某个技能要求date字段必须是“YYYY-MM-DD”格式结果LLM在回答用户“明天提醒我”时生成的是“明天”这个词汇校验直接报错。后来我在Schema的description里明确写了“如果用户说的是相对时间比如明天、下周一请先换算成具体日期再填入本字段”问题立刻消失了。这说明很多校验问题不是校验本身的问题而是给LLM的提示不够充分。先优化描述再放宽校验这个顺序不能反。还有一类问题是“太松”。一次LLM调用“发送邮件”技能时收件人一栏填了用户的备注名“老王”而不是邮箱地址。因为我的Schema只校验了字符串非空没校验格式结果邮件服务端拒收了。我后来给所有涉及外部通讯的技能都加了格式校验如果参数看起来不像是邮箱格式就返回错误信息并附上一句“请向用户确认正确的收件邮箱”。这样做其实是把“校验失败”设计成了“与用户澄清”的触发点。Agent会主动追问用户而不是默默吞掉错误。4.2 技能描述膨胀导致决策退化技能多了之后清单本身会变得很长。几十个技能的描述叠在一起会让LLM在选择技能时的准确率明显下降。我在一个项目里最多注册了47个技能结果发现模型经常在相似技能之间犹豫有时还会连续选错两次。解决这个问题我采取了两步走。第一步是精简描述每条描述控制在50字以内重点保留“什么时候用”和“不用于什么场景”。第二步是分组把技能清单按领域拆成多个小的skill group在每次和LLM交互前先根据用户的当前意图粗筛出最相关的2-3个技能组再在这几个组里做精排。比如用户的问题涉及“日历”那我就不需要向LLM暴露“执行Python代码”这样的技能。粗筛可以用一个简单的关键词匹配也可以再用一层轻量级LLM分类器。实测下来把技能从47个压缩到每次最多8个待选项准确率从大约82%提升到了96%以上。这一步几乎零成本但收益巨大。4.3 状态管理与技能幂等性技能不是永远无状态的。“发送邮件”技能发了一次就不能再发这是系统设计决定的。但Agent在多轮对话中可能会出现重复调用同一个技能的失误。比如用户说“发送邮件”和“再确认一下发送状态”Agent可能会误解为“再发一遍”。这就是状态管理要解决的问题。我的做法是在技能库层面维护一个执行历史记录每次技能调用都会写入一条日志字段包括技能名称、参数摘要、执行时间、结果状态。这个记录有几个作用一是当Agent询问“你刚才做了什么”时可以直接从日志里读取不需要重新执行任何技能二是给技能增加“重复调用检测”如果同一个技能在较短时间内被连续调用且参数完全一样就会触发确认机制让Agent先向用户澄清是否真的要再次执行。这套机制实现起来并不复杂却能挡住大量低级失误。幂等性也很关键。对于写入类技能能设计成“重复执行不产生副作用”就尽量设计成幂等。比如“创建待办事项”技能如果连续调用两次结果应该是一模一样的一个待办而不是两个重复项。实现思路是在写入前先检查是否已经存在相同内容如果存在就直接返回已有记录。这个习惯可以减少很多内部冲突。4.4 技能冲突与优先级Agent选错技能怎么办技能之间的权限冲突总会存在。比如“删除文件”和“归档文件”看起来是完全不同的两个技能但在某个边界场景下比如文件路径相同Agent可能不知道该调用哪一个。我的处理思路是给每个技能加上priority元数据默认都是0。当两个技能都能满足用户意图时LLM优先选择优先级更高的那个。更重要的是要在技能描述中显式说明“如果遇到XX情况请优先使用另一个技能”。比如我同时有“读取文件”和“搜索文件内容”两个技能。如果用户问“帮我看一下config.json里的端口配置”这两个技能都符合。但读取文件更直接所以我给“读取文件”设置的描述是“当用户明确指定了文件路径时优先使用本技能”给“搜索文件内容”设置的描述是“当用户不确定具体是哪个文件时使用本技能”。这样一来LLM的决策依据就非常清晰了。这种“描述级别的互斥声明”是解决技能冲突最便宜、最有效的手段。5. 扩展方向让技能库具备自我进化能力5.1 从一次调用记录中提炼新技能当我积累了一定量的技能调用日志后我开始做一件事定期把高频出现的“多步骤调用序列”固化成新的复合技能。具体流程是我跑一批日志分析任务统计那些由Agent在运行时自行编排的、重复出现的三五步操作序列。比如我好几次看到Agent在处理“Read file - Calculate - Summarize”这个序列那我就会把这三步打包成一个名叫analyze_file_statistics的复合技能。这样一来以后LLM就不需要重复规划路径直接一步到位。这个过程很像代码重构中的“提取函数”核心是识别重复模式并封装。这个机制不需要太复杂基于调用日志的简单频率统计和人工确认就能运转起来。还有一类更高级的做法是“策略迁移”。如果我发现某个技能在特定用户场景下的表现不佳我可以把这个用户场景的典型案例追加进技能的描述里作为few-shot示例。比如“读取文件”技能的描述中增加一句“如果用户提到‘日志’‘报错’‘堆栈’请优先读取最新的日志文件并向用户提示文件的行数”。这不需要重新训练模型只更新技能的元数据就能生效反馈周期非常短。5.2 技能质量评测不能只看调用成功率我见过很多团队评估技能体系时只看“调用成功率”这是远远不够的。一个技能调用成功了但结果不是用户想要的这样的成功没有任何意义。我的评测框架包括四个维度调用准确率该调用时调用、不该调用时不调用、执行成功率工具层面执行不报错、结果满意度外部评估或用户反馈、以及资源消耗token数、延迟。其中结果满意度最难量化我在实操中用了一个替代方案让一个“评审Agent”扮演用户对每次技能执行结果打一个1-5分的质量分然后把低分样本捞出来人工分析。这个做法虽然不是100%准确但能自动发现大量问题。评测要形成持续循环发现问题、修改技能元数据或执行逻辑、重新评测、发布新版本。技能的版本管理可以复用Git每次改动技能定义文件时走一次代码评审流程。这样做听起来重但对于生产环境来说非常有必要——毕竟你的Agent是在替用户做真实的事情技能体系的任何一次变更都应该是可控的、可回滚的。5.3 技能的跨Agent复用团队级共享如果你所在的团队同时维护多个Agent应用各个Agent之间的技能不可能完全独立。我建议把技能库设计成一个独立的内部包通过标准接口暴露给不同的Agent实例。这就意味着技能的定义和执行逻辑要与具体的Agent上下文分离。技能内部不要直接引用某个Agent的专属状态如果必须引用就以参数的形式传入。这样设计之后团队里一个“日历技能”可以被会议Agent、客服Agent、助理Agent同时使用只需要传入不同的Calendar API配置。跨Agent复用的标准化带来的最大价值不是省代码量而是让技能的质量随着使用次数的增加而持续提升——很多隐性Bug都是在这种多场景复用中被发现的。还有一个值得尝试的方向是“技能市场”。公司内部的技能库可以像插件市场一样允许不同团队的开发者发布自己的技能其他团队可以引用。引用时可以选择“引用最新版本”或者“锁定版本”。这个模式听起来遥远但在一些成熟的中型互联网公司里已经跑起来了只要做好权限管理和审批流它能大幅降低重复造轮子的成本。我自己在多次技能体系的迭代中最深刻的感受是不要试图一夜之间做出一套完美无缺的技能库。技能体系的成长一定是循序渐进的过程——先建一个能跑的最小闭环再根据真实调用数据持续迭代。那些你预设得很完美的流程很可能在第一次面对真实用户需求时就被彻底推翻。反而是那些从小处着手、在失败中不断修正的技能才真正经受住了考验。就像我经常和团队说的技能库不是写出来的是“养”出来的。如果你打算给Agent扩充技能不妨从你现在最常处理的那一类任务开始写出第一个带描述、带Schema、带执行逻辑的skill跑通一条完整链路然后再慢慢扩展。这个过程会比你预想的更快见到效果。
返回列表