1. 项目概述为什么我们需要一个结构化的 Skill 体系如果你正在构建或研究 Agent智能体系统尤其是在尝试让 Agent 去完成一些稍微复杂、需要多步骤协作的任务时你很可能已经遇到了一个核心痛点能力管理混乱。今天想加个“联网搜索”功能明天想整合“代码执行”后天又觉得“文本总结”必不可少。这些功能我们称之为 Skill如果只是以一堆零散的函数、脚本或 API 调用的形式堆砌在代码库里很快就会变得难以维护、复用和迭代。最终你的 Agent 核心逻辑会被各种if-else和硬编码的函数调用淹没系统变得僵化任何新能力的接入都像是一场外科手术风险高且效率低下。这正是《从零实现 Agent 系统》连载到第 23 期要深入探讨的主题Skill 体系与 Skill Creator。这个主题的核心就是将 Agent 所需的各种能力进行标准化“打包”并建立一套可持续的“生产线”来创造和迭代这些能力包。它解决的远不止是代码整洁度的问题更是关乎 Agent 系统的可扩展性、健壮性和进化能力。一个设计良好的 Skill 体系能让你的 Agent 像乐高积木一样通过组合不同的 Skill 来应对千变万化的任务而 Skill Creator 则是制造这些标准化积木的模具和流水线。简单来说这一讲我们要做两件事一是定义什么是“好”的 Skill为其建立一套从描述、输入输出到执行逻辑的完整规范即“打包”二是设计一套机制能够高效、可靠地生产出符合规范的 Skill即“迭代”的流水线。这不仅是理论更是我踩过无数坑之后总结出的让 Agent 项目从玩具走向工程化的关键一步。2. Skill 体系深度解析超越“函数”的标准化能力单元当我们谈论 Agent 的 Skill 时很多人的第一反应就是一个 Python 函数。这个理解方向是对的但深度远远不够。一个合格的 Skill 体系需要将这个“函数”升级为一个自描述、可发现、可组合、可安全执行的标准化能力单元。2.1 Skill 的核心构成要素一个设计完善的 Skill至少应该包含以下五个核心元数据这构成了它的“标准化接口”唯一标识符 (Name/ID): 一个全局唯一的字符串用于在系统中精确引用该 Skill例如web_search、python_code_executor、send_email。自然语言描述 (Description): 用人类和 LLM都能理解的语言清晰说明这个 Skill 是做什么的。例如“在互联网上搜索相关信息并返回摘要”而不仅仅是“搜索”。好的描述是 Agent 能否正确“理解”并调用该 Skill 的关键。输入参数规范 (Input Schema): 明确定义调用这个 Skill 需要哪些参数每个参数的类型字符串、数字、列表等、是否必填、以及参数的描述。这通常可以用 JSON Schema 来定义。例如一个搜索 Skill 的输入可能包括query字符串必填搜索关键词和max_results整数选填默认为5。输出格式规范 (Output Schema): 同样明确地定义 Skill 执行后的返回结果格式。这保证了下游 Skill 或决策逻辑能够可靠地解析和使用其结果。例如搜索 Skill 的输出可能是一个包含summary字符串和sources对象列表的 JSON 对象。执行逻辑 (Execution Function): 这才是真正的“函数”本体即实现该能力的具体代码。但关键在于这个函数的实现被前面的元数据“封装”和“隔离”了。2.2 为什么需要如此复杂的“包装”你可能会问我直接调用函数不行吗为什么要大费周章地定义 Schema原因在于 Agent 系统的特殊性——决策与执行的分离。在传统编程中是程序员你在代码里直接决定何时、如何调用哪个函数。但在 Agent 系统中这个决策权很大程度上交给了 Agent 的“大脑”通常是 LLM。LLM 需要根据当前的任务和上下文自主决定调用哪个 Skill并生成符合要求的调用参数。如果没有清晰的、机器可读的 Skill 描述Description 和 Input SchemaLLM 就如同一个面对一堆未贴标签工具的新手根本不知道每样工具是干嘛的、该怎么用。因此Skill 的元数据本质上是一份给 LLM 看的“工具说明书”。一个强大的 Agent 框架如 LangChain、AutoGen 或我们自建的框架会收集所有已注册 Skill 的“说明书”在需要时提供给 LLM。LLM 根据这些说明书生成结构化的调用请求如符合特定格式的 JSON框架再根据这个请求找到对应的 Skill 并执行其逻辑。这个过程就是 Agent 的“工具调用”Tool Calling或“函数调用”Function Calling能力。2.3 Skill 的分类与层级设计在实践中我们可以根据 Skill 的复杂度和作用范围对其进行分类管理这有助于系统的架构清晰。基础 Skill (Atomic Skills): 完成单一、原子性操作的 Skill。例如get_current_time获取当前时间、calculate执行数学计算、read_file读取文件内容。这些 Skill 通常没有外部依赖或依赖很轻。复合 Skill (Composite Skills): 由多个基础 Skill或其他复合 Skill按一定逻辑组合而成的 Skill。例如analyze_financial_report分析财务报告这个 Skill内部可能依次调用了download_file从URL下载、extract_text_from_pdf从PDF提取文本、summarize_text总结文本和sentiment_analysis情感分析等多个 Skill。复合 Skill 的实现本身就可以利用 Skill 体系的编排能力。领域 Skill (Domain Skills): 针对特定垂直领域如客服、编程、数据分析封装的一系列高内聚 Skill 集合。它们可能包含基础 Skill 和复合 Skill共同提供该领域的专业能力。建立这种层级观念有助于我们在设计 Skill Creator 时考虑不同层级 Skill 的创建模式和复用策略。3. Skill Creator 设计构建能力“生产线”有了 Skill 的标准定义下一步就是如何高效地生产它们。Skill Creator 不是一个单一的工具而是一套涵盖从构思、生成、测试到注册的完整工作流和工具集。它的目标是降低 Skill 开发门槛提升开发速度与质量并确保所有产出的 Skill 都符合系统规范。3.1 核心工作流程一个完整的 Skill Creator 工作流通常包含以下环节需求描述与解析: 开发者或用例提供者用自然语言描述他们想要的能力。例如“我需要一个 Skill能根据用户提供的城市名查询该城市未来三天的天气预报并返回一个格式化的字符串。”框架代码生成: Skill Creator 的核心组件通常由 LLM 驱动根据需求描述和系统预定义的 Skill 模板自动生成符合规范的 Skill 框架代码。这包括生成一个唯一的 Skill ID如get_weather_forecast。编写清晰、完整的 Skill 描述。推导并生成合理的输入/输出 JSON Schema。生成一个包含正确函数签名的 Python 函数骨架以及必要的 import 语句。逻辑填充与集成: 生成的骨架代码包含了关键的TODO注释或占位符。开发者需要填充核心的业务逻辑例如集成第三方天气 API、处理返回数据等。这一步目前仍需人工介入因为涉及具体的业务知识、API 密钥管理和错误处理。自动化测试与验证: Skill Creator 应能生成或关联基础的单元测试和集成测试。测试会验证输入参数是否符合 Schema执行逻辑是否在预期时间内完成输出结果是否符合定义的 Output Schema这能极大保障 Skill 的质量。安全与合规审查: 对于涉及外部调用、数据访问或敏感操作的 Skill如发送邮件、执行数据库查询、调用付费 APICreator 流程应强制触发安全审查环节检查代码是否存在注入风险、密钥是否硬编码、权限是否过高等问题。注册与上线: 通过所有检查的 Skill会被自动注册到中央 Skill 仓库Registry中。注册过程会将其元数据名称、描述、Schema存入可供 Agent 核心查询的目录并将其执行代码部署到可执行的环境中。3.2 实现一个基于 LLM 的 Skill Creator 原型让我们来看一个简化的、基于 LLM例如 OpenAI GPT-4的 Skill Creator 核心生成环节是如何实现的。这里我们假设使用 LangChain 的框架来构建。from langchain.prompts import ChatPromptTemplate from langchain.chat_models import ChatOpenAI import json class SkillCreator: def __init__(self, llm_modelgpt-4): self.llm ChatOpenAI(modelllm_model, temperature0.1) # 低随机性保证生成稳定 self.prompt_template ChatPromptTemplate.from_messages([ (system, 你是一个专业的AI智能体Skill代码生成器。请根据用户的需求生成一个完整的、可执行的Python Skill类。 Skill必须包含以下部分 1. skill_id: 一个简短、清晰的蛇形命名字符串。 2. description: 详细描述该Skill的功能、输入和输出。 3. input_schema: 一个符合JSON Schema规范的字典定义输入参数。 4. output_schema: 一个符合JSON Schema规范的字典定义输出格式。 5. execute 方法: 实现Skill核心逻辑的方法参数名必须与input_schema中的属性对应。 请严格按照以下JSON格式输出不要包含任何其他解释 { skill_id: ..., description: ..., input_schema: {...}, output_schema: {...}, code: class GeneratedSkill: ... (完整的Python类代码) } ), (human, 需求{requirement}) ]) def create_from_requirement(self, requirement: str) - dict: 根据自然语言需求生成Skill定义和代码 chain self.prompt_template | self.llm response chain.invoke({requirement: requirement}) try: # 解析LLM返回的JSON result json.loads(response.content) # 这里可以添加额外的验证比如检查schema有效性代码语法等 return result except json.JSONDecodeError as e: print(fLLM返回无法解析为JSON: {response.content}) # 可以加入重试或更复杂的解析逻辑 raise e # 使用示例 if __name__ __main__: creator SkillCreator() requirement 创建一个Skill能够对输入的文本进行情感分析判断其情感是积极、消极还是中性并返回情感标签和置信度分数。 skill_blueprint creator.create_from_requirement(requirement) print(f生成的Skill ID: {skill_blueprint[skill_id]}) print(f描述: {skill_blueprint[description]}) print(输入Schema:, json.dumps(skill_blueprint[input_schema], indent2)) print(\n生成的代码:) print(skill_blueprint[code])这个原型展示了如何利用 LLM 的理解和代码生成能力将一段模糊的自然语言需求转化为结构化的 Skill 蓝图包括元数据和代码骨架。生成的code字段是一个完整的 Python 类开发者可以将其保存为文件然后填充execute方法中的具体逻辑例如集成一个情感分析模型或 API。注意在实际生产环境中这个生成过程需要更严谨。例如需要验证生成的 JSON Schema 是否有效需要对生成的代码进行安全扫描AST 分析防止注入恶意代码。同时skill_id的生成需要与中央仓库进行查重避免冲突。3.3 从 Creator 到工厂模板与脚手架对于更成熟的系统Skill Creator 会进化成“Skill 工厂”它提供的不再是一次性的生成而是一套可复用的模板和脚手架。技能模板 (Skill Templates): 针对常见类型的 Skill如 HTTP API 调用、数据库查询、文件操作、数据转换预先制作好标准模板。当创建同类 Skill 时Creator 只需向模板中填充特定参数如 API 端点、SQL 语句、文件路径即可快速生成高质量、符合最佳实践的代码大大减少重复劳动和错误。交互式脚手架 (Interactive Scaffolding): 提供一个命令行工具或图形界面引导用户一步步定义 Skill。例如$ python -m skill_cli create ? 选择Skill类型: HTTP API调用 ? 输入Skill名称: get_github_repo_info ? 简要描述: 获取GitHub仓库的星标数、fork数和最近更新时间 ? 输入参数 (例如: repo_owner, repo_name): repo_owner, repo_name ? API端点URL: https://api.github.com/repos/{repo_owner}/{repo_name} ? HTTP方法: GET工具会根据这些回答自动生成一个包含错误处理、重试机制和结果解析的完整 Skill 文件。4. Skill 的迭代、管理与最佳实践创建 Skill 只是开始如何管理一个不断增长的 Skill 仓库并确保其持续迭代优化是另一个重要课题。4.1 版本控制与迭代Skill 也应该像软件库一样进行版本控制。每次对 Skill 的输入输出 Schema 或执行逻辑进行修改都应产生一个新版本。这有助于向后兼容性管理: 明确哪些改动是破坏性的Breaking Change。例如删除了一个输入参数就是破坏性变更需要主版本号升级如从 1.x 到 2.0。而新增一个可选参数则可以只升级次版本号如从 1.1 到 1.2。依赖关系追踪: 复合 Skill 或特定的 Agent 配置可以锁定其所依赖的基础 Skill 的版本避免因底层 Skill 的意外更新导致上层应用出错。灰度发布与回滚: 可以将新版本的 Skill 先部署到测试环境或小流量环境验证无误后再全量发布。如果出现问题可以快速回滚到上一个稳定版本。4.2 Skill 仓库与发现机制所有 Skill 都应该注册到一个中央化的Skill 仓库 (Skill Registry)中。这个仓库提供以下功能技能目录: 提供所有可用 Skill 的列表支持按名称、描述、标签进行搜索和过滤。元数据服务: 对外提供统一的 API供 Agent 核心或编排引擎查询 Skill 的描述和 Schema。这是实现动态工具调用的基础。依赖解析: 管理 Skill 之间的依赖关系例如复合 Skill A 依赖于基础 Skill B 和 C。权限与租户隔离: 在企业级应用中不同团队或项目可能只能访问和使用特定的 Skill 集合。4.3 实操心得与避坑指南在设计和实现 Skill 体系的过程中我总结出以下几点核心经验Schema 设计要“严进宽出”: 输入 Schema 可以定义得严格一些这有助于 LLM 生成更准确的参数也便于早期发现调用错误。但输出 Schema 在保证核心结构稳定的前提下可以保留一定的扩展性例如使用additionalProperties: true或包含一个extra_info字段为 Skill 未来的功能扩展留有余地。Skill 的执行必须是幂等的和安全的: 尽可能让 Skill 的执行不产生副作用或者副作用是可预期的。对于有副作用的 Skill如发送邮件、修改数据库必须在 Description 中明确警告并在执行前通过确认机制如需要 Agent 或用户明确授权来增加安全阀。重视错误处理与超时控制: Skill 的execute方法必须有完善的异常捕获和错误信息返回。同时一定要设置执行超时。一个网络请求 Skill 如果无限期挂起会拖垮整个 Agent 的执行线程。将错误信息结构化地返回例如{“success”: false, “error”: “API request timeout”, “code”: “TIMEOUT”}有助于上层进行智能重试或故障转移。为 Skill 添加丰富的测试用例: 除了测试正常流程更要测试边界情况和异常情况。例如输入参数缺失、类型错误、API 返回异常数据、网络超时等。这些测试用例应该作为 Skill 资产的一部分随 Skill 代码一起管理。建立 Skill 的性能监控与质量评估体系: 记录每个 Skill 被调用的频率、平均执行时间、成功率等指标。对于性能瓶颈明显的 Skill如某些复杂的计算或慢速的 API可以考虑优化或提供缓存机制。对于失败率高的 Skill则需要触发告警进行排查。5. 实战构建一个复合 Skill —— 智能信息助手让我们通过一个具体的例子将上述所有概念串联起来。我们要构建一个名为intelligent_research_assistant的复合 Skill。它的功能是给定一个研究主题它能自动进行联网搜索获取多篇相关文章然后对文章内容进行总结并最终生成一份综合性的研究报告。这个复合 Skill 将由以下基础 Skill 组合而成web_search: 根据查询词返回搜索结果的链接和摘要。fetch_webpage_content: 根据 URL 获取网页的纯净文本内容。summarize_text: 对长文本进行摘要。synthesize_report: 将多个摘要综合成一份连贯的报告。5.1 定义复合 Skill 的接口首先我们定义这个复合 Skill 的元数据skill_id:intelligent_research_assistantdescription: “对一个给定的研究主题进行深入的自动化研究。该技能会执行以下步骤1) 在互联网上搜索相关主题2) 获取并分析多篇高质量文章的内容3) 生成一份包含关键发现、不同观点和引用来源的综合性研究报告。”input_schema:{“type”: “object”, “properties”: {“research_topic”: {“type”: “string”, “description”: “需要研究的主题例如‘量子计算的最新进展’”}, “max_sources”: {“type”: “integer”, “description”: “最多参考的资料来源数量”, “default”: 5}}, “required”: [“research_topic”]}output_schema:{“type”: “object”, “properties”: {“report”: {“type”: “string”, “description”: “生成的研究报告正文”}, “sources_used”: {“type”: “array”, “items”: {“type”: “string”}, “description”: “实际使用的资料来源URL列表”}}, “required”: [“report”, “sources_used”]}5.2 实现复合 Skill 的执行逻辑接下来我们在execute方法中编排各个基础 Skill 的调用。这里假设我们已经有一个SkillRegistry的客户端可以通过skill_id调用任何已注册的 Skill。class IntelligentResearchAssistantSkill: skill_id “intelligent_research_assistant” description “...” # 如上所述 input_schema {...} # 如上所述 output_schema {...} # 如上所述 def __init__(self, skill_registry): self.registry skill_registry async def execute(self, research_topic: str, max_sources: int 5) - dict: # 1. 调用 web_search 技能获取初步结果 search_results await self.registry.execute_skill( “web_search”, {“query”: research_topic, “max_results”: max_sources * 2} # 多搜一些以备过滤 ) if not search_results.get(“items”): return {“report”: “未找到相关资料来源。”, “sources_used”: []} # 2. 获取网页内容并过滤例如只保留内容长度足够的 valid_contents [] sources_used [] for item in search_results[“items”][:max_sources]: # 限制处理数量 url item[“link”] try: content await self.registry.execute_skill( “fetch_webpage_content”, {“url”: url} ) if len(content.get(“text”, “”)) 500: # 简单的内容长度过滤 valid_contents.append(content[“text”]) sources_used.append(url) except Exception as e: print(f”获取 {url} 内容失败: {e}”) continue if not valid_contents: return {“report”: “未能获取到有效的文本内容进行分析。”, “sources_used”: []} # 3. 并行或串行地对每篇内容进行摘要 summaries [] for text in valid_contents: summary await self.registry.execute_skill( “summarize_text”, {“text”: text, “max_length”: 300} ) summaries.append(summary.get(“summary”, “”)) # 4. 将所有摘要合成为一份最终报告 combined_input “\n\n---\n\n”.join(summaries) final_report await self.registry.execute_skill( “synthesize_report”, { “topic”: research_topic, “source_summaries”: combined_input, “format”: “detailed” } ) return { “report”: final_report.get(“report”, “”), “sources_used”: sources_used }5.3 关键实现细节与优化在这个复合 Skill 的实现中有几个点值得深入探讨错误处理与鲁棒性: 我们对每一个基础 Skill 的调用都进行了try-except包裹。在真实场景中fetch_webpage_content失败如网络问题、反爬虫是常态。复合 Skill 必须能容忍部分子步骤的失败并做出降级处理例如跳过该来源或返回部分完成的结果。异步执行: 注意我们使用了async/await。像fetch_webpage_content这样的 I/O 密集型操作非常适合异步并发执行可以大幅缩短整体耗时。Skill 体系的设计应支持异步执行模式。流程控制与决策: 当前的流程是线性的搜索 - 获取 - 摘要 - 综合。更复杂的复合 Skill 可能需要根据中间结果动态调整流程。例如如果第一步搜索的结果质量不高可以尝试用不同的搜索词重新搜索。这需要将更多的决策逻辑编码到复合 Skill 中或者引入更高级的“规划”能力。结果缓存: 对于research_topic相同或相似的请求其结果在短时间内很可能不变。可以在复合 Skill 或底层 Skill如web_search层面引入缓存机制避免重复计算和网络请求提升响应速度并降低开销。通过这个例子你可以看到一个强大的复合 Skill 本身就是一个微型的、目标明确的自动化工作流。而 Skill 体系的价值就在于它让构建这样的工作流变成了组装标准化组件的过程清晰、可控且易于调试。6. 总结与展望Skill 体系是 Agent 生态的基石走到这里我们已经深入剖析了 Skill 体系从概念定义、标准化接口、创建流水线到管理迭代的全过程。回顾一下核心脉络我们首先将 Agent 的离散能力标准化为自描述的 Skill然后通过Skill Creator这套“生产线”来高效、规范地生产这些能力单元最后通过复合与编排将这些单元组合成解决复杂任务的强大智能体。这套体系带来的好处是显而易见的对开发者而言开发新能力变得模块化和高效无需每次都与 Agent 的核心决策逻辑耦合。对 AgentLLM而言它获得了一份清晰、可理解的“工具手册”能更准确、可靠地使用外部能力。对系统架构而言实现了关注点分离系统更易于维护、测试和扩展。Skill 可以独立部署、升级和扩展。然而这远不是终点。一个蓬勃发展的 Agent 系统其 Skill 体系最终会演变成一个内部生态。我们可以展望几个进阶方向Skill 的自动化测试与评估未来Skill Creator 或许能根据 Skill 的描述和代码自动生成更全面的测试用例甚至利用 LLM 来评估 Skill 的输出是否符合预期目标。Skill 的自动发现与组合Agent 能否根据一个全新的任务目标自动从 Skill 仓库中发现并组合出合适的 Skill 流程这需要更高级的规划Planning和工具学习Tool Learning能力。Skill 的联邦与共享不同团队、不同项目甚至不同组织之间能否安全、可控地共享和复用 Skill这涉及到 Skill 的权限模型、计费机制和标准化协议类似 Docker Hub 对于容器镜像的意义。构建 Skill 体系就像是为你 Agent 的“双手”打造一个功能齐全、井然有序的工具箱并为这个工具箱建立了一套源源不断补充新工具的生产和管理规范。当你的工具箱变得足够强大和智能时你的 Agent 所能触及的世界和解决问题的能力将不再受限于初始代码而是取决于这个生态的丰富程度和进化速度。这正是 Agent 系统从单点智能迈向群体智能和持续进化的重要一步。