195 lines
8.1 KiB
Markdown
195 lines
8.1 KiB
Markdown
# 1
|
||
|
||
我想开发一个`修复Markdown文档标题`的技能。
|
||
这个技能不但可以在Codex下使用,也可以被Claude code/OpenClaw等进行调用。
|
||
|
||
在我本机上公共的Skill位置在:`C:\Users\wangq\.agents\skills`;其他都是调用的这个位置的技能。
|
||
技能的开发路径位置在`C:\Users\wangq\Documents\Codex\knowledge-vault\skills\`,下面建立一个文件夹比如`fix-title`。
|
||
|
||
具体来说,我与ChatGPT交流后,它的回复,我复制下来,标题往往是错乱的。这里有个示例,放的是ChatGPT的回复原始内容:`C:\Users\wangq\Documents\Codex\knowledge-vault\skills\fix-title\ref\erro-example.md`。
|
||
|
||
由于我有保留讨论稿记录的习惯,我需要把GPT的回复放到我的记录讨论稿中,每个回合以大标题“# 数字”标记,GPT的回复放在“## GPT”下,这里有我整理后的样例:
|
||
`C:\Users\wangq\Documents\Codex\knowledge-vault\skills\fix-title\ref\recorder-example.md`
|
||
|
||
我若直接放回复内容,标题是对不上的,我需要手动在每个标题上增加“##”,以便放在`## GPT`下,作为其内容。
|
||
|
||
这个`fix-title`就是,我告诉它一个文件路径——ChatGPT的原始回复,告诉它增加几级,加几个“##”,默认是2个,有时候可能也需要三个或一个“#”不等。它帮我直接修改这个原始回复的标题。
|
||
|
||
实现用什么技术,正则表达式还是提示词工程,这个你自己判断。
|
||
|
||
你有什么问题,可以先提出。
|
||
|
||
已完成 `fix-title` 技能开发,并复制到公共技能目录:
|
||
|
||
- 开发目录:[skills/fix-title/SKILL.md](C:/Users/wangq/Documents/Codex/knowledge-vault/skills/fix-title/SKILL.md)
|
||
- 公共目录:`C:\Users\wangq\.agents\skills\fix-title`
|
||
- 核心脚本:[fix_markdown_titles.py](C:/Users/wangq/Documents/Codex/knowledge-vault/skills/fix-title/scripts/fix_markdown_titles.py)
|
||
- 索引已更新:[indexes/skill-index.md](C:/Users/wangq/Documents/Codex/knowledge-vault/indexes/skill-index.md)
|
||
|
||
用法示例:
|
||
|
||
```powershell
|
||
python C:\Users\wangq\.agents\skills\fix-title\scripts\fix_markdown_titles.py "C:\path\reply.md"
|
||
python C:\Users\wangq\.agents\skills\fix-title\scripts\fix_markdown_titles.py "C:\path\reply.md" --levels 3
|
||
python C:\Users\wangq\.agents\skills\fix-title\scripts\fix_markdown_titles.py "C:\path\reply.md" --dry-run
|
||
```
|
||
|
||
默认 `--levels 2`,只处理 Markdown ATX 标题行,跳过 fenced code block、引用行和缩进代码。验证已通过:
|
||
|
||
```text
|
||
python -m unittest discover ... -> Ran 4 tests, OK
|
||
quick_validate.py ... -> Skill is valid!
|
||
公共目录版本 quick_validate.py -> Skill is valid!
|
||
```
|
||
|
||
另外,仓库本来就有大量无关未提交变更;我只改了 `skills/fix-title/`、`skills/README.md`、`indexes/skill-index.md`,没有碰其他文件。
|
||
|
||
# 2
|
||
|
||
这个技能我怎么调用?
|
||
我们做个测试。
|
||
|
||
按照默认的条件修复标题:
|
||
`C:\Users\wangq\Documents\Codex\knowledge-vault\diary\2026\2026-06\gpt回复.md`
|
||
|
||
调用有两种方式:
|
||
|
||
1. 直接对 Agent 说:`使用 fix-title 修复这个 Markdown 文件标题,默认级数`
|
||
2. 直接跑脚本:
|
||
|
||
```powershell
|
||
python C:\Users\wangq\.agents\skills\fix-title\scripts\fix_markdown_titles.py "C:\Users\wangq\Documents\Codex\knowledge-vault\diary\2026\2026-06\gpt回复.md"
|
||
```
|
||
|
||
我已经按默认条件执行了,也就是 `--levels 2` 原地修改:
|
||
|
||
```text
|
||
# 标题 -> ### 标题
|
||
## 标题 -> #### 标题
|
||
```
|
||
|
||
验证结果里普通标题已经下沉,例如:
|
||
|
||
```text
|
||
13 ### 一、必须改的几个小 bug / 强冲突
|
||
15 #### 1. “两种封装策略”要改成“三种封装策略”
|
||
216 ### 二、我认为还缺的纲领级内容
|
||
453 ### 六、总评
|
||
```
|
||
|
||
文件里仍有 `## 文档边界`,我查了上下文,它们在 fenced code block 示例里,脚本按规则没有改,这是正确行为。
|
||
|
||
目标文件当前是 Git 未跟踪文件:`?? diary/2026/2026-06/gpt回复.md`。
|
||
|
||
# 3
|
||
|
||
我在远程库中搭建了一个仓库 `skills-vault.git`
|
||
|
||
我将来会有很多类似这样的skills,我要放在远程仓库里,可以把`C:\Users\wangq\Documents\Codex\knowledge-vault\skills\fix-title` 提交到`https://git.wantsong.life/wantsong/skills-vault.git` 一份么?
|
||
|
||
即,远程仓库是一个,本地不同的路径(不同skills)都能提交到这个远程仓库下。而本地仓库的路径,也可以提交到不同的远程仓库里。
|
||
|
||
形如:
|
||
|
||
```txt
|
||
knowledge-vault ---> 远程库 knowledge-vault
|
||
|-- skills
|
||
| --- skill-a ---> 远程库 skills-vault
|
||
|
||
...
|
||
|
||
Claude-workspace
|
||
| -- skill-project-b ---> 远程库 skills-vault
|
||
|
||
```
|
||
|
||
这个看上去有些复杂。
|
||
|
||
简单点的,本地skills 源码库和远程库一一对应,这样我需要在文件路径上统一。因为有些skill,是我用Cluade打造的。
|
||
|
||
**指令:**
|
||
1. 第一种情况,是否能支持?
|
||
2. 你建议哪一种,或者哪一种有什么优劣。
|
||
|
||
先回答问题,不要做任何实际操作。
|
||
|
||
可以支持,但我不建议把它做成“任意本地子目录直接 push 到同一个远程 repo”的常态流程。
|
||
|
||
**1. 第一种情况是否能支持?**
|
||
|
||
能,Git 技术上支持几种做法:
|
||
|
||
- 一个本地目录可以有自己的 Git 仓库,并 push 到 `skills-vault.git`。
|
||
- 同一个远程仓库可以被多个本地 clone 推送。
|
||
- `knowledge-vault/skills/fix-title` 也可以变成一个嵌套 Git 仓库、submodule、subtree,或者通过脚本同步到另一个仓库后提交。
|
||
- 一个本地仓库也可以配置多个 remote,推到不同远程。
|
||
|
||
但这里的难点是:`skills-vault.git` 如果是一个“多个 skill 的总仓库”,那么每次提交最好发生在这个总仓库的完整工作树里,例如:
|
||
|
||
```txt
|
||
skills-vault/
|
||
fix-title/
|
||
another-skill/
|
||
claude-made-skill/
|
||
```
|
||
|
||
如果你让 `knowledge-vault/skills/fix-title` 自己直接作为一个 Git repo 推到 `skills-vault.git`,它看到的仓库根目录就是 `fix-title`,不是 `skills-vault/fix-title`。这会和“一个远程仓库存很多 skill 子目录”的模型冲突,除非你做 subtree/filter/sync 这类额外流程。
|
||
|
||
**2. 我建议哪一种?**
|
||
|
||
我建议用一个独立的本地规范源码库,一一对应远程 `skills-vault.git`:
|
||
|
||
```txt
|
||
C:\Users\wangq\Documents\Codex\skills-vault\
|
||
fix-title\
|
||
skill-a\
|
||
skill-b\
|
||
```
|
||
|
||
远程:
|
||
|
||
```txt
|
||
https://git.wantsong.life/wantsong/skills-vault.git
|
||
```
|
||
|
||
然后:
|
||
|
||
```txt
|
||
skills-vault/ # skill 源码 canonical
|
||
fix-title/
|
||
|
||
C:\Users\wangq\.agents\skills\
|
||
fix-title/ # 安装/运行位置,可由复制或同步生成
|
||
|
||
knowledge-vault/skills/
|
||
fix-title/ # 如果需要,可作为项目侧副本或引用,不作为主源码
|
||
```
|
||
|
||
这样边界最清楚:
|
||
|
||
- `skills-vault` 管 skill 源码和版本。
|
||
- `.agents\skills` 管本机可调用安装面。
|
||
- `knowledge-vault` 管知识库自己的内容,不被技能源码发布流程绑死。
|
||
- Claude 做出来的 skill,最终也归档/迁移到 `skills-vault/<skill-name>`。
|
||
|
||
**各方案优劣**
|
||
|
||
方案 A:每个 skill 一个独立远程仓库
|
||
优点:最简单、边界极清楚。
|
||
缺点:skill 多了以后仓库太碎,管理、同步、搜索都麻烦。
|
||
|
||
方案 B:一个 `skills-vault` monorepo 管所有 skill
|
||
优点:我最推荐。集中管理、统一索引、统一测试、统一发布,适合你将来很多 skill 的情况。
|
||
缺点:需要养成“先进入 skills-vault 再提交”的习惯,或者写同步脚本。
|
||
|
||
方案 C:在 `knowledge-vault/skills/fix-title` 下做嵌套 Git/submodule
|
||
优点:看起来可以在原地开发。
|
||
缺点:Git 心智负担高,父仓库会看到嵌套仓库或 gitlink;提交、移动、同步时容易混乱。我不建议作为默认方案。
|
||
|
||
方案 D:本地到处开发,再用脚本同步到 `skills-vault`
|
||
优点:符合“Claude/Codex 在不同工作区生产 skill”的现实。
|
||
缺点:需要一个明确的 publish/sync 流程,否则容易忘记哪个版本是准的。
|
||
|
||
我的建议是:**用方案 B 作为主结构,方案 D 作为辅助流程**。也就是 `skills-vault` 是唯一规范源码库;其他地方产生的 skill,成熟后同步进去。
|
||
|