Skills根本不是你想的那样!一个真实案例看懂 Skills 全流程

Skills根本不是你想的那样!

Han Lee 通过抓包和逆向工程从第一性原理深度解析 Claude Agent Skills 系统的内部架构与工作机制,还原了Skills的运行原理(原文链接见文末)

一句话:Claude Skills 并非可执行代码,而是一套基于 prompt 注入的元工具架构。

Skills根本不是你想的那样!一个真实案例看懂 Skills 全流程

原文包含了大量的图表和概念,理解起来还是会有一些些困难的,所以我另外再结合官方的仓库提供的SkillA社自家的Claude  Skills 仓库都有哪些宝贝技能?将流程进行了进一步的简化,相信会让你对于Skills 全流程有一个更清晰的了解。

在使用官方Skill处理一个 PDF 文件时,你在终端输入:

> 帮我从 report.pdf 提取文字

现在我们来看背后到底发生了什么

第一步:Claude Code 启动时做了什么

你看到的

$ claude  Claude Code v1.0.0  Ready.  >

实际发生的(抓包内容)

Claude Code 扫描了这些目录:

~/.claude/skills/# 你的个人 skills.claude/skills/# 项目 skillsplugins/*/skills/# 插件提供的 skills

找到了一个 pdf skill,文件结构:

~/.claude/skills/pdf/  ├── SKILL.md# 主文件  ├── scripts/  │ └── extract.py# Python 脚本  └── references/  └── api-docs.md # API 文档

读取 SKILL.md 的头部:

---name: pdfdescription: 从 PDF 提取文字和表格。当用户提到 PDF、文档提取时使用allowed-tools: Bash(python:*), Read, Write---

注意这里只读这几行! 完整的 SKILL.md 有 800 行,但现在不读

第二步:你的请求发送到 Claude

实际的 HTTP 请求简化后的版本如下:

POST https://api.anthropic.com/v1/messages{  "model": "claude-sonnet-4-5",  "messages": [{"role": "user","content": "帮我从 report.pdf 提取文字"}  ],  "tools": [{"name": "Skill","description": "执行一个 skillnn可用的 skills:n"pdf": 从 PDF 提取文字和表格。当用户提到 PDF、文档提取时使用n"excel": 创建和编辑 Excel 文件n"ppt": 创建演示文稿","input_schema": {"type": "object","properties": {"command": {"type": "string"}}}},{"name": "Bash","description": "执行 bash 命令","input_schema": {...}},{"name": "Read","description": "读取文件","input_schema": {...}}  ]}

关键点

  1. pdf skill 的 800 行内容没有发送
  2. 只发送了描述:"从 PDF 提取文字和表格。当用户提到 PDF、文档提取时使用"
  3. 这只有 20 个 token

第三步:Claude 决定调用 pdf skill

Claude 的响应(抓包内容)

{  "content": [{"type": "text","text": "我会帮你从 PDF 中提取文字。"},{"type": "tool_use","id": "toolu_abc123","name": "Skill","input": {"command": "pdf"}}  ]}

Claude 的思考过程,我们看不到,大概它这么想的:

用户说 "从 report.pdf 提取文字"  → 关键词: PDF, 提取, 文字  → 看看我有什么工具...  → "Skill" 工具里有 "pdf": 从 PDF 提取文字和表格  → 完美匹配!  → 调用 Skill 工具,command="pdf"

第四步:执行 Skill 工具(这里是重点了!)

Claude Code 收到 Claude 要调用 Skill("pdf")

现在才读取完整的 SKILL.md(800 行):

---  name: pdf  description: 从 PDF 提取文字和表格allowed-tools: Bash(python:*), Read, Write  ---    # PDF 处理专家    你是一个 PDF 处理专家。    ## 工作流程    ### 步骤 1: 检查文件  使用 Read 工具检查 PDF 文件是否存在    ### 步骤 2: 提取文字  运行脚本:    python {baseDir}/scripts/extract.py report.pdf    ### 步骤 3: 读取结果  Read 工具读取 output.txt    ### 步骤 4: 展示给用户    ## 可用工具  - Bash(python:*) - 运行 Python 脚本  - Read - 读取文件  - Write - 保存结果    基础目录: {baseDir}

准备发送给 Claude 的两条消息:

消息 1 (用户可见):

<command-message>正在加载 "pdf" skill</command-message><command-name>pdf</command-name>

消息 2 (用户看不见,但发给 API):

你是一个 PDF 处理专家。## 工作流程### 步骤 1: 检查文件使用 Read 工具检查 PDF 文件是否存在  ...  (完整 800 行)

第五步:发送增强后的请求给 Claude

你在界面上看到

> 帮我从 report.pdf 提取文字    正在加载 "pdf" skill

实际发送的完整 HTTP 请求

POST https://api.anthropic.com/v1/messages{  "model": "claude-sonnet-4-5",  "messages": [{"role": "user","content": "帮我从 report.pdf 提取文字"},{"role": "assistant","content": [{"type": "text", "text": "我会帮你从 PDF 中提取文字。"},{"type": "tool_use", "name": "Skill", "input": {"command": "pdf"}}]},{"role": "user","content": "<command-message>正在加载 "pdf" skill</command-message>"// 这条你能看到 ↑},{"role": "user","content": "你是一个 PDF 处理专家。nn## 工作流程nn### 步骤 1: 检查文件...","isMeta": true// ↑ 这条你看不到,但发给了 Claude!// 完整 800 行都在这里!},{"role": "user","content": {"type": "command_permissions","allowedTools": ["Bash(python:*)", "Read", "Write"]}// ↑ 这个告诉系统:这些工具预先批准了}  ]}

