用 SKILL.md 给 Agent 装 App:模块化技能加载与代码审查实战
1. 为什么 Agent 需要像装 App 一样加载技能很多人第一次接触 Agent 开发时习惯把所有能力都塞进一个巨大的 system prompt 里代码审查规则、文档生成模板、数据分析流程全写在一起。结果就是提示词越写越长改一处逻辑要翻几百行测试一个功能得把整个 Agent 跑一遍。这种「单体式」写法在技能少的时候还能忍一旦超过三五个技能维护成本就会指数级上升。我试过把代码审查、文档生成、数据分析三套逻辑混在一个 prompt 里最后连自己都分不清哪段规则属于哪个技能调试时只能靠注释硬猜。后来换成模块化思路每个技能独立成一个目录Agent 按需加载整个世界就清爽了。deepagents 的 FilesystemBackend 正是为这种模块化设计的。它允许你把技能以 SKILL.md 文件的形式放在磁盘上Agent 启动时扫描技能目录提取每个技能的元数据名称、描述生成一份「可用技能清单」。当用户请求进来时Agent 用语义匹配找到最合适的技能再把该技能的完整指令加载到对话上下文中执行。整个过程对用户透明你只需要表达意图Agent 自己决定调用哪个技能。这套机制的核心价值在于三点。第一是独立开发每个技能就是一个文件夹包含 SKILL.md 和可选的 scripts、references开发者可以单独编写、单独测试互不干扰。第二是动态加载技能不需要预先注册到某个中心化配置里放进 skills 目录就能被识别删掉就失效像手机装 App 一样自然。第三是可复用同一个代码审查技能可以挂载到不同的 Agent 实例上不用复制粘贴提示词。适合谁用如果你正在做多能力 Agent或者团队里多人协作维护不同技能又或者你想把某个成熟的工作流沉淀成可复用的模块这套方案会帮你省下大量重构时间。接下来我会从目录结构讲起一步步带你跑通「新增一个代码审查技能并验证」的完整流程。2. TaoToken 前置准备模型接入与 FilesystemBackend 配置在写 SKILL.md 之前得先把模型接入和 backend 配置搞定。deepagents 本身不绑定特定模型供应商只要兼容 OpenAI 接口协议就能用。这里我用 TaoToken 作为模型接入层它提供统一的 API 入口省去在不同供应商之间切换的麻烦。首先安装依赖。deepagents 目前需要 Python 3.10 以上建议用虚拟环境隔离python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install deepagents langchain langchain-community python-dotenv接着配置环境变量。在项目根目录创建.env文件填入 TaoToken 的 API Key 和模型信息QWEN_API_KEY你的_TaoToken_API_Key QWEN_BASE_URLhttps://taotoken.net/api QWEN_MODELqwen-plus这里的QWEN_BASE_URL指向 TaoToken 的 API 地址注意不要加多余的路径后缀。API Key 可以在 TaoToken 控制台的 API Keys 页面生成模型 ID 根据你实际使用的模型填写。关键的一步是 backend 配置。deepagents 的create_deep_agent默认使用内存后端 StateBackend它只能读取对话上下文里的内容无法访问本地文件系统。如果你把 SKILL.md 放在磁盘上却不显式传入 FilesystemBackendAgent 扫描技能目录时会返回空列表然后你就看着日志发呆不知道哪里出了问题。正确的做法是显式构造 FilesystemBackend 并指定根目录import os from dotenv import load_dotenv from deepagents import create_deep_agent from deepagents.backends import FilesystemBackend from langchain_community.tools import WriteFileTool, ReadFileTool, ListDirectoryTool load_dotenv() os.environ[OPENAI_API_KEY] os.getenv(QWEN_API_KEY) os.environ[OPENAI_BASE_URL] os.getenv(QWEN_BASE_URL) model fopenai:{os.getenv(QWEN_MODEL)} backend FilesystemBackend(root_diros.getcwd()) agent create_deep_agent( modelmodel, tools[WriteFileTool(), ReadFileTool(), ListDirectoryTool()], system_prompt你是一个助手会按需加载技能完成任务。, skills[skills], backendbackend, debugTrue )注意skills[skills]这个参数它告诉 Agent 去哪个目录扫描 SKILL.md。root_diros.getcwd()则限定了文件系统访问的根路径避免 Agent 越权读取项目外的文件。debugTrue 会在控制台打印技能扫描和加载的详细日志调试阶段强烈建议打开。如果你用的是 Claude Code 或 Cline 这类工具做辅助开发记得把 Base URL、API Key、Model ID 三件套配全否则会出现 401 或连接失败。TaoToken 的接入文档里有各客户端的配置示例照着填就行。3. 可复制的 SKILL.md 目录结构与加载配置技能目录的组织方式直接决定了后续维护的难易度。推荐的结构是每个技能一个独立文件夹文件夹名用英文小写加连字符内部固定包含 SKILL.md可选 scripts 和 referencesskills/ ├── code-review/ │ ├── SKILL.md │ ├── scripts/ │ │ └── review.py │ └── references/ │ └── style-guide.md ├── doc-generator/ │ └── SKILL.md └──>--- name: code-review description: 审查代码质量、检查常见问题。当用户要求代码审查、review 代码、检查 bug 时使用。 --- # 代码审查 审查代码文件检查以下问题 - 语法错误和潜在 Bug - 代码风格和规范 - 性能问题 - 安全隐患 ## 使用方法 当用户要求审查代码时执行 bash python skills/code-review/scripts/review.py file_path输出格式按严重程度分类严重问题必须修复警告建议改进提示可选优化配套的 scripts/review.py 可以写一个简单的静态检查脚本 python import sys import ast def review(file_path): with open(file_path, r, encodingutf-8) as f: source f.read() issues [] try: tree ast.parse(source) except SyntaxError as e: issues.append(f严重问题: 语法错误 第{e.lineno}行 {e.msg}) return issues for node in ast.walk(tree): if isinstance(node, ast.FunctionDef) and len(node.body) 50: issues.append(f警告: 函数 {node.name} 过长建议拆分) if isinstance(node, ast.ExceptHandler) and node.type is None: issues.append(f警告: 第{node.lineno}行 裸 except建议指定异常类型) if not issues: issues.append(提示: 未发现明显问题) return issues if __name__ __main__: for item in review(sys.argv[1]): print(item)加载配置方面除了前面提到的skills参数和FilesystemBackend还有一个容易踩的坑deepagents 目前不支持通过init_chat_model构造的模型对象必须用字符串形式指定模型。所以你会看到代码里用model fopenai:{os.getenv(QWEN_MODEL)}而不是init_chat_model(...)。这个限制在官方文档里写得比较隐蔽我第一次配置时卡了很久。如果你需要更细粒度的控制可以在 frontmatter 里加version、author、tags等自定义字段Agent 扫描时会一并读取但只有name和description参与匹配逻辑。4. 验证请求新增代码审查技能后的完整测试配置写好后最关键的一步是验证技能真的被加载并生效了。很多人配完就直接跑复杂任务结果出错时分不清是技能没加载还是模型能力问题。建议先用一个最小化的测试脚本确认链路通畅。创建test_agent.pyimport os from dotenv import load_dotenv from deepagents import create_deep_agent from deepagents.backends import FilesystemBackend from langchain_community.tools import WriteFileTool, ReadFileTool, ListDirectoryTool load_dotenv() os.environ[OPENAI_API_KEY] os.getenv(QWEN_API_KEY) os.environ[OPENAI_BASE_URL] os.getenv(QWEN_BASE_URL) model fopenai:{os.getenv(QWEN_MODEL)} agent create_deep_agent( modelmodel, tools[WriteFileTool(), ReadFileTool(), ListDirectoryTool()], system_prompt你是一个助手会按需加载技能完成任务。, skills[skills], backendFilesystemBackend(root_diros.getcwd()), debugTrue ) queries [ 审查 skills/code-review/scripts/review.py 代码, 列出当前目录文件 ] for q in queries: print(f\n问{q}) result agent.invoke({messages: [{role: user, content: q}]}) print(f答{result[messages][-1].content})运行python test_agent.py观察控制台输出。debug 模式下你会看到类似这样的日志[DEBUG] Scanning skills directory: skills [DEBUG] Found skill: code-review - 审查代码质量、检查常见问题... [DEBUG] Matching query against skill descriptions... [DEBUG] Loaded skill: code-review如果看到Found skill: code-review说明 SKILL.md 被正确扫描到了。如果看到Loaded skill: code-review说明语义匹配成功技能指令已注入上下文。最后 Agent 会调用 review.py 脚本并返回审查结果类似答审查完成发现以下问题 - 警告: 第15行 裸 except建议指定异常类型 - 提示: 未发现其他明显问题这里有个细节值得注意Agent 并不是每次都调用脚本。如果 SKILL.md 的指令写的是「分析代码并给出建议」Agent 可能直接用模型能力回答不走脚本。所以如果你希望强制走脚本要在 SKILL.md 里明确写「执行以下命令」并给出具体路径。验证通过后你可以尝试新增第二个技能比如文档生成观察 Agent 是否能在两个技能之间正确切换。测试查询用「为 review.py 生成文档」和「审查 review.py 代码」交替发送看日志里的Loaded skill是否对应变化。5. 常见报错排查401、local proxy failed 与技能未加载配置过程中最容易遇到的几类报错我按出现频率排个序附上排查思路。401 Unauthorized通常是 API Key 没读到或格式不对。检查.env文件是否在项目根目录load_dotenv()是否在读取环境变量之前调用。另外注意os.environ[OPENAI_API_KEY]的赋值要在create_deep_agent之前执行否则模型初始化时拿不到 Key。如果用的是 TaoToken确认 Key 没有多余空格Base URL 是https://taotoken.net/api而不是带路径的地址。local proxy failed / connection refused这类错误一般是 Base URL 写错或网络不通。先确认QWEN_BASE_URL的值然后用 curl 直接测试curl -X POST https://taotoken.net/api/chat/completions \ -H Authorization: Bearer 你的Key \ -H Content-Type: application/json \ -d {model:qwen-plus,messages:[{role:user,content:hi}]}如果 curl 能通但 Python 报错检查是否有多余的代理环境变量干扰比如HTTP_PROXY、HTTPS_PROXY。在代码开头加os.environ.pop(HTTP_PROXY, None)可以临时排除。技能未加载 / Found skill 为空三个可能原因。第一skills参数路径写错确认是相对项目根目录的路径。第二SKILL.md 的 frontmatter 格式错误YAML 要求---开头结尾name和description必须有值。第三backend 没传 FilesystemBackend默认的 StateBackend 读不到磁盘文件。用debugTrue看日志如果连Scanning skills directory都没有说明 skills 参数没生效。reading choices 报错这个错误通常出现在模型返回格式不符合预期时比如 Agent 试图解析一个非 JSON 响应。检查 SKILL.md 里是否有要求模型输出特定格式但没给示例。解决办法是在指令里加一句「以 JSON 格式返回示例{issues: []}」。OAuth 相关错误如果你用的是 Claude Code 或类似工具做辅助可能会遇到 OAuth token 过期。这类问题跟 deepagents 本身无关重新走一遍客户端的授权流程即可。TaoToken 的接入文档里有各客户端的配置说明对照检查 Base URL 和 Key 是否填对。排查时养成看 debug 日志的习惯deepagents 的日志会明确告诉你技能扫描到几个、匹配到哪个、加载是否成功。大部分问题看日志就能定位。6. 把技能开发流程跑通从独立测试到复用技能模块化最大的好处是开发流程可以拆开。你不需要每次改技能都启动完整 Agent可以单独测试 SKILL.md 的指令是否清晰、脚本是否能跑通。独立测试脚本的方法很简单直接运行python skills/code-review/scripts/review.py 目标文件.py确认脚本本身没问题。然后写一个最小 Agent 只挂载这一个技能用两三句测试查询验证匹配逻辑。确认无误后再合并到主 Agent 的技能列表里。复用方面同一个技能目录可以挂载到不同项目。比如你在 A 项目里写好了代码审查技能B 项目只需要把skills/code-review整个文件夹复制过去在create_deep_agent的skills参数里加上路径即可。如果多个项目共享同一套技能可以把 skills 目录放在公共位置用绝对路径引用。版本管理建议把每个技能目录纳入 GitSKILL.md 的变更单独提交方便回溯。如果技能依赖外部脚本在 references 目录里放一份依赖说明避免换环境后跑不起来。最后提醒一点技能描述不要写得太宽泛。比如「处理代码相关任务」这种 description 会导致 Agent 在任何代码问题上都加载这个技能反而干扰匹配。好的 description 应该像 App Store 的应用简介一句话说清「我解决什么问题、什么时候用我」。整套流程跑通后你会发现新增一个技能的成本很低建目录、写 SKILL.md、放脚本、加测试查询、验证日志。这种「装 App」式的开发体验比维护一个巨型 prompt 要舒服得多。

