1. 从零认识 knowledge-work-plugins:它到底解决什么问题
第一次看到knowledge-work-plugins这个仓库名,很多人会以为它只是某个工具的插件合集,随手 clone 下来翻两眼就丢到一边。但如果你真的在 Claude Code 或 Claude Cowork 里干过几天活,就会发现这个仓库解决的是一个非常具体的痛点:把散落在各个项目里的重复性知识工作流程,沉淀成可复用、可组合、可版本管理的插件单元。
说白了,它不是一个“工具”,而是一套工作方式的封装。你平时写周报、整理会议纪要、做竞品调研、生成 API 文档、批量重命名文件、把一堆 Markdown 转成结构化 JSON——这些活儿单次做不费劲,但每周都做、每个项目都做,就是纯消耗。knowledge-work-plugins的思路是:把这些流程写成插件,通过 slash commands 一键触发,让 Claude Code 在本地直接执行,而不是每次重新描述需求。
这个仓库适合三类人:第一类是每天和 Claude Code 打交道的开发者,想把自己的常用操作固化下来;第二类是团队里的效率负责人,想把团队的知识工作流程标准化;第三类是刚接触 Claude Code 的新手,想通过现成的插件快速理解这套工具的能力边界。不管你是哪一类,理解这个仓库的组织逻辑,比记住某一条命令重要得多。
我最初接触它的时候,正好在做一个需要频繁整理会议记录的项目。每次都要手动把录音转写文本丢给模型,再让它按固定格式输出。用了knowledge-work-plugins里的一个会议纪要插件之后,整个流程从“打开对话、粘贴、描述格式、等结果、复制”变成了“一条 slash command 加一个文件路径”。这个体验差异,就是它存在的意义。
2. 仓库整体设计与思路拆解
2.1 为什么是“插件”而不是“脚本”
很多人第一反应是:我写个 shell 脚本不也能干这些事吗?为什么要用插件?这个问题的答案藏在 Claude Code 的运行模型里。
普通脚本只能做确定性操作,比如“把 a 目录下所有 .txt 改成 .md”。但知识工作的特点是半结构化:你要从一段自然语言里提取行动项,要判断一份文档的语气是否合适,要把散乱的要点归纳成三层结构。这些事脚本做不了,必须交给模型。而knowledge-work-plugins的价值就在于,它把“模型调用”和“确定性操作”缝在了一起——插件里既有 prompt 模板,也有可执行的命令定义,Claude Code 在执行时会根据上下文决定调用哪一部分。
另一个原因是可组合性。脚本之间互相调用要靠参数传递和退出码,写多了就是一团乱麻。插件通过 slash command 暴露接口,每个插件只关心自己的输入输出,组合起来非常干净。比如你可以先跑一个“提取要点”插件,再把输出喂给“生成周报”插件,中间不需要写任何胶水代码。
2.2 目录结构背后的分层逻辑
一个典型的knowledge-work-plugins仓库通常长这样:
knowledge-work-plugins/ ├── plugins/ │ ├── meeting-notes/ │ │ ├── plugin.json │ │ ├── commands/ │ │ │ └── summarize.md │ │ └── prompts/ │ │ └── extract-actions.md │ ├── weekly-report/ │ │ ├── plugin.json │ │ └── commands/ │ │ └── generate.md │ └── doc-convert/ │ ├── plugin.json │ └── commands/ │ └── to-json.md ├── shared/ │ └── templates/ └── README.md这个结构不是随便定的。plugins/下每个子目录是一个独立插件,plugin.json是元数据清单,commands/放 slash command 定义,prompts/放可复用的 prompt 片段。shared/目录用来放跨插件共享的模板,避免每个插件都复制一份。
我特别想强调的是plugin.json这个文件。它看起来不起眼,但决定了插件能不能被 Claude Code 正确加载。里面至少要声明插件名、版本、作者、命令列表和依赖关系。很多人第一次写插件时忘了写commands字段,结果 slash command 死活出不来,排查半天才发现是清单没写全。
2.3 与 Claude Code 的集成方式
knowledge-work-plugins不是独立运行的程序,它依赖 Claude Code 的插件加载机制。Claude Code 在启动时会扫描配置目录下的插件路径,读取每个插件的plugin.json,然后把里面定义的 slash command 注册到命令系统里。
这里有个容易踩的坑:插件路径的配置方式在不同平台上不一样。在 macOS 和 Linux 上,通常是放在~/.claude/plugins/下;在 Windows 上,路径里如果有空格或者中文,加载就会失败。我见过有人把插件放在C:\Users\张三\我的文档\下面,结果 Claude Code 一直报 “failed to load plugins”,换成纯英文无空格路径就正常了。
提示:插件目录路径尽量用纯英文、无空格、无特殊字符。这不是 Claude Code 的 bug,而是很多命令行工具在处理路径时的通病。
3. 核心细节解析与实操要点
3.1 plugin.json 的关键字段怎么写
plugin.json是整个插件的入口,写错了后面全白搭。一个最小可用的清单大概是这样:
{ "name": "meeting-notes", "version": "1.0.0", "description": "从会议转写文本中提取要点和行动项", "author": "your-name", "commands": [ { "name": "summarize", "description": "生成会议纪要", "file": "commands/summarize.md" } ], "dependencies": [] }几个字段的坑我逐个说。name必须和目录名一致,不一致的话 Claude Code 会按目录名找命令,但元数据里显示的是另一个名字,排查起来很迷惑。version建议用语义化版本,因为后续如果要做插件更新,版本号是判断依据。commands数组里每个对象的file路径是相对于插件根目录的,不要写成绝对路径。
dependencies字段目前用得不多,但如果你写的插件依赖另一个插件提供的 prompt 模板,就要在这里声明。我建议即使没有依赖也保留这个空数组,方便后续扩展。
3.2 slash command 的定义规范
commands/summarize.md这个文件的内容,决定了用户输入/summarize之后发生什么。它的写法不是普通的 Markdown,而是一种带 frontmatter 的模板:
--- description: 从会议记录中提取要点 arguments: - name: input description: 会议转写文本文件路径 required: true --- 请阅读以下会议记录,提取三个部分的内容: 1. 核心结论(不超过5条) 2. 待办事项(包含负责人和时间节点) 3. 需要进一步讨论的问题 会议记录内容: {{input}}这里的{{input}}是参数占位符,Claude Code 会把用户传入的文件内容替换进去。arguments里定义的参数会在用户输入命令时提示补全。
我实测下来,参数描述写得越具体,模型执行越准。比如你把input描述成“文件路径”,模型就知道要去读文件;如果你只写“输入”,它可能会把用户输入的字面量当成内容。这个细节看起来小,但直接影响插件的可用性。
3.3 prompt 模板的复用策略
prompts/目录下的文件是可复用的 prompt 片段。比如你有一个“提取行动项”的 prompt,会议纪要插件要用,周报插件也要用,那就把它抽到prompts/extract-actions.md里,两个插件都引用它。
引用的方式是在 command 文件里用{{include: prompts/extract-actions.md}}。这个机制的好处是,当你发现行动项提取的 prompt 需要优化时,只改一个地方,所有引用它的插件都生效。
但这里有个优先级问题:如果 command 文件里既有{{include}}又有直接写的 prompt,Claude Code 会先展开 include,再拼接直接写的部分。所以你要注意顺序,别让两段 prompt 互相矛盾。
3.4 参数传递与文件读取的边界
Claude Code 在执行 slash command 时,对文件读取是有权限控制的。默认情况下,它只能读取当前工作目录下的文件。如果你的插件需要读取目录外的文件,要么在命令里显式指定绝对路径,要么在 Claude Code 的配置里放开权限。
我踩过的一个坑是:插件里写了{{input}},用户传了一个~/Documents/meeting.txt,结果报错说文件不存在。原因是~在 Claude Code 的解析上下文里没有被展开成用户主目录。解决办法是让用户传绝对路径,或者在 command 定义里加一段预处理逻辑,把~替换掉。
注意:涉及文件路径的参数,最好在文档里明确写“请使用绝对路径”,减少用户的试错成本。
4. 实操过程与核心环节实现
4.1 环境准备:Claude Code 的安装与插件目录确认
在动手写插件之前,先把 Claude Code 装好。不同平台的安装方式不一样,我按我实际用过的顺序说。
macOS 上,如果你用 Homebrew,可以直接brew install claude-code。但更推荐的方式是从官方渠道下载安装包,因为 Homebrew 的版本更新有时滞后。安装完之后,在终端输入claude,如果看到欢迎信息和版本号,说明装好了。
Windows 上,建议用 WSL2 环境,因为 Claude Code 的很多插件机制在纯 Windows 环境下路径处理会有问题。我试过在 Win11 原生环境跑,插件加载成功率大概只有七成,换到 WSL2 之后基本没出过问题。
Ubuntu 上,安装完之后要确认~/.claude/目录存在。如果不存在,手动创建:
mkdir -p ~/.claude/plugins然后把knowledge-work-plugins仓库 clone 到本地,把plugins/下的子目录复制或软链接到~/.claude/plugins/下。
git clone https://github.com/your-org/knowledge-work-plugins.git cd knowledge-work-plugins ln -s $(pwd)/plugins/meeting-notes ~/.claude/plugins/meeting-notes用软链接的好处是,你在仓库里改了插件内容,Claude Code 下次启动就能直接生效,不用反复复制。
4.2 写第一个插件:从会议纪要开始
我拿会议纪要插件举例,完整走一遍流程。
第一步,创建目录结构:
mkdir -p ~/.claude/plugins/meeting-notes/commands mkdir -p ~/.claude/plugins/meeting-notes/prompts第二步,写plugin.json:
{ "name": "meeting-notes", "version": "1.0.0", "description": "会议纪要生成插件", "author": "me", "commands": [ { "name": "summarize", "description": "从会议转写文本生成结构化纪要", "file": "commands/summarize.md" } ], "dependencies": [] }第三步,写commands/summarize.md:
--- description: 生成会议纪要 arguments: - name: input description: 会议转写文本的绝对路径 required: true --- 你是一名专业的会议记录整理助手。请阅读以下会议转写文本,输出三部分内容: ## 核心结论 用不超过5条要点概括本次会议达成的共识。 ## 待办事项 以表格形式列出,包含:事项、负责人、截止时间。如果原文没有明确负责人或时间,标注“待确认”。 ## 待讨论问题 列出会议中没有形成结论、需要后续跟进的问题。 会议转写文本: {{input}}第四步,重启 Claude Code,输入/summarize,如果能看到命令提示,说明插件加载成功。
4.3 参数计算与选择:为什么用绝对路径
这里展开说一下为什么我坚持让用户传绝对路径。Claude Code 在执行命令时,工作目录可能是项目根目录,也可能是用户上次所在的目录。如果用户传相对路径,模型解析时依赖当前工作目录,一旦目录变了,文件就找不到了。
绝对路径虽然写起来长,但确定性高。我通常会在插件的 README 里给一个示例:
/summarize /Users/yourname/Documents/meeting-2024-01-15.txt用户照着改一下用户名和文件名就行,比让他们理解相对路径的解析规则简单得多。
4.4 实测记录:从输入到输出的完整链路
我拿一段真实的会议转写文本测试。输入是一个 3000 字左右的转写稿,包含多人对话、口语化表达和一些重复内容。
执行/summarize /path/to/meeting.txt之后,Claude Code 先读取文件,然后把内容填充到 prompt 模板里,再调用模型生成结果。整个过程大概 15 到 30 秒,取决于文本长度和模型响应速度。
输出结果里,核心结论部分提炼得比较准,待办事项表格也能正确识别“张三负责”、“下周三之前”这类信息。但有一个问题:原文里有一句“这个事让小李跟进一下”,模型把负责人写成了“小李”,但原文没有明确小李的全名。这种情况下,我在 prompt 里加了一句“如果负责人只有名字没有全名,保留原文称呼”,输出就符合预期了。
这个迭代过程说明,插件不是一次写完就完事的,要根据实际输出反复调 prompt。我一般会攒够五到十个真实案例,再统一优化一次 prompt,避免过度拟合单个案例。
5. 常见问题与排查技巧实录
5.1 插件加载失败的排查顺序
“failed to load plugins” 是最高频的问题。我整理了一个排查顺序,按这个顺序走,基本能定位到原因。
| 排查步骤 | 检查内容 | 常见问题 |
|---|---|---|
| 1 | 插件目录路径 | 含空格、中文、特殊字符 |
| 2 | plugin.json 语法 | 缺少逗号、引号不匹配 |
| 3 | commands 字段 | 文件路径写错或文件不存在 |
| 4 | 文件权限 | 插件目录没有读权限 |
| 5 | Claude Code 版本 | 版本过旧不支持插件机制 |
我遇到最多的是第 2 条。JSON 文件里多一个逗号或者少一个引号,整个插件就加载不了,而且报错信息不会告诉你具体哪一行有问题。建议写完plugin.json之后,用python -m json.tool plugin.json验证一下语法。
5.2 slash command 不出现的三种原因
命令加载成功但 slash command 不出现,通常是这三个原因:
第一,plugin.json里的commands数组为空或者没写。Claude Code 只注册清单里声明的命令,没声明就不会出现在提示里。
第二,command 文件的 frontmatter 格式不对。---必须是文件的第一行,前面不能有空行。我有一次在---前面多敲了一个回车,命令就死活出不来。
第三,命令名和已有命令冲突。比如你定义了一个叫help的命令,和 Claude Code 内置的冲突,就会被忽略。建议命令名加个前缀,比如kw-summarize,避免冲突。
5.3 模型输出不稳定的应对策略
同一个插件,同样的输入,两次输出可能不一样。这是模型本身的特性,不是插件的问题。但你可以通过几个手段降低波动:
- 在 prompt 里明确输出格式。比如“用 Markdown 表格输出”、“每条不超过 20 字”,约束越具体,输出越稳定。
- 降低 temperature。如果 Claude Code 的配置里能调 temperature,把它调到 0.2 以下,输出会稳定很多。
- 加 few-shot 示例。在 prompt 里给一两个输入输出示例,模型会照着示例的风格走。
我实测下来,加 few-shot 示例对稳定性的提升最明显,但代价是 prompt 变长,响应时间会增加。折中方案是只给一个示例,且示例尽量短。
5.4 插件之间的依赖管理
当你有多个插件,且它们共享 prompt 模板时,依赖管理就变得重要。我的做法是:
- 把共享模板放在
shared/prompts/下 - 每个插件的
plugin.json里声明dependencies,指向共享模板所在的插件 - 在 command 文件里用相对路径引用共享模板
但这里有个限制:Claude Code 目前对跨插件引用的支持还不完善,如果共享模板所在的插件没加载,引用就会失败。所以我的建议是,初期尽量让每个插件自包含,等插件数量多了再考虑抽共享层。
5.5 权限与安全边界
Claude Code 执行插件时,会调用文件读写和命令执行。如果你写的插件涉及删除文件、修改系统配置这类操作,一定要在 prompt 里加确认步骤,或者限制操作范围。
我见过有人写了一个“批量重命名”插件,prompt 里直接让模型执行mv命令,结果模型理解错了规则,把一批文件改得面目全非。后来改成先生成重命名方案,让用户确认后再执行,就安全多了。
提示:涉及文件修改的插件,建议采用“先生成方案,再执行”的两段式设计。多一步确认,少一堆麻烦。
6. 进阶玩法:把插件组合成工作流
6.1 串联多个 slash command
单个插件解决单点问题,多个插件串联起来就能解决一整条工作流。比如“会议纪要”插件生成纪要后,可以接着跑“周报生成”插件,把本周所有会议纪要汇总成周报。
串联的方式有两种。一种是在 Claude Code 里手动依次执行命令,适合低频场景。另一种是写一个“编排”插件,在 prompt 里调用其他插件的输出。后者的实现方式是在 command 文件里用{{include}}引入其他插件的 prompt,然后组合成一个新的流程。
我目前用的是手动串联,因为编排插件的调试成本比较高,而且一旦某个环节的输出格式变了,整个链路都要跟着改。等插件稳定下来之后,再考虑自动化编排。
6.2 用插件封装团队规范
团队里每个人写周报的格式不一样,汇总的时候很头疼。用插件可以把格式规范固化下来:定义一个weekly-report插件,prompt 里明确规定周报的章节、每节的字数范围、必须包含的字段。团队成员只需要输入原始素材,输出就是统一格式。
这个做法的好处是,规范不是靠文档传达的,而是靠工具强制的。新人入职第一天,装上插件,写出来的周报就符合团队要求,省去了大量沟通成本。
6.3 插件的版本管理与分发
插件写多了之后,版本管理就成了问题。我的做法是:
- 每个插件独立版本号,遵循语义化版本
- 用 Git 管理插件仓库,每次修改 prompt 都提交一次
- 在
plugin.json的description里写清楚这个版本改了什么
分发方面,如果团队内部用,直接共享 Git 仓库,大家 clone 下来软链接到插件目录就行。如果要对外发布,建议打包成压缩包,附上安装说明,因为不是所有人都会用 Git。
6.4 从插件到技能的演进路径
Claude Code 除了插件机制,还有 skills 的概念。两者的区别是:插件偏重命令和流程,skills 偏重能力和知识。一个成熟的插件,如果积累了大量领域知识,可以考虑拆出一部分做成 skill,让模型在对话中自动调用,而不是等用户输入 slash command。
我目前的策略是:高频、固定流程的操作做成插件;低频、需要灵活判断的知识做成 skill。两者配合使用,覆盖大部分知识工作场景。
7. 我踩过的坑和给你的建议
写插件这件事,看起来简单,实际上细节很多。我把自己踩过的坑列一下,你对照着检查,能省不少时间。
第一个坑是prompt 写得太笼统。一开始我写“请总结这段文字”,结果模型输出的详略程度完全看心情。后来改成“用不超过 5 条要点总结,每条不超过 30 字”,输出就稳定了。prompt 里的每一个约束,都是在缩小模型的发挥空间,让它更可控。
第二个坑是忽略文件编码。有一次处理一个 GBK 编码的文本文件,模型读出来全是乱码。后来在插件里加了一步编码检测和转换,才解决问题。如果你处理的文件来源复杂,建议在 prompt 里加一句“如果文件编码不是 UTF-8,先转换再处理”。
第三个坑是命令名太长。我一开始把命令名写成generate-meeting-summary-from-transcript,每次输入都要打一长串。后来改成ms,效率高多了。命令名短一点,用起来才顺手。
第四个坑是没有写 README。插件写完过了一个月,自己都忘了参数怎么传。后来每个插件都配一个 README,写清楚用途、参数、示例,回头看的时候一目了然。
最后一个建议:从最简单的插件开始。不要一上来就写复杂的多步骤工作流,先写一个单命令、单参数的插件,跑通了再逐步加功能。我见过太多人一开始就设计了一个庞大的插件体系,结果卡在第一个插件的加载问题上,就再也没继续下去。
插件这东西,价值在于用起来。写得再漂亮,不用就是一堆 Markdown 文件。先跑起来,再优化,这是我做了几十个插件之后最深的体会。