大模型驱动的 API 文档自动生成与接口契约治理落地

日期:2026-08-17

一、项目背景

我们微服务接口上百个,文档一直靠人写。开发改了接口字段,文档忘更,或者更了半截,前端按旧文档接进来一堆 500。联调会上有一半时间在对齐字段名和类型,谁都说不清到底以代码为准还是以文档为准。更麻烦的是历史接口,换了几拨人,文档和代码早就各走各路,新同事接手一个老接口要先猜半天。我们算了下,联调返工大半是文档和代码对不上引起的。

二、落地场景

现在文档不再手写,而是从代码注解自动生成。每个接口写好注解,标注路径、参数、返回、错误码,流水线在构建时抽出这些注解,生成在线 API 文档,和当次代码版本绑定。契约治理接在变更评审环节,有人改了接口,系统比对新旧契约,把破坏性变动标红,评审的人一眼能看到哪些调用方会受影响。文档和代码同版本存,想看某个历史版本的接口长什么样,直接调那个版本的文档。

三、关键技术挑战与解决思路

首先要解决的是注解覆盖率,代码里一半接口没写注解,生成出来残缺,我们把它接进门禁,构建时注解覆盖不够就不让合并,逼着大家补。接着要解决的是契约差异误报,字段改个注释也标红就太吵,我们做了语义级比对,只把类型、必填、路径这类真破坏兼容的变动算破坏,纯描述改动画线不报警。还有一块难啃的是文档与代码同步,我们让文档生成挂在同一个构建产物里,代码发哪版文档就跟到哪版,不用专人去点发布。

案例片段(已脱敏): 注解提取与契约差异检测配置片段(字段示意):doc_gen:  source: code_annotation  gate: { min_coverage: 0.9 } contract_diff:    level: semantic    breaking: [type, required, path]    ignore: [description, example]    on_breaking: block_in_review一次拦截:某接口把 response 里 order_status 由 string 改为 enum,契约差异标红,评审发现 3 个调用方依赖原 string,提前改完才合入,避免了一次线上 500 潮。

四、效果数据

文档与代码一致率从之前的大约六成提到九成以上,因为文档跟着代码走,没人手写就没人写错。联调返工下降明显,前端按自动生成的文档接,字段对不上的情况少了一大半。契约破坏拦截数累计抓到几十起,基本都是改了类型或必填忘了通知调用方。文档更新时效从按天算收到构建即更新。得坦白,注解覆盖率门禁刚上时开发怨声载道,但为了治这个老大难,我们顶住压力没放开。

五、可复用经验总结

接口文档这事,手写就是个错题,人写着写着就和代码分家,这是规律不是意外。从代码注解自动生成,等于把文档的真相源钉死在代码上,谁也赖不掉。契约差异卡在评审环节,比等前端报错再回头找人要省力得多,那次 order_status 改成 enum 要是放出去,又是一轮线上救火。覆盖率门禁我后来觉得该更早立,越早立阻力越小,拖到后面接口成百上千再补注解才是真折磨。这套做法我们正往其他语言栈的团队推。

结语

接口文档手写就是个错题,人写着写着就和代码分家,这是规律不是意外。从代码注解自动生成,等于把文档真相源钉死在代码上,谁也赖不掉。契约差异卡在评审环节,比等前端报错再回头找人要省力得多,那次 order_status 改成枚举要是放出去,又是一轮线上救火。注解覆盖率门禁我后来觉得该更早立,越早立阻力越小,拖到后面接口成百上千再补注解才是真折磨,开发当时的抱怨是必经之路。现在文档跟代码同版本,想看老接口长什么样直接调对应版本,新同事接手老系统不再靠猜。我们把契约破坏的调用方清单自动列在评审页,改接口的人一眼看到谁会受影响,沟通的力气从联调会挪到了评审前。语义级比对我们只把类型、必填、路径这类真破坏兼容的变动算破坏,纯描述改动不报警,误报少了大家才信这套。联调返工我们量过,文档代码一致后下降一大半,前端五百错少了很多。契约破坏拦截几十起,基本是改类型或必填忘通知调用方。我们当初吃过联调返工的亏才下决心治,现在前端后端关系都缓和了,这额外收益当初没料到。注解覆盖门禁我们设了百分之九十,低于就卡合并,开发从抱怨到习惯只用了两周。契约破坏那次 order_status 案例我们写进了评审模板,改类型必看调用方。文档和代码同版本后,我们甚至敢让客户看最新接口,透明度反而成了卖点。

注解覆盖门禁设了百分之九十,低于就卡合并,开发从抱怨到习惯只用了两周。联调返工我们量过,一致后下降一大半,前端五百错少了很多。语义级比对我们只把类型、必填、路径这类真破坏兼容的变动算破坏,纯描述改动不报警,误报少了大家才信这套。契约破坏的调用方清单自动列在评审页,改接口的人一眼看到谁会受影响,沟通的力气从联调会挪到了评审前。这套正往其他语言栈推,复用起来比想象顺,前端后端的关系都缓和了,这额外收益当初没料到。