相关新闻

【认知颠覆】申论微缩对策题不考“决策”考“解码”:材料本位洞察与信息熵实战指南

【认知颠覆】申论微缩对策题不考“决策”考“解码”:材料本位洞察与信息熵实战指南

【认知颠覆】申论微缩对策题不考“决策”考“解码”:材料本位洞察与信息熵实战指南 摘要:在公务员申论、遴选笔试及结构化面试中,微缩字数对策题(30-50字)是拉开分差的“修罗场”。绝大多数考生陷入致命误区&#xff1…

2026/10/4 19:19:22 阅读更多 →
把 Minimax M3 接上本地 Agent Hermes 后,我慌了:这大模型,我怕它把我的“马”养傻——TaoToken 统一 Key 通道实测

把 Minimax M3 接上本地 Agent Hermes 后,我慌了:这大模型,我怕它把我的“马”养傻——TaoToken 统一 Key 通道实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 19:18:21 阅读更多 →
记一次真实 openEuler(欧拉)环境中 fstab / sysctl / limits 配置错误的连环排查与修复全过程

记一次真实 openEuler(欧拉)环境中 fstab / sysctl / limits 配置错误的连环排查与修复全过程

一、故障背景环境信息:操作系统:openEuler 22.03 LTS SP4(内核 5.10.0-216.12.3.0119.oe22003sp4.x86_64)CPU 架构:x86_64(TaiShan 200 机型也有 aarch64 版本,排查命令通用)业务角色…

