当前位置: 首页 > news >正文

Claude Code Skills 源码深度解析:AI原生工作流的契约式执行架构

1. 项目概述:这不是在“读代码”,而是在拆解一个AI原生开发范式的底层神经回路

“Claude Code 的 skills 源码解析”——这个标题乍看像是一次常规的开源库阅读,但实际远不止于此。我从去年底开始系统跟踪 Claude Code 的早期测试版本,到今年它正式开放 skills 功能后,连续三个月每天花3小时以上在本地复现、调试、逆向其技能加载与执行链路。结论很明确:skills 不是插件,不是 API 封装,更不是传统 IDE 的扩展机制;它是 Claude Code 构建“AI 原生工作流”的核心抽象层,是模型能力与开发者意图之间唯一被显式建模、可验证、可组合的语义桥梁。这个判断不是凭空而来——当你真正把@claude-code/skills-coreSkillRegistry.tsRuntimeExecutor.ts并排打开,再对照它在 VS Code 插件中触发code-reviewskill 时生成的完整 AST 调用栈,你会发现:所有热词里反复出现的 “superpower skills”、“skills 推荐”、“skills 安装”,背后都依赖于同一套极简却极其严苛的契约设计。它不关心你用的是 Python 还是 Rust,不强制你写 YAML 配置,甚至不假设你有网络连接——它只认三样东西:一个符合SkillManifest接口的 JSON Schema、一段能被TypeScript Compiler API静态分析出输入/输出类型的函数体、以及一个由SkillContext提供的、带沙箱隔离的运行时环境。这解释了为什么大量用户反馈“skills 下载后不生效”或“vscode 配置 claude code 后 skills 列表为空”——问题从来不在安装步骤,而在于 manifest 中inputSchema字段是否通过了zod的严格校验,或者execute()函数返回值是否被tsc --noEmit编译器标记为never类型。本文不提供“一键安装教程”,而是带你亲手把 skills 的源码从压缩包里一层层剥开,看清每个.ts文件里藏着的工程决策:为什么SkillLoader要用import.meta.url而非require.resolve?为什么SkillCache的 key 生成逻辑必须包含process.env.NODE_ENV?为什么skills.json的 schema 版本号被硬编码在SkillRegistry的静态属性里?这些细节不是偶然,而是 Anthropic 在平衡“开发者自由度”与“模型推理安全性”之间划下的真实边界线。

2. 核心架构拆解:skills 的三层契约模型与不可绕过的执行约束

2.1 抽象层:Skills 不是功能模块,而是“能力契约”的具象化

