Agent Skills实战:从概念到代码,打造大模型智能体技能包

发布时间:2026/9/8 3:18:31
Agent Skills实战:从概念到代码,打造大模型智能体技能包 现在的大模型应用开发已经慢慢从“单次问答”走向“多工具协同”和“智能体自主完成任务”。不少同学在看完各种 Agent 科普后仍然会有一个困惑模型能力再强怎么让它真正帮我执行一个复杂任务比如“帮我整理一个目录下的所有图片按拍摄时间重命名并生成一份 Markdown 索引”如果只靠提示词大模型做不到但如果你给它写好一个 Skill技能它就能非常稳定地完成。这就是 Agent Skills 存在的意义。这篇文章会从概念入手讲清楚它和 Function Calling、Tools、MCP 之间的关系然后带你在本地搭建一个最小可运行的 Agent Skill 项目最后通过一个完整实战代码走通“定义技能 → 注册技能 → 让 Agent 调用技能 → 输出结果”的闭环。文章较长建议先收藏再慢慢看。1. 为什么 Agent 需要 Skills1.1 Agent 的“手”和“脑”大模型本身擅长的是“思考”也就是根据上下文生成文本。但它有几个天然短板不知道实时数据比如今天的天气、最新股价。不能调用外部系统比如发邮件、操作数据库、调用支付接口。执行过程不稳定同一个任务换一种问法可能流程就乱了。为了解决这些问题业界慢慢形成了“模型 工具”的架构。模型负责拆解任务、决定调用哪个工具工具负责具体执行。早期大家管这些工具叫 Function Calling 或者 Plugins后来随着智能体框架的发展出现了更细分的概念Agent Skills。1.2 Skills 是什么Agent Skills 可以理解为“给 Agent 预装的一项专项能力包”。它不仅仅是一个 API 接口而是一套完整的“技能描述 执行脚本 使用说明”。典型结构如下skills/ └── image-sorter/ ├── SKILL.md # 技能说明文档 └── sort_images.py # 实际执行脚本SKILL.md 告诉模型“这个技能是干什么的、什么时候该用、怎么用”脚本负责真正干活。模型读 SKILL.md 后决定要不要调用这个技能一旦调用就执行对应脚本。用一句话概括Tools 是单个动作Skills 是完成一类任务的方法包。1.3 Skills 与传统 Tools 的区别很多同学容易把 Skills 和 Tools 混在一起。这里做一个简单区分维度ToolsAgent Skills粒度单个函数/接口一组脚本说明文档触发方式模型根据函数描述调用模型理解技能说明后触发学习成本需要写清楚函数入参出参需要写清楚使用场景和步骤可复用性一般只能复用函数本身整个方法包可复制到其他项目典型例子查询天气接口完整的数据清洗方法包Skills 更接近“教模型一套方法”而不是“给模型一把螺丝刀”。1.4 本文实战目标接下来我们会做一个完整的 Agent Skill 实战案例目标是让 Agent 具备一个自定义技能“文件归档助手”。需求场景用户告诉 Agent把某个目录下的文件按扩展名分类。Agent 调用 file-archiver 技能。技能脚本扫描目录按扩展名创建子文件夹并移动文件。技能脚本生成一份归档报告。整个项目不需要额外的大模型服务也能运行核心是为了讲清楚 Skills 的机制。最后我们还会接入一个大模型客户端演示“用户自然语言 → Agent 决策 → 调用 Skill”的完整流程。2. 环境准备与项目结构2.1 运行环境说明本文示例代码使用 Python 编写依赖很少重点在于理解 Skills 的组织方式。推荐环境Python 3.103.8 及以上应该也能运行但本文示例用 3.10 语法。操作系统Windows / macOS / Linux 均可。编辑器VS Code 或者任意你习惯的 IDE。可选依赖OpenAI SDK 或 Anthropic SDK用于最后的大模型联动示例。版本提示大模型 SDK 更新速度很快文中涉及的 SDK 库以常见稳定版本为例如果你安装的版本更新调用方式可能略不同建议以官方文档为准。2.2 安装 Python 依赖创建项目目录并进入mkdir agent-skills-demo cd agent-skills-demo建议先创建虚拟环境python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate安装后续可能用到的依赖pip install openai如果只是先跑通文件归档技能本身不需要任何第三方库Python 标准库的os、shutil、pathlib就够了。2.3 项目结构规划我们要在一个小项目中体现 Skills 的完整生命周期建议按下面的目录组织agent-skills-demo/ ├── skills/ │ └── file-archiver/ │ ├── SKILL.md │ └── archive_files.py ├── data/ │ └── sample_files/ # 测试目录 │ ├── readme.md │ ├── notes.txt │ ├── photo.jpg │ ├── report.pdf │ └── script.py ├── agent/ │ └── skill_runner.py # 技能加载与执行器 ├── demo_manual.py # 手动调用技能示例 └── demo_with_model.py # 接入大模型的完整 DEMO这个结构不算复杂但已经能体现出“技能包”和“执行器”分开的思想。后面每个文件都会给出详细代码。3. Agent Skills 的核心概念拆解3.1 SKILL.md 规范在 Anthropic 的 Claude Skills 文档中一个 Skill 目录的核心是SKILL.md文件它使用 Markdown 编写描述技能的使用场景、输入参数、输出格式和注意事项。一个规范的 SKILL.md 通常包含name技能名称。description技能作用描述模型会根据这段文字判断是否调用。when_to_use什么情况下应该使用这个技能。inputs需要哪些输入参数。outputs会返回什么结果。examples使用示例。notes注意事项。这样设计的本质是让模型在没有执行脚本的情况下也能准确判断“什么时候该调用、调用了会得到什么”。3.2 技能脚本的调用方式技能脚本是真正干活的代码。它和普通 Python 脚本没有本质区别但有几个设计上的要求支持命令行参数输入。结果尽量输出为结构化文本JSON 或纯文本。失败时要返回清晰的错误信息。不要硬编码路径路径从参数传入。这样设计是为了让 Agent 可以通过“构造命令”的方式灵活调用技能而不是把逻辑写死。3.3 技能发现与加载机制所谓技能发现就是让 Agent 在运行前知道“我有哪些技能可以用”。常见实现方式有两种约定目录扫描Agent 启动时扫描skills/目录下的所有SKILL.md把技能说明注入系统提示词。工具注册表通过代码显式注册技能把技能名称、描述、调用函数放入一个注册表。本文采用方式一因为更贴近“Skills 作为独立包”的设计理念。3.4 Skills 和 Function Calling 的关系这里再补充一个容易被问到的点Skills 和 Function Calling 有重叠但定位不同。Function Calling 是模型接口层面的能力它让模型输出一个结构化调用请求。 Skills 是应用层面的封装它包含说明文档和执行脚本。实际开发中经常是“Skills 里的脚本被封装成 Function Calling 接口暴露给模型”。你可以把 Skills 看成“技能的仓库”把 Function Calling 看成“技能暴露给模型的通道”。4. 从零实现一个 Agent Skill文件归档助手4.1 编写技能说明文档 SKILL.md首先创建技能目录和说明文件。文件路径skills/file-archiver/SKILL.md--- name: file-archiver description: 将指定目录下的文件按扩展名分类归档并生成一份归档报告。适合整理下载目录、项目文档目录等场景。 --- # File Archiver Skill 将指定目录下的所有文件按扩展名移动到对应子目录中并在目录下生成 archive_report.json 报告文件。 ## When to Use - 用户希望整理某个目录下的文件时。 - 需要按文件类型分类存放时。 - 希望生成文件清单报告时。 ## Inputs - directory: 要归档的目录路径必填。 - dry_run: 是否只预览不实际移动可选默认 false。 ## Outputs - 归档后的目录结构描述。 - archive_report.json 文件内容包含处理文件数和分类统计。 ## Examples 输入 python archive_files.py --directory /tmp/test_dir 输出 归档完成。共处理 5 个文件分为 3 类。 报告文件/tmp/test_dir/archive_report.json ## Notes - 脚本不会处理子目录内的文件只处理目标目录下的一层文件。 - 如果目标文件已存在会重命名为 filename_1.ext 避免覆盖。 - 建议先使用 dry_run 模式预览效果。这份文档是给模型读的所以要写清楚触发条件和输入输出格式。4.2 编写技能执行脚本文件路径skills/file-archiver/archive_files.py这个脚本接受命令行参数完成三个动作扫描目录。按扩展名归档。生成报告。完整代码如下#!/usr/bin/env python3 文件归档技能脚本。 用法示例 python archive_files.py --directory /path/to/dir python archive_files.py --directory /path/to/dir --dry_run import argparse import json import shutil from collections import defaultdict from pathlib import Path def get_file_category(ext: str) - str: 根据扩展名返回分类名。 ext ext.lower() if ext in {.jpg, .jpeg, .png, .gif, .bmp, .webp, .svg}: return images if ext in {.md, .txt, .doc, .docx, .pdf}: return documents if ext in {.py, .js, .java, .go, .ts}: return code if ext in {.zip, .rar, .7z, .tar, .gz}: return archives return others def archive_directory(directory: Path, dry_run: bool False) - dict: 按扩展名归档目录文件。 返回包含处理统计的字典。 if not directory.exists() or not directory.is_dir(): raise ValueError(f目录不存在: {directory}) # 分类统计 category_map defaultdict(list) moved_count 0 for item in directory.iterdir(): # 只处理文件跳过子目录和报告文件本身 if not item.is_file(): continue if item.name archive_report.json: continue category get_file_category(item.suffix) category_map[category].append(item.name) # 创建分类子目录 target_dir directory / category if not dry_run: target_dir.mkdir(exist_okTrue) # 目标路径避免重名覆盖 target_path target_dir / item.name if target_path.exists(): stem item.stem suffix item.suffix counter 1 while target_path.exists(): target_path target_dir / f{stem}_{counter}{suffix} counter 1 shutil.move(str(item), str(target_path)) moved_count 1 # 生成报告 report { directory: str(directory), dry_run: dry_run, file_count: sum(len(files) for files in category_map.values()), moved_count: moved_count if not dry_run else 0, categories: {k: len(v) for k, v in category_map.items()}, files: dict(category_map), } if not dry_run: report_path directory / archive_report.json report_path.write_text( json.dumps(report, ensure_asciiFalse, indent2), encodingutf-8, ) return report def main(): parser argparse.ArgumentParser(description文件归档技能) parser.add_argument(--directory, requiredTrue, help要归档的目录路径) parser.add_argument(--dry_run, actionstore_true, help只预览不实际移动) args parser.parse_args() try: report archive_directory(Path(args.directory), dry_runargs.dry_run) print(json.dumps(report, ensure_asciiFalse, indent2)) except Exception as exc: print(f归档失败: {exc}) raise SystemExit(1) if __name__ __main__: main()这里有几个细节值得说明get_file_category函数把常见扩展名归为五类映射关系可以按实际需求调整。重名文件使用_1、_2后缀避免覆盖防止数据丢失。dry_run模式只统计不移动便于模型先向用户确认。报告统一输出为 JSON方便上层解析。4.3 测试技能脚本先创建测试数据目录和几个文件mkdir -p data/sample_files cd data/sample_files echo # 测试文档 readme.md echo 一些笔记 notes.txt touch photo.jpg echo 测试PDF report.pdf echo print(hello) script.py cd ../..先以 dry_run 模式运行确认分类结果python skills/file-archiver/archive_files.py \ --directory data/sample_files \ --dry_run预期输出类似{ directory: data/sample_files, dry_run: true, file_count: 5, moved_count: 0, categories: { images: 1, documents: 3, code: 1 }, files: { images: [photo.jpg], documents: [readme.md, notes.txt, report.pdf], code: [script.py] } }确认没有异常后正式归档python skills/file-archiver/archive_files.py \ --directory data/sample_files运行后查看目录结构tree data/sample_files预期结果data/sample_files/ ├── archive_report.json ├── code/ │ └── script.py ├── documents/ │ ├── notes.txt │ ├── readme.md │ └── report.pdf └── images/ └── photo.jpg到这一步技能本身的逻辑已经完整了。5. 实现技能加载器让 Agent 能发现技能5.1 技能加载器的作用前面我们写了技能脚本但 Agent 还不会自动发现它。现在写一个小型技能加载器模拟 Agent 框架的“技能发现”机制。它的职责扫描skills/目录下的所有子目录。读取每个目录中的SKILL.md文件。解析技能名称和描述。提供执行技能的统一入口。文件路径agent/skill_runner.py 技能加载器扫描 skills 目录提供技能发现与执行能力。 import json import subprocess from pathlib import Path class SkillRunner: def __init__(self, skills_root: str skills): self.skills_root Path(skills_root) self.skills {} self._scan_skills() def _scan_skills(self): 扫描技能目录读取每个技能的 SKILL.md 基本信息。 if not self.skills_root.exists(): return for skill_dir in self.skills_root.iterdir(): if not skill_dir.is_dir(): continue skill_md skill_dir / SKILL.md if not skill_md.exists(): continue # 简单解析 name 和 description name skill_dir.name description in_front_matter False for line in skill_md.read_text(encodingutf-8).splitlines(): if line.strip() --- and not in_front_matter: in_front_matter True continue if line.strip() --- and in_front_matter: break if in_front_matter and line.startswith(description:): description line.split(:, 1)[1].strip() self.skills[name] { name: name, description: description, path: str(skill_dir), script: str(skill_dir / (name .py)), } def list_skills(self) - list: 返回所有技能的基本信息。 return list(self.skills.values()) def get_skill_prompt_block(self) - str: 生成一段可供注入系统提示词的技能描述文本。 lines [可用技能列表] for skill in self.skills.values(): lines.append(f- {skill[name]}: {skill[description]}) return \n.join(lines) def run_skill(self, skill_name: str, args: list) - dict: 执行指定技能。 参数 skill_name: 技能名称例如 file-archiver args: 命令行参数列表例如 [--directory, data/sample_files, --dry_run] 返回 stdout、stderr 和返回码。 if skill_name not in self.skills: raise ValueError(f未找到技能: {skill_name}) script self.skills[skill_name][script] cmd [python, script] args result subprocess.run( cmd, capture_outputTrue, textTrue, encodingutf-8, ) return { stdout: result.stdout, stderr: result.stderr, returncode: result.returncode, } def run_skill_with_json(self, skill_name: str, args: list) - dict: 执行技能并将 stdout 解析为 JSON。 result self.run_skill(skill_name, args) if result[returncode] ! 0: return { success: False, error: result[stderr], } try: data json.loads(result[stdout]) return { success: True, data: data, } except json.JSONDecodeError: return { success: True, raw: result[stdout], }这个加载器的核心是subprocess.run它通过命令行调用技能脚本。这样的好处是技能脚本可以用任何语言编写不一定非得是 Python只要支持命令行参数即可。5.2 手动调用技能测试文件路径demo_manual.pyfrom agent.skill_runner import SkillRunner def main(): runner SkillRunner(skills_rootskills) print( 可用技能 ) for skill in runner.list_skills(): print(f- {skill[name]}: {skill[description][:50]}...) print(\n 注入系统提示词的文本 ) print(runner.get_skill_prompt_block()) print(\n 以 dry_run 方式调用 file-archiver ) result runner.run_skill_with_json( file-archiver, [--directory, data/sample_files, --dry_run], ) print(result) if __name__ __main__: main()运行python demo_manual.py如果输出中包含“归档失败”或者 JSON 报错先检查技能脚本路径是否与skills/file-archiver/file-archiver.py一致。这里要说明一个问题我们的技能脚本起名是archive_files.py但加载器默认脚本名是技能目录名.py所以这里要么把脚本改名要么修改加载器逻辑。为了让项目一致推荐把脚本名改为file-archiver.py。修改命令mv skills/file-archiver/archive_files.py skills/file-archiver/file-archiver.py如果保持原脚本名不变也可以修改SkillRunner中的逻辑让每个技能在 SKILL.md 中声明脚本文件名。这更像真实框架的做法。这里为了简单统一使用“技能目录名.py”作为脚本名。再次运行确认技能加载器正常工作。6. 接入大模型用自然语言触发 Skill6.1 整体思路现在到了最关键的一步让大模型根据用户输入自动决定是否调用 file-archiver 技能。流程如下用户输入“帮我把 data/sample_files 整理一下”。系统把技能描述注入系统提示词。模型返回一个结构化 JSON 调用请求比如{skill: file-archiver, args: [--directory, data/sample_files]}。系统解析 JSON调用 SkillRunner 执行技能。把执行结果返回给模型模型生成人类可读的总结。6.2 使用 OpenAI SDK 实现先安装依赖pip install openai然后编写demo_with_model.py。这里需要说明OpenAI SDK 不同版本调用方式略有差异本文以 1.x 版本为例。如果你用的是 0.x 老版本API 调用方式需要相应调整。 接入 OpenAI 的 Agent Skill 演示。 流程 1. 调用模型把技能描述和用户请求一起发送。 2. 模型返回结构化 JSON指定要调用的技能和参数。 3. 执行技能。 4. 将结果再次交给模型总结。 import json import os from openai import OpenAI from agent.skill_runner import SkillRunner client OpenAI(api_keyos.getenv(OPENAI_API_KEY, your-api-key)) SYSTEM_PROMPT_TEMPLATE 你是一个智能助手。你有以下技能可以调用 {skill_prompt} 如果用户请求涉及可用的技能你必须返回如下 JSON不要返回其他文字 {{ skill: 技能名称, args: [参数1, 参数2] }} 如果用户请求不涉及任何技能请直接回复普通文本。 def build_messages(user_input: str, skill_prompt: str): system_prompt SYSTEM_PROMPT_TEMPLATE.format(skill_promptskill_prompt) return [ {role: system, content: system_prompt}, {role: user, content: user_input}, ] def extract_skill_call(content: str): 解析模型返回内容。如果包含技能调用 JSON则返回对应结构。 try: data json.loads(content) if skill in data and args in data: return data except json.JSONDecodeError: pass return None def main(): runner SkillRunner(skills_rootskills) skill_prompt runner.get_skill_prompt_block() user_input 请把 data/sample_files 目录按类型整理一下先预览不要真移动 messages build_messages(user_input, skill_prompt) response client.chat.completions.create( modelgpt-4o-mini, # 或你账号可用的其他模型 messagesmessages, temperature0, ) model_content response.choices[0].message.content print(模型返回, model_content) skill_call extract_skill_call(model_content) if skill_call is None: print(模型未调用技能直接回复, model_content) return skill_name skill_call[skill] args skill_call[args] print(f\n执行技能{skill_name}) print(参数, args) # 这里注意如果模型没有传 --dry_run我们可以补上防止误操作 if --directory in args and --dry_run not in args: args.append(--dry_run) print(已自动追加 --dry_run安全预览。) result runner.run_skill_with_json(skill_name, args) print(技能执行结果) print(json.dumps(result, ensure_asciiFalse, indent2)) # 把执行结果交给模型总结 summarize_messages [ {role: system, content: 你是一个助手请用简洁的中文总结技能执行结果。}, {role: user, content: f技能执行结果如下\n{json.dumps(result, ensure_asciiFalse)}}, ] summary_response client.chat.completions.create( modelgpt-4o-mini, messagessummarize_messages, temperature0, ) print(\n总结, summary_response.choices[0].message.content) if __name__ __main__: main()6.3 安全说明上面代码中我先强制加入了--dry_run这是很重要的一个工程习惯。文件移动、删除、覆盖这类操作在生产环境中风险很高。如果你让 Agent 直接操作真实目录建议遵循以下原则默认先 dry-run。需要用户二次确认后再真正执行。操作前备份关键文件。尽量使用测试目录验证。6.4 没有 OpenAI Key 怎么办如果你暂时没有 OpenAI API Key也可以不运行这一段前面第 4、5 章的本地技能本身已经能说明 Skills 的核心机制。如果想要一个完全离线、不依赖外部 API 的演示方式可以写一个“伪模型决策”函数用关键词规则模拟模型判断def mock_skill_call(user_input: str): 模拟模型决策过程不使用外部 API。 if 整理 in user_input or 归档 in user_input: return { skill: file-archiver, args: [--directory, data/sample_files], } return None这种设计在学习阶段非常实用能让你在没有 API 的情况下先跑通整个调用链。7. 常见问题与排查思路在实际开发和运行中下面几个问题出现频率最高。问题现象常见原因解决思路技能脚本无法导入项目根目录不在 sys.path在项目根目录运行或用python -m agent.skill_runner技能脚本名称与目录名不一致加载器默认拼接脚本路径统一脚本名或在 SKILL.md 中声明脚本名模型返回的不是 JSON提示词约束不够强增加 few-shot 示例使用更低 temperaturedry_run 模式下仍然移动了文件参数解析逻辑有误检查脚本中 dry_run 分支确保移动代码在 if 内Windows 下 subprocess 中文乱码编码未指定在 subprocess.run 中设置 encodingutf-8技能目录被当成普通文件处理扫描逻辑判断错误检查是否使用 is_dir() 过滤模型调用了不存在的技能SKILL.md 描述不清楚重新检查技能描述降低描述歧义文件重名导致覆盖没有做重名处理使用带序号的新文件名避免覆盖这里特别要说一下编码问题。在 Windows 下Python 默认编码可能是 GBK如果你在执行脚本时遇到中文乱码或编码异常可以在调用脚本前设置环境变量# Windows PowerShell $env:PYTHONIOENCODINGutf-8或者在 Python 代码里在main()开头加import sys sys.stdout.reconfigure(encodingutf-8)另外排查任何 Agent Skill 问题时建议先脱离大模型手动运行技能脚本。如果脚本本身能正常工作那问题基本出在模型提示词或参数解析环节。8. 最佳实践与工程建议8.1 Skill 命名与目录规范技能目录名使用短横线分隔例如file-archiver、db-backup。脚本名与目录名保持一致减少加载器复杂度。每个技能目录必须包含 SKILL.md否则加载器应跳过并告警。同一个技能目录里如果有多个脚本确保只有一个入口脚本其他作为辅助模块。8.2 提示词与技能描述设计SKILL.md 里的 description 是模型判断是否调用的关键不要写得太模糊。反面示例description: 整理文件的技能。正面示例description: 将指定目录下的文件按扩展名分类归档并生成归档报告。适合整理下载目录、项目文档目录等场景。关键词是“什么时候用”和“效果是什么”。8.3 参数安全与权限控制Agent Skill 落地到生产环境时一定要关注参数注入问题。比如你的技能脚本接收目录参数那用户可以让 Agent 访问服务器任意目录。建议配置白名单目录只允许技能操作允许范围内路径。对参数做路径标准化检查避免../穿越。敏感操作增加确认机制。对执行用户做最小权限控制不要用 root 运行 Agent。涉及数据库变更、删除操作时先备份再执行最后验证。8.4 结果输出与可观测性技能执行结果不要只输出一句“完成”。建议输出结构化 JSON。记录执行耗时。记录操作前后的状态变化。写入执行日志。这样上层 Agent 才能更好地判断“这次执行到底成功没有”。8.5 Skill 的测试方法一个成熟的 Skill 应该配套测试单元测试测试核心函数。集成测试模拟命令行调用。干跑测试在测试目录中完整执行一次。建议为每个 Skill 维护一个tests/目录。学习阶段也许觉得麻烦但一旦技能数量多了以后回归测试能帮你省下大量时间。9. 学习路线与进阶方向9.1 本文掌握要点到这里你已经完成了 Agent Skills 从概念到实战的闭环理解了 Skills 和 Tools、Function Calling 的区别。掌握了 SKILL.md 的结构和编写规范。用 Python 实现了一个文件归档技能。写了一个技能加载器实现了技能自动发现。通过大模型接口实现了自然语言触发技能调用。了解了生产环境下的安全和排错思路。这套流程并不只适用于某一个框架。无论你以后使用 Claude Skills、OpenAI 的 Assistant 工具还是 Dify、AgentScope 等国产框架底层思想都很接近。9.2 下一步可以学什么学习 Anthropic 官方 Claude Skills 格式它和本文结构非常接近。研究主流 Agent 框架比如 LangChain、CrewAI、Dify看它们的 Tools 和 Skills 是怎么注册的。尝试写一个“多技能协作”案例比如一个技能负责收集数据另一个技能负责生成报告。学习 MCPModel Context Protocol理解 Agent 如何通过标准化协议访问外部数据源。9.3 项目落地时的风险提示最后给你一个真实项目中的实用建议先跑通最小闭环再扩展技能数量。很多开发者在学习 Agent 时会犯一个错误——一开始就追求技能数量今天加一个天气查询明天加一个数据库操作最后发现模型经常选错工具。更好的做法是先把 1 到 2 个高质量技能打磨好让模型的调用率稳定在较高水平再逐步扩展。存储、目录、文件操作类技能是练手首选因为它们逻辑清晰、容易验证结果。等这一类技能稳定了再去挑战数据库操作、外部 API 集成这些更复杂的技能。希望这篇教程能帮你迈过 Agent Skills 的入门门槛。如果觉得有用可以收藏备用有任何问题也欢迎在评论区交流。