2026/10/4 19:18:21 阅读更多 →

最新新闻

11. 利用PY32Studio+HAL库开发ADC单次多通道扫描采样+中断

11. 利用PY32Studio+HAL库开发ADC单次多通道扫描采样+中断

前言在第十章中,我们扫描方式采集3个通道,每个通道要等待其采集完成后,才能读取数据,等待期间一直处于阻塞状态,浪费CPU的时间。本章我们利用ADC的扫描模式中断的方式来采集3个通道,大大降低CPU的负载。一、…

2026/10/4 19:59:53 阅读更多 →
插件加载失败排查指南:IAR、MusicFree与web boot问题全解析

插件加载失败排查指南:IAR、MusicFree与web boot问题全解析

最近很多人搜 "plugins",搜出来的东西很有意思:有人问 "iar plugins 是干什么的",有人贴出 "failed to load plugins web boot: 2 entries did not activate" 这种报错,还有人琢磨 "musicfree…

2026/10/4 19:59:53 阅读更多 →
概率论与数理统计核心概念与工程应用实战手册

概率论与数理统计核心概念与工程应用实战手册

概率论与数理统计是数据分析、机器学习、风控模型这些方向绕不开的地基。说实话,我在刚接触这门课的时候也觉得很抽象,样本空间、分布函数、极大似然估计这些东西到底在干啥,和写代码有什么关系?直到后面真正做A/B测试、搭推荐系统…