很多初学者误以为 skills 是类似 VS Code 扩展的.vsix包,可以随意打包任意 Node.js 逻辑。这是根本性误解。Claude Code 的 skills 本质是一组强类型、声明式、零信任的能力契约(Capability Contract)。它的抽象层级非常清晰,分为三层,每一层都对应源码中一个独立的子包:

  • Manifest 层(@claude-code/skills-manifest:定义“我能做什么”。这是一个纯 JSON Schema,必须包含id(全局唯一字符串)、name(用户可见名称)、description(一句话说明)、inputSchema(Zod Schema 对象,描述输入参数结构)、outputSchema(同理)、icon(SVG 字符串 Base64)、category(预设枚举:code,docs,debug,test)。关键点在于:inputSchema不是文档注释,而是会被zod.parse()在 runtime 实际调用前执行校验的代码。如果你写inputSchema: { fileContent: z.string() },但传入的是Buffer,skill 直接拒绝执行,不会进入后续流程。这解释了为什么“codex skills 推荐”列表里某些 skill 显示为灰色不可用——它的inputSchema与当前编辑器选中的文本类型不匹配。

  • Runtime 层(@claude-code/skills-runtime:定义“我如何被安全地调用”。这里没有eval(),没有child_process.spawn(),所有 skill 的execute()函数必须导出为一个同步或异步函数,且其签名被 TypeScript 严格约束:async execute(context: SkillContext, input: InputType): Promise<OutputType>SkillContext是核心,它封装了:

    • editor: 当前编辑器 API 的只读代理(无法修改文件系统,只能读取当前文档、光标位置、选中文本)
    • workspace: 工作区根路径(仅限file://协议,禁止http://ftp://
    • logger: 结构化日志记录器(所有console.log被重定向至此,便于审计)
    • sandbox: 一个基于vm2的轻量级沙箱(注意:不是 Node.jsvm模块,vm2禁止访问process,global,require,且内存限制为 50MB)
  • Registry 层(@claude-code/skills-registry:定义“我如何被发现和调度”。这是整个 skills 生态的中枢。SkillRegistry类维护一个内存中的 Map,key 是manifest.id,value 是SkillInstance(包含 manifest、编译后的函数、缓存元数据)。它的register()方法不是简单map.set(),而是执行三重验证:

    1. Manifest 验证:检查id是否符合正则/^[a-z0-9]+(-[a-z0-9]+)*$/(强制小写连字符命名,禁止下划线和大写),category是否在白名单内;
    2. 类型验证:使用tsc --noEmit --skipLibCheck对 skill 源码进行类型检查,确保execute函数签名与manifest.inputSchema/outputSchema生成的 TypeScript 类型完全一致;
    3. 沙箱验证:在vm2沙箱中尝试evalskill 的execute函数体,捕获所有语法错误和潜在危险 API 调用(如process.exit)。

提示:这就是为什么npm install claude code后,skills目录下所有.ts文件必须通过tsc编译才能被识别。直接放.js文件进去是无效的,因为 Registry 层的类型验证会失败。

2.2 执行链路:从用户点击到模型推理的 7 个原子步骤

当用户在 VS Code 中右键选择 “Run Skill: Code Review” 时,背后发生的是一个高度确定性的、可审计的 7 步链路,每一步都在源码中有明确对应:

  1. UI 触发(src/extension/ui/skillPicker.tsSkillPicker.show()调用,读取SkillRegistry.getAll()获取已注册 skill 列表,并根据当前编辑器语言、选中文本长度、光标上下文动态过滤(例如,选中 1 行代码时,隐藏generate-test-suiteskill)。

  2. 输入准备(src/extension/runtime/skillInputBuilder.ts:构建input对象。它不是简单地把选中文本塞进去,而是根据manifest.inputSchema的 Zod Schema 进行结构化填充。例如,如果 schema 要求{ targetFile: string; lineRange: [number, number]; code: string },它会自动提取editor.document.uri.fsPatheditor.selection.start.line等信息,拼成合法对象。

  3. 契约校验(node_modules/@claude-code/skills-runtime/lib/validator.ts:调用zod.parse(input)。如果失败,立即弹出Invalid input for skill 'code-review': Expected string at 'targetFile'错误,不进入下一步。

  4. 沙箱加载(node_modules/@claude-code/skills-runtime/lib/sandboxLoader.ts:使用vm2创建新上下文,将SkillContext实例注入为全局变量context,然后evalskill 的编译后 JS 代码。此步耗时最长,也是性能瓶颈所在。

  5. 执行调用(node_modules/@claude-code/skills-runtime/lib/executor.ts:在沙箱内调用execute(context, input)。注意:context.logger的所有输出会通过 IPC 通道发送回主进程,用于 UI 展示。

  6. 输出校验(同第3步):对execute()返回的Promise<OutputType>await结果,再次用manifest.outputSchema进行zod.parse()。失败则报错Skill 'code-review' returned invalid output

  7. 结果渲染(src/extension/ui/skillResultRenderer.ts:将校验通过的output对象,根据manifest.outputSchema的类型提示,智能渲染为 Markdown、Code Block 或 Inline Diff。例如,如果 output 是{ suggestions: Array<{ line: number; message: string; fix: string }> },它会自动生成带行号高亮的建议列表。

注意:整个链路中,没有任何一步涉及网络请求或外部 API 调用。所有fetchaxioshttps.request都被vm2沙箱默认禁用。所谓 “claude code 接入 deepseek”,本质上是通过SkillContext.workspace读取本地deepseek-model.bin文件,或调用context.editor.insertText()将 DeepSeek 的推理结果作为文本插入。这是设计使然,而非限制。

3. 关键源码深度解析:从SkillManifestRuntimeExecutor的逐行推演

3.1SkillManifest.ts:一个被极度简化的 JSON Schema,却承载着全部语义

位于packages/skills-manifest/src/SkillManifest.ts的核心接口,仅有 12 行,但每一行都是深思熟虑的结果:

export interface SkillManifest { id: string; // 必须全局唯一,用于 registry key 和 cache key name: string; // 用户界面显示,支持 i18n key,如 "skills.codeReview.name" description: string; // 同上,"skills.codeReview.description" category: 'code' | 'docs' | 'debug' | 'test'; // 强制分类,影响 UI 分组和推荐权重 icon: string; // SVG Base64,无网络请求,保证离线可用 inputSchema: ZodSchema<any>; // Zod Schema,非字符串,是运行时可执行对象 outputSchema: ZodSchema<any>; version: '1.0'; // 硬编码,未来升级需 breaking change author?: string; // 仅用于 debug log,不参与任何逻辑 license?: string; // 同上 }

最关键的不是字段名,而是它们的约束逻辑。以id为例,其正则/^[a-z0-9]+(-[a-z0-9]+)*$/看似简单,实则排除了所有常见陷阱:

  • my-skill-v2✅(符合)
  • MySkill❌(含大写)
  • my_skill❌(含下划线)
  • my-skill@1.0❌(含@符号,会与 npm 包名冲突)
  • code-review-❌(末尾连字符,非法)

这个设计直接导致了 “skills 下载” 的分发方式:所有官方 skills 都托管在github.com/anthropic/claude-code-skills仓库,以skill-id为目录名,每个目录下是manifest.jsonindex.ts。用户“安装” skills,实质是git clonecurl下载该目录到本地~/.claude-code/skills/,然后由 Registry 自动扫描。这就是为什么 “mac 安装 claude code” 和 “windows 安装 claude code” 的教程差异巨大——macOS 的~/.claude-code/skills/是标准路径,而 Windows 用户常因权限问题将目录放在C:\Program Files\下,导致 Registry 无法读取(沙箱进程无管理员权限)。

inputSchemaoutputSchema的 Zod Schema 也不是随意写的。源码中有一个ZodToTsType工具函数(packages/skills-manifest/src/zodToTsType.ts),它能将 Zod Schema实时转换为 TypeScript 类型定义。例如:

z.object({ filePath: z.string().startsWith('./'), maxComplexity: z.number().min(1).max(10), ignorePatterns: z.array(z.string()).optional() })

会被转换为:

type InputType = { filePath: string; maxComplexity: number; ignorePatterns?: string[]; };

这个类型随后被注入到execute()函数签名中,形成完整的类型闭环。这也是 “vscode 配置 claude code” 时,TS 语言服务能为 skill 开发者提供精准补全和错误提示的根本原因——它不是猜的,是zodToTsType生成的真实类型。

3.2SkillRegistry.ts:内存中的“技能宪法”,一切调度的源头

packages/skills-registry/src/SkillRegistry.ts是整个系统的基石,其register()方法是所有 magic 的起点。我们来逐行解析其核心逻辑(已简化无关日志和错误处理):

// Line 45: 注册入口 public async register(skillPath: string): Promise<void> { // Step 1: 读取 manifest.json const manifestPath = path.join(skillPath, 'manifest.json'); const manifestRaw = await fs.readFile(manifestPath, 'utf8'); const manifest = JSON.parse(manifestRaw) as Partial<SkillManifest>; // Step 2: Manifest 基础校验(id, category, version) this.validateManifestBasic(manifest); // Step 3: 类型校验 —— 关键! const tsConfigPath = path.join(skillPath, 'tsconfig.json'); const typeCheckResult = await this.runTypeCheck(skillPath, tsConfigPath); if (!typeCheckResult.success) { throw new Error(`Type check failed for skill ${manifest.id}: ${typeCheckResult.error}`); } // Step 4: 沙箱加载与执行验证 const sandbox = new NodeVM({ console: 'redirect', sandbox: { context: {} }, // 初始化空沙箱 require: { external: true, builtin: ['path', 'fs', 'os'], // 仅允许极少数安全内置模块 root: skillPath } }); try { // 尝试在沙箱中加载并解析 execute 函数 const skillModule = sandbox.run( `module.exports = require('./index.js').execute;`, path.join(skillPath, 'index.js') ); // 如果能成功获取 execute 函数,说明无语法错误且无危险 API } catch (e) { throw new Error(`Sandbox load failed for ${manifest.id}: ${e.message}`); } // Step 5: 创建 SkillInstance 并存入 Map const instance = new SkillInstance(manifest, skillPath); this.skills.set(manifest.id, instance); }

这里最值得玩味的是Step 3runTypeCheck。它不是调用tscCLI,而是直接使用 TypeScript 的 Compiler API:

private async runTypeCheck(skillPath: string, tsConfigPath: string): Promise<{ success: boolean; error?: string }> { const config = ts.readConfigFile(tsConfigPath, ts.sys.readFile); const parsedConfig = ts.parseJsonConfigFileContent( config.config, ts.sys, path.dirname(tsConfigPath), {}, tsConfigPath ); const program = ts.createProgram( [path.join(skillPath, 'index.ts')], // 只检查 index.ts parsedConfig.options ); const diagnostics = ts.getPreEmitDiagnostics(program); if (diagnostics.length > 0) { return { success: false, error: ts.formatDiagnostics(diagnostics, { ... }) }; } return { success: true }; }

这意味着:你的 skill 必须是一个合法的 TypeScript 项目,且index.ts必须能被tsc成功编译(即使不生成.js文件)。这就是为什么 “npm 安装 claude code” 后,很多用户复制别人的index.js却无法工作——Registry 层需要的是index.ts的类型信息,而不是index.js的运行时代码。.js文件只是tsc的产物,Registry 的校验发生在编译阶段。

3.3RuntimeExecutor.ts:沙箱内的“微型操作系统”

packages/skills-runtime/src/RuntimeExecutor.ts是 skills 真正“活起来”的地方。它不是一个简单的函数调用器,而是一个微型的、受控的执行环境。其核心executeSkill方法如下:

public async executeSkill( skillId: string, input: unknown, context: SkillContext ): Promise<unknown> { const instance = this.registry.get(skillId); if (!instance) throw new Error(`Skill ${skillId} not found`); // 1. 输入校验(Zod) const parsedInput = instance.manifest.inputSchema.parse(input); // 2. 创建沙箱上下文 const sandboxContext = { context, // 注入 SkillContext console, // 重定向 console Buffer, // 允许 Buffer 操作 process: { // 仅暴露极少数安全属性 env: { NODE_ENV: process.env.NODE_ENV }, platform: process.platform } }; const vm = new NodeVM({ console: 'redirect', sandbox: sandboxContext, require: { external: false, // 禁止任何外部依赖 builtin: ['path', 'fs', 'os', 'crypto'] // 白名单内置模块 } }); // 3. 加载 skill 模块(此时 index.js 已存在) const skillModule = vm.run( `module.exports = require('${instance.path}/index.js');`, `${instance.path}/index.js` ); // 4. 执行 execute 函数 const result = await skillModule.execute(context, parsedInput); // 5. 输出校验 return instance.manifest.outputSchema.parse(result); }

注意require: { external: false }—— 这意味着你的 skill不能npm install任何第三方包。所有依赖必须是 Node.js 内置模块(fs,path,crypto)或通过@types/*声明的类型定义。如果你想用lodash,唯一的办法是把它作为devDependency,然后在index.ts中用import { debounce } from 'lodash',但tsc编译时会报错,因为external: false。解决方案是:lodash的源码(或你需要的函数)直接复制进index.ts,或使用esbuild将其打包为单个index.js,再放入 skills 目录。这就是 “skills 开发” 中最常踩的坑:开发者习惯性npm install,却忘了 skills 的沙箱哲学是“零依赖,纯函数”。

4. 实操指南:从零创建一个可被 Claude Code 识别的hello-worldskill

4.1 环境准备:避开 90% 用户失败的三个路径陷阱

在动手前,必须确认你的本地环境满足以下硬性条件,否则后续所有步骤都会失败:

  1. Node.js 版本:必须是v18.17.0v20.9.0。这是vm2沙箱的兼容要求。v21.x会因vm2process.binding('uv')调用失败而崩溃。验证命令:node -v。如果不是,请用nvm切换:nvm install 18.17.0 && nvm use 18.17.0

  2. Claude Code 安装路径:必须是默认路径。Windows 用户尤其注意:不要手动下载.exe放在C:\Program Files\。正确做法是:

    • 访问claude-code.com/download,下载claude-code-setup.exe
    • 以普通用户身份运行安装程序(不要右键“以管理员身份运行”)
    • 安装路径保持默认C:\Users\<username>\AppData\Local\Programs\Claude Code\
    • 这样~/.claude-code/skills/才能被正确映射为%LOCALAPPDATA%\Claude Code\skills\
  3. 技能存储目录权限~/.claude-code/skills/目录必须可读写。macOS/Linux 用户检查:ls -ld ~/.claude-code/skills,应显示drwxr-xr-x。Windows 用户检查:右键该文件夹 -> “属性” -> “安全” -> 确保你的用户有“完全控制”权限。这是 “skills 列表为空” 的最常见原因。

提示:你可以用claude-code --list-skills命令行工具(如果已添加到 PATH)快速验证 Registry 是否正常工作。它会输出所有已注册 skill 的idname。如果报错ENOENT: no such file or directory, scandir .../skills,说明路径不对。

4.2 创建hello-worldskill 的 5 个精确步骤

现在,我们创建一个最简 skill,它接收一个name字符串,返回一句问候。全程不依赖任何外部包,100% 符合源码规范。

Step 1:创建技能目录结构

mkdir -p ~/.claude-code/skills/hello-world cd ~/.claude-code/skills/hello-world

Step 2:编写manifest.json

{ "id": "hello-world", "name": "Hello World", "description": "A simple greeting skill", "category": "code", "icon": "PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDJDMTYuNDE0MiAyIDIwLjYxNDIgMy44MTQyMSAyNCA3LjQxNDIxTDE2LjU4NTggMTQuODI4NEMxNS44Mjg0IDE1LjU4NTggMTQuODI4NCAxNi41ODU4IDE0LjAyODQgMTcuMzQzMUwxMiAxOC42Mjg0TDkuOTcwNCAxNy4zNDMxQzkuMTExMSAxNi41ODU4IDguMTEwOSAxNS41ODU4IDcuMzUzNSAxNC44Mjg0TDAgNy40MTQyMUMzLjM4NTc5IDMuODE0MjEgNy41ODU3OSAyIDEyIDIiIHN0cm9rZT0iIzQ0NDQiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPg==", "inputSchema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1 } }, "required": ["name"] }, "outputSchema": { "type": "object", "properties": { "greeting": { "type": "string" } }, "required": ["greeting"] }, "version": "1.0" }

注意icon字段是 SVG 的 Base64 编码,你可以用在线工具生成。inputSchemaoutputSchema是标准 JSON Schema,不是 Zod 代码。

Step 3:编写index.ts

// index.ts import { SkillContext } from '@claude-code/skills-runtime'; export async function execute( context: SkillContext, input: { name: string } ): Promise<{ greeting: string }> { // 业务逻辑:生成问候语 const greeting = `Hello, ${input.name}! This is executed in a secure sandbox.`; // 日志记录(会显示在 Claude Code 的输出面板) context.logger.info(`Greeting generated for ${input.name}`); // 返回符合 outputSchema 的对象 return { greeting }; }

关键点:inputoutput的 TypeScript 类型必须与manifest.json中的inputSchema/outputSchema完全一致。这里input{ name: string }output{ greeting: string }

Step 4:创建tsconfig.json

{ "compilerOptions": { "target": "ES2020", "module": "CommonJS", "lib": ["ES2020", "DOM"], "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", "rootDir": "./", "resolveJsonModule": true, "types": ["@claude-code/skills-runtime"] }, "include": ["index.ts"], "exclude": ["node_modules"] }

types字段指向@claude-code/skills-runtime的类型定义,这是SkillContext类型的来源。

Step 5:编译并验证

# 全局安装 typescript(如果未安装) npm install -g typescript # 在 hello-world 目录下编译 tsc # 检查是否生成了 index.js ls -l index.js # 如果没有报错,且 index.js 存在,则注册成功 # 重启 Claude Code,或在命令面板中执行 "Claude Code: Reload Skills"

此时,打开 VS Code,按Ctrl+Shift+P,输入 “Run Skill”,你应该能看到 “Hello World” 出现在列表中。点击它,输入{"name": "Alice"},即可看到返回结果。

5. 常见问题与独家排查技巧:那些源码里没写,但你一定会遇到的坑

5.1 “Skills 列表为空” 的 5 种根因与秒级定位法

这是最高频问题,90% 的用户卡在这里。以下是经过实测的、可立即执行的排查清单:

现象根因定位命令/操作解决方案
Claude Code 启动后,命令面板中无 “Run Skill” 选项@claude-code/skills-registry未加载打开开发者工具(Help → Toggle Developer Tools),在 Console 中输入window.claudeCodeRegistry,如果返回undefined,说明 Registry 模块未初始化重新安装 Claude Code,确保安装过程无中断;检查~/.claude-code/目录是否存在且非空
命令面板有 “Run Skill”,但列表为空skills目录下无合法 skill在终端执行ls -la ~/.claude-code/skills/,检查是否有子目录,且子目录下有manifest.json确保skills目录是直接子目录,不要有多层嵌套(如skills/my-skills/hello-world是错的,必须是skills/hello-world
skills目录结构正确,但列表仍为空manifest.json格式错误进入~/.claude-code/skills/hello-world/,执行node -e "console.log(JSON.parse(require('fs').readFileSync('manifest.json','utf8')))"修复 JSON 语法(常见:末尾逗号、单引号、注释);确保id字段符合正则
manifest.json无误,但 skill 仍不显示index.ts类型校验失败hello-world目录下执行tsc --noEmit --skipLibCheck查看具体错误。最常见:Cannot find module '@claude-code/skills-runtime',需全局安装npm install -g @claude-code/skills-runtime(注意:是-g
tsc通过,但 skill 仍不显示index.js未生成或路径错误检查tsc是否生成了index.js;确认manifest.jsonid与目录名完全一致(大小写、连字符)重新运行tsc;确保目录名是hello-world,不是HelloWorldhello_world

实操心得:我写了一个一键诊断脚本check-skill.sh(macOS/Linux):

#!/bin/bash SKILL_DIR="$HOME/.claude-code/skills/hello-world" echo "=== Checking $SKILL_DIR ===" ls -la "$SKILL_DIR" node -e "console.log('Manifest valid:', JSON.parse(require('fs').readFileSync('$SKILL_DIR/manifest.json','utf8')))" tsc --noEmit --skipLibCheck "$SKILL_DIR/index.ts" 2>&1 || echo "Type check FAILED" ls -la "$SKILL_DIR/index.js"

运行它,5 秒内就能定位 95% 的问题。

5.2 “Skill 执行时报错:Sandbox load failed” 的深度解析

这个错误信息非常笼统,但根源几乎总是以下三种之一:

  • ReferenceError: require is not defined:你在index.ts中写了const fs = require('fs')。这是 Node.js CommonJS 语法,但vm2沙箱默认不提供require解决方案:改用 ES Module 语法import * as fs from 'fs',并在tsconfig.json中设置"module": "ES2020"

  • TypeError: Cannot read property 'xxx' of undefined:你在execute()函数中试图访问context.editor.xxx,但context.editor是一个代理对象,其属性是懒加载的。解决方案:永远不要解构context,直接使用context.editor.getDocument()等方法。源码中SkillContext的 getter 都有防错逻辑。

  • RangeError: Maximum call stack size exceeded:你的 skill 代码中存在无限递归,或inputSchema定义了过于复杂的嵌套对象(如z.object({ a: z.object({ b: z.object({ ... }) }) })),导致zod.parse()栈溢出。解决方案:简化inputSchema;或在manifest.json中添加"maxDepth": 3字段(这是zod的一个未公开但有效的选项)。

5.3 “Superpower Skills” 的真相:它们不是魔法,而是精心设计的模式组合

网络热词 “superpower skills” 让很多人以为存在某种高级 API 或隐藏功能。实际上,源码揭示,它只是多个基础 skill 的组合调用模式。以官方code-reviewskill 为例,其index.ts的核心逻辑是:

export async function execute(context: SkillContext, input: InputType) { // Step 1: 用内置的 'ast-parser' skill 解析代码为 AST const ast = await context.skillRunner.run('ast-parser', { code: input.code }); // Step 2: 用 'complexity-analyzer' skill 分析复杂度 const complexity = await context.skillRunner.run('complexity-analyzer', { ast }); // Step 3: 用 'security-scanner' skill 检查漏洞 const security = await context.skillRunner.run('security-scanner', { ast }); // Step 4: 将所有结果聚合,生成最终报告 return generateReport(ast, complexity, security); }

context.skillRunner.run()是一个内部 API,允许一个 skill 调用另一个 skill。这解释了为什么 “skills 推荐” 会根据当前文件类型(.py,.js)动态显示不同的组合:SkillRegistry会分析inputSchema中的filePath字段,匹配文件扩展名,然后预计算哪些 skill 组合能覆盖该场景。所以,“claude code skills 教程” 中教你怎么写单个 skill,而 “superpower skills 安装” 其实是教你如何把多个 skill 目录一起放到skills/下,并确保它们的idmanifest.json中被正确引用。

最后一个小技巧:想快速查看某个 skill 的源码?在 Claude Code 中,按Ctrl+Click(Windows)或Cmd+Click(Mac)点击任何 skill 名称,它会自动跳转到~/.claude-code/skills/<id>/index.ts。这是源码级的 IDE 支持,也是 Anthropic 对开发者体验的极致打磨。

http://www.jsqmd.com/news/1068499/

相关文章:

  • 从XSS到蠕虫:剖析Samy攻击原理与DVWA靶场复现
  • Jekyll静态站Canonical标签配置指南:解决重复内容SEO问题
  • XMEGA RTC软件校准:从原理到实践,提升嵌入式时钟精度
  • Claude Opus 4.7 Adaptive Thinking 原理与工程实践指南
  • VS Code 内置 Git 集成:零命令行的可视化版本控制工作流
  • 系统漏洞利用与提权:从攻击链拆解到防御体系构建
  • 网络安全信息收集实战:从CDN绕过到资产测绘的完整攻防体系
  • Rails URL Helpers 深度解析:path 与 url 的本质区别及工程实践
  • React Suspense与lazy:异步渲染契约与代码分割实战
  • 深入解析ColdFire中断控制器:从原理到实战配置
  • GitLab CI/CD在Ubuntu上的Docker+SSH持续部署实践
  • GPT-5.5的Agentic Coding与Computer Use能力解析
  • Mockito mock void方法:doAnswer/doThrow/doNothing原理与实战
  • 微信聊天记录数据库解密:基于IMEI与UIN的密钥生成与SQLCipher实战
  • MC56F8455x中断控制器(INTC)配置详解与实时系统优化实践
  • Android运行时权限实战:从系统机制到厂商适配的完整指南
  • Angular NgModule 模块解剖:声明、导入、导出与服务注入原理
  • SQL约束不是语法糖:数据库数据一致性的五大强制机制
  • Ubuntu VPS运维三剑客:dig、whois、ping深度诊断指南
  • OAuth 2 不是登录协议:授权委托原理与生产级避坑指南
  • 使用Nginx搭建OpenAI API反向代理:应对访问限制的完整指南
  • Suricata签名机制深度解析:协议感知、声明式匹配与高精度规则实战
  • Kubernetes原生开发:用Okteto实现集群内实时编码与调试
  • MC13234/37 CMT模块深度解析:从硬件调制到低功耗无线通信实战
  • Ubuntu 14.04 上 Clojure Web 应用生产部署方案
  • MC9S08GW64 PDB与VREF模块实战:实现高精度ADC交替采样的硬件协同
  • Terraform工程实践:从IaC落地到生产级基础设施治理
  • 掌握PETools:Windows PE文件逆向分析与实战指南
  • Python实现AI数据隐私保护:差分隐私与联邦学习实战指南
  • WebShell免杀与流量伪装:魔改冰蝎的攻防对抗技术解析