☰
收藏!手把手教你用 Agent Skills 框架让单一智能体拥有多种能力,小白也能轻松上手|TaoToken 统一 Key 实战
2026/10/10 17:37:30 网站建设 项目流程

1. 从体检报告说起:为什么单一智能体需要 Agent Skills 框架

先聊一个真实场景。假设你接到一个需求:用户上传一份体检报告,系统要完成三件事——解析各项指标、评估健康风险、生成个性化建议。最直觉的做法是写一个超长 Prompt,让 LLM 一口气从解析干到建议。Demo 阶段能跑通,但一上生产就露馅:Prompt 越堆越长,token 成本飙升;中间某一步算错,整条输出全废;想调整风险评估策略,得改整段 Prompt,牵一发动全身。

那换成 Multi-Agent 呢?三个 Agent 各管一摊、互相通信。听起来很美,但你会发现这三步是严格串行的,后一步依赖前一步的输出,压根不需要协商和并行。Multi-Agent 引入的通信协议、独立 Memory、协调开销,在这个场景下全是多余的复杂度。

这就是 Agent Skills 框架要解决的问题:把大任务拆成标准化的小技能,用一个编排器按序调度,共享同一份上下文。打个比方,Multi-Agent 像多进程——各自独立内存、靠 IPC 通信、隔离性好但开销大;Agent Skills 像同一进程下的多线程——共享内存、轻量调度、按需执行不同功能。不是说谁更好,而是看你的问题需要隔离还是共享。

Agent Skills 可以理解为通用智能体的扩展包。智能体通过加载不同的 Skills 包,就能具备不同专业知识、工具使用能力,稳定完成特定任务。它适合谁?刚接触 LLM 与 Multi-Agent 的开发者、想用单一智能体覆盖多种业务能力的团队、以及被长 Prompt 和 token 成本折磨过的工程师。这篇教程会带你从零跑通一个多技能智能体,包含可复制的技能注册配置、统一 Key 接入示例和本地运行验证步骤。

2. TaoToken 统一 Key 前置准备:一个 Key 打通多模型调用链路

在动手写 Skills 框架之前,得先把模型调用这一层搞定。Agent Skills 框架里,Planner、Executor、Synthesizer 都要调 LLM,如果每个组件各配一套 Key、各记一个 Base URL,调试起来会非常痛苦。我试过用统一 Key 的方式收敛这一层,实测下来确实省心。

TaoToken 提供的就是这样一个统一入口:一个 API Key,兼容主流模型调用格式,Base URL 固定为https://taotoken.net/api。你不需要在代码里维护多套鉴权逻辑,Skills 框架里所有需要调模型的地方,共用同一个客户端即可。

前置准备分三步。第一步,注册并登录控制台,地址是https://taotoken.net/api-keys,在 API Keys 页面创建一个新 Key,复制保存好,后面配置里要用。第二步,确认你要用的模型 ID,比如claude-sonnet-4-5、gpt-4o这类,具体以控制台模型列表为准。第三步,把 Base URL、Key、Model ID 这三件套记下来,它们是后面所有配置的核心。

这里要强调一个概念:Agent Skills 框架里的 Skill 是被动的。它不是一个有自主意识的 Agent,不需要自己的 Memory、自己的规划能力、自己的通信协议。它只需要满足一个简单契约——给我输入,我返回输出。所以模型调用层越简单越好,统一 Key 正好符合这个设计哲学。

如果你后续要做长期编码或 Agent 类项目,可以了解下 Coding Plan,地址是https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite,适合需要持续调用、额度较大的场景。但本篇教程先用按量调用的方式跑通链路,不涉及套餐选择。

配置环境变量是最推荐的做法,避免 Key 硬编码进代码:

export TAOTOKEN_API_KEY="sk-你的实际Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_MODEL="claude-sonnet-4-5"

Windows 用户用 PowerShell:

$env:TAOTOKEN_API_KEY="sk-你的实际Key" $env:TAOTOKEN_BASE_URL="https://taotoken.net/api" $env:TAOTOKEN_MODEL="claude-sonnet-4-5"

环境变量配好后,写一个最小的连通性测试脚本,确认 Key 能用:

