惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
T
Tailwind CSS Blog
罗磊的独立博客
B
Blog
博客园_首页
A
About on SuperTechFans
有赞技术团队
有赞技术团队
V
V2EX
U
Unit 42
I
InfoQ
IT之家
IT之家
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
H
Help Net Security

鸟窝

鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 LLM 究竟是如何工作的? Go 实验特性详解
一行代码使用 Claude Skill 和 deepseek
by smallnest · 2025-11-01 · via 鸟窝

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;

}