goskills:Claude Skills 功能强大,为我所用

在去年年底Claude推出MCP的功能后,MCP热度维持了小半年,MCP开发和研究风生水起。一年后,Claude又推出了一个新的概念:Skills

Claude 的各种应用(desktop、code cli、claude.ai等)现在可以使用 “Skills” 来改进其执行特定任务的方式。“Skills”是包含指令、脚本和资源的文件夹,Claude 应用可以根据需要加载这些文件夹。

Claude 应用只会在Skill与当前任务相关时才会使用该Skill。使用Skill后,克劳德可以更高效地完成特定任务,例如使用 Excel 或操作pdf。

在执行任务时,Claude 应用会扫描可用Skill以查找相关匹配项。找到匹配项后,它只会加载所需的最少信息和文件——既保证了Claude的运行速度,又能让他快速获取专业知识。

Skills 功能强大:

  • 可组合 :技能可以叠加使用。Claude 会自动识别所需技能并协调其使用。
  • 可移植性 :技能在所有地方都使用相同的格式。只需构建一次,即可在 Claude 应用、Claude Code 和 API 中使用。
  • 高效 :只在需要时加载所需内容。
  • 强大的技能包括编写可执行代码,以完成传统编程比令牌生成更可靠的任务。

下面是官方的一些资源:

除了官方的示例技能,很快又一群网友开发和整理了一批Claude资源,比如:

Claude 官方对SKILL的规范描述的比较清楚了,但是对于LLM 怎么使用SKILLs并没有一个详细的描述,这对于其他大语言模型使用SKILLs带来了很大的挑战。现在你看网上所有的关于Claude Skills讨论都是基于Claude 的各种应用的,鲜有openai、qwen、deepseek如何使用SKILLs的资料。考虑到 Claude官方对中国的敌意,以及在国内也很少能够购买Claude会员和使用Claude应用,我们对其他大语言模型使用SKILLs的研究还是很有意义的。

少有的几篇资料,从外部的视角分析Claude如何调用SKILLs的:

作为对SKILLs在其他大语言模型的探索,我实现了一个Claude SKILL的Go语言库,它提供了下面的功能:

  • 对skill包的解析
  • 提供了一个inspector功能,可以在命令行中分析skill包。inspired by raw391-ai/skill-cli
  • 实现了一个 deepseek调用SKILL的示例。事实上可以支持任意的兼容openai API的llm

接下来我就详细介绍这个库的功能。 库地址: https://github.com/smallnest/goskills

解析SKILL包

Claude Skill 可以打包成一个zip文件上传,最终会解开到一个文件夹(比如.claude/skills/xxx),包含一个SKILL.md文件和其它的一些资源。

