一块内容可以只有一个名称,但想让它在团队里流转起来,通常需要一串数字。做技术文档这些年,我看了太多 README 从一行简介长成一座迷宫,也见过有人为了找某个配置说明,把整个仓库翻个底朝天。最后我发现,让 README 真正稳定下来的,不是华丽的排版,而是一套简单的分类数字。ReadMe:分类数字说明,说白了就是把 README 里的章节、模块、配置、功能点全部映射到一套编号规则上,再在文档里把规则讲清楚,让读者看到任何一个编号,都能立刻反查它属于什么、管什么、和谁相关。
这篇文章想把我在实际项目中怎么定编号、怎么写入 README、怎么让团队愿意跟着用的过程完整说一遍,给那些正在被 README 结构折磨的人一份可抄的作业。先声明一下,我这里说的分类数字,不是什么高深算法,就是"1、1.1、1.1.1"这样的层级编号,加上"API-01、DOC-02"这类带前缀的语义编号。它们的共同点是:一个数字对应一条内容,同前缀的数字聚成同类,级别关系靠位数一眼可辨。你可以把它理解成图书馆的索书号,也可以当成办公室的房间号。房间号里藏着楼层、朝向和功能,分类数字里则藏着模块归属、相对位置和文档层级。这篇文章既适合一个人维护开源项目的新手,也适合要统一团队文档规范的人。
1. 给 README 做"分类数字"这件事,到底在解决什么
1.1 README 最常见的几种混乱
大多数 README 的核心问题不是缺内容,是内容没有分类。我见过太多种混乱形态,这里挑最典型的三种说。
第一种是流水账式。从安装到使用到 FAQ 一路往下写,所有章节都是平级的大标题,读者不知道重点在哪,更不知道段落之间是什么关系。第二种是伪层级式。章节有标题但没编号,目录跳动靠搜索,跨章节引用只能写"见下文"。第三种是多头并列式。功能和模块不分家,说明和示例混在一起,条目之间看不出从属关系。
打个比方:你拿到一个项目的 README,里面同时出现"安装依赖"和"部署到生产",它们到底属于同一层还是不同层?没有编号时,大家靠缩进猜;有编号时,2.1 和 3.5 的关系一眼可见。分类数字解决的就是这种"模棱两可"。
我之前帮朋友维护过一个库,它的 README 底部有个"其他说明"章节,里面混着配置项、常见错误、贡献指南。新用户来了,问的问题都在同一个章节里来回翻。后来我只做了一件事:给这些内容分了类,贴上 5.1、5.2、5.3 的编号,目录结构立刻清晰了。这就是分类数字最朴素的作用——逼着你先把内容归好类,编号只是结果。
1.2 把"随手写"变成"按图索骥":到底谁在受益
很多人觉得分类数字是给读者看的,这话对了一半,更受益的其实是维护者自己。
对读者来说,定位内容的方式从"上下滚动"变成"看编号跳转"。比如有人提 issue 说"问题出在 README 4.2",比写"就是那个讲 logo 配置的地方"精确得多。对维护者来说,当 README 被拆成有边界的数字块,改一处内容不需要通读全文,只需要在对应编号的段落里操作,受影响范围一下缩小了。
第二个受益者是工具。编号稳定的文档是能被脚本检查的。标题有没有跳号、目录链接是否失效、语义编号在登记表里是否存在,这些都可以用正则或简单脚本自动校验。听起来像"工程化文档",实际做起来成本很低,一行正则就能查。分类数字说明里如果能带上编号规则,这类自动化会顺畅很多。
第三类受益者是新加入的协作者。他们不需要有人手把手讲"我们这个项目文档都放在哪、哪些章节讲了什么",只要看一遍"分类数字说明",整个文档的地图就装进脑子里了。这种低成本上手体验,对于开源项目尤其值钱。
1.3 分类数字说明,重点在"说明"二字
标题里最容易被忽略的是"说明"。只给章节编个号,不算完成。真正的分类数字说明,至少包含三件事。
第一,编号的层级规则。多少位表示什么级别,1.X 和 1.1.X 分别代表什么,读者看到编号要能判断出它属于哪一层的粒度。第二,每个编号段留给了哪类内容。比如 2.X 是安装、3.X 是用法、4.X 是 API,这些约定要写出来,不能靠读者自己猜。第三,变更约定。编号是稳定锚点,不该随意重排;相同含义的内容应该尽量保持相同编号,哪怕是不同项目的同类文档。
一句话总结:编号是形式,说明是契约。README 里可以没有专门的说明章节,但至少要有一张"分类数字说明表",让后来者看着数字不迷茫。这张表我会在第四章给出完整模板。
2. 分类数字怎么设计,才不容易被推翻
2.1 先分清两种编号:层级编号与语义编号
设计数字体系之前,先要分清两种编号类型,因为它们解决的问题完全不同。
层级编号是 1.1.1 这种,特点是位置即身份。它表达的是"我在文档的哪个位置、和上下文的从属关系如何",适合做目录、段落标题、步骤序列。语义编号是 API-01、CFG-03 这种,特点是前缀给类别、数字给序号。它表达的是"我是哪一类事物、在同类中的第几个",适合做功能点、配置项、模块 ID。
我通常的建议是:README 正文结构用层级编号,涉及具体资源或功能条目时用语义编号。两者混用没问题,但一定要在不同场景里明确出来,否则读者会困惑:"3.2 和 MOD-02 到底谁是上级?"
这里有个经验法则:目录层级编号用于"讲述",语义编号用于"标记"。讲述关心顺序和从属;标记关心稳定性和唯一性。设计数字体系前,先把"这份 README 里哪些数字是目录类、哪些是对象标识类"想清楚,后面就不容易打架。
2.2 数字拆到几层才合适
三层以内最佳。第一层是大的章节主题,第二层是主题下的操作步骤或模块,第三层是步骤内的细节或配置项。超过三层,数字的认知负担陡增,人眼容易把 1.2.3.4 看成乱码。
我见过很激进的做法,一个 README 把配置项拆到五级,几乎每个段落都带编号。最后的结果是没人再引用编号,因为打不出来。这里有个实际判断标准:如果读者需要数小数点个数才能说出自己在哪一层,说明层级已经过深。
给你一个推荐结构对照表作为参考:
| 层级 | 数量建议 | 典型用途 | 示例 |
|---|---|---|---|
| 一级 | 4~8 个章节 | 大主题分组 | 2. 安装部署 |
| 二级 | 每章 3~8 段 | 主题下的一级操作 | 2.3 初始化项目 |
| 三级 | 按需出现 | 操作内细节 | 2.3.1 配置数据库连接 |
这个三层结构足以覆盖绝大多数 README。如果你的项目复杂到文档需要四层以上,我往往建议拆成多份文档,而不是把层级无限加深。
2.3 前缀怎么设计:一眼可知类别
语义编号总会涉及前缀,比如 API、DB、UI、DOC。前缀设计遵循三个原则:短、有区分度、有全局字典。别用难以拼读的缩写,比如 KPF-01,没人记得住;也别用容易过时的词,比如 New、Old,等你的项目迭代半年,这几个前缀就全变笑话了。
我实际常用的做法是:大写 2~4 位字母 + 中划线 + 两位数字。字母表分类,数字表序号。例如:
- CORE-01:核心模块
- PLUGIN-02:插件扩展
- CFG-03:配置项
- API-04:对外接口
- DOC-05:文档说明
前缀的字典应该出现在 README 的"分类数字说明"小节里,一个表格列清楚所有前缀。表格里最好再补一列"状态",标注稳定、试用、废弃,这样读者使用编号时心里有数,知道哪些编号值得依赖。
2.4 预留扩展位,给未来的自己留条路
设计编号最容易被忽略的是扩展位。内容长到一定程度,你必然要在已有章节中间插入新内容。如果编号是严格的顺序连续,插一个新章节就会把后面全部重排。
这时候有两种常见方案。一种是按 10 进位扩展位,比如 10、20、30,中间插入直接给 15。但 README 标题显示 10、20 不够常规,而且很多工具对跳号目录支持不友好。
第二种是干脆允许跳号,但用"说明"告诉读者编号不连续是正常的。也就是说,把分类数字说明写成"编号只为表达顺序与关系,不为严格连续"。我倾向于这个方案,因为 README 的读者大多数情况下并不关心编号是否连续,只关心层级关系和定位。允许跳号,就允许在任意位置插入新内容而不重排,这是维护文档时最大的灵活性来源。
3. 分类数字如何落到 README 的各个角落
3.1 正文章节的层级编号怎么写
写过开源项目 README 的人都知道,标准套路是徽章、简介、安装、使用、API、贡献、许可证。但"套路"不等于"编号"。我们要做的是给每个标题配上稳定编号,并在开头的目录里列清。
我常用的顶层骨架长这样:
# my-tool ## 1. 项目简介 ### 1.1 它能做什么 ### 1.2 它不做什么 ## 2. 快速开始 ### 2.1 环境要求 ### 2.2 安装方式 ### 2.3 第一个例子 ## 3. 使用指南 ### 3.1 命令行用法 ### 3.2 配置文件 ### 3.3 高级技巧 ## 4. API 参考 ### 4.1 核心函数 ### 4.2 错误码 ## 5. 运维与排查 ### 5.1 日志 ### 5.2 常见问题 ## 6. 参与贡献 ### 6.1 开发环境 ### 6.2 提交流程这套编号的好处是:你在任何一条 issue 里写"详见 3.2",别人打开 README 就能从上往下扫到准确位置。要注意的是,目录区也要原样带编号,别让读者还得回翻正文才能看到编号。
3.2 目录区怎么呈现分类数字
目录不是可选项。用 Markdown 写目录,我建议直接用带锚点的链接,把编号和标题同时写进去。示例如下:
- [1. 项目简介](#1-项目简介) - [1.1 它能做什么](#11-它能做什么) - [2. 快速开始](#2-快速开始)GitHub 会自动生成中文锚点,但其他平台不一定。所以我在团队内部约定:标题尽量简短,锚点按平台规则生成后人工核对一遍。目录里的编号必须与正文一致,这是分类数字说明最基本的约束。
我见过不少 README 的目录和正文不一致,或者目录里只列大标题不列二级标题。这样编号体系就打了折扣。既然要做分类数字,就做彻底:目录区就是个迷你地图,二级标题一个都别漏。
3.3 功能项、配置、API 的语义编号怎么和正文联动
正文用层级编号,具体条目用语义编号,两者怎么共存?我的做法是:在 README 里维护一张"编码登记表",每个条目有语义编号、名称、说明、状态四列。
比如:
| 编号 | 名称 | 说明 | 状态 |
|---|---|---|---|
| CORE-01 | 数据加载 | 读取本地文件 | 稳定 |
| CORE-02 | 数据转换 | 格式标准化 | 测试中 |
| API-03 | 批量查询 | 分页查询接口 | 稳定 |
| CFG-04 | 超时时间 | 控制请求耗时 | 稳定 |
然后把这张表放到 README 的"分类数字说明"或"资源总表"章节。当正文提到 CORE-01 时,读者可以顺着这张表找到更完整的上下文。这张表也是团队协作的主锚点:issue 写"CORE-01 出问题了",所有人秒懂是哪个模块,不需要再翻代码。
3.4 与 CHANGELOG、版本号的联动
README 不是唯一该用分类数字的地方,真正让体系发挥威力的,是把编号延伸到变更记录。每次发版时,变更条目里直接写"CORE-01 新增批量参数 page_size",比写"优化数据加载模块"精确得多。如果读者用出问题,他可以回溯:这个模块上次改动是什么版本,改了什么内容,一眼全通。
版本号本身也是一种分类数字体系。我习惯在 README 中单独留一块"版本说明",把 v1.2.0 到 v1.3.0 的语义、兼容性变化列清楚。版本数字和功能编号一起,就形成了一条可追溯的演进链条。任何时候想回看某个功能的发展过程,用编号一搜全出来。
4. 实操过程:把一个流水账 README 改造成分类数字版本
4.1 第一步:清点内容,划出分类边界
改造第一步不是写编号,而是把所有内容堆出来。把你现在 README 里的每个小节标题、每段话列在一个表格里,然后问两个问题:这段内容和其他哪段属于同一主题?它应该出现在第几步?把关系理顺后,你会得到几个大堆,它们就是顶层章节。
举例来说,我处理过一个工具库的 README,原本只有四大块:简介、安装、示例、其他。其中"其他"里混了 API 列表、常见错误、更新日志,足足三十行。我先把"常见错误"提出来单独成章,"更新日志"改成独立的 CHANGELOG 文件,API 列表整理成表格。清理后,顶层章节从 4 个变成 6 个,每个都有了清晰边界。
这一步最关键的动作不是合并,是拆。把那些"什么都能装一点"的杂物章节拆开,分类数字才有存在的意义。杂物章节一旦被拆分,原来的模糊地带就会暴露出来,你可能发现有些内容既属于安装又属于使用,这时候要果断决定归属,别让一个条目脚踏两船。
4.2 第二步:分配编号,先写数字字典再写正文
给大堆定序号,给子堆定子序号,过程中会不断发现遗漏和交叉。我强烈建议先写"数字字典",再写正文。数字字典是这么一张表:
| 编号段 | 内容范围 | 说明 |
|---|---|---|
| 1.x | 项目简介 | 定位、适用对象、特性 |
| 2.x | 快速开始 | 安装、初始化、最小示例 |
| 3.x | 使用指南 | 命令行、配置、进阶用法 |
| 4.x | API 参考 | 函数、错误码 |
| 5.x | 运维与排查 | 日志、常见问题 |
| 6.x | 参与贡献 | 开发环境、提交规则 |
写完字典,正文其实是在照着字典写,而不是边写边想编号。这个顺序能避免大量返工:内容结构和编号在纸面已经定了,正文只是填充。我在实际操作中发现,凡是跳过数字字典直接改 README 的,后面几乎都会遇到两个问题:一是章节顺序靠感觉排,编号连续性一团乱;二是越写越偏,写着写着就把本不属于该章节的内容塞进来。
4.3 第三步:写 README 的"分类数字说明"小节
这个小节建议放在目录之后、正文开始之前,不一定长,但必须存在。我会写类似这样的文本:
本文档使用分类数字组织内容。1.x 为项目简介,2.x 为快速开始,3.x 为使用指南,4.x 为 API 参考,5.x 为运维与排查。资源条目使用语义编号,前缀含义见下表。编号不追求连续,只为表达顺序与从属关系,新增内容可在段内插入并跳号。
后面跟一张前缀对照表。这段看似不起眼,却是整套规则的核心。没有它,编号只是装饰;有了它,编号才变成团队共识。有了这段说明,任何新读者看到 "5.2" 都会条件反射地知道这是"运维与排查"里的内容,而不是傻乎乎地发问。
4.4 第四步:校验链接、编号和引用
改完 README,我会做三层校验。第一层是 Markdown 结构是否能正常渲染;第二层是目录锚点是否能跳转;第三层是全文搜索一遍语义编号,确认每个编号都能在登记表里找到。这个过程可以用脚本做,也可以靠人工盯,但发布前必须做完。
如果仓库是 Git 管理,我还会做一次"编号变更提交":每次调整编号,都在提交说明里写清楚改动。这样以后翻历史,能追溯数字体系的演化过程。旧版本的 README 编号虽然已经失效,但在提交记录里还能查到当时为何这样编,这本身就是一份很有价值的变更说明。
5. 常见问题与排查技巧实录
5.1 编号改不动的历史包袱
最典型的问题是:项目已经上线,README 编号被外部引用,结果某天你发现 2.3 和 2.4 的顺序需要交换。怎么办?我通常不交换编号,而是把 2.3 的内容并到其他小节附近,或用"见 2.4"做跳转。原因很简单:任何在 issue、文档、聊天记录里引用 2.3 的地方,都会因为你重排而失去锚点。
编号一旦发布,就带上了契约属性。这个道理和软件接口兼容性一样:改接口名要所有调用方一起改,改编号要所有引用方一起追。所以最好的处理方式是:发布之后就尽量冻结顶层编号,新增章节用跳号或追加编号,而不是重排已有编号。
5.2 层级越写越深,没人看
我踩过最深的坑就是把编号细化到极致。一开始觉得编号越细越清晰,后来发现 README 里全是数字,读起来像试卷。我的解药是三层上限原则,并且把"细节类编号"从正文挪到表格里。配置项的细节让读者看登记表,而不是散在正文标题里。
当某个编号段内部内容膨胀到难以管理时,我会先检查是不是分类粒度过粗——比如把"配置"拆成"环境配置"和"行为配置"两个二级章节,而不是把配置项一路排到 3.1.1.1。如果检查下来两层标题确实够用,那就让细节待在表格里,别为了备忘而生造层级。
5.3 分类数字和内容对不上
这个问题的根源往往是"先写正文后补编号"。编号是后贴的标签,内容一变,标签就错位。我的经验是:让"数字字典"成为唯一事实源,改内容先改字典,再改正文。两者永远同步提交。
实际操作中,我会在 README 的顶部目录旁边放一个"最近更新"提示,每次改动内容后检查字典表是否受影响。如果只是改错别字,字典不用动;只要分类范围变化,字典必须同步。长期下来,字典就是那份 README 的骨架,正文反而可以频繁改动而不破坏整体结构。
5.4 自动化排查:一分钟找出失效编号
分享个小脚本思路:用正则提取所有顶层标题的编号,检查是否有不连续;再提取语义编号,和登记表里的集合比对。用 Node 或 Python 都行,核心逻辑只有二十行左右。
我会在 CI 里挂一个极简检查任务,PR 合入前跑一遍,发现跳号、重号或登记表缺失就自动失败。项目刚开始会觉得多此一举,等 README 被改过五六个版本后再看,这层自动化至少拦住过三四次"改完标题忘改目录"的低级错误。这种检查不能替代人工审阅,但能把最机械、最重复的校验成本几乎降到零。
6. 最后分享几个只有踩过坑才懂的经验
第一个经验是"先号后人"。新项目启动时就定好分类数字的骨架,哪怕内容还没写,也先把编号框架立起来。后续所有人往骨架里填充内容,不会有太多结构冲突。等文档长到一定程度再回头补编号,等于一边修房子一边换地基,代价成倍上升。
第二个经验是编号命名要尽量"低语义"。得忍住给前缀起"好记名字"的冲动。你团队里可能有个模块叫"超级分析引擎",前缀千万别用 SUPER-,等半年后它被拆成两个模块,SUPER 就成了历史笑话。用 CORE、MOD、PLUGIN 这类通用词,反而更耐折腾。
第三个经验是在团队里开一次半小时的"编号说明会"。分类数字约定光写进 README 不够,得在站会上花二十分钟过一遍:为什么要有编号、核心编号段是什么、issue 和提交信息里怎么引用编号。这半小时的投入,换来的是整个团队在协作中一致引用数字锚点,而不是各写各的自由发挥。
第四个经验是给大仓库设置"编码管理员"。规模上去之后,编号分配如果没有专人把关,很容易出现重号、错号、前缀滥用。这个人不一定是什么负责人,懂一点文档结构就行,职责就一条:所有新增编号先向他登记。很多项目文档不是没人写,而是没人管,一个编码管理员的角色就能解决大半。
这套方法我在多个项目里试过,最常见的结果是前两周不适应,第三周开始没人再写"找一下 README 最底下那段"。分类数字不负责解决代码问题,它解决的是协作时"说不清内容在哪"的问题。只要文档还在被人读、被人引用,分类数字就始终是值得维护的文档地基。