
1. 为什么你的 Agent 总是“只会聊天”从一次真实翻车说起先说一个我踩过的坑。去年我给团队做了一个内部知识助手提示词写了三千多字把公司规范、接口文档、常见问题全塞进 system prompt。刚开始效果还行直到有一次用户问“帮我按公司规范生成一份周报”模型开始胡编字段名把project_id写成projectId把日期格式从YYYY-MM-DD改成2026年3月6日。我盯着输出看了半天才反应过来不是模型笨是我把“技能”和“知识”搅成了一锅粥。这就是 Agent Skills 要解决的核心问题。Agent Skills 是一套让 AI 具备可复用技能包的工程化约定它把一个技能拆成入口文件SKILL.md加三类资源目录references/、scripts/、assets/让模型按需加载、按需执行而不是一次性把所有上下文灌进去。适合谁适合那些已经会用 Claude Code、Cline、Codex 这类工具但发现“提示词越写越长、效果越来越飘”的开发者。你可以把 Agent Skills 理解成给 AI 装“技能插件”。以前你教 AI 做事是把整本说明书念给它听现在你告诉它“说明书在书架上第几章讲什么需要的时候自己去翻”。这个差别在 token 消耗和输出稳定性上是数量级的。我实测下来一个组织良好的 Skill 能把同类任务的 token 消耗压到原来的三分之一左右而且字段格式错误率明显下降——因为格式规范写在references/里模型只在需要时读取不会被无关内容干扰。这篇会从目录结构讲到SKILL.md模板再到scripts/里脚本怎么被调用、assets/里的模板怎么被引用最后用 TaoToken 的统一 API 通道做一次完整的联调验证。全程可复制你跟着建目录、填文件、发请求就能跑通。2. TaoToken 前置准备统一 Key 与 API 通道怎么配在动手写 Skill 之前得先把“调用通道”理顺。因为 Skill 里的scripts/脚本最终要发 HTTP 请求给模型如果每个脚本各自维护一套 Key 和 Base URL后面排查问题会非常痛苦。我的做法是统一走 TaoToken 的 API 通道一个 Key 管所有模型调用。TaoToken 在这里扮演的角色是统一的模型调用入口你拿到一个 API Key配一个 Base URL就能在脚本里调用不同模型不用为每个模型单独申请和切换。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址后面不加任何 UTM 参数保持干净。具体操作分三步。第一步登录后在控制台创建 API Key路径是 console 页面建议给这个 Key 起个能识别的名字比如agent-skills-dev方便后面在脚本里区分环境。第二步把 Key 写进环境变量不要硬编码进scripts/里的代码这是很多人后面 Key 泄露的根源。第三步确认你要用的 Model ID比如做代码类 Skill 常用claude-sonnet-4-5这类标识具体以控制台模型列表为准。环境变量这样配Linux/macOS 写进~/.zshrc或~/.bashrcexport TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/apiWindows PowerShell 用$env:TAOTOKEN_API_KEYsk-你的key $env:TAOTOKEN_BASE_URLhttps://taotoken.net/api配完之后验证一下环境变量有没有生效echo $TAOTOKEN_BASE_URL # 期望输出https://taotoken.net/api这里有个细节要注意Base URL 是https://taotoken.net/api很多 OpenAI 兼容的 SDK 会自动在末尾拼/v1/chat/completions所以你在代码里不要再手动加/v1否则会变成/api/v1/v1/...这种重复路径直接 404。这个坑我在第一次接入时踩过报错信息是404 page not found排查了半小时才发现是路径重复。如果你用的是 Claude Code 这类工具配置方式略有不同通常在settings.json里指定ANTHROPIC_BASE_URL和ANTHROPIC_API_KEYBase URL 同样填https://taotoken.net/api。Cline 这类 VS Code 插件则在设置面板里填 Base URL、API Key、Model ID 三件套。Codex 的auth.json里对应的是base_url和api_key字段。不管哪种工具Base URL Key Model ID 这三件套必须齐全缺一个就会报鉴权或模型不存在的错。把通道理顺之后Skill 里的脚本就只需要读环境变量不用关心底层是哪个模型、哪个 Key。这样你换模型、换 Key 都只改一处Skill 本身不用动。3. 可复制配置SKILL.md 模板与四类资源目录结构现在进入正题。一个标准的 Skill 目录长这样你可以直接复制这个结构weather-skill/ ├── SKILL.md ├── references/ │ ├── city-codes.md │ └── api-notes.md ├── scripts/ │ └── fetch_weather.py └── assets/ └── icons/ ├── sunny.png └── rainy.pngSKILL.md是唯一必填的文件它是技能的入口。模型先读它判断“这个技能是干什么的、什么时候触发、触发后按什么步骤走”。下面是一个可以直接用的模板注意 frontmatter 里的name和description是给模型做技能路由用的写得越准触发越稳--- name: weather-skill description: 查询国内城市天气用户问天气、气温、是否下雨时使用 version: 1.0.0 --- # 天气查询技能 ## 什么时候用 用户询问某个城市的天气、温度、是否下雨、穿衣建议时触发。 ## 怎么用 1. 从用户输入中提取城市名 2. 读取 references/city-codes.md把城市名转成城市代码 3. 执行 scripts/fetch_weather.py传入城市代码 4. 把脚本返回的 JSON 结果整理成自然语言回复 ## 输入格式 用户说“北京天气怎么样”“上海明天会下雨吗” ## 输出格式 “北京今天晴25℃适合外出。” ## 注意事项 - 城市名无法识别时引导用户补充 - 脚本执行失败时返回友好提示不要暴露堆栈references/放的是“大块知识”比如城市代码对照表、API 字段说明、公司命名规范。它的价值在于渐进式加载SKILL.md里只写“去读 references/city-codes.md”模型在真正需要时才读不需要时这部分内容不占上下文。city-codes.md可以长这样# 城市代码对照表 | 城市 | 代码 | | :--- | :--- | | 北京 | 101010100 | | 上海 | 101020100 | | 广州 | 101280101 | | 深圳 | 101280601 |scripts/放真正能跑的代码。它的关键作用是把计算和外部调用从模型脑子里挪出来脚本执行不消耗模型 token跑完只把结果返回。下面这个fetch_weather.py演示了怎么读环境变量、怎么发请求注意 Base URL 和 Key 都从环境变量取import os import sys import json import urllib.request API_KEY os.environ.get(TAOTOKEN_API_KEY) BASE_URL os.environ.get(TAOTOKEN_BASE_URL, https://taotoken.net/api) def fetch_weather(city_code: str) - dict: # 这里演示调用模型做结果整理实际天气数据可换成任意数据源 payload { model: claude-sonnet-4-5, messages: [ {role: user, content: f城市代码 {city_code} 的天气用一句话描述} ] } req urllib.request.Request( f{BASE_URL}/v1/chat/completions, datajson.dumps(payload).encode(utf-8), headers{ Content-Type: application/json, Authorization: fBearer {API_KEY} }, methodPOST ) with urllib.request.urlopen(req, timeout30) as resp: return json.loads(resp.read().decode(utf-8)) if __name__ __main__: code sys.argv[1] if len(sys.argv) 1 else 101010100 result fetch_weather(code) print(json.dumps(result, ensure_asciiFalse, indent2))assets/放成品模板和素材比如周报 PPT 模板、公司 Logo、天气图标。它的加载时机是“生成产物时引用”不是“推理时读取”。比如用户说“生成一份带图标的天气卡片”模型才会去assets/icons/里取sunny.png。四类资源的加载时机可以这样对照资源加载时机是否必填典型内容SKILL.md技能路由时必读是触发条件、步骤、格式references/需要背景知识时读否文档、对照表、规范scripts/需要执行动作时跑否Python/Shell 脚本assets/需要生成产物时取否模板、图片、字体把目录建好、文件填好之后Skill 的“静态部分”就完成了。接下来要验证它能不能真的被调用起来。4. 验证请求从本地脚本到模型对话的完整联调验证分两层先验证scripts/里的脚本能独立跑通再验证模型能按SKILL.md的流程调用脚本。第一层是基础脚本跑不通后面全是空谈。先跑脚本确认 API 通道没问题cd weather-skill python scripts/fetch_weather.py 101010100如果环境变量配对了你会看到类似这样的返回{ id: chatcmpl-xxx, object: chat.completion, choices: [ { index: 0, message: { role: assistant, content: 北京今天晴气温 25℃适合外出。 } } ] }看到choices[0].message.content里有内容说明 Base URL、Key、Model ID 三件套都对了。如果这里就报错先别往下走去第 5 节对照报错排查。第二层验证把 Skill 挂到支持 Agent Skills 的工具里比如 Claude Code。在项目根目录建.claude/skills/目录把weather-skill/整个放进去然后在对话里问“北京天气怎么样”。模型应该会先读SKILL.md再读references/city-codes.md然后执行scripts/fetch_weather.py最后返回自然语言结果。如果你想在纯 API 层面验证模型是否理解了这个 Skill可以把SKILL.md的内容作为 system prompt 的一部分发过去观察模型是否按步骤走。用 curl 这样测curl -s https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: claude-sonnet-4-5, messages: [ {role: system, content: 你有一个技能 weather-skill触发条件是用户问天气。步骤1 提取城市名 2 读 references/city-codes.md 3 执行 scripts/fetch_weather.py 4 整理结果。}, {role: user, content: 北京天气怎么样} ] }观察返回内容里有没有出现“提取城市名”“城市代码”这类步骤痕迹。如果模型直接开始编天气数据说明SKILL.md的步骤描述不够明确回去把“怎么用”那节写得更具体。验证通过后你可以把 Skill 分享给团队。这里有个实用技巧把SKILL.md的description写得像搜索关键词比如“查询国内城市天气、气温、降雨、穿衣建议”这样模型在技能路由时更容易命中。我试过把 description 写成“天气相关”结果模型经常不触发改成具体场景词之后触发率明显提升。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来。你在接入过程中大概率会遇到下面几个我按出现频率排。401 Unauthorized。最常见的原因是 Key 没读到。先确认环境变量在当前 shell 里生效echo $TAOTOKEN_API_KEY如果输出为空说明~/.zshrc改了但没source或者你用的是另一个终端会话。另一个原因是 Key 前后带了空格或引号比如export TAOTOKEN_API_KEY sk-xxx 脚本读到的就是带空格的字符串。检查方法是echo $TAOTOKEN_API_KEY | cat -A看有没有多余的$或空格。local proxy failed / connection refused。这个报错通常出现在你本地配了某个代理端口但代理没启动。检查环境变量里有没有HTTP_PROXY、HTTPS_PROXY、ALL_PROXYenv | grep -i proxy如果有临时清掉再试unset HTTP_PROXY HTTPS_PROXY ALL_PROXY注意这里说的是清理本地环境变量不是让你去配什么网络工具纯粹是排除干扰项。reading choices of undefined。这个报错说明代码在解析返回时choices字段不存在。原因通常是返回体是一个错误对象比如{error: {message: ...}}但你的代码直接去读data[choices][0]。修复方法是先判断if choices not in result: print(接口返回异常, json.dumps(result, ensure_asciiFalse)) sys.exit(1)打印出完整返回体你就能看到真实错误信息通常是模型名写错或路径重复。OAuth / authentication_error。如果你用的是 Claude Code 或 Codex 这类工具报 OAuth 相关错误说明工具在走它自己的登录流程而不是用你配的 API Key。以 Claude Code 为例需要在settings.json里显式指定{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的key } }Codex 的auth.json对应字段是{ base_url: https://taotoken.net/api, api_key: sk-你的key }Cline 在 VS Code 设置里填 API Provider 为 OpenAI CompatibleBase URL 填https://taotoken.net/apiAPI Key 填你的 KeyModel ID 填控制台里看到的模型标识。三件套缺一不可只填 Key 不填 Base URL 会走默认端点直接鉴权失败。还有一个隐蔽的坑scripts/里的脚本用了相对路径读references/但执行时工作目录不对。比如脚本里写open(references/city-codes.md)而你在项目根目录执行python weather-skill/scripts/fetch_weather.py工作目录是根目录就会FileNotFoundError。修复方法是用__file__定位import os BASE_DIR os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ref_path os.path.join(BASE_DIR, references, city-codes.md)这样不管从哪个目录执行路径都对。6. 把 Skill 用起来从单技能到技能库的落地建议跑通一个 Skill 之后下一步是把它变成可维护的技能库。我的做法是在项目里建一个skills/目录每个技能一个子目录共享同一套环境变量和 API 通道。这样新增技能只需要复制目录结构、改SKILL.md和脚本不用重新配 Key。关于references/的拆分粒度有个经验单个 reference 文件控制在 200 行以内超过就再拆。因为模型读取时是按文件读的文件太大反而浪费上下文。比如城市代码表如果超过 500 个城市就按省份拆成多个文件SKILL.md里写“根据城市名首字母选择对应文件”。scripts/里的脚本建议统一加一个--dry-run参数只打印将要执行的请求而不真正发送。这样调试 Skill 流程时不会产生真实调用排查路径问题特别方便。实现很简单import argparse parser argparse.ArgumentParser() parser.add_argument(--dry-run, actionstore_true) args parser.parse_args() if args.dry_run: print(将请求, BASE_URL, payload) sys.exit(0)assets/里的模板文件建议加版本号比如weekly-report-v2.pptx避免模型引用到旧模板。SKILL.md里写清楚“使用 assets/weekly-report-v2.pptx”模型就不会拿错。最后说一个团队协作的细节SKILL.md的description字段是技能路由的唯一依据多人维护时容易写重。建议在技能库里加一个INDEX.md列出所有技能的 name 和 description新增技能前先查一遍有没有语义重叠。这个习惯能避免模型在多个相似技能之间反复横跳。如果你还没配好 API 通道先去 https://taotoken.net/api-keys 创建 Key再对照 https://taotoken.net/doc 的接入文档确认 Base URL 和模型标识。想先验证模型对话效果可以直接在 https://taotoken.net/chat 里试长期做编码类 Agent 的可以看 https://taotoken.net/coding-plan 的套餐说明。通道理顺了Skill 的工程化落地就是水到渠成的事。