这个库做了以下的事情:

  • 解析SKILL.md, 得到skill的元数据和指令
  • 抽取YAML frontmatter到Go数据结构SkillMeta
  • 获取skill的markdown信息
  • 发现scripts/references/assets/` 目录下的资源

如果你使用这个库,你可以执行下面的命令引入:

1
go get github.com/smallnest/goskills

下面是一个使用这个库解析skill的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main
import (
"fmt"
"log"
"github.com/smallnest/goskills"
)
func main() {
// Path to the skill directory you want to parse
skillDirectory := "./examples/skills/artifacts-builder"
skillPackage, err := goskills.ParseSkillPackage(skillDirectory)
if err != nil {
log.Fatalf("Failed to parse skill package: %v", err)
}
// Print the parsed information
fmt.Printf("Successfully Parsed Skill: %s\n", skillPackage.Meta.Name)
// ... and so on
}

goskills库在examples复制了Claude官方的SKILLs例子,你也可以手工clone官方的例子:https://github.com/anthropics/skills

上面这个例子使用ParseSkillPackage 函数解析某个SKILL的文件夹,得到它的信息,后续就可以结合LLM进行调用了。

inspector

raw391-ai/skill-cli启发,我基于这个库,实现了一个SKILL imspector的命令行工具,可以在命令行中审视某个SKILL。

它包含几个子命令:

  1. list - 查看某个目录下包含的所有的SKILL
  2. parse - 显示某个SKILL的概览
  3. detail - 显示某个SKILL的详情
  4. files - 检查某个SKILL的所有文件
  5. search - 搜索某个SKILL

比如我们在项目的使用下面的命令编译出这个cli程序:

1
go build -o goskills-cli ./cmd/skill-cli

./goskills-cli list ./examples/skills就可以显示出此目录下的所有SKILL:

./goskills-cli parse ./examples/skills/artifacts-builder 显示artifacts-builder 这个skill的基本信息:

其它命令的使用方法类似。

正如这个 cli 的名称所示,它可以用来检查SKILL的信息, 它也是goskills库的一个应用示例。

和deepseek结合

最终,这个库的目的是能够提供和其他大语言模型结合的能力。

它提供了goskills-runner 的命令行工具,演示了deepseek-v3 调用SKILL的能力。

目前这个演示还只是『演示』,并没有考虑到调用SKILL的安全性问题,并且调用SKILL还没有达到非常深入的研究,但是它已经提供了一个SKILL应用在其他LLM中的基础,为后续的功能的深入和演化打下来一个很好的基础。

接下来让我们看看它是怎么实现的?

首先我们通过下面的命令编译出这个工具:

1
go build -o goskills-runner ./cmd/skill-runner

然后,你就可以使用openai API 兼容的大模型进行测试了:

1
2
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
./goskills-runner run --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 "create an algorithm that generates abstract art"

环境变量OPENAI_API_KEY 设置你在服务商中生成的key, 无论你使用的是deepseek、千问、文心还是openai等。

命令行中传入模型名称和api_base地址,这在各模型服务商的文档中都有提供。这周我会整理几家大的模型服务器的信息和使用方法,我会单写一篇文章。

这里我使用的是百度云提供的deepseek服务,它的模型和官方的模型名称不太一样,deepseek官方的模型名称是deepseek-chat, 百度云提供的模型名称是deepseek-v3, 其实都无所谓啦。然后百度云的调用的api的地址是https://qianfan.baidubce.com/v2

create an algorithm that generates abstract art这个就是我们作为用户的请求。

先看一下输出效果:

采用三步走的策略:

  1. discoverSkills: 第一步是找到所有可用的SKILL, 加到上下文中
  2. selectSkill:让LLM选择一个SKILL
  3. executeSkillWithTools: 执行一个SKILL, 使用它的定义的tool执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// --- STEP 1: SKILL DISCOVERY ---
fmt.Println("🔎 Discovering available skills...")
availableSkills, err := discoverSkills(skillsPath)
if err != nil {
return fmt.Errorf("failed to discover skills: %w", err)
}
if len(availableSkills) == 0 {
return errors.New("no valid skills found")
}
fmt.Printf("✅ Found %d skills.\n\n", len(availableSkills))
// --- STEP 2: SKILL SELECTION ---
fmt.Println("🧠 Asking LLM to select the best skill...")
selectedSkillName, err := selectSkill(ctx, client, userPrompt, availableSkills)
if err != nil {
return fmt.Errorf("failed during skill selection: %w", err)
}
selectedSkill, ok := availableSkills[selectedSkillName]
if !ok {
fmt.Printf("⚠️ LLM selected a non-existent skill '%s'. Aborting.\n", selectedSkillName)
return nil
}
fmt.Printf("✅ LLM selected skill: %s\n\n", selectedSkillName)
// --- STEP 3: SKILL EXECUTION (with Tool Calling) ---
fmt.Println("🚀 Executing skill (with potential tool calls)...")
fmt.Println(strings.Repeat("-", 40))
err = executeSkillWithTools(ctx, client, userPrompt, selectedSkill)
if err != nil {
return fmt.Errorf("failed during skill execution: %w", err)
}

具体的实现代码可以看代码库。这里我们仅仅是显示了一个简单的SKILL的调用逻辑。

下一步就是在每个步骤进行细化,尤其是第三个步骤,要加上安全性检查、沙盒执行、文件嵌套、命令抽取和执行更复杂的逻辑。

tool

为了让SKILL执行bash、python的等脚本,我们还需要实现执行shell命令的工具。

所以tool 包下还实现几个常用的命令

  • file_tool: 文件操作工具
  • knowledge_tool: wiki知识库查询
  • python_tool: python调用工具
  • shell_tool: shell脚本执行工具
  • web_search_tool: duckduckgo 搜索工具等

未来这个工具集会越来越丰富