Claud Skills 虽好,但是只能使用在Claude 的工具中,想在我们自己的应用中使用Skill 还得想想办法。
上周我介绍了goskills, 支持在常见的LLM 中集成Claude Skills的能力。没两天百度厂内的同学就基于它做了提效的工具,自动为批量的表结构按照特定的要求创建创建“建表SQL”: 类似cat user.data | goskills。
这激发了我的灵感,当初做这个工具的时候我还没想到可以这么简化调用Claude Skills,这促使我进一步优化这个工具,产品化并发布v0.1.3版本,更方便下载使用。
基本上,下载后在命令行中只需执行一句./goskills run --auto-approve --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584", 就可以调用markitdown这个Skill将百度百科上关于孔子的网页转换成markdown格式:

所以你只需在程序中调用goskills run --auto-approve your_prompt 即可。文章后面我附上各种编程语言的示例。
安装
你可以在 goskills/releases 下载 Mac/Linux/Windows + amd64/arm64 环境的已经编译好的可执行二进制文件,放在PATH路径中就可以使用。
对于 Mac系统,你还可以使用 brew install smallnest/goskills/goskills 进行安装,或者分步安装:
1 2 3 4 5
| brew tap smallnest/goskills brew install goskills
|
安装完成后,你可以尝试执行goskills run -h 检查是否安装成功。正常情况下它应该输出:

- -b: 设置大模型API的调用基地址
- -k:设置大模型API的Key
- --auto-approve: 是否自动批准调用Skill中的脚本,在不需要人工干预的情况下启用此参数,否则命令在执行的时候可能需要用户的批准(输入y或者N)
- -m: 要使用的模型名称
- -d:Claude Skills所在的目录。 Claude工具默认放在
~/.Claude/skills目录下
你可以在环境变量中设置 api-base、api-key和model 这三个参数,这样你就不必在命令行中设置它们了。
你可以在网上下载你想使用的Skills,下面几个站点是常见的Skills收集地:
markitdown Skill
markitdown 是 微软开发的一个轻量级 Python 工具,用于将各种文件格式转换为 Markdown,主要服务于大语言模型(LLM)和文本分析流程 GitHub。
支持的文件格式广泛 : markitdown 能够转换多种文件格式,包括 Word 文档、Excel 表格、PowerPoint 演示文稿、PDF、HTML、图片、音频文件、文本格式(如 CSV、JSON、XML)甚至 ZIP 压缩包 。
专为 LLM 优化 :该工具注重保留重要的文档结构和内容,如标题、列表、表格、链接等,转换为 Markdown 格式后可被主流 LLM(如 GPT-4o)直接理解和使用。
所以理论上网上应该有相应的Skill发布出来,实际上不是太好找,不过最终让我在一个项目中找到了:scientific-skills/markitdown,这个项目包含了120+个科学Skill, markitdown就是其中一个。
功能强大的Skill的SKILL.md文件内容一向 很长,markitdown Skill也不例外,所以我不粘贴在这里了,只附上链接地址:SKILL.md
它包含了一个通用的python脚本以及5 种要转换的类型的更详细的参考手册。
实际在使用过程中我发现它处理网页转换很容易失败,所以我扩展了这个Skill,增加了一个处理网页的脚本convert_webpage.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import sys from markitdown import MarkItDown if len(sys.argv) != 2: print("Usage: python convert_webpage.py <URL>") sys.exit(1) url = sys.argv[1] try: md = MarkItDown() result = md.convert(url) print(result.text_content) except Exception as e: print(f"An error occurred: {e}") sys.exit(1)
|
其他都没有做修改,就处理网页转换非常好了。
使用这个技能的一个很好的例子,就是文章最开始的例子(我已经安装goskills到PATH环境变量的一个路径中,并且设置大模型的三个环境变量):
1
| `goskills run --auto-approve "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584
|
既然它是一个命令行,那么我们很容易就可以在各种编程语言中调用它,不用写复杂的LLM和Claude Skill解析和调用。下面是常见的几种编程语言的例子。
各种编程语言调用例子
在运行任何 goskills 命令之前,您必须设置您的大模型API的密钥:
1
| export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
|
这些示例的基础命令是:
1
| goskills run --auto-approve --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 --skills-dir=~/.claude/skills "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584"
|
Shell (Bash)
这是运行该命令最直接的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #!/bin/bash PROMPT="使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584" RESULT=$(goskills run --auto-approve --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 --skills-dir=$HOME/.claude/skills "$PROMPT") echo "输出:" echo "$RESULT"
|
Python
使用 subprocess 模块是在 Python 中运行外部命令的标准方法。为了正确处理 ~ 符号,我们需要使用 os.path.expanduser 来获取完整路径。
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 34 35 36 37 38 39 40 41 42 43 44 45
| import subprocess import shlex import os prompt = "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584" skills_dir_path = os.path.expanduser("~/.claude/skills") skills_dir_arg = f"--skills-dir={skills_dir_path}" command = [ "goskills", "run", "--auto-approve", "--model", "deepseek-v3", "--api-base", "https://qianfan.baidubce.com/v2", skills_dir_arg, prompt ] try: result = subprocess.run( command, check=True, capture_output=True, text=True ) print("命令执行成功:") print("输出:\n", result.stdout) except FileNotFoundError: print("错误: 'goskills' 命令未找到。请确保它在您的 PATH 中。") except subprocess.CalledProcessError as e: print(f"命令失败,退出码 {e.returncode}:") print("标准错误输出:\n", e.stderr)
|
JavaScript (Node.js)
在 Node.js 中,您可以使用 child_process 模块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const { exec } = require('child_process'); const command = 'goskills run --auto-approve --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 --skills-dir=$HOME/.claude/skills "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584"'; exec(command, (error, stdout, stderr) => { if (error) { console.error(`执行错误: ${error.message}`); if (stderr) { console.error(`标准错误输出: ${stderr}`); } return; } console.log(`命令输出:\n${stdout}`); });
|
Go
在 Go 中,使用 os/exec 包来运行外部命令。为了正确处理 ~ 符号,我们需要手动获取用户主目录并构建路径。
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 34 35 36 37 38 39
| package main import ( "fmt" "os" "os/exec" "path/filepath" ) func main() { prompt := "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584" homeDir, err := os.UserHomeDir() if err != nil { fmt.Printf("无法获取主目录: %v\n", err) return } skillsDirPath := filepath.Join(homeDir, ".claude", "skills") skillsDirArg := "--skills-dir=" + skillsDirPath cmd := exec.Command("goskills", "run", "--auto-approve", "--model", "deepseek-v3", "--api-base", "https://qianfan.baidubce.com/v2", skillsDirArg, prompt) output, err := cmd.CombinedOutput() if err != nil { fmt.Printf("执行命令时出错: %v\n", err) fmt.Printf("输出:\n%s\n", string(output)) return } fmt.Printf("命令输出:\n%s\n", string(output)) }
|
Java
使用 ProcessBuilder 是在 Java 中执行命令的现代和推荐方式。为了正确指定 --skills-dir 参数,我们需要手动获取用户的主目录并构建完整路径。
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 34 35 36 37 38 39 40 41 42 43 44 45
| import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.nio.file.Paths; public class GoSkillsRunner { public static void main(String[] args) { try { String userHome = System.getProperty("user.home"); String skillsDirPath = Paths.get(userHome, ".claude", "skills").toString(); String skillsDirArg = "--skills-dir=" + skillsDirPath; ProcessBuilder pb = new ProcessBuilder( "goskills", "run", "--auto-approve", "--model", "deepseek-v3", "--api-base", "https://qianfan.baidubce.com/v2", skillsDirArg, "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584" ); pb.redirectErrorStream(true); Process process = pb.start(); StringBuilder output = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { output.append(line).append("\n"); } } int exitCode = process.waitFor(); System.out.println("退出码: " + exitCode); System.out.println("输出:\n" + output.toString()); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
|
Rust
在 Rust 中,使用 std::process::Command 结构体来执行外部命令。为了正确处理 $HOME 环境变量,我们需要手动获取它的值并构建路径。
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
| use std::process::Command; use std::env; use std::path::PathBuf; fn main() { let prompt = "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584"; let home_dir = env::var("HOME").expect("HOME 环境变量未设置"); let skills_dir_path = PathBuf::from(home_dir).join(".claude").join("skills"); let skills_dir_arg = format!("--skills-dir={}", skills_dir_path.to_str().expect("路径无效")); let output = Command::new("goskills") .arg("run") .arg("--auto-approve") .arg("--model") .arg("deepseek-v3") .arg("--api-base") .arg("https://qianfan.baidubce.com/v2") .arg(&skills_dir_arg) .arg(prompt) .output() .expect("未能执行命令"); if output.status.success() { println!("命令执行成功:"); println!("输出:\n{}", String::from_utf8_lossy(&output.stdout)); } else { eprintln!("命令失败,退出码: {:?}", output.status.code()); eprintln!("标准错误输出:\n{}", String::from_utf8_lossy(&output.stderr)); } }
|
C++
在 C++ 中,std::system 提供了一种简单的方式来执行 shell 命令。然而,为了捕获命令的输出,popen 是一个更好的选择。popen 会执行一个命令并创建一个管道,允许程序读取该命令的标准输出。
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
| #include <iostream> #include <cstdio> #include <string> #include <array> int main() { std::string prompt = "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584"; std::string command = "goskills run --auto-approve --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 --skills-dir=$HOME/.claude/skills \"" + prompt + "\""; FILE* pipe = popen(command.c_str(), "r"); if (!pipe) { std::cerr << "无法执行命令!" << std::endl; return 1; } std::array<char, 256> buffer; std::string result; while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) { result += buffer.data(); } int exit_code = pclose(pipe); std::cout << "命令输出:" << std::endl; std::cout << result << std::endl; std::cout << "退出码: " << WEXITSTATUS(exit_code) << std::endl; return 0; }
|
C
在 C 语言中,system() 函数是 stdlib.h 的一部分,允许执行 shell 命令。但它不容易捕获输出。为了读取命令的输出,推荐使用 popen 函数,它会创建一个管道来连接到被调用进程的标准输出。
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
| #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 256 int main() { char prompt[] = "使用markitdown 工具解析网页 https://baike.baidu.com/item/%E5%AD%94%E5%AD%90/1584"; char command[512]; snprintf(command, sizeof(command), "goskills run --auto-approve --model deepseek-v3 --api-base https://qianfan.baidubce.com/v2 --skills-dir=$HOME/.claude/skills \"%s\"", prompt); FILE *pipe = popen(command, "r"); if (pipe == NULL) { fprintf(stderr, "无法执行命令!\n"); return 1; } char buffer[BUFFER_SIZE]; printf("命令输出:\n"); while (fgets(buffer, sizeof(buffer), pipe) != NULL) { printf("%s", buffer); } int exit_code = pclose(pipe); fprintf(stdout, "\n退出码: %d\n", WEXITSTATUS(exit_code)); return 0; }
|