
1. 为什么你的 Agent 总是“学不会新技能”很多人第一次搭 Agent 的时候都会遇到同一个尴尬明明模型能力不差但一到具体任务就开始“自由发挥”。你让它审查代码它给你写一段总结你让它按公司规范生成文档它按自己的风格来。问题不在模型而在于我们把所有能力都硬编码进了 system prompt 里Agent 根本不知道自己“会什么、什么时候该用什么”。AI Skills 技能系统就是来解决这件事的。它的核心思路特别像给手机装 AppAgent 本身是一个操作系统每个 Skill 是一个独立 App用SKILL.md描述这个 App 能干什么、怎么用、什么时候触发。Agent 在收到请求时先扫描所有技能的元数据做一次语义匹配命中后把对应技能的完整指令加载进上下文再执行任务。整个过程对用户透明你只说需求Agent 自己找技能。这套机制最适合三类人一是正在用 deepagents、LangChain 这类框架做多技能 Agent 的开发者二是手里有一堆重复性任务、想让 Agent 自动分派的团队三是想统一管理模型 Key、不想在每个项目里重复配环境的人。我试过把代码审查、文档生成、数据清洗三个技能拆成独立目录后Agent 的命中准确率比全塞进 prompt 高了不止一个档次。而要让这套系统真正跑起来除了技能文件本身还需要一个稳定的模型通道。下面我会用 TaoToken 的统一 Key 接入把技能注册、模型调用、端到端验证完整走一遍你可以直接复制配置。2. TaoToken 统一 Key 接入一次配置多技能共用在讲 SKILL.md 之前先把模型通道打通。因为 deepagents 在加载技能后最终还是要调用模型来执行指令如果每个技能都单独配一套 Key 和 Base URL维护成本会非常高。TaoToken 的思路是给你一个统一的 API 入口所有技能共用同一个 Key切换模型只改一个 Model ID。先拿到你的 Key。打开 https://taotoken.net/api-keys 登录后创建一个新的 API Key复制出来。这个 Key 就是后面所有配置里唯一的凭证。注意不要把它写进代码仓库用环境变量管理。接着确认你的接入地址。TaoToken 的 API 根地址是https://taotoken.net/api兼容 OpenAI 风格的调用方式。也就是说任何支持自定义 Base URL 的框架都可以直接指向这里。deepagents 底层走的是 LangChain 的模型初始化所以我们只需要设置两个环境变量export OPENAI_API_KEYsk-你的TaoTokenKey export OPENAI_BASE_URLhttps://taotoken.net/api如果你用的是.env文件写成这样OPENAI_API_KEYsk-你的TaoTokenKey OPENAI_BASE_URLhttps://taotoken.net/api然后在 Python 里用load_dotenv()加载。这里有个细节deepagents 目前对init_chat_model构造的模型对象支持不完整所以更稳的做法是直接用字符串形式指定模型让 LangChain 走 OpenAI 兼容通道。比如import os from dotenv import load_dotenv load_dotenv() os.environ[OPENAI_API_KEY] os.getenv(OPENAI_API_KEY) os.environ[OPENAI_BASE_URL] os.getenv(OPENAI_BASE_URL) model fopenai:{os.getenv(TAOTOKEN_MODEL, claude-sonnet-4-5)}这里的 Model ID 你可以根据任务复杂度选。轻量任务用便宜的快模型代码审查这种需要推理的用强一点的。TaoToken 的模型列表在 https://taotoken.net/models 可以查到切换只需要改TAOTOKEN_MODEL这一个变量所有技能自动生效。为什么要强调“统一 Key”因为当你后面注册了五六个技能每个技能内部都可能触发模型调用。如果 Key 分散在各处一旦要换模型或者额度调整你得改一堆文件。统一通道之后技能只负责描述“怎么做”模型通道负责“用哪个大脑”职责分离维护起来轻松很多。配置完成后建议先做一次最小验证确认通道是通的from openai import OpenAI client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL) ) resp client.chat.completions.create( modelos.getenv(TAOTOKEN_MODEL, claude-sonnet-4-5), messages[{role: user, content: 回复 ok}] ) print(resp.choices[0].message.content)如果输出ok说明 Key 和 Base URL 都没问题可以进入技能系统的搭建。3. 可复制配置SKILL.md 模板与 deepagents 编排现在进入核心部分。一个 Skill 的目录结构是这样的skills/ └── code-review/ ├── SKILL.md ├── scripts/ │ └── review.py └── references/ └── rules.mdSKILL.md是必须的scripts/和references/可选。SKILL.md由两部分组成开头的 YAML Frontmatter 元数据和后面的 Markdown 指令正文。元数据里的description最关键它决定了 Agent 能不能在正确的时机找到这个技能。下面是一个可以直接复制的代码审查技能模板--- name: code-review description: 审查代码质量、检查常见问题。当用户要求代码审查、review、检查代码时使用。 --- # 代码审查 审查代码文件检查以下问题 - 语法错误和潜在 Bug - 代码风格和规范 - 性能问题 - 安全隐患 ## 使用方法 当用户要求审查代码时执行 bash python /skills/code-review/scripts/review.py file_path输出格式按严重程度分类严重问题必须修复警告建议改进提示可选优化注意 description 里我特意写了触发条件“当用户要求代码审查、review、检查代码时使用”。这句话不是给人看的是给 Agent 做语义匹配用的。写得越具体命中越准。 接下来是 deepagents 的编排代码。这里有一个容易踩的坑create_deep_agent 默认使用内存后端 StateBackend它读不到本地磁盘上的技能文件。你必须显式传入 FilesystemBackend并指定 root_dir。 python import os from dotenv import load_dotenv from deepagents import create_deep_agent from deepagents.backends import FilesystemBackend from langchain_core.tools import BaseTool from langchain_community.tools import WriteFileTool, ReadFileTool, ListDirectoryTool load_dotenv() os.environ[OPENAI_API_KEY] os.getenv(OPENAI_API_KEY) os.environ[OPENAI_BASE_URL] os.getenv(OPENAI_BASE_URL) model fopenai:{os.getenv(TAOTOKEN_MODEL, claude-sonnet-4-5)} class CalculateTool(BaseTool): name: str calculate description: str 计算数学表达式的值 def _run(self, expression: str) - str: try: return f计算结果: {eval(expression)} except Exception as e: return f计算错误: {str(e)} async def _arun(self, expression: str) - str: return self._run(expression) calculate CalculateTool() write_file WriteFileTool() read_file ReadFileTool() list_dir ListDirectoryTool() agent create_deep_agent( modelmodel, tools[calculate, write_file, read_file, list_dir], system_prompt你是一个助手会用工具计算、读写文件、列出目录。, skills[skills], backendFilesystemBackend(root_diros.getcwd()), debugTrue )关键参数就三个skills[skills]告诉 Agent 去哪个目录扫描技能backendFilesystemBackend(root_diros.getcwd())让它能读到磁盘文件debugTrue方便你看到技能匹配过程。如果你用的是 Cline 或者 Claude Code 这类工具配置逻辑是一样的核心三件套是 Base URL、Key、Model ID{ baseUrl: https://taotoken.net/api, apiKey: sk-你的TaoTokenKey, model: claude-sonnet-4-5 }把这段放进你的工具配置文件里技能目录指向同一个skills/文件夹即可。这样无论你用哪个客户端技能和模型通道都是统一的。4. 验证请求一次端到端跑通技能自动升级配置写完了怎么确认 Agent 真的会“自动找技能”跑一组查询就能看出来。下面这段代码会依次触发代码审查、计算、文件读写观察 Agent 是否在第一个请求里自动加载了 code-review 技能。queries [ 审查 mcp_weather.py 代码, 计算 2024*12500然后把结果保存到 result.txt, 读取 result.txt 的内容, 列出当前目录文件 ] for q in queries: print(f\n问{q}) result agent.invoke({messages: [{role: user, content: q}]}) print(f答{result[messages][-1].content})跑起来之后重点看第一个请求的输出。如果技能系统工作正常你会在 debug 日志里看到类似这样的过程Agent 先扫描skills/目录提取到code-review的 name 和 description然后把用户请求“审查 mcp_weather.py 代码”和描述做语义匹配命中后调用load_skill把完整的 Markdown 指令加载进上下文最后按指令里的步骤执行review.py。实测下来命中后的回答会明显更“专业”它会按严重程度分类输出问题而不是泛泛地说“这段代码看起来还行”。这就是技能注入的效果——Agent 不是变聪明了而是拿到了具体的操作手册。第二个请求验证的是工具调用和技能共存。计算和写文件走的是普通 tool不涉及技能加载但它们在同一个 Agent 里协同工作。第三个请求验证文件确实被写入了。第四个请求验证目录读取正常。如果你想让验证更直观可以在skills/下再加一个技能比如doc-gendescription 写“当用户要求生成文档、写 README 时使用”。然后发一句“帮我写个 README”观察 Agent 是否切换到新技能。两个技能互不干扰各自独立加载这就是模块化的价值。端到端跑通的标准是技能被正确匹配、指令被加载、工具被调用、结果符合技能里定义的输出格式。四个条件都满足说明你的技能系统已经生效。5. 常见报错排查401、local proxy failed 与技能不命中接入过程中最容易遇到几类报错我按实际踩过的坑整理一下。401 Unauthorized这个基本是 Key 的问题。先检查OPENAI_API_KEY是否真的被加载了在代码里 print 一下前几位确认。如果 Key 没错检查 Base URL 是不是写成了https://taotoken.net/api/带尾斜杠有些框架对尾斜杠敏感。另外确认 Key 没有过期或被删除去 https://taotoken.net/api-keys 重新生成一个试试。local proxy failed / connection error这类报错通常是网络层的问题。先确认你的OPENAI_BASE_URL拼写正确是https://taotoken.net/api而不是别的路径。然后在终端里用 curl 直接测一下curl https://taotoken.net/api/models \ -H Authorization: Bearer sk-你的Key如果 curl 能通但 Python 不通检查是不是有全局代理环境变量干扰比如HTTP_PROXY、HTTPS_PROXY临时 unset 掉再试。reading choices of undefined这个报错说明请求发出去了但返回结构不对。常见原因是 Model ID 写错了或者用了 TaoToken 不支持的模型名。去 https://taotoken.net/models 核对一下可用的 Model ID确保TAOTOKEN_MODEL和列表里的一致。另一个可能是init_chat_model的配置方式不对改用字符串形式fopenai:{model_id}通常能解决。技能不命中 / Agent 不加载 SKILL.md先确认skills参数指向的目录存在且里面每个技能子目录都有SKILL.md。然后检查backend是不是FilesystemBackend默认的内存后端读不到磁盘文件。如果都对了还不命中大概率是description写得太模糊。把触发条件写具体比如“当用户要求审查代码时使用”而不是“代码相关”。语义匹配靠的就是这句话。OAuth 相关报错如果你用的是 Claude Code 或类似工具报 OAuth 错误通常是因为它默认走官方登录流程。你需要在配置里显式指定 API Key 模式把 Base URL 指向https://taotoken.net/api并填入 Key。具体配置参考 https://taotoken.net/doc 里的客户端接入说明。排查的核心思路是分层先确认 Key 和 Base URL 能通再确认模型 ID 正确最后确认技能目录和后端配置。一层层排除大部分问题都能定位。6. 把技能系统用起来从单技能到技能库跑通一个技能之后真正的价值在于积累。你可以把团队里重复性最高的任务逐个拆成技能代码审查、接口文档生成、SQL 审核、日志分析、周报汇总。每个技能一个目录一个SKILL.md需要脚本就放scripts/需要参考规范就放references/。Agent 的能力边界不再取决于你写了多长的 system prompt而取决于你积累了多少技能。新任务来了写个新技能丢进去Agent 自动就能用。模型通道那边TaoToken 的统一 Key 让你不用为每个技能单独配环境换模型只改一个变量。如果你想让 Agent 长期跑编码任务或者做多步骤 Agent 编排可以考虑用 Coding Plan 把额度固定下来避免按量计费时的心跳。地址是 https://taotoken.net/coding-plan 。日常调试和验证模型响应用模型对话页面就够了https://taotoken.net/chat 。接入文档在 https://taotoken.net/doc 遇到配置问题先翻这里。最后留一个实用技巧给每个SKILL.md的description加上明确的触发词并且在技能正文里写清楚“什么时候不该用这个技能”。这能显著减少误命中。技能库越大边界越重要。