假设你是一家米其林餐厅的主厨,后厨里有十二位厨师同时开工。以前每个人把自己研发的菜谱随手写在纸条上:有的贴在墙上,有的塞在抽屉里,有的记在自带的小本子上。某天换季换菜单,你想改进糖醋排骨的糖色技巧,结果翻纸条翻了半小时,还发现两张内容已经对不上的旧版本。团队写 Markdown 文档,就是这种“后厨”状态:文件随意命名、标题想到哪写到哪、图片散落各处、链接随手贴个网址——文档越多,维护成本越高。 这篇文章就是一份“后厨管理条例”。我们用一盘菜从杂乱到上桌的全过程,讲清楚团队 Markdown 的最佳实践:目录结构怎么分抽屉、标题层级怎么排顺序、代码块怎么贴标签、图片链接怎么进仓库、版本记录怎么写清楚,以及怎么用 lint 工具当“质检员”自动守住这些规矩。学完之后你再看团队文档,就会像老主厨看菜谱柜一样:一切井井有条。
对 AI 从业者而言,文档规范决定了团队知识资产的复用效率:模型训练、Prompt 迭代、架构评审都依赖高质量文档,掌握这套实践能大幅降低协作成本,是 Tech Lead 和技术写作者的硬技能。
目录
可视化演示
展示Markdown团队协作规范流程:撰写(Wrt)→Lint检查→评审(Rev)→CI集成→发布(Pub),涵盖标题层级(H1-H6)、代码块、图片Alt和Git Diff规范。
本节配有交互动效(进入视口后自动加载,约 3KB)。
Markdown协作规范流程 撰写(Wrt)遵循H1-H6不跳级、代码块(```)标注语言、图片含Alt文本规范,提交前Lint检查 评审(Rev)后CI集成自动校验,发布(Pub)采用一句一行(1Sent/1Line)策略利于Git Diff精确追踪 Write → Lint → Review → CI → Publish
目录结构规范:给菜谱柜分好抽屉
老主厨接手后厨的第一件事,是把柜子分成几个带标签的抽屉:柜门贴总菜单,里面按冷菜、热菜、甜品分格,每本菜谱再编上号。新厨师第一天上班,不用问任何人,顺着标签就能找到“01-红烧肉”。目录结构的意义就在于此:让每一个文件都拥有唯一且确定的家,任何人打开仓库都能在三步之内定位到要找的东西。
对应到团队文档仓库,就是一套目录结构规范。仓库根目录只放一个 README.md 作为唯一入口,相当于柜门上的总菜单;正文全部走进 docs/ 目录,按模块再分子目录,相当于菜谱按凉菜、热菜分格;图片和附件分别进 images/ 与 assets/,相当于照片夹和工具区。除此之外,文件命名也要统一,推荐“数字编号-主题”的小写短横线风格,如 01-quickstart.md、02-api-guide.md,并且目录嵌套一般不超过三层,避免“套娃式”的层层包裹。
这套结构可以用一个组合式来表达:
抽屉分好之后,后厨再也没有“找不到菜谱”的抱怨。同理,当目录结构成为团队共识,新成员加入的第一天就能独立找到任何文档,文档数量的增长不再带来混乱——这就是规范的第一层价值:位置的确定性让查找变成条件反射。
- 左侧“仓库”表示整个文档仓库的结构把所有文件和文件夹看成一个整体表达式,表达式的每一项都承担唯一职责,没有“随便放”的灰色地带。
- 第一项 README.md 是总入口它必须待在仓库根目录,相当于柜门上唯一的总菜单,整个仓库只能有一份。
- docs/ 是正文的主目录所有菜谱按“模块/文档”两层组织,目录深度不超过三层,避免无限嵌套。
- images/ 与 assets/ 分类收纳资源图片只有 images 一个家,附件只有 assets 一个家,正文目录里不允许混放资源文件。
标题层级规范:菜谱章节要像菜单一样清楚
一份好菜谱,先写菜名,再分“食材准备”“烹饪步骤”两大块,每块下面再列小点。客人翻开菜单,先看大类再看小类,绝不会迷路。如果哪页菜谱直接从菜名跳到“糖色的第三个细节”,读者一定会怀疑自己漏看了几页,这份菜谱也就失去了引导作用。
Markdown 的标题层级遵循同样的规矩。H1 是文档唯一的大标题,相当于菜名;H2 是主要章节;H3 是章节之下的小节,依此类推。markdownlint 工具中的 MD001 规则专门检查“标题只能逐级递增,不能跳级”:全篇有且只有一个 H1;同级 H2 之间是并列关系;H2 下面只能是 H3,不能直接蹦出 H4。
把标题层级写成规则公式,就是对“逐级递增”最精确的描述:
就像好菜单让客人十秒决定点什么菜,统一的标题层级让读者十秒读懂文档结构。大纲即骨架,骨架站得稳,内容才有地方挂。标题规范不是束缚文风,而是保证文档的目录永远可读、可导航、可自动生成。
- $L_i$ 表示文档中第 i 个标题的层级数H1 记成 1,H2 记成 2,每个标题都可以被一个数字唯一标记。
- $L_{i+1} \in \{ L_i ,\, L_i + 1 \}$ 表示下一个标题只有两种合法选择要么与当前标题同级(并列内容),要么比当前标题深一级(子内容),跳级会破坏大纲的树状结构。
- $L_1 = 1$ 表示文档第一个标题必须是 H1每篇文档从一级标题开始,而且全篇 H1 有且只有一个,作为文档的门面。
代码块规范:标准化的刀工说明
后厨里最怕两个词:“少许”和“适量”。老师傅写菜谱,会把刀工单独列成标准:什么刀、什么形、什么尺寸。写代码说明也是同一个道理,不能只说“运行这段代码”,得先告诉读者这是什么语言的代码。否则就像给了厨师一把刀却不说是拿来切葱还是剁骨。
Markdown 代码块用三个反引号围栏包起来,开栏紧跟语言名:python、bash、yaml 等。标注语言之后,渲染器才能做语法高亮,读者才能快速辨认;不标注,代码就是一段没有表皮的灰条。除了标注语言,代码块内部要保持统一的缩进(推荐 4 空格),单行不要太长(80 字符左右),关键代码配一行注释。围栏必须成对闭合,否则渲染器会把后面所有内容都吞进代码块——这是新手最容易踩的坑。
代码块的标准结构可以写成:
标准化刀工让厨房切出的每盘菜大小一致,标准化代码块让团队复制的每段代码开箱即用。代码块规范省下的是“怎么都跑不起来”的沟通成本,让技术文档真正成为可以放心照做的说明书。
- 开栏 + 语言标注代码块第一行用三个反引号开头,紧接着写语言名,相当于给配料表贴上分类标签,渲染器才知道用哪套语法规则上色。
- 代码体 + 缩进维持代码块内部保留原始空格和换行,缩进统一用 4 空格,行宽控制在 80 字符左右,严禁 Tab 与空格混用。
- 闭栏最后一行必须用同样数量的反引号闭合,开栏与闭栏数量相等,否则渲染器会误吞后续所有内容。
图片管理规范:照片统一进照片夹
好菜谱都有成品照片,但如果照片随手塞在围裙口袋里,菜谱上就永远空着一块。规范的后厨会备一个照片夹,所有菜品照片按“菜名-序号”排好,菜谱里只写“成品照见照片夹:红烧肉-01”。取用、替换、盘点都方便,菜谱正文永远干净。
团队文档也一样:所有图片统一放进 images/ 目录,按模块分子目录,命名用“模块-序号-用途”的格式,例如 images/guide-03-architecture.png。文档里引用图片用相对路径,写,而不是粘贴一串外链网址。为什么不用外链图床?因为图床可能失效、可能被墙、可能换域名——一旦失效,文档里就只剩一个破图标。图片放在仓库内,克隆下来就能看,文档自包含。同时要控制图片体积,截图尽量压缩到 200KB 以内,避免文档仓库越来越臃肿。
图片引用的标准写法,拆开看是两个部分的拼接:
当所有照片都躺在照片夹里时,主厨一句话就能让人找出某道菜某一步的图。图片管理规范的意义,就是让文档在一年之后依然完整、依然自包含,而不是散落一地的破图链接。
- ![占位说明] 是图片的“点名”部分渲染正常时它显示为图片下方的说明小字,图片加载失败时它替代图片出现,让读者知道这里本来该有什么内容。
- (images/名称.ext) 是图片的“取货路径”写仓库内的相对路径而非完整网址,保证仓库克隆到任何机器上,图片都跟着走。
- 命名规则统一为“模块-序号-用途”例如 guide-03-architecture.png,方便按文件名直接检索、排序、去重。
链接管理规范:菜谱之间的交叉引用要精确
菜谱之间经常要互相引用:“糖色技巧详见《糖醋排骨》第三步”。如果写成“那道菜里讲过”,厨师得把整个柜子翻一遍;写成“糖醋排骨 03”,一趟就能拿到。文档链接也是同样的道理:写得越精确,知识之间的跳转成本就越低。
Markdown 链接同理。仓库内文档互链,用相对路径写清楚目标位置,比如 [安装说明](../guide/02-install.md),不要复制一条带域名的完整网址——因为仓库迁移域名后,绝对网址全部失效,相对路径却纹丝不动。链接文字要有描述性,写“参见数据持久化方案”而不是“点这里”,因为链接文字本身就是读者唯一能看到的导航线索。跳转本页某个标题,用锚点 # 加标题名;外部链接要标注网站域名或“[外部]”,提醒读者已经离开仓库。文档数量多了以后,还要定期扫描死链。
链接的结构可以正式写为:
精确的交叉引用让整个后厨的菜谱连成一张网,而不是一本本孤立的册子。文档之间互相可达,知识才能被反复复用和引用,团队的经验才能沉淀成真正可导航的资产。
- [描述文字] 是链接的“门牌文字”读者看到的是它,所以要写“参见安装说明”而不是“点这里”,让链接脱离上下文也自洽。
- (相对路径或锚点) 是链接的目的地仓库内文档用
../开头的相对路径,跳转本页标题用 # 加标题名。 - 外链必须标注来源外部网址要在链接后注明域名或“[外部]”字样,防止读者误以为还在仓库内部。
版本控制规范:主厨的修订记录本
老主厨有一本修订记录本,每道菜改动一行都记一笔:哪天、谁、为什么改、改成了什么样。三个月后菜单大改,翻着本子就能复盘每道菜的演变,谁都不用凭记忆猜。没有这本记录的后厨,改过的菜谱多了,就再也说不清哪一版是“现在用的”。
团队文档的版本控制靠 Git。文档不是一次性写完就结束,而是要像代码一样纳入版本管理。提交信息建议采用 Conventional Commits(约定式提交)格式:type(scope): 摘要,例如 docs(guide): 补充安装步骤。其中 type 表示提交类型,feat 是新增功能、fix 是修复缺陷、docs 是文档变更;scope 表示改动涉及的模块;摘要用一句话说明“做了什么”,不超过 50 字。
提交信息的模板可以写成:
修订记录本是后厨的“记忆”,版本控制是团队文档的“记忆”。文档变更最好和代码变更一起提交、一起走 Pull Request(合并请求)评审:改接口时同步更新 API 文档,提交信息写明“feat(api): 新增用户查询接口”,至少一位同事看过再合入。有了清晰的提交规范,三个月后回看文档历史,每一条变更都像昨天写的一样清楚。
- type 表示提交的类型feat 表示新增功能、fix 表示修复缺陷、docs 表示文档变更,让历史记录一眼可分门别类。
- (scope) 表示改动涉及的模块如 api、guide、config,帮助快速定位本次变更的影响范围。
- 冒号后的摘要用祈使句动词加对象、不超过 50 字、不用过去时,写“补充安装步骤”而不是“补充了安装步骤”。
工具与 Lint:请一个不睡觉的质检员上岗
管理规范再多,靠人守总会有疏漏。后厨的解法是请一位质检员,每天开市前把菜谱柜巡查一遍:编号对不对、章节乱没乱、围栏闭没闭。文档仓库的质检员,就是 markdownlint——一个开源的 Markdown 风格检查工具,每条规则有唯一编号:MD001 查标题跳级、MD013 查单行长度、MD024 查重复标题、MD041 查首行必须是 H1 等。
规矩只有写进工具里才叫规矩,否则只是“建议大家遵守”。markdownlint 的落地方式分三层:编辑器安装 markdownlint 插件,写文档时实时提示,就像质检员站在桌边提醒;Pre-commit 钩子在提交前自动检查;CI(持续集成)流水线在每次 Pull Request 上执行 lint,不通过就不允许合入,就像质检员在大门上把关。配合 markdownlint-cli 的 --fix 参数还能自动修复大部分格式问题。
这套“全规则通过”的判定,可以形式化为:
质检员不睡觉、不讲情面、从不漏检。当 lint 在 CI 里稳稳当当地守着每个 PR,团队文档的规范就不再依赖某个人记住多少规矩,而是变成了一条自动化的流水线。规则一旦自动化,规范才真正落地。
- 左侧“文档通过”表示这篇文档有资格进入团队仓库主干这里的“通过”是一个整体结论,不由任何单条规则单独决定。
- $\bigwedge$ 表示“并且”所有规则必须同时满足,有一条不通过整体就不通过——就像质检员查菜谱,任何一条不合格都会被打回修改。
- $\mathcal{R}$ 是规则集合markdownlint 的每条规则有唯一编号,常用 MD001 查标题跳级、MD024 查重复标题、MD041 查首行 H1,团队可按需增删。
AI 应用场景
场景一:AI 文档体检助手
阶段:LLM 应用与工具链
解决的问题:团队文档量达到几百篇之后,标题跳级、死链、图片缺失等问题靠人工 review 费时又漏检。传统方式是“人肉跑 lint 再手动改”,需要逐个文件打开;用 AI 对文档做批量体检,让模型读取目录树和文档内容,找出违反规范的位置并生成修复建议,再配合脚本自动修,能把耗时从小时级降到分钟级。
具体案例:某技术团队的 300 篇文档,每天早上由 AI 巡检一次,输出一份“文档健康报告”:列出 12 处标题跳级、5 个失效图片路径、3 个死链,并直接生成修复 commit 供技术负责人确认。Tech Lead 只需要 review,而不是一篇一篇地打开文档。
场景二:AI 按规范生成文档骨架
阶段:生成式 AI 应用与 Prompt 工程
解决的问题:新成员写文档习惯“从零开始”,出来的格式往往不符合团队规范。通过 Prompt 工程让 AI 按团队规范直接生成文档初稿:目录结构正确、H1 唯一、H2 章节齐全、代码块自动标注语言、图片链接指向统一资源目录。
具体案例:在内部文档系统接入 LLM,输入“为订单服务生成一篇部署文档”,AI 自动创建 docs/order/deploy.md,包含 H1 菜名式的标题、yaml 与 bash 代码块,并预留 images/order/ 下的图片占位引用。人只需要填充细节、走评审流程,规范问题在源头就被消灭。
Python 演示
# -*- coding: utf-8 -*-"""简易 Markdown 规范检查器: 标题层级、代码块围栏与语言标注、图片相对路径。"""import refrom pathlib import Path def check_headings(lines): """检查标题规范: 全篇唯一 H1, 标题层级只能同级或 +1, 禁止跳级。""" errors = [] headings = [] for i, line in enumerate(lines, 1): m = re.match(r"^(#{1,6})\s+", line) if m: headings.append((len(m.group(1)), i)) h1_count = sum(1 for lv, _ in headings if lv == 1) if h1_count != 1: errors.append("document should have exactly one H1, got %d" % h1_count) for idx in range(1, len(headings)): prev_lv, prev_line = headings[idx - 1] cur_lv, cur_line = headings[idx] if cur_lv > prev_lv + 1: errors.append("line %d heading jumps: H%d -> H%d" % (cur_line, prev_lv, cur_lv)) return errors def check_code_blocks(lines): """检查代码块: 围栏成对闭合, 开栏必须标注语言。""" errors = [] in_block = False for i, line in enumerate(lines, 1): if line.startswith("
m = re.match(r"^(#{1,6})\s+", line)用正则识别标题行,并抓取#的个数作为层级。headings.append((len(m.group(1)), i))记录每个标题的层级和行号,供后面的相邻比较。if cur_lv > prev_lv + 1:这正是标题公式 $L_{i+1} \in \{L_i, L_i+1\}$ 的落码:一旦跳级就报错。if line.startswith("```"):识别围栏行,用于进入或退出代码块状态机。if not line[3:].strip():开栏后面没跟语言名就报错,落实“代码块必须标注语言”。re.finditer(r"!\[[^\]]*\]\(([^)]+)\)", text)扫描所有图片引用,把相对路径逐个收集出来。if rel and not (doc_dir / rel).exists():用 pathlib 拼接当前文档目录,检查目标图片是否真实存在。
常见误区
误区我一直以为搞标题层级、统一命名这些规范,是为了让文档排版更漂亮,所以只要我的文档“看起来还行”就不用遵守。
正解规范的核心目标是降低协作与维护成本,美观只是副产品。统一目录结构是为了让所有人“秒找”文件,标题逐级递增是为了大纲可导航,lint 自动化是为了守住底线。就像菜谱柜分抽屉不是为了好看,而是让每个厨师都能在五秒内拿到食材。排版美观是渲染器的事,规范解决的是“人怎么协作”的事。
为何常见:Markdown 的默认渲染已经足够好看,初学者容易把视觉观感当作唯一标准,看不到规范对搜索、导航、自动化检查的深层价值。
误区我觉得一篇文档里多堆几层 H4、H5,显得内容特别有深度,反正 Markdown 支持六级标题,随便用不好吗?
正解标题层级是文档大纲的骨架,跳级会让骨架变形。H2 直接跳到 H4,阅读者会找不到 H3 在哪,生成的目录树也会出现“断层”。规范要求的是“逐级递增”:允许同级并列或深一级,禁止跳级。就像一份菜单,从“热菜”直接跳到“第三道菜的配料”,客人一定觉得自己漏看了几页。
为何常见:标题数量多容易被误认为“结构细致”,而实际上细不等于有序;大纲的有效性来自层级的规整,而不是层级的数量。
误区我习惯直接把图片拖进文档编辑器,有时用截图工具生成一个外链,反正渲染出来能看到图就行,放哪里不重要。
正解图片管理是文档能否长期存活的关键。外链图床可能失效、换域名、被墙,一旦失效文档就破相;图片散落在不同目录,克隆仓库后就显示不出来。规范要求统一进 images/ 并按模块分目录、用相对路径引用,保证文档自包含。哪怕一年后换电脑、换公司,这份文档依然完整可读。
为何常见:编辑器的拖拽上传太顺手,让人忽略了图片的“存储位置”和“引用路径”是两个必须显式管理的东西,等图挂了才追悔莫及。
误区markdownlint 老是在我的文档上画红线,看着闹心。既然规则这么烦人,直接把这条 rule 关掉不就行了吗?反正文档能正常渲染。
正解报错是在帮你发现结构问题,不是故意找茬。正确做法是理解规则意图,把文档改规范;如果确实有合理例外(比如某些表格行必须超长),用 HTML 注释对单条规则做局部豁免。把规则整体禁用,等于因为质检员拦下一道不合格的菜就把质检员开除,后厨只会越来越乱。
为何常见:人天然倾向于“消除提示”而非“解决问题”,把 lint 报错当作噪音而不是信号,是工具使用中最常见的心理误区。
误区我提交文档时经常只写“update“或者”fix”,反正代码能跑、文档能看,历史记录谁会在意?
正解提交信息是文档历史的第一检索入口。写了“fix“,三个月后没人知道修了什么;写成 docs(guide): 补充安装步骤,任何人都能从历史里快速定位变更。约定式提交还让版本号、变更日志可以自动生成。修订记录本上每页只写”改了”,这本子就失去了全部价值。
为何常见:提交信息属于“写完就忘”的内容,短期看不到后果,团队规模变大、文档变多之后,检索成本才指数级上升。
面试题
Q1. 一篇符合最佳实践的 Markdown 文档,全篇 H1 标题应该有几个?
- A.可以有多个
- B.有且仅有一个← 正确答案
- C.至少有两个
- D.可以没有标题
答案:B。H1 相当于菜谱的菜名,全篇唯一。多个 H1 会让文档大纲出现多个根节点;“没有标题”则让文档缺少门面。只有“有且仅有一个”符合标题层级规范。
Q2. 下列哪种标题衔接会触发 markdownlint 的 MD001 跳级检查?
- A.H2 之后继续写 H2
- B.H2 之后接着写 H3
- C.H2 之后直接写 H4← 正确答案
- D.H1 之后接着写 H2
答案:C。MD001 要求标题层级只能同级或深一级。C 从 H2 跳到 H4,跳了两级,违反 $L_{i+1} \in \{L_i, L_i+1\}$;A 同级并列、B 深一级、D 从 H1 到 H2 都合法。
Q3. 团队成员每次写完文档,图片文件应该统一放到哪里?
- A.散落在各文档同级的目录
- B.统一归入 images 资源目录← 正确答案
- C.随意放在项目中的任意位置
- D.直接放在桌面临时截图区
答案:B。图片管理规范要求所有图片统一进 images/,按模块分子目录,文档用相对路径引用。A 造成资源分散,C 无组织,D 的桌面不在仓库内、无法提交。只有 B 让仓库自包含。
Q4. 代码块开栏没有标注语言,会带来什么直接后果?
- A.文档渲染后语法高亮失效← 正确答案
- B.文档标题层级发生错乱
- C.文档在仓库中无法保存
- D.文档目录深度明显增加
答案:A。语言标注决定渲染器用哪套语法规则上色,不标注只会让高亮失效。它不影响保存、不影响标题结构、也不影响目录深度,所以 B、C、D 都与事实不符。
Q5. 团队文档仓库中,文档之间互相引用时最推荐哪种写法?
- A.复制粘贴整篇目标文档全文
- B.使用仓库内相对路径的链接← 正确答案
- C.粘贴不带文字的完整网址链接
- D.把目标内容截图后放进文档里
答案:B。相对路径链接让文档在仓库内可迁移、克隆后依然有效;A 会造成内容重复、维护困难;C 的裸链接没有引导文字且仓库换域名就失效;D 截图不可检索且体积膨胀。
Q6. 想在文档内部跳转到当前页的某个标题,规范的做法是什么?
- A.使用带域名的完整网址链接
- B.使用井号加标题名的锚点链接← 正确答案
- C.把标题内容复制到当前位置
- D.在文中插入一张截图代替跳转
答案:B。渲染器会把每个标题自动生成 id,用 [文字](#标题名) 即可实现本页跳转。A 会离开当前文档,C 造成内容重复,D 不可检索。锚点跳转是唯一既轻量又稳定的做法。
Q7. 提交信息 docs(guide): 补充安装步骤 中 docs 的含义是什么?
- A.表示本次提交新增了新的功能
- B.表示本次提交修复了某个缺陷
- C.表示本次提交只涉及文档变更← 正确答案
- D.表示本次提交重构了模块代码
答案:C。约定式提交里 feat 表示新增功能、fix 表示修缺陷、docs 表示文档变更。这条提交带了 guide 模块作用域和“补充安装步骤”摘要,明显属于文档更新。A、B、D 分别对应 feat、fix、refactor。
Q8. 以下哪些属于团队 Markdown 代码块的规范要求?
- A.代码块需要标注编程语言← 正确答案
- B.围栏必须成对正确闭合← 正确答案
- C.块内缩进格式必须统一← 正确答案
- D.块内禁止出现任何注释
答案:ABC。标注语言、闭合围栏、统一缩进都是代码块规范的核心;规范反而鼓励关键代码配注释以提升可读性,所以 D 错误。
Q9. 关于标题层级规范,下列哪些说法是正确的?
- A.下一级标题允许任意跳级提升
- B.同级标题表示内容之间相互并列← 正确答案
- C.全篇只能出现唯一的一个 H1← 正确答案
- D.H2 下面可以直接跟一个 H4
答案:BC。B 和 C 分别对应“同级并列”与“H1 唯一”两条铁律。A 会触发 MD001 跳级检查,D 从 H2 蹦到 H4 也是跳级,都属于违规。
Q10. 团队引入 markdownlint 之后,下列哪些落地方式是合理的?
- A.只要报错就永久禁用对应规则
- B.在 CI 中集成 lint 自动检查← 正确答案
- C.编辑器安装插件做到实时提示← 正确答案
- D.为图省事一次性关闭所有规则
答案:BC。CI 集成和编辑器实时提示是“工具与 Lint”的推荐落地方式,让规范自动化。A 和 D 属于“报错就关规则”,等于把质检员开除,是典型误区。