Token 对比:

  • 第一次请求: ~50 tokens (只有描述)
  • 第二次请求: ~2,000 tokens (完整 skill 内容)

第六步:Claude 按照 skill 指令执行

现在 Claude 的"记忆"里有:
1.用户原始请求:"帮我从 report.pdf 提取文字"
2. 新注入的指令:"你是一个 PDF 处理专家。按照以下步骤。。。"
3. 预批准的工具  Bash(python:*)ReadWrite

Claude 开始工作

第 1 个工具调用 – 检查文件:

{  "type": "tool_use",  "name": "Read",  "input": {"path": "report.pdf","description": "检查 PDF 文件是否存在"  }}

系统返回:

{  "type": "tool_result",  "content": "文件存在,大小 1.2MB"}

第 2 个工具调用 – 运行 Python 脚本:

{  "type": "tool_use",  "name": "Bash",  "input": {"command": "python ~/.claude/skills/pdf/scripts/extract.py report.pdf","description": "提取 PDF 文字"  }}

这个调用不需要用户确认
为什么? 因为 Bash(python:*)allowed-tools 里被预批准了!

系统执行脚本,返回:

{  "type": "tool_result",  "content": "提取完成,输出保存到 output.txt"}

第 3 个工具调用 – 读取结果:

{  "type": "tool_use",  "name": "Read",  "input": {"path": "output.txt"  }}

返回:

{  "type": "tool_result",  "content": "这是一份关于 2024 年度财务报告...nn总收入: 1000 万美元n..."}

第七步:Claude 返回结果给你

你看到的

> 帮我从 report.pdf 提取文字    正在加载 "pdf" skill    ✓ 已从 report.pdf 提取文字    内容如下:    这是一份关于 2024 年度财务报告    总收入: 1000 万美元  总支出: 800 万美元  净利润: 200 万美元  ...

为什么Skill高效又节省呢?

没有 Skill 的情况

你需要这样说

> 用 pdftotext 命令从 report.pdf 提取文字,  > 然后读取输出文件,  > 如果遇到错误要处理,  > 最后格式化显示给我

每次都要重复这些指令!

API 请求(每次都发):

{  "messages": [{"role": "user","content": "用 pdftotext 命令从 report.pdf 提取文字,然后读取输出文件,如果遇到错误要处理,最后格式化显示给我"}  ]}

Token: ~80 tokens × 每次使用

有 Skill 的情况

你只需要说

> 帮我从 report.pdf 提取文字

第一次 API 请求(只发描述):

{  "tools": [{"name": "Skill","description": "..."pdf": 从 PDF 提取文字和表格..."  }]}

Token: ~20 tokens

第二次 API 请求(发完整指令):

{  "messages": [...,{"content": "你是 PDF 专家...(完整 800 行)", "isMeta": true}  ]}

Token: ~2,000 tokens × 只在激活时发一次

算下来你要处理 10 个 PDF

没有 Skill

10 次 × 80 tokens = 800 tokens

有 Skill

启动时: 20 tokens (描述)  第 1 次激活: 2,000 tokens (完整指令)  后续 9 次: 0 tokens (已在上下文中)  总计: 2,020 tokens

但实际上,Skill 会在对话过程中被压缩,所以后续调用可能会重新加载。

Skills根本不是你想的那样!一个真实案例看懂 Skills 全流程

如果你真的抓包 Claude Code,你会看到:

请求头

POST /v1/messages HTTP/1.1  Host: api.anthropic.com  anthropic-version: 2023-06-01  content-type: application/json  x-api-key: sk-ant-...

请求体(关键部分):

{  "model": "claude-sonnet-4-5-20250929",  "max_tokens": 4096,  "tools": [{"name": "Skill","description": "Execute a skill within the main conversationnn<skills_instructions>nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively...nn<available_skills>n"pdf": 从 PDF 提取文字和表格。当用户提到 PDF、文档提取时使用n"xlsx": 创建和编辑 Excel 文件n</available_skills>","input_schema": {"type": "object","properties": {"command": {"type": "string","description": "The skill name (no arguments). E.g., "pdf" or "xlsx""}},"required": ["command"]}}  ],  "messages": [...]}

看到了吗?pdf skill 的 800 行内容不在这里只有一行描述

所以Skills 到底是怎么工作的?

就这几步:

  1. 启动时: 扫描所有 skills,只读前几行(name + description)
  2. 发请求时: 把所有 skills 的简短描述塞进 "Skill" 工具里
  3. Claude 匹配: 用 AI 理解能力匹配用户意图和 skill 描述
  4. 激活 skill: 读取完整的 SKILL.md,注入到对话中
  5. 执行: Claude 按照注入的指令工作,工具预批准,不用确认

Skills根本不是你想的那样!一个真实案例看懂 Skills 全流程

这种架构的设计核心优势

不用的 skill 不加载完整内容,可以有 100 个 skills,只占 2000 tokens,所有 skills 格式一样,容易分享安全, 工具权限仅在 skill 执行时有效。

前沿技术新闻资讯模型微调

从workflow到ReAct提升AI Agent智能化水平

2026-5-2 17:19:54

企业落地新闻资讯智能化改造

大模型还干不掉BI

2026-5-2 17:27:38

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
购物车
优惠劵
搜索