2026/10/4 19:59:53 阅读更多 →
C#超市管理系统实战:WinForms+SQL Server数据库附加与部署全攻略

C#超市管理系统实战:WinForms+SQL Server数据库附加与部署全攻略

简介:基于C#与SQL Server 2008的超市管理系统,完整提供项目源码和数据库文件,是一份可用于课程设计、毕业设计或C#数据库开发入门实践的优质资源。系统面向中小型超市的日常运营,覆盖商品管理、采购管理、销售管理、会员管理、库存…

2026/10/4 19:59:53 阅读更多 →
高性价比AI API聚合站怎么选:2026年六家平台实测与分层策略

高性价比AI API聚合站怎么选:2026年六家平台实测与分层策略

两个月、六家平台、累计超过 50 万次接口调用——这是本文评测的原始口径。测试环境统一为腾讯云上海节点,维度集中在开发者最关心的五项:价格、稳定性、模型覆盖、速度、客服响应。结论先行:没有全项第一,但有明确的分层组合策略…

2026/10/4 19:59:53 阅读更多 →
Linux Nginx 怎么通过日志分析 TLS 握手失败的错误原因

Linux Nginx 怎么通过日志分析 TLS 握手失败的错误原因

前言排查 TLS 握手失败时,最常听到的一句话是:"日志里全是 200,哪有握手失败?"这句话本身没错,但它说明找错了地方。Nginx 处理一个 HTTPS 连接的顺序是:接受 TCP 连接 → 完成 TLS 握手 → 解析…

2026/10/4 19:58:53 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →