给 AI 写的 Markdown 做批注:CriticMarkup、MarkMark 和 Windows 工作流
最近用 Codex 写文档、方案和博客草稿时,有一个反馈动作越来越别扭:我明明是在改一篇 Markdown,却经常要回到聊天框里写「第 37 行那句话删掉」「第 52 行改成另一种说法」。
这套反馈方式把文章当成代码补丁来处理。文章里的问题常常落在段落、证据、标题和例子上:一段表达方向不对,一个概念需要补证据,一个标题该收紧,一个例子该换掉。只用行号描述,反馈者要费力定位,Agent 也要重新理解上下文。行号成了中间损耗。
MarkMark 给我的启发,是把「批注」变成 Markdown 文件里的可读文本协议。人直接在文章上标,AI 直接读这些标记,再把文章改回干净版本。反馈不需要旁边另写一套说明,修改意图已经嵌在原文里。
让模型读到批注
很多写作工具已经能批注。AI 协作更看重另一件事:标完以后,模型能不能完整读懂这些批注。
Google Docs、Word、飞书文档这类工具的批注体验很好,但批注通常存在文档模型或云端协作层里。要把它交给 Codex,就需要导出、复制、截图,或者让模型读一个带格式的中间文件。这个过程一复杂,日常反馈又会退回到聊天框里的行号和口述。
Markdown 的优势在这里反而很朴素:它本来就是纯文本。只要批注也是纯文本,文件本身就能成为沟通介质。
CriticMarkup 做的正是这件事。它把常见审阅动作写成几种内联标记:
{++新增文字++}
{--删除文字--}
{~~旧文字~>新文字~~}
{==需要注意的文字==}{>>这里补一句为什么<<}
{>>单独评论<<}这些标记对人来说还能读,对 Git 来说还是普通 diff,对 AI 来说也很容易解释。你不需要额外数据库、隐藏元数据或截图 OCR。文件里已经同时包含原文、修改建议和评论。
MarkMark 的关键设计
MarkMark README 将它定位为 macOS Markdown 阅读器,并在阅读器上加了 CriticMarkup 审阅流程。你在渲染后的页面里选中文字,可以做删除、替换、评论、高亮,然后一键复制「引导提示词 + 带 CriticMarkup 标注的全文」交给 AI。
我读源码时更在意它的中间链路。用户不必在源码 Markdown 里手写 {~~ ~> ~~},批注入口放在渲染视图里:
- Markdown 先被渲染到
WKWebView。 - 前端脚本捕获选区,并把选中文本、行号或附近上下文传回 Swift 层。
- Swift 的文档模型把这次动作转换成 CriticMarkup。
- 源 Markdown 被写入批注标记。
- 导出时把说明 prompt 和完整标注文档一起放进剪贴板。
这条链路把应用状态压到最低。MarkMark 负责选区、浮层和预览,文件里留下 CriticMarkup 文本;换一个编辑器或模型,批注仍然能被读到。
这次查阅时,MarkMark 的 README 要求 macOS 14.0 或更高版本,release 页可见的版本是 v2.0.19。下面的 Windows 工具清单也属于这次调研;安装前仍应确认扩展支持、维护状态和权限,不把这份记录当成永久推荐。
Windows 上能用什么
我按「能不能真的支持 AI 文稿审阅」这个标准看了一圈,最值得优先试的是 VS Code。
| 编辑器 | 可选工具 | 适合程度 | 判断 |
|---|---|---|---|
| VS Code | MarkReview | 高 | 直接面向「Markdown 审阅 + AI 辅助编辑」,支持 CriticMarkup、侧边栏管理、导出 AI prompt 和清理/接受批注,跟这个需求非常接近。 |
| VS Code | Review Markup Sidebar | 高 | 支持 Markdown CriticMarkup 和 LaTeX changes,侧边栏能列出批注、跳转、创建、删除、替换,文件变化也能实时反映,适合把审阅当成日常编辑动作。 |
| VS Code | CriticMarkup for Visual Studio Code | 中 | 更偏语法高亮和片段,轻量,但不是完整批注工作台。 |
| Obsidian | Review Critic | 高 | 支持新增、删除、替换、高亮、评论、变更面板、接受/拒绝、Live Preview 和 Reading View;如果你的草稿本来在 Obsidian,体验会比纯源码编辑舒服。 |
| Obsidian | Fevol/obsidian-criticmarkup | 中 | 思路完整,有 suggestion mode 和 comment mode,但 README 明确提醒 beta 风险,不建议直接放进主 vault。 |
| Emacs | criticmarkup-emacs | 中 | 有 minor mode、跳转、接受/拒绝、follow changes,适合 Emacs 用户;多行标记高亮有边界。 |
| Sublime Text | MarkdownEditing / CriticMarkup toolkit | 中 | MarkdownEditing 文档里有 reviewer/author 快捷键;官方 CriticMarkup toolkit 也列了 Sublime、TextMate、BBEdit、PopClip、Keyboard Maestro 等工具。生态偏旧,但文本协议仍然可用。 |
| Kate | criticmarkup-kate | 低到中 | 主要是语法高亮,更新很早,适合作为补充而不是主流程。 |
| Typora / JetBrains / Zed | 暂无成熟主方案 | 低 | Typora 有 CriticMarkup 支持请求,但不是可依赖功能;JetBrains 和 Zed 我没找到成熟的 CriticMarkup 审阅插件。 |
如果目标只是让 Codex 能读到批注,插件不用一步到位。最小可用形态其实很简单:编辑器能帮你快速插入 CriticMarkup,最好能列出批注、跳转、接受或拒绝。AI prompt 可以手写,也可以让插件导出。
Windows 上我会先试两条线:
- 日常工程文档和博客草稿放 VS Code,优先试 MarkReview 或 Review Markup Sidebar。
- 如果草稿已经在 Obsidian,就试 Review Critic,把它当成文稿审阅层。
和 Codex 添加到对话的关系
Codex 自己也有「添加到对话」一类入口。它适合把选区、打开文件或已有聊天材料放进当前请求,让模型立刻拿到上下文。ChatGPT 的项目文档也提到,编辑器里的当前选区和打开文件会为当前 turn 提供上下文;项目里的 Sources 则负责跨聊天复用文件和来源。
这个功能解决的是材料进入模型的问题。选中一段文字让 Codex 改短、解释一个段落、临时带入某个文件,直接添加到对话就很好。它的成本低,动作短,不需要额外协议。
CriticMarkup 更像审稿层。正式审稿时,一篇 Markdown 里可能同时出现删除、替换、补句子、评论语气和补证据提醒。只靠添加到对话,这些意见往往会挤在一次 prompt 里;文档一长,人和模型都要重新定位。
把它们写成 CriticMarkup 后,意见留在文件里。隔几天再打开,批注仍然跟着原句走;换一个编辑器或 Agent,文本标记也还能读。
所以这两套机制适合合用:
- 轻量反馈用「添加到对话」:选中一段,让 Codex 解释、缩短、润色或顺手改一处。
- 正式改稿用 CriticMarkup:把一篇文档当成审稿对象,逐段标删除、替换、补充和评论。
- 长文返工可以叠加使用:先在编辑器里标好 CriticMarkup,再把文件或小节添加到对话,让 Codex 按批注输出 clean 版。
我会怎样放进 Codex 工作流
这套机制落到 Codex,不需要复杂集成。先按反馈重量选入口,再固定文件和口径。
轻量反馈直接走 Codex 的添加到对话。选中文本后,让 Codex 处理当前段落即可;这种场景不需要把所有意见写进文件。
一旦进入正式审稿,就让 Codex 把草稿写成一个真实 Markdown 文件。文件可以是博客草稿、方案文档、README 或临时审阅稿。
接着用 VS Code 或 Obsidian 在原文上标 CriticMarkup。能直接替换的地方就用 substitution;只想表达方向,就用 highlight + comment;明确不要的段落就用 deletion;需要补一句内容就用 addition。
然后把同一个文件交回 Codex,并附一句明确口径:
请读取这个 Markdown,按 CriticMarkup 批注修改正文,输出干净版本。
删除标记表示删掉,新增标记表示保留新增内容,替换标记采用新文本,高亮和评论表示按评论意图重写。如果文件就在当前工作区,Codex 可以直接读文件;如果文件不在当前工作区,可以把带批注的小节添加到对话。长文不必整篇复制,每次给一个小节更稳。片段前面带上标题,模型就能定位语境。
最后让 Codex 输出 clean 版,并保留必要 diff。对博客这种内容,我更愿意让它直接改文件,然后跑一次 Markdown 风格扫描和站点生成;对方案文档,可以先输出一版 clean Markdown,再决定是否覆盖。
这比行号反馈舒服很多。你不需要描述「第三段第二句」,也不需要担心换行后行号变了。批注本身跟着文字走。
边界要提前接受
CriticMarkup 把审阅意见留在纯文本里,使用时要注意标记范围、定位上下文和清理方式。
第一,不要把大段跨多小节内容塞进同一个标记。多行、跨表格、跨代码块的批注会增加解析和渲染风险。更稳的做法是拆成几处小批注。
第二,代码块里要谨慎使用。Markdown fenced code 里的 {++ ++} 可能本来就是示例代码,AI 也可能误判它是批注。给代码示例提意见时,我更倾向于在代码块外加 comment。
第三,重复文本需要上下文。同一句话在文章里出现多次时,只复制一句批注回来,模型未必知道改哪里。保留所在标题和前后两三句,命中率会高很多。
第四,接受和拒绝最好由工具或脚本做,不要靠肉眼全局替换。尤其是 substitution 和 comment 混在一起时,手工清理很容易漏掉半个标记。
第五,它不解决「谁说了算」。批注只是把意见带回模型,最终仍然要有人看 clean 版。AI 可以执行改稿,但不能替你判断文章是否真的变好了。
批注也不是天然获得授权的指令。自己写的改稿意见,可以连同明确任务一起交给 Agent;来自外部文档、他人批注或示例代码的标记,仍只是待审阅材料。意见与事实、权限或当前任务冲突时,应先核对,不能因为它写在 comment 里就执行命令或删掉其他文件。未解决的批注也不应在「清理标记」时悄悄消失。
我想保留的判断
MarkMark 的价值主要落在反馈通道上:AI 协作文稿可以用纯文本承载批注,不必依赖某个编辑器的私有批注模型。
代码已经有 diff、review comment 和 patch,Markdown 文稿却经常退回到聊天框里的口头描述。CriticMarkup 刚好补上中间那层:它比行号自然,比截图可靠,比云文档批注更容易交给 Agent。
所以我不会先等一个完美的跨平台 MarkMark,也不会把所有反馈都压到 CriticMarkup 里。现在就可以让两条入口各做各的事:
轻量反馈:选区或文件添加到对话 -> Codex 直接处理当前问题
正式改稿:Codex 生成 Markdown -> 编辑器里用 CriticMarkup 批注 -> Codex 读取批注并改成 clean 版 -> 我再审一次这条链路的成本低:Markdown 还是 Markdown,文件里多了一层可复制、可 diff、可让 Agent 读取的修改意图。对 AI 写作和技术文档改稿来说,这层意图正是最容易丢的东西。