
1. 从 Changelog 到 README 的自动化链路到底在解决什么维护过开源项目或者长期迭代的内部工具库的人大概率都经历过这种场景代码提交记录里躺着几十条fix、feat、refactorChangelog 文件更新得断断续续README 里的功能列表还停留在三个月前的版本。新同事接手项目第一件事不是看代码而是翻 Git 历史猜这个模块到底改了什么。这种信息断层带来的沟通成本远比写文档本身要高。这个项目的核心思路很直接把 Changelog 作为中间产物用 LLM 来驱动 README 的更新策略测试。换句话说不是让模型凭空生成文档而是给它一个结构化的变更输入让它判断哪些变更值得写进 README、以什么粒度写、放在哪个章节。关键词里的LLM、README、Changelog三个词恰好构成了这条链路的起点、终点和中间态。适合读这篇内容的人有三类一是正在维护中大型项目、被文档同步问题困扰的开发者二是想在自己的工具链里引入 LLM 能力、但不确定从哪个环节切入的工程师三是对LLM as Judge、基于 LLM 的单元测试这类评估范式感兴趣、想找一个具体落地场景的技术人。整篇内容会围绕怎么测测什么测出来怎么判断好坏展开不会停留在概念层面。需要提前说明一点这里的测试 LLM 更新策略不是指测试模型本身的能力而是把 LLM 当作一个文档更新决策器用一套可复现的评估流程去比较不同策略的产出质量。这个区分很关键后面章节会反复用到。2. Changelog 作为中间层的结构化处理2.1 为什么不让 LLM 直接读 Git Log很多人第一反应是既然有 LLM直接把git log丢进去让它写 README 不就行了。实测下来这条路走不通原因有三个。第一Git Log 的噪声太大。一个正常的开发周期里提交信息包含大量wip、typo fix、merge branch、revert这类对文档毫无价值的内容。模型面对这种输入要么被带偏去描述一些无关紧要的改动要么直接忽略掉真正重要的功能变更。第二Git Log 缺少语义分组。同一个功能可能分散在十几个提交里跨了好几天。模型没有上下文去判断这十几个提交其实是一件事。第三Changelog 天然带有版本边界和分类标签。一份规范的 Changelog 通常按Added、Changed、Fixed、Removed、Deprecated、Security这几个维度组织每个条目对应一个用户可感知的变更。这个结构本身就是给 LLM 的强先验。所以第一步要做的是把 Git Log 聚合成 Changelog。这一步可以用工具自动化也可以用脚本半自动处理。核心逻辑是按提交类型过滤、按功能模块聚合、按版本区间切分。2.2 Changelog 条目的最小信息单元在把 Changelog 喂给 LLM 之前需要定义清楚一个条目包含哪些字段。我试过几种粒度最后稳定下来的结构是这样的{ version: 2.3.0, category: Added, scope: auth, summary: 支持基于 OAuth2 的第三方登录, details: 新增 /auth/oauth/callback 端点支持 Google 和 GitHub 两种 provider, breaking: false, related_issues: [#412, #418] }这个结构里summary是给 LLM 看的主信号details是补充上下文scope用来做章节归属判断breaking决定是否需要高亮提示。related_issues在评估阶段有用可以追溯变更来源。为什么要拆这么细因为后面测试不同更新策略时需要控制变量。比如策略 A 只看summary策略 B 看summary details策略 C 额外带上scope。如果条目本身是一坨非结构化文本这些对比就无从谈起。2.3 版本区间的切分策略Changelog 是按版本累积的但 README 通常反映的是当前最新状态不是每个版本改了什么。所以需要决定给 LLM 喂哪个区间的 Changelog。常见的三种切法全量喂入把项目所有历史 Changelog 都给模型。优点是上下文完整缺点是 token 消耗大而且早期变更对当前 README 的参考价值有限。滑动窗口只给最近 N 个版本。N 的取值需要实验我一般从 3 开始试。增量喂入只给上次 README 更新之后的 Changelog。这要求维护一个 README 与 Changelog 的版本对应关系。实测下来滑动窗口 增量标记的组合效果最稳。具体做法是默认给最近 5 个版本的 Changelog但对每个条目打一个already_documented标记告诉模型哪些内容在上一版 README 里已经体现过了。这样既控制了输入规模又避免了重复描述。注意already_documented标记的准确性直接影响输出质量。如果标记错了模型可能会漏掉本该更新的内容或者重复写入已有信息。建议在评估阶段专门测一下标记错误对最终产出的影响。3. 三种 LLM 更新策略的设计与对比3.1 策略一全量重写这是最直观的策略。把当前 README 全文 Changelog 窗口一起给模型让它输出一份新的 README。提示词的核心指令大概是你是一个技术文档维护者。以下是项目当前的 README 和最近的变更记录。请输出更新后的 README确保所有用户可感知的变更都被准确反映保持原有结构和语气。这个策略的优点是简单不需要维护 README 和 Changelog 的映射关系。缺点是每次都要重新生成全文token 成本高而且模型可能会顺手改掉一些不该改的地方比如调整了章节顺序、改写了没变更的段落。我在一个中型项目上跑过这个策略发现一个典型问题模型倾向于把 README 写得更完整会主动补充一些它认为应该有的内容比如给一个只有三个参数的配置项补上它猜测的第四个参数。这种幻觉在文档场景里是致命的。3.2 策略二差异补丁这个策略不让模型重写全文而是让它输出一个补丁——具体来说是一组操作指令描述在 README 的哪个位置插入、修改或删除什么内容。输出格式可以设计成结构化的{ operations: [ { type: insert, anchor: ## 功能特性, position: after, content: - 支持 OAuth2 第三方登录Google / GitHub }, { type: update, anchor: ### 配置项, old_text: | timeout | 请求超时时间 |, new_text: | timeout | 请求超时时间默认 30s | } ] }这个策略的好处是可控性强每次改动都是显式的、可审计的。缺点是模型需要准确理解 README 的结构锚点定位容易出错。实测中锚点匹配失败是最常见的失败模式尤其是当 README 里有多个相似标题时。改进方法是给 README 的每个章节加一个稳定的 ID 注释比如!-- section: features --让模型基于 ID 而不是标题文本来定位。这个改动看起来很小但把锚点匹配成功率从大概六成提升到了九成以上。3.3 策略三分章节独立更新这个策略把 README 拆成若干章节每个章节独立处理。对于每个章节只把与该章节相关的 Changelog 条目喂给模型。章节与 Changelog 的关联可以通过scope字段来建立。比如scope: auth的条目关联到认证章节scope: config的条目关联到配置章节。这个策略的优点是精准每个章节的更新只受相关变更影响不会出现改 A 章节结果 B 章节也被动了的情况。缺点是需要维护一份 scope 到章节的映射表而且有些变更可能跨多个章节需要特殊处理。三种策略的对比可以整理成下面这张表维度全量重写差异补丁分章节更新Token 消耗高中低可控性低高中幻觉风险高低中实现复杂度低中高适合场景小项目、README 短结构稳定的项目大型项目、章节独立3.4 策略选择的决策依据选哪个策略取决于项目的 README 规模和变更频率。我的经验是README 在 200 行以内、变更不频繁的项目直接用全量重写省事。README 超过 500 行、结构比较稳定的项目用差异补丁。README 章节之间耦合度低、变更集中在特定模块的项目用分章节更新。还有一个容易被忽略的因素评估成本。全量重写的产出是一份完整 README评估时可以直接和人工维护的版本做 diff。差异补丁的产出是一组操作评估时需要先应用操作再对比。分章节更新的产出是多个章节片段评估时需要拼装。评估流程的复杂度会反过来影响你迭代策略的速度。4. 用 LLM as Judge 构建评估闭环4.1 为什么人工评估不够用测试不同更新策略最直接的方法是人工看产出质量。但这条路在策略迭代阶段走不通原因很简单每次调整提示词、调整输入结构都要重新人工评估一遍成本太高而且不同人的判断标准不一致。LLM as Judge在这里的价值就体现出来了。用一个独立的模型实例最好是不同参数的模型避免自我偏好来评估更新产出的质量给出结构化评分和理由。这样每次策略调整后评估可以自动跑迭代速度提升一个量级。4.2 评估维度的设计评估一个 README 更新结果我关注四个维度完整性Changelog 里所有用户可感知的变更是否都在 README 里体现了。漏掉一个 breaking change 是严重问题。准确性README 里描述的内容是否和实际变更一致。模型有没有编造不存在的功能。一致性更新后的 README 在语气、格式、术语使用上是否和原有内容保持一致。简洁性有没有把不该写进 README 的内部实现细节也写进去了。每个维度用 1-5 分打分judge 模型需要给出评分理由。提示词里要明确每个维度的评分标准比如完整性 5 分要求所有 Added 和 Changed 类别的条目都被准确反映无遗漏。4.3 Judge 提示词的编写要点写 judge 提示词有几个坑我踩过第一不要让 judge 直接看 Changelog 和 README 的全文。信息量太大judge 会抓不住重点。正确做法是先把 Changelog 条目逐条列出来让 judge 逐条判断这条变更是否在 README 中体现然后再做整体评分。第二要给 judge 提供参考答案。如果项目有人工维护的 README 版本把它作为参考给 judge让它对比模型产出和人工产出的差异。这比让 judge 凭空判断要可靠得多。第三评分标准要具体到可操作。不要说准确性高要说README 中描述的功能参数与 Changelog 中 details 字段一致无编造内容。一个实际用的 judge 提示词片段请逐条检查以下变更记录是否在 README 中有对应描述 [Changelog 条目列表] 对每条记录输出 - status: covered / partially_covered / missing - evidence: README 中的对应文本如果 covered - reason: 判断理由 然后基于以上结果给出完整性评分1-5和理由。4.4 评估结果的聚合与解读单次评估的分数波动可能比较大尤其是当 Changelog 条目数量少的时候。我的做法是每个策略跑 3 次取平均分同时记录方差。方差大的策略说明稳定性差即使平均分高也要谨慎采用。另外judge 的评分要和人工抽查做校准。我会随机抽 10% 的评估结果人工复核一遍看 judge 的判断是否合理。如果发现 judge 在某类问题上系统性偏差就调整提示词。这个校准过程在初期很重要跑通之后可以降低频率。5. 实操中踩过的坑与应对方案5.1 模型对用户可感知的理解偏差Changelog 里有一类条目是内部重构比如将数据库连接池从 HikariCP 换成 Druid。对用户来说这个变更通常不需要写进 README。但模型往往会把它当作重要变更写进去因为它看起来很技术。解决办法是在提示词里明确定义什么算用户可感知影响 API 签名、影响配置项、影响默认行为、影响性能特征、影响依赖要求的变更。内部实现细节、代码风格调整、测试覆盖率提升这些不算。更稳的做法是在 Changelog 条目里加一个user_facing布尔字段在聚合阶段就做好判断而不是让 LLM 去猜。5.2 长 README 的截断问题当 README 超过模型的上下文窗口时全量重写策略会失败。差异补丁策略虽然输入短但如果 README 本身很长模型在定位锚点时也会因为看不到全文而犯错。应对方案是分块处理。把 README 按章节切分每个章节单独处理最后合并。合并时要注意章节间的引用关系比如详见配置章节这种交叉引用如果配置章节被移动了引用就会失效。我在一个 1200 行的 README 上试过分块方案切成了 8 个章节块。合并后的 README 在结构上没有问题但出现了两处交叉引用失效需要人工修复。所以分块方案要配一个引用检查步骤。5.3 版本号与日期的一致性README 里经常有当前版本x.y.z和最后更新YYYY-MM-DD这类信息。模型在更新时可能会保留旧版本号或者编造一个日期。这类信息不应该让模型生成而应该在更新流程的最后由脚本从 Changelog 的版本信息里读取并注入。模型只负责内容部分元信息由确定性逻辑处理。这个分工原则在文档自动化里很通用需要精确的地方用代码需要理解的地方用模型。5.4 评估中的位置偏差LLM as Judge 有一个已知问题对排在前面和后面的内容评分不一致。在逐条检查 Changelog 条目时排在前面的条目更容易被 judge 认为已覆盖排在后面的容易被判遗漏。缓解方法是把条目顺序随机打乱跑多次评估取平均。或者在提示词里明确要求 judge 对每条独立判断不要受前后文影响。实测下来随机打乱 多次平均能把位置偏差降低到可接受范围。6. 把评估流程接入日常开发6.1 触发时机这套流程不需要每次提交都跑。合理的触发时机是准备发版时、README 有重大结构调整时、更换 LLM 更新策略时。我目前的配置是在 CI 里加一个手动触发的 job输入版本区间自动跑 Changelog 聚合、策略执行、judge 评估输出一份报告。报告里包含每个策略的评分、产出 diff、以及 judge 的详细理由。人工 review 报告后决定采用哪个策略的产出。6.2 成本控制跑一次完整评估的 token 消耗取决于 Changelog 条目数量和 README 长度。在一个中等规模项目上三种策略各跑 3 次加上 judge 评估大概消耗 15 万到 20 万 token。如果用便宜的小模型做 judge成本可以压到很低。一个省钱技巧先用小模型做初筛把明显有问题的产出比如完整性评分低于 3 的过滤掉只对通过的产出用大模型做精细评估。这样能省掉大概一半的 judge 成本。6.3 持续改进的方向这套流程跑顺之后可以往几个方向扩展。一是把评估结果反馈到提示词优化上用失败案例自动生成提示词改进建议。二是把 README 更新和 Changelog 生成打通从提交信息直接生成 Changelog再驱动 README 更新形成完整链路。三是引入基于 LLM 的单元测试思路为文档更新写测试用例比如给定这组 ChangelogREADME 的配置章节必须包含新增的配置项。我在实际使用中最大的体会是LLM 在文档更新这个场景里最大的价值不是写得比人好而是不会忘记。人维护文档最大的问题是遗漏模型不会遗漏只要你把输入给全了。所以整套流程的设计重心应该放在如何把变更信息完整、结构化地喂给模型以及如何用评估机制兜住模型的幻觉风险。把这两件事做好文档同步的自动化就成功了一大半。