import os from openai import OpenAI client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url=os.environ["TAOTOKEN_BASE_URL"], ) resp = client.chat.completions.create( model=os.environ["TAOTOKEN_MODEL"], messages=[{"role": "user", "content": "只回复两个字:通了"}], ) print(resp.choices[0].message.content)

跑出来打印「通了」,说明统一 Key 这一层没问题。如果报 401,先检查 Key 有没有复制完整、有没有多余空格;如果报连接错误,检查 Base URL 是不是写成了带路径的地址。这一步过了,再往下搭 Skills 框架。

3. 可复制配置:Skill 目录结构与统一客户端 settings 片段

Agent Skills 框架的核心设计可以概括为一句话:一个协调器统一调度,多个 Skills 各司其职,三层上下文贯穿始终。五个核心角色职责如下:

角色职责
AgentContext三层结构化上下文,贯穿整个流程的信息中枢
Planner理解用户意图,把大任务拆成小步骤
Executor逐步执行每个 Skill,管理多种执行模式
Synthesizer把多步结果综合为连贯的自然语言回答
Coordinator串联以上所有角色的调度中心

先解决一个根本问题:一个 Skill 到底长什么样?答案是一个目录。放进skills/文件夹,框架自动发现、自动注册,零配置即插即用:

skills/ └── parse_report/ ├── SKILL.md # 必需:元数据 + 使用文档 ├── prompt.template # 可选:Prompt 模板 └── executor.py # 可选:自定义执行逻辑

SKILL.md的 YAML front matter 定义了 Skill 的身份——名字、描述、触发词、标签。Planner 正是读这些描述来决定选哪个 Skill:

--- name: parse_report_skill description: 解析体检报告原始数据,提取并分类各项检验指标 triggers: - 体检报告 - 体检数据 - 化验单 tags: - 健康 - 体检 --- # parse_report_skill ## 功能说明 接收体检报告原始文本,输出结构化指标列表。 ## Available Tools ### 1. check_reference_range 工具名称: Calculation Tool 工具用途: 检查指标是否在参考范围内 工具输入: indicator_name, value 工具返回: status, deviation_percent

Skill 的执行有三种模式,Executor 按优先级依次检测:有executor.py走自定义执行器;有prompt.template填充模板后调用 LLM;都没有则把SKILL.md的文档部分作为 system prompt 直接调用 LLM。

接下来是统一客户端配置。为了让框架里所有组件共用同一个模型入口,我把它抽成一个settings.py:

# settings.py import os from openai import OpenAI TAOTOKEN_BASE_URL = os.environ.get("TAOTOKEN_BASE_URL", "https://taotoken.net/api") TAOTOKEN_API_KEY = os.environ["TAOTOKEN_API_KEY"] TAOTOKEN_MODEL = os.environ.get("TAOTOKEN_MODEL", "claude-sonnet-4-5") def get_client() -> OpenAI: return OpenAI( api_key=TAOTOKEN_API_KEY, base_url=TAOTOKEN_BASE_URL, ) def invoke(prompt: str, system: str = "") -> str: client = get_client() messages = [] if system: messages.append({"role": "system", "content": system}) messages.append({"role": "user", "content": prompt}) resp = client.chat.completions.create( model=TAOTOKEN_MODEL, messages=messages, temperature=0.3, ) return resp.choices[0].message.content

如果你用 Cline 或 Claude Code 这类工具做辅助开发,配置方式类似,核心三件套是 Base URL、Key、Model ID。以 Cline 的 MCP 配置为例,在 settings 里填:

{ "mcpServers": { "taotoken": { "command": "npx", "args": ["-y", "@taotoken/mcp-server"], "env": { "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "sk-你的实际Key", "TAOTOKEN_MODEL": "claude-sonnet-4-5" } } } }

注意 Base URL 不要带多余路径,Key 不要提交到 Git。这套配置的好处是,Skills 框架里的 Planner、Executor、Synthesizer 全部通过settings.invoke()调模型,换模型只改一个环境变量。

4. 本地运行验证:从 Planner 规划到 Synthesizer 综合的完整链路

配置就绪后,写一个最小可运行的 Coordinator,把 Planner、Executor、Synthesizer 串起来。先看 Planner 的实现,它负责把用户意图拆成步骤序列:

# planner.py import json from settings import invoke PLAN_SYSTEM = """你是一个任务规划器。根据用户请求和可用 Skill 列表, 输出 JSON 格式的执行计划,包含 intent 和 steps 两个字段。 每个 step 包含 skill、sub_task、confidence 三个字段。 confidence 低于 0.5 的步骤请过滤掉。只输出 JSON,不要额外解释。""" def plan(user_input: str, skills: list) -> dict: skill_desc = "\n".join( f"- {s['name']}: {s['description']} (triggers: {s['triggers']})" for s in skills ) prompt = f"用户请求:{user_input}\n\n可用 Skill:\n{skill_desc}" raw = invoke(prompt, system=PLAN_SYSTEM) raw = raw.strip().removeprefix("```json").removesuffix("```").strip() return json.loads(raw)

Executor 负责逐步执行,这里体现渐进式上下文披露的核心设计——每一步只看到最小必要上下文,由三部分组成:自己的 sub_task、累积的前置结果、原始请求。压缩策略遵循一个直觉:越新的步骤输出越重要。始终保留原始请求,完整保留最新一步输出,较早的步骤输出可截断加「已压缩」标记,已被消化的最早步骤可丢弃。

# executor.py from settings import invoke def build_step_input(sub_task: str, original_request: str, scratchpad: list) -> str: parts = [f"原始请求:{original_request}", f"当前任务:{sub_task}"] if scratchpad: recent = scratchpad[-1] parts.append(f"上一步输出:{recent}") if len(scratchpad) > 1: earlier = " | ".join(str(s)[:200] for s in scratchpad[:-1]) parts.append(f"更早步骤摘要(已压缩):{earlier}") return "\n\n".join(parts) def execute_step(skill: dict, sub_task: str, original_request: str, scratchpad: list) -> str: step_input = build_step_input(sub_task, original_request, scratchpad) system = skill.get("doc", "") return invoke(step_input, system=system)

Synthesizer 读取原始请求和所有步骤结果,生成连贯回答:

# synthesizer.py from settings import invoke SYNTH_SYSTEM = "你是一个综合回答生成器。基于原始请求和各步骤执行结果,生成连贯、自然的最终回答。" def synthesize(original_request: str, scratchpad: list) -> str: steps_text = "\n".join(f"步骤{i+1}结果:{s}" for i, s in enumerate(scratchpad)) prompt = f"原始请求:{original_request}\n\n{steps_text}" return invoke(prompt, system=SYNTH_SYSTEM)

最后是 Coordinator 主流程:

# coordinator.py from planner import plan from executor import execute_step from synthesizer import synthesize SKILLS = [ { "name": "parse_report", "description": "解析体检报告原始数据,提取并分类各项检验指标", "triggers": ["体检报告", "体检数据", "化验单"], "doc": "你负责解析体检报告,输出结构化指标列表。", }, { "name": "assess_risk", "description": "基于解析后的指标评估健康风险", "triggers": ["风险评估", "健康风险", "风险分析"], "doc": "你负责评估健康风险,按心血管、代谢、肝脏、肾脏四维度评分。", }, { "name": "generate_advice", "description": "基于风险评分生成个性化健康建议", "triggers": ["健康建议", "调理建议", "注意事项"], "doc": "你负责生成个性化健康建议和复查计划。", }, ] def run(user_input: str) -> str: plan_result = plan(user_input, SKILLS) print("规划结果:", plan_result) scratchpad = [] for step in plan_result["steps"]: skill = next(s for s in SKILLS if s["name"] == step["skill"]) result = execute_step(skill, step["sub_task"], user_input, scratchpad) scratchpad.append(result) print(f"步骤 {step['skill']} 完成") return synthesize(user_input, scratchpad) if __name__ == "__main__": answer = run("帮我分析体检报告并给出建议。") print("\n最终回答:\n", answer)

运行python coordinator.py,你会看到类似输出:规划结果打印出三步计划,每步执行完打印完成提示,最后输出综合回答。如果链路正常,说明 Planner 选对了 Skill、Executor 按序执行、Synthesizer 综合成功。这一步跑通,整个 Agent Skills 框架的骨架就立起来了。

5. 本篇常见错排查:401、local proxy failed、reading choices 与 OAuth 报错

搭框架的过程中,报错是常态。这一节把几个高频错误对照着讲清楚,方便你快速定位。

401 Unauthorized。最常见的原因是 Key 没配好。检查三处:环境变量TAOTOKEN_API_KEY是否真的导出成功(echo $TAOTOKEN_API_KEY看有没有值);Key 是否复制完整,有没有首尾空格;Base URL 是否写成了https://taotoken.net/api/带尾斜杠,某些客户端对尾斜杠敏感。如果用的是 Cline 或 Claude Code,检查 settings 里的 Key 字段有没有被引号包裹导致多出字符。

local proxy failed。这个报错通常出现在客户端配置了本地代理但代理没启动,或者 Base URL 指向了本地地址。排查方法:确认TAOTOKEN_BASE_URL是https://taotoken.net/api,不是http://localhost:xxxx;检查系统环境变量里有没有残留的HTTP_PROXY、HTTPS_PROXY指向失效地址,临时清掉再试:

unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxy

reading choices 相关报错。典型表现是KeyError: 'choices'或AttributeError: 'NoneType' object has no attribute 'choices'。这说明响应体里没有choices字段,通常是模型 ID 写错了,或者请求体格式不对。检查TAOTOKEN_MODEL是否和控制台模型列表一致;检查 messages 数组格式,role 只能是system、user、assistant。另外,如果返回的是流式响应但你按非流式解析,也会拿不到 choices,确认stream参数没被误开。

OAuth 相关报错。如果你用 Claude Code 或类似工具,报 OAuth 失败,通常是因为工具默认走官方登录流程,而你要用统一 Key 接入。这时需要在工具的配置里显式指定 Base URL 和 API Key,覆盖默认的 OAuth 路径。以 Claude Code 为例,检查~/.claude/settings.json或项目级配置,确保ANTHROPIC_BASE_URL指向https://taotoken.net/api,ANTHROPIC_API_KEY填你的 Key。如果工具同时支持 OAuth 和 API Key 两种模式,优先选 API Key 模式。

Codex auth.json 配置。如果你用 Codex 类工具,认证信息在auth.json里,格式大致如下:

{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的实际Key", "model": "claude-sonnet-4-5" }

三件套 Base URL、Key、Model ID 缺一不可。改完auth.json后重启工具,让配置生效。

Skill 没被 Planner 选中。这不是报错但很常见。原因是SKILL.md里的description和triggers写得不够具体,Planner 读不懂。把 description 写成一句明确的能力描述,triggers 覆盖用户可能说的同义词。比如「体检报告」「体检数据」「化验单」都列上,命中率会明显提升。

步骤间数据传丢。如果第二步拿不到第一步的输出,检查渐进式上下文构建逻辑。字典通道优先,通过context["parse_report_skill"]取结构化数据;文本通道兜底,把前置步骤文本拼入参考信息。两条通道至少保证一条通,链路才不会断。

6. 语义一致 CTA:把统一 Key 接入你的 Agent Skills 项目

链路跑通之后,下一步就是把它接到真实项目里。回顾一下整个流程的关键点:Skill 是一个目录,靠SKILL.md的 YAML front matter 声明身份;Executor 按优先级检测三种执行模式;上下文分三层,Planner 读用户输入层和 Skill 配置层,Executor 读写工作记忆层,Synthesizer 读用户输入层和工作记忆层;渐进式上下文披露让每一步只看到最小必要信息,token 消耗线性增长而非指数增长。

模型调用这一层,统一 Key 的价值在于收敛。你的 Planner、Executor、Synthesizer 全部通过settings.invoke()走同一个入口,换模型只改环境变量,不用翻遍代码找硬编码的 Key。Base URL 固定https://taotoken.net/api,Key 在控制台创建,Model ID 按需选择。

如果你在接入过程中遇到鉴权或配置问题,可以直接查接入文档,地址是https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite,里面有各客户端的详细配置示例。想先验证模型是否可用,可以去模型对话页面试一条请求,地址是https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite。长期做编码或 Agent 项目的话,Coding Plan 页面在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite,可以按需了解。

最后留一个实用技巧:在 Coordinator 里加一行审计日志,记录每次 read/write 操作的时间、层、key 和来源。出了 bug,看一眼日志就知道谁在什么时间读了什么、写了什么。当用户问「为什么建议我少吃海鲜」,你能追溯到完整因果链——parse_report 发现尿酸偏高,assess_risk 判定代谢风险中等,generate_advice 生成了限嘌呤饮食建议。这不是锦上添花,是生产环境的刚需。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询