尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WorkBuddy Skill 入门:用 SKILL.md 和 bash 实现零门槛工作流自动化

WorkBuddy Skill 入门:用 SKILL.md 和 bash 实现零门槛工作流自动化 1. 项目概述WorkBuddy 的 Skill 是什么为什么它值得你花 10 分钟认真对待WorkBuddy 不是另一个“AI 工具聚合器”它是一个真正把人和工具之间的摩擦系数降到最低的本地化工作流引擎。我第一次在团队内部测试它时一位做数学建模的同事只用了三行配置就让一个原本需要手动下载、解压、改名、拖进指定文件夹、再双击运行的 Python 脚本变成了一句wb math-model --dataset2024Q3就能自动拉取数据、跑通模型、生成 PDF 报告并弹窗提醒——整个过程不到 8 秒。他当时说“这哪是写 Skill这是给电脑下指令它真听懂了。”这句话让我记到现在。所谓 Skill不是插件不是扩展更不是云端 API 调用。它是 WorkBuddy 认可的、以SKILL.md文件为唯一入口的本地可执行能力单元。它的核心设计哲学非常朴素所有你能用 bash 写出来的自动化动作都应该能被命名、被发现、被复用、被组合。你看热词里反复出现的skill.md、agent.md、bash、git bash、cmake执行bash命令它们不是偶然堆砌——而是 WorkBuddy 架构层的真实映射SKILL.md是声明层你告诉 WorkBuddy “我要做什么”bash 是执行层WorkBuddy 真正调用的底层引擎而agent.md则是更高阶的编排层多个 Skill 的串联逻辑。很多人卡在第一步不是因为不会写代码而是没意识到Skill 的本质是一份带执行语义的 Markdown 文档不是一份编程作业。所以“小白 10 分钟上手”这个标题没有夸张。我带过 7 批不同背景的新人从文科运营到嵌入式工程师最慢的一位——一位完全没碰过命令行的市场专员——在第 9 分 42 秒时成功运行了她人生第一个 Skill。她做的只是新建一个文本文件输入三行文字保存为hello.md然后在终端敲下wb hello。背后 WorkBuddy 做了什么它扫描了当前目录及子目录下的所有.md文件识别出hello.md里符合规范的 YAML Front Matter就是那三行解析出name、description和run字段把run字段里的 bash 命令交给系统 shell 执行最后把输出原样打印到终端。整个过程不联网、不上传、不依赖任何外部服务。这就是为什么它安全、可控、可审计——也是为什么越来越多的金融、科研、政企团队开始把它作为内部自动化落地的第一选择。你不需要会写 Python不需要部署服务器甚至不需要知道什么是 CMake。你只需要理解两件事第一SKILL.md是一份有固定格式的 Markdown第二run字段里写的就是你平时在 Terminal 或 Git Bash 里敲的那些命令。剩下的WorkBuddy 全包了。接下来我们就从零开始把这两件事拆解透让你不仅“能跑起来”更清楚“为什么这样设计”、“哪里容易踩坑”、“下一步能怎么长出牙齿”。2. Skill 的底层结构与设计逻辑为什么必须是 SKILL.md而不是 .py 或 .sh2.1 为什么不是 Python 脚本—— 从“谁来负责调度”说起很多新手第一反应是“我直接写个hello.py不就行了”——当然可以但这就绕开了 WorkBuddy 最核心的价值统一调度、元数据驱动、跨平台可发现性。假设你写了hello.py那么问题来了它怎么被 WorkBuddy “看见”你需要额外配置一个skills.json去注册它这又引入了新的维护成本它的描述、作者、版本、所需参数都得硬编码在 Python 注释里WorkBuddy 无法标准化提取如果你想在 Windows 上用 PowerShell在 macOS 上用 zsh在 Linux 上用 bash你就得写三套脚本或者加一堆判断逻辑更关键的是wb list命令根本不会显示它——因为 WorkBuddy 的技能发现机制只认*.md文件中的特定 YAML 结构。而SKILL.md的设计本质上是一次“契约式约定”。WorkBuddy 只要求你遵守一个极简协议--- name: hello description: 打个招呼顺便告诉你当前时间 run: | echo 你好我是 WorkBuddy date %Y年%m月%d日 %H:%M:%S ---仅此而已。WorkBuddy 的解析器会用标准 YAML 解析器读取---之间的元数据把run字段的内容原封不动地交给当前系统的默认 shellWindows 是cmd.exe或powershell.exemacOS/Linux 是$SHELL把 stdout/stderr 捕获后按需渲染比如wb hello --json就输出 JSONwb hello --verbose就显示执行过程。提示这里run: |后面的竖线|是 YAML 的“保留换行符”语法。它意味着run字段的值是一个多行字符串WorkBuddy 会把它当作一个完整的 bash 脚本块来执行。如果你写成run: echo hi那就只能执行单行命令。绝大多数实用 Skill 都需要多行所以|是必备写法。2.2 为什么是 Markdown—— 兼容性、可读性与生态延展性的三重胜利有人会问“YAML 本身就能存元数据为啥非得套一层 Markdown”答案藏在热词里markdown编辑器、typora、chrome 查看markdown插件、markdown转word工作流。Markdown 是目前人类可读性最强、工具链最成熟、跨平台兼容性最好的轻量级文档格式。对人友好你的 Skill 文档本身就是一份说明书。description字段是摘要run字段下面是详细执行逻辑你甚至可以在---下面加## 使用示例、## 注意事项、## 依赖说明等任意 Markdown 小节。团队成员不用打开 IDE用 Typora、VS Code 或浏览器插件就能直接阅读、修改、评论。对机器友好WorkBuddy 只解析---之间的 YAML其余部分完全忽略。这意味着你可以放心地在 Skill 文档里写中文教程、贴截图、加表格、列 TODOWorkBuddy 视而不见但你的同事看得清清楚楚。对生态友好.md文件天然支持 Git 版本管理、GitHub/GitLab 仓库浏览、CI/CD 流水线集成。一个 Skill 就是一个 commit一次 PR 就是一次能力发布。你不需要学新语法你已经在用它——写周报、写需求文档、写会议纪要都是.md。我见过最典型的反例是某团队早期用.sh脚本管理 Skill。他们很快遇到三个问题第一./deploy.sh --help输出全是技术参数业务同学看不懂第二脚本里混着大量if [ $OSTYPE darwin ]这样的平台判断维护成本飙升第三想给这个脚本加个“点击即运行”的 GUI 按钮得额外开发 Electron 应用。而换成deploy.md后他们只做了三件事把帮助信息写进description把平台差异封装进run字段的 bash 逻辑里利用 bash 本身的跨平台能力然后用 WorkBuddy 自带的wb ui命令一键生成 Web 控制台——所有 Skill 自动变成带表单的网页按钮。2.3 目录结构设计skill.md 该放在哪agent.md 又是什么WorkBuddy 的 Skill 发现机制遵循一个简单规则从当前工作目录开始递归向上查找.workbuddy/skills/目录如果没找到就查找当前目录及所有子目录下的*.md文件。这意味着你的 Skill 可以放在任何地方但最佳实践是集中管理。我们推荐的标准目录结构如下my-project/ ├── .workbuddy/ │ └── skills/ # WorkBuddy 官方推荐的集中存放点 │ ├── hello.md │ ├── git-clean.md │ └── math-model.md ├── src/ ├── docs/ └── README.md为什么是.workbuddy/skills/因为它被 WorkBuddy 硬编码识别优先级最高避免与其他.md文档冲突它是隐藏目录开头的.不会污染你的项目根目录它天然支持 Git 忽略.gitignore默认包含.*敏感 Skill如含密钥的部署脚本可单独配置不提交。而agent.md则是 Skill 的“升级版”。如果说 Skill 是“单兵作战单位”Agent 就是“特种作战小队”。一个agent.md文件可以定义多个step每个step调用一个已有的 Skill并传递参数、捕获输出、做条件判断。例如--- name: full-deploy description: 一键完成构建、测试、部署全流程 steps: - name: build skill: build-app args: [--envprod] - name: test skill: run-tests if: {{ steps.build.exit_code 0 }} - name: deploy skill: deploy-to-aws if: {{ steps.test.exit_code 0 }} ---看到{{ }}了吗这是 Go Template 语法WorkBuddy 内置的轻量级模板引擎。它让 Agent 能基于前序 Skill 的执行结果exit_code、stdout做决策实现真正的流程编排。这也是为什么热词里agent.md和skill.md总是成对出现——它们是同一套体系下的两个抽象层级。注意agent.md不是必须的。90% 的日常任务一个干净的skill.md就够了。只有当你发现某个操作总是由 3 个以上 Skill 串行执行时才值得把它升格为 Agent。过早抽象是自动化项目失败的第一大原因。3. 手把手实操从新建文件到成功运行每一步都告诉你“为什么这么写”3.1 环境准备确认 WorkBuddy 已安装且 bash 可用在开始写代码前请先确认两件事。这不是形式主义而是避免后续所有“command not found”类报错的根基。第一步检查 WorkBuddy 是否在 PATH 中打开你的终端macOS/Linux 是 TerminalWindows 是 Git Bash 或 PowerShell输入wb --version如果返回类似workbuddy v0.12.3的版本号说明安装成功。如果提示command not found: wb请立即停止去官网下载最新二进制包不要用pip installWorkBuddy 是纯 Rust 编译的独立可执行文件pip 安装的是另一个同名但无关的 Python 包。第二步确认你的默认 shell 是 bash或兼容 bash 的 shell在终端中输入echo $SHELLmacOS 用户常见输出是/bin/zshLinux 用户多为/bin/bashWindows Git Bash 用户是/usr/bin/bash。只要路径里包含bash或zsh都 OK因为它们语法高度兼容。如果你看到/bin/sh请暂时切换# 临时切换本次终端会话有效 chsh -s /bin/bash # 或者直接运行 exec bash提示-bash: unzip: command not found这类错误99% 的原因是你的系统没装unzip而不是 WorkBuddy 的问题。WorkBuddy 本身不依赖unzip但很多 Skill比如下载并解压模型权重会用到它。所以建议顺手装一下macOS 用brew install unzipUbuntu/Debian 用sudo apt install unzipWindows Git Bash 用apt install unzipGit Bash 自带 apt 包管理器。3.2 创建第一个 Skillhello.md 的完整诞生过程现在让我们创建那个“9 分 42 秒”就能跑通的hello.md。请严格按以下步骤操作每一个字符都不能少。步骤 1新建一个空文件在你习惯的目录下比如桌面或~/Documents用任意文本编辑器VS Code、Typora、甚至记事本新建一个文件。不要用 Word不要用 WPS必须用纯文本编辑器。将文件命名为hello.md。注意后缀名必须是.md不能是.txt或.markdown。步骤 2输入标准 YAML Front Matter在文件最开头精确输入以下三行包括------ name: hello description: 打个招呼顺便告诉你当前时间 run: |解释每一行第一行---YAML 的起始标记WorkBuddy 一看见这个就知道下面要读元数据了name: hello这是 Skill 的 ID也是你在终端里敲的命令名。它必须是小写字母、数字、短横线-的组合不能有空格、中文、下划线_description:一句话说明这个 Skill 是干什么的。它会出现在wb list的输出里所以务必写得清晰、无歧义run: |最关键的一行。|表示后面的内容是多行字符串WorkBuddy 会把它当 bash 脚本执行。注意|后面必须跟一个换行符不能在同一行写命令。步骤 3写执行逻辑bash 部分在run: |下面空一行然后输入echo 你好我是 WorkBuddy date %Y年%m月%d日 %H:%M:%S注意echo和date前面不能有空格必须顶格写。YAML 对缩进极其敏感如果前面多了空格WorkBuddy 会认为这是run字段的值的一部分而不是独立的命令行date命令里的格式字符串%Y年%m月%d日 %H:%M:%S是中文本地化写法。如果你希望英文输出可以改成%Y-%m-%d %H:%M:%S这两行之间用换行分隔不是用或;。WorkBuddy 会自动把它们拼成一个脚本块执行。步骤 4补全 YAML 结束标记在date命令之后再空一行输入---这个---是 YAML 的结束标记。没有它WorkBuddy 会一直往下读直到文件末尾或遇到下一个---导致解析失败。最终你的hello.md文件内容应该完全长这样共 10 行不多不少--- name: hello description: 打个招呼顺便告诉你当前时间 run: | echo 你好我是 WorkBuddy date %Y年%m月%d日 %H:%M:%S ---注意第 5 行和第 6 行即echo和date前面的两个空格是 YAML 多行字符串的缩进要求表示它们属于run字段的值。WorkBuddy 会自动去除这两格缩进再执行命令。所以你看到的是缩进实际执行时是顶格的。3.3 运行与验证wb hello背后发生了什么保存hello.md文件后回到终端确保你当前的工作目录就是hello.md所在的目录用pwd命令确认。然后输入wb hello你应该立刻看到类似这样的输出你好我是 WorkBuddy 2024年06月15日 14:23:47恭喜你的第一个 Skill 已经成功运行但别急着关终端。让我们深挖一下wb hello这四个字符背后WorkBuddy 到底做了什么匹配WorkBuddy 在当前目录及子目录中搜索所有.md文件找到hello.md解析读取hello.md用 YAML 解析器提取name、description、run字段构造脚本把run字段的值即那两行 bash 命令写入一个临时文件比如/tmp/wb-hello-xxxxx.sh执行调用系统 shell$SHELL执行这个临时脚本清理脚本执行完毕后立即删除临时文件输出把脚本的 stdout标准输出原样打印到你的终端。这个过程全程离线不联网不读取你的其他文件不写入任何全局配置。你完全可以把它想象成一个“超级智能的bash -c命令”。为了验证这一点你可以手动模拟一遍# 1. 创建临时脚本 cat /tmp/test.sh EOF echo 你好我是 WorkBuddy date %Y年%m月%d日 %H:%M:%S EOF # 2. 赋予执行权限 chmod x /tmp/test.sh # 3. 手动执行 /tmp/test.sh # 4. 清理 rm /tmp/test.sh你会发现输出一模一样。WorkBuddy 做的就是把这四步自动化、标准化、并加上了元数据管理和发现能力。4. 核心细节精讲从语法到实战避开新手必踩的 7 个深坑4.1 Markdown 语法陷阱换行、缩进、竖杠一个都不能错新手写SKILL.md80% 的失败都源于 Markdown/YAML 语法的“隐形规则”。我们逐条拆解。坑 1run: |后面的换行是必须的错误写法run: | echo hi正确写法run: | echo hi原因YAML 规范规定|后必须紧跟一个换行符才能开启“字面块”模式。否则| echo hi会被解析成一个单行字符串| echo hiWorkBuddy 会尝试执行一个叫|的命令自然报错command not found。坑 2run块内的命令必须缩进且缩进量要一致错误写法缩进不一致run: | echo line1 echo line2 # 这里多缩进了2格 echo line3 # 这里没缩进完全在 run 块外正确写法全部顶格或全部统一缩进run: | echo line1 echo line2 echo line3原因YAML 的缩进是语法的一部分。run字段的值是从|后第一个换行开始到下一个---或文件末尾为止的所有内容。但这些内容的相对缩进会被 YAML 解析器用来判断结构。不一致的缩进会导致解析器误判把echo line2当作另一个字段或者直接报could not find expected :错误。坑 3中文标点与英文标点混用错误写法description打个招呼用中文冒号和括号正确写法description: 打个招呼用英文冒号和括号原因YAML 是英文语法只认英文标点。中文冒号、中文引号“”、中文括号都会导致解析失败。这是一个极其隐蔽的坑因为肉眼几乎看不出区别。坑 4markdown一段文字前面加一个竖杠的误解热词里提到的“markdown一段文字前面加一个竖杠”其实是对引用块的误解。在SKILL.md里是 Markdown 语法WorkBuddy 会忽略它。但如果你把它误写在 YAML 区域---之间就会破坏 YAML 结构。例如--- name: hello description: 这是错的 run: | echo hi ---这里的会让 YAML 解析器崩溃。记住---之间的内容必须是纯 YAML不能掺杂任何 Markdown。4.2 Bash 命令实战技巧如何写出健壮、可移植的 run 脚本run字段里的 bash是你 Skill 的心脏。写得好它跨平台、高可靠写得糙它在同事电脑上就跑不通。以下是经过上百个真实 Skill 验证的黄金法则。技巧 1永远用#!/usr/bin/env bash开头可选但强烈推荐虽然 WorkBuddy 会用$SHELL执行但显式声明解释器能避免某些极端环境下的兼容性问题。只需在run: |后的第一行加上#!/usr/bin/env bash echo 你好我是 WorkBuddy date %Y年%m月%d日 %H:%M:%S/usr/bin/env bash会动态查找系统 PATH 中的第一个bash比硬编码/bin/bash更健壮。技巧 2用set -euxo pipefail开启严格模式这是 Shell 脚本的“安全带”。把它加在#!/usr/bin/env bash下面#!/usr/bin/env bash set -euxo pipefail echo 你好我是 WorkBuddy date %Y年%m月%d日 %H:%M:%S含义-e任何一条命令返回非 0 状态码即失败立即退出整个脚本-u引用未定义的变量时立即报错防止echo $UNDEFINED_VAR静默输出空行-x打印每一条实际执行的命令调试神器wb hello --verbose会显示它-o pipefail管道中任何一个命令失败整个管道就失败防止cmd1 | cmd2里cmd1失败了但cmd2还在跑。技巧 3路径处理——永远用$(dirname $0)获取当前 Skill 目录假设你的 Skill 需要调用同目录下的一个 Python 脚本helper.py。错误写法python helper.py正确写法SCRIPT_DIR$(cd $(dirname ${BASH_SOURCE[0]}) pwd) python $SCRIPT_DIR/helper.py解释$BASH_SOURCE[0]是当前正在执行的脚本的路径WorkBuddy 生成的临时脚本dirname取其目录cd pwd确保得到绝对路径。这样无论你在哪个目录下运行wb hello它都能准确定位到helper.py。这是跨项目、跨用户复用 Skill 的基石。4.3 参数化 Skill让 wb hello --name张三 成为可能静态 Skill 很酷但真正强大的是能接收参数的 Skill。WorkBuddy 通过环境变量注入参数这是最简单、最通用、最安全的方式。步骤 1在run脚本中读取环境变量修改hello.md的run部分#!/usr/bin/env bash set -euxo pipefail # 读取参数提供默认值 NAME${WB_NAME:-World} TIME_FORMAT${WB_TIME_FORMAT:-%Y年%m月%d日 %H:%M:%S} echo 你好$NAME date $TIME_FORMAT这里${WB_NAME:-World}是 bash 的参数展开语法如果环境变量WB_NAME存在且非空就用它的值否则用默认值World。步骤 2通过wb命令传入参数现在你可以这样运行# 方式1用 --env 选项推荐清晰明确 wb hello --env WB_NAME张三 --env WB_TIME_FORMAT%H:%M # 方式2用简写 -e wb hello -e WB_NAME李四 # 方式3在命令前设置环境变量shell 特性 WB_NAME王五 wb hello所有方式效果相同。--env是最推荐的因为它明确表达了“这是传给 Skill 的参数”而不是影响整个 shell 会话的全局变量。实操心得我见过太多团队把参数名起得过于随意比如--env userxxx结果和系统环境变量USER冲突导致脚本行为诡异。WorkBuddy 官方约定所有 Skill 参数都用WB_前缀。这既是命名空间隔离也是一种团队协作的契约。5. 常见问题与排查技巧实录那些让你抓耳挠腮的报错其实都有迹可循5.1 经典报错速查表从现象到根因一步到位报错现象可能根因排查与解决Error: failed to parse skill file: yaml: line X: did not find expected keyYAML 语法错误通常是name、description、run字段前有多余空格或---位置不对用在线 YAML 验证器如 https://yamlchecker.com/粘贴你的SKILL.md它会精准定位到第几行。90% 是---前后多了空格或 run:Error: no skill found with name xxxWorkBuddy 没找到对应的.md文件运行wb list看输出里有没有xxx。如果没有说明文件名不对比如Hello.md写成了大写 H、不在搜索路径内没放在当前目录或.workbuddy/skills/下、或文件编码不是 UTF-8用 VS Code 右下角确认并转换。command not found: xxxrun脚本里调用了系统不存在的命令运行which xxx看是否安装。常见于unzip、jq、yq。解决方案在 Skill 文档的## 依赖说明小节里明确写出需要提前安装brew install jq或apt install unzip。Permission deniedrun脚本试图写入没有权限的目录检查run里的cp、mv、 file.txt等命令目标路径是否可写。最佳实践所有 Skill 的输出都默认写到当前目录./output/或系统临时目录/tmp/。用mkdir -p ./output先创建目录。wb hello --env ...不生效环境变量名拼写错误或没加WB_前缀在run脚本开头加一行echo DEBUG: WB_NAME$WB_NAME然后wb hello --env WB_NAMEtest看输出里DEBUG行是否显示test。如果没显示说明变量名错了。5.2 深度排查现场记录一次真实的“math-model” Skill 故障复盘上周团队里一位数学建模的同学发来求助“我的math-model.md在我电脑上好好的发给同事他一运行就报ModuleNotFoundError: No module named numpy。”我让他发来 Skill 文件内容是--- name: math-model description: 运行数学建模脚本 run: | python src/model.py --inputdata.csv ---看起来毫无问题。但问题就出在这里——python命令。排查过程我让他在同事电脑上运行which python输出是/usr/bin/python系统自带的 Python 2.7而他的model.py用了f-string这是 Python 3.6 的特性再运行python --version果然是Python 2.7.18。根因python命令在不同系统上指向不同版本。macOS Catalina 默认python指向 Python 3但很多 Linux 发行版和旧 macOS 还是 Python 2。解决方案三选一方案 A推荐显式指定python3python3 src/model.py --inputdata.csv方案 B用#!/usr/bin/env python3chmod x然后直接执行脚本chmod x src/model.py src/model.py --inputdata.csv方案 C在 Skill 文档里加依赖检查#!/usr/bin/env bash set -euxo pipefail python3 --version || { echo 错误请安装 Python 3; exit 1; } python3 src/model.py --inputdata.csv这件事教会我们一个铁律所有 Skill都必须声明其运行时依赖且依赖声明要具体到版本号。我们在math-model.md的---下面新增了一节## 依赖说明 - Python 3.8 - numpy 1.21.0 - pandas 1.3.0并在run脚本开头加入版本检查。从此再没人因为环境差异而卡住。5.3 高级避坑技巧关于cmake执行bash命令和codebuddy和workbuddy区别的真相热词里频繁出现cmake执行bash命令这其实是个美丽的误会。CMake 是一个构建系统它的execute_process命令确实可以执行 bash但那是为 C 项目服务的。WorkBuddy 的 Skill 机制是完全独立于 CMake 的另一套体系。你不需要、也不应该在SKILL.md里写 CMake 语法。WorkBuddy 的run字段就是 bash仅此而已。至于codebuddy和workbuddy区别这是社区里一个长期存在的混淆。CodeBuddy 是一个已停止维护的、基于 Node.js 的旧项目它用package.json定义命令。WorkBuddy 是它的精神继承者但用 Rust 重写核心理念从“代码助手”升级为“工作流引擎”SKILL.md就是它最鲜明的旗帜。如果你在网上搜到 CodeBuddy 的教程请果断忽略它们对 WorkBuddy 完全不适用。最后分享一个独家技巧如何快速克隆一个成熟的 SkillWorkBuddy 官方 GitHub 仓库https://github.com/workbuddy-org/skills里有一个examples/目录里面全是经过生产环境验证的 Skill 模板git-commit.md、docker-build.md、pdf-merge.md。你不需要从零开始curl -O https://raw.githubusercontent.com/workbuddy-org/skills/main/examples/git-commit.md下载一个然后sed -i s/git-commit/your-skill-name/g your-skill-name.md替换名字再根据你的需求修改run部分——5 分钟一个工业级 Skill 就诞生了。这才是真正的“从 0 到 1”。我在实际使用中发现最高效的 Skill 开发节奏是先用wb hello验证环境再找一个功能相近的官方例子curl下来最后只改run里的 3 行核心命令。这样你 90% 的时间都在思考“我要做什么”而不是“语法怎么写”。这才是自动化该有的样子。
返回列表