228 lines
14 KiB
Markdown
228 lines
14 KiB
Markdown
# 1
|
||
|
||
这里有个需求单:
|
||
[llm-markdown-intake-normalizer.md](<C:\Users\wangq\Documents\Codex\video-workbench\requirements\skills-vault\llm-markdown-intake-normalizer.md>)
|
||
|
||
我们之前打造了`fix-title`,但是这个技能不好用,必须由我指定从哪开始,下沉几层,不智能。
|
||
打造`fix-title`的主要原因就是ChatGPT回复后,复制出来的标题错乱;同时我还有记录讨论过程的习惯:
|
||
|
||
```md
|
||
|
||
# 1 --- 表示第一个回合
|
||
|
||
xxx --- 我的输入
|
||
|
||
## GPT --- 表示第一个回合 GPT的回复
|
||
|
||
### --- GPT回复就需要默认从三个###开始了,这样有下沉的需求
|
||
|
||
```
|
||
|
||
现在发现,GPT回复时,有时候用一个`#`,有时候用`##`不稳定;而且出现了`##` 后面继续用`#`的情况。
|
||
这不是python代码能解决的,必须有语义理解。
|
||
|
||
---
|
||
|
||
我期望,将fix-title升级成具有语义理解能力的skill,可以真正修复标题。
|
||
|
||
谈谈你对问题的理解,有什么问题?
|
||
|
||
我理解这个问题不是“标题下沉”,而是“把 GPT 输出重新还原成可用文档结构”。现有 [fix-title](</C:/Users/wangq/Documents/Codex/skills-vault/skills/fix-title/SKILL.md>) 只是固定把 `#` 加深几层,适合简单粘贴块;但你现在遇到的是 GPT 自己在一个回复里混用 `#`、`##`、`###`,甚至后面又跳回 `#`。这必须判断“这个标题在语义上是文档标题、一级章节、子章节、另一个 artifact,还是助手废话”,不能靠统一加 `##` 解决。
|
||
|
||
我会把需求拆成两个层次:
|
||
|
||
1. `fix-title` 的真实升级目标:修复“讨论记录里的 GPT 回复”
|
||
- 外层 `# 1`、`## GPT` 是记录结构,不能动。
|
||
- GPT 回复内部默认应从 `###` 开始。
|
||
- 如果回复里出现 `# 一、...`、`## 1. ...`、后面又 `# 二、...`,要按语义重排为 `###/####/#####`。
|
||
- 这类场景更像“semantic heading repair”。
|
||
|
||
2. [需求单](</C:/Users/wangq/Documents/Codex/video-workbench/requirements/skills-vault/llm-markdown-intake-normalizer.md>) 的更大目标:清洗 `video-workbench` 的 GPT intake
|
||
- 不只修标题,还要识别助手闲聊、重复粘贴、多 artifact 拼接、非 canonical 内容。
|
||
- 输出应是 `intake-clean/` 和 cleaning report,而不是直接改原始 `intake/`。
|
||
- 这更像新 Skill:`normalize-llm-markdown-intake`。
|
||
|
||
我的技术判断:不是“完全不能用 Python”,而是不能让 Python 独立做语义判断。合理架构应该是混合式:
|
||
|
||
- Python 负责安全解析、保护代码块/表格/引用、列出 heading map、执行确定性改写、生成 diff/report。
|
||
- Codex/LLM 负责语义判断:哪个标题是真标题、哪个是章节、哪个是新 artifact、哪个是助手过渡语。
|
||
- Skill 负责规定流程、模式、输出约束和人工确认门槛。
|
||
|
||
关键问题是:要不要把这两个场景放进同一个 `fix-title`?我的倾向是不要硬塞。保留 `fix-title` 作为低层工具,新增或重命名一个语义 Skill 更稳;否则 `fix-title` 这个名字会误导未来 Codex 继续把它当“标题加深脚本”。
|
||
|
||
我现在最需要你定的是一个边界问题:你希望这次优先解决哪一个?
|
||
|
||
- A. 升级 `fix-title`,主攻“讨论记录中 GPT 回复标题错乱”的语义修复。
|
||
- B. 按需求单新建 `normalize-llm-markdown-intake`,主攻 `video-workbench/projects/*/intake/` 的批量清洗。
|
||
- C. 两者都做:`fix-title` 变成低层兼容工具,新 Skill 调用/复用它,但用户以后主要用新 Skill。
|
||
|
||
我推荐 C,但第一轮实现应以 B 的需求单为验收主线,顺手把 `fix-title` 标记成低层工具或兼容入口。这样不会继续在一个名字很小的 Skill 里堆一个很大的语义清洗系统。
|
||
|
||
# 2
|
||
|
||
旧的`fix-title` 没有被用起来,这个技能已经没有存在的意义了。
|
||
|
||
我做了两个样例文件,一个是讨论稿,一个是成果稿/intake稿,及这两个稿子的修复稿,你可以对比着看:
|
||
* 讨论稿,有问题的:`C:\Users\wangq\Documents\Codex\knowledge-vault\discussions\technology\Codex\4.Skills\fix-title\fix文档标题样例-讨论稿.md`
|
||
* 讨论稿,修复后的:`C:\Users\wangq\Documents\Codex\knowledge-vault\discussions\technology\Codex\4.Skills\fix-title\fix文档标题样例-讨论稿-fixed.md`
|
||
|
||
* 成果稿,有问题的:`C:\Users\wangq\Documents\Codex\knowledge-vault\discussions\technology\Codex\4.Skills\fix-title\fix文档标题样例-intake稿.md`
|
||
* 成果稿,修复后的:`C:\Users\wangq\Documents\Codex\knowledge-vault\discussions\technology\Codex\4.Skills\fix-title\fix文档标题样例-intake稿-fixed.md`
|
||
|
||
在样例文件中,只放了二级标题的错误及修复,这个是递归的,所有下面的子标题都需要修复,这个必须要有语义理解能力,纯python这种干不了。
|
||
|
||
---
|
||
|
||
你先更深刻的理解问题。
|
||
|
||
我看完四个样例后,问题比“标题级别错了”更准确地说是:
|
||
|
||
**GPT 粘贴文本丢失了它本来应该服从的容器结构,导致 Markdown 的 `#` 层级不能直接信任。**
|
||
|
||
在讨论稿里,真实结构是:
|
||
|
||
```md
|
||
# 回合
|
||
## 用户/任务/指令
|
||
## GPT
|
||
### GPT 回复里的一级内容
|
||
#### GPT 回复里的二级内容
|
||
```
|
||
|
||
所以 [讨论稿样例](</C:/Users/wangq/Documents/Codex/knowledge-vault/discussions/technology/Codex/4.Skills/fix-title/fix文档标题样例-讨论稿.md>) 里,`## GPT` 后面的 `## 1.xxxx` 实际不是和 `## GPT` 平级,而是 `## GPT` 的子内容,修复后变成 `### 1.xxxx`。第二回合里更明显:原文 `# 1.xxxx`、`# 2.xxx`、`## 3.xxx` 三个在语义上都是 GPT 回复内部的同级章节,所以修复后统一为 `###`,而不是保留原始的 `# / ##` 差异。
|
||
|
||
在 intake/成果稿里,真实结构变成:
|
||
|
||
```md
|
||
# 文档根标题
|
||
## 成果稿内部一级章节
|
||
### 成果稿内部二级章节
|
||
```
|
||
|
||
所以 [intake 样例](</C:/Users/wangq/Documents/Codex/knowledge-vault/discussions/technology/Codex/4.Skills/fix-title/fix文档标题样例-intake稿.md>) 中同样的 `# 1.xxxx`,正确目标不是 `###`,而是 `##`。这说明同一个原始标题错误,在不同文档模式下有不同修复结果。旧 `fix-title` 的固定加深模型天然不可能成立。
|
||
|
||
我现在的深层理解是:这个 Skill 要做的不是“修改标题符号”,而是先判断文档类型和语义容器,再重建标题树。
|
||
|
||
核心规则应该是:
|
||
|
||
- 讨论稿:保护外层记录结构,比如 `# 1`、`# 2`、`## 任务`、`## 指令`、`## GPT`;只修复 GPT 回复块内部标题。
|
||
- intake/成果稿:保护唯一文档根标题;把后续误用的 `#` 修复为根标题下的章节。
|
||
- 原始 `#` 数量只是弱信号,不能当真;编号、段落位置、容器标题、上下文语义才是主信号。
|
||
- 修复必须递归:一旦判断某个标题是父级,它下面的子标题也要按新的父级重新挂载。
|
||
- 不能只做“整体下沉 N 级”,因为有些标题需要下沉,有些需要保持,有些甚至要从错误的子级拉平成同级。
|
||
- Python 可以负责保护代码块、扫描标题、生成 diff/report,但最终“这个标题语义上属于哪一层”必须由 Codex/LLM 判断。
|
||
|
||
这也意味着旧 `fix-title` 确实可以废掉。它解决的是一个不存在的理想化问题:假设 GPT 输出只差一个固定偏移量。真实问题是 GPT 输出的标题树本身不可信,需要语义重建。
|
||
|
||
我还有一个关键问题:未来成果稿/intake 稿里,如果开头是 `# GPT的回复`,你希望默认保留它作为根标题,还是当正文里出现更真实的 artifact 标题时,把根标题替换成那个 artifact 标题?这个会影响 Skill 的默认修复策略。
|
||
|
||
# 3
|
||
|
||
我给的样例稿子,实际上做了简化——缺少内容,只能通过标题;而GPT的回复是上下文紧密关联的,不然人也没法判别了。
|
||
所以粗浅的上下文语义理解上,LLM做起来没问题。
|
||
|
||
> 未来成果稿/intake 稿里,如果开头是 `# GPT的回复`
|
||
|
||
这种可能性不存在,intake稿都是我手工放进去的;而`# GPT的回复` 是我手工加的。
|
||
如果确实出现了,那就按成果稿的逻辑,该咋办咋办——默认最上面是文档标题,全部修复一遍;即使错了,也是我的问题,skill不背锅。
|
||
|
||
我放了两个文档,这个都是真实的文档,供你将来测试用:
|
||
* 讨论稿:`C:\Users\wangq\Documents\Codex\skills-vault\tmp\测试用-在路上-策划导演.md`
|
||
* 成果稿:`C:\Users\wangq\Documents\Codex\skills-vault\tmp\测试用-阶段三-MV 总纲.md`
|
||
|
||
这个skill,可以跑这两个文档,测试结果也放到`tmp/`下,不要覆盖原文档,我可以人工配合检查。
|
||
|
||
---
|
||
|
||
还有问题么,可以开始重构这个fix-title了么?
|
||
|
||
可以,已经重构完并安装到可用 Skill 面了。
|
||
|
||
旧的固定下沉脚本已移除,`fix-title` 现在改成“语义判断 + 安全执行”的模式:Codex 先读全文判断讨论稿/成果稿结构,再写一份 line-level JSON heading plan,脚本只按计划改标题层级、保护 fenced code block、输出 fixed 文件和 report。核心文件是 [SKILL.md](</C:/Users/wangq/Documents/Codex/skills-vault/skills/fix-title/SKILL.md>) 和 [semantic_heading_repair.py](</C:/Users/wangq/Documents/Codex/skills-vault/skills/fix-title/scripts/semantic_heading_repair.py>)。
|
||
|
||
我也把安装面同步了:`C:\Users\wangq\.agents\skills\fix-title`。旧安装版备份到了:
|
||
`C:\Users\wangq\.agents\skills\fix-title.backup-20260623121809`
|
||
|
||
样例输出放在 `tmp/`,没有覆盖原文件:
|
||
|
||
- 讨论稿 fixed: [测试用-在路上-策划导演.fixed.md](</C:/Users/wangq/Documents/Codex/skills-vault/tmp/测试用-在路上-策划导演.fixed.md>)
|
||
- 讨论稿 report: [测试用-在路上-策划导演.heading-report.md](</C:/Users/wangq/Documents/Codex/skills-vault/tmp/测试用-在路上-策划导演.heading-report.md>)
|
||
- 成果稿 fixed: [测试用-阶段三-MV 总纲.fixed.md](</C:/Users/wangq/Documents/Codex/skills-vault/tmp/测试用-阶段三-MV 总纲.fixed.md>)
|
||
- 成果稿 report: [测试用-阶段三-MV 总纲.heading-report.md](</C:/Users/wangq/Documents/Codex/skills-vault/tmp/测试用-阶段三-MV 总纲.heading-report.md>)
|
||
|
||
验证结果:
|
||
|
||
- `conda run -n skills-vault python -B -m unittest discover -s skills\fix-title\tests -v` 通过,4 个测试。
|
||
- `conda run -n skills-vault python -B scripts\quick_validate.py skills\fix-title` 通过。
|
||
- `git diff --check` 没有 whitespace error,只有 Windows CRLF 提示。
|
||
- 样例结构检查:成果稿 fixed 只剩 1 个真实 H1;讨论稿 fixed 只剩 `# 1 / # 2 / # 3` 三个回合 H1。
|
||
|
||
有一个真实样例细节:讨论稿后段有 fenced Markdown 示例边界不稳定,部分示例标题被 Markdown 解析成了正文标题。我按“仍属于第 3 回合 GPT 回复”的语义修了可见标题;代码块内部标题没有动。
|
||
|
||
# 4
|
||
|
||
我检查了修复的结果,很满意。
|
||
|
||
我有个问题,修文档这个:
|
||
1. 之前python,不占用会话窗口
|
||
2. 现在LLM,会占用会话窗口,而且这个又比较独立,不依赖于上下文
|
||
1. 我们是否可以包装成一个独立的子会话或子Agent,还是必须调用方自己做?
|
||
2. 在输入时可以允许调用方传入文件数组
|
||
|
||
我们还需要做后续的一些完善:
|
||
1. 之前的fix-title是支持Cli的,我觉得这次,输入1文件路径数组,输入2是成果/还是讨论稿,就够了吧
|
||
2. 配套的规则、说明等完善
|
||
|
||
没有新的阻塞问题,可以开始做二期。
|
||
|
||
我的判断:
|
||
|
||
1. 可以包装成子 Agent,而且应该这么做。
|
||
这个任务上下文独立、会消耗窗口、产物也清晰,适合“主会话薄调度,子 Agent 修文档”。当前 Codex 也确实有 `spawn_agent` 能力,所以 Skill 可以写成:如果调用环境支持子 Agent,默认把批量修复委派出去;主会话只传 `files[] + mode + output_dir`,最后验收 fixed/report。
|
||
|
||
2. CLI 仍然要保留,但不能假装纯 Python 能完成语义修复。
|
||
更准确的 CLI 分两层:
|
||
- Python CLI:批量 inspect、生成 heading-map、应用 JSON plan、产出 report。
|
||
- Agent CLI/Skill 入口:接受 `files[]` 和 `mode=discussion|artifact`,由 LLM/子 Agent 读文档并写 plan,再调用 Python CLI 落盘。
|
||
|
||
我建议二期设计这样落:
|
||
|
||
- `SKILL.md` 增加 “Batch / Delegated Workflow”:
|
||
- 输入:文件路径数组、模式、输出目录。
|
||
- 默认不覆盖原文。
|
||
- 如果支持子 Agent,主会话生成一个委派 prompt,让子 Agent 完成修复。
|
||
- 如果不支持子 Agent,当前调用方自己执行同一流程。
|
||
|
||
- `semantic_heading_repair.py` 增加批量辅助命令:
|
||
- `inspect-batch --mode discussion|artifact --output-dir ... file1.md file2.md`
|
||
- 为每个文件生成 heading map 和 plan 模板。
|
||
- 保留 `apply` 的严格校验。
|
||
|
||
- 规则完善:
|
||
- 讨论稿:保护回合标题和用户区,只修 GPT 回复块。
|
||
- 成果稿:首个 H1 默认是文档标题,后续递归修。
|
||
- 子 Agent 产物必须包括 fixed 文件、heading report、计划 JSON。
|
||
- 主会话不得把“子 Agent 说修好了”当证据,必须看文件/报告。
|
||
|
||
如果你确认这个设计,我下一步直接改:测试先行,补 batch CLI、补 Skill 子 Agent 委派规则、再跑你那两个样例回归。
|
||
|
||
# 5
|
||
|
||
我实际使用skill,都是Agentic:
|
||
* VS Code Copilot
|
||
* Cluade Code
|
||
* Codex
|
||
* OpenClaw
|
||
|
||
CLI 只保留Agent Cli即可。去掉python Cli
|
||
|
||
> 如果支持子 Agent,主会话生成一个委派 prompt,让子 Agent 完成修复。
|
||
> 如果不支持子 Agent,当前调用方自己执行同一流程。
|
||
|
||
增加上子会话(Thread),这个也可以避免会话窗口撑爆;Codex也支持这种方式。
|
||
|
||
其他都同意。
|
||
|
||
可以继续了。
|
||
|