ChatGPT充值后,很多开发者会使用 Codex 编写接口、补充参数说明,或者根据现有代码生成 Swagger、OpenAPI 文档。

刚开始时,文档看起来很完整,但项目继续迭代后,经常出现一些问题:

  • 文档写的是字符串,接口实际返回数字;

  • 请求参数已经删除,文档中仍然存在;

  • 接口返回了新的字段,前端却不知道;

  • 状态码说明与真实行为不一致;

  • 示例数据可以参考,但无法通过实际校验;

  • 测试环境文档正常,生产接口却使用旧版本;

  • Codex修改了业务代码,却没有同步更新文档。

这类问题通常不是文档工具失效,而是项目把接口代码和接口说明当成了两套独立内容。

接口一旦发生变化,就需要开发者手动修改多处。时间一长,文档自然会逐渐失真。

一、为什么API文档很容易过期?

一个接口通常同时存在于多个位置:

后端路由
请求参数类型
响应数据类型
接口文档
前端调用代码
自动化测试

例如,原来的用户接口返回:

{
  "id": 1001,
  "name": "Tom"
}

后续业务增加了状态字段:

{
  "id": 1001,
  "name": "Tom",
  "status": "active"
}

如果 Codex 只修改后端返回值,却没有同步更新 OpenAPI Schema、类型声明和前端接口定义,就会出现多个版本。

因此,接口文档不一致的根本原因通常是:

接口结构没有唯一可信来源。

二、先确定谁是接口的唯一来源

项目中常见两种方案。

Code First

先编写接口代码和类型,再从代码生成 OpenAPI 文档。

这种方式适合已经存在大量后端代码的项目。

优点是:

  • 文档更接近实际实现;

  • 减少重复编写;

  • 修改类型后可以重新生成;

  • 适合快速迭代。

风险是:

  • 注解不完整时文档仍会缺失;

  • 运行时返回结果可能绕过类型;

  • 部分动态逻辑难以自动推导。

Schema First

先编写 OpenAPI Schema,再根据契约生成服务端类型、客户端代码和测试。

这种方式适合前后端协作、多团队开发和接口稳定性要求较高的项目。

优点是:

  • 开发前先明确接口;

  • 前端可以提前生成客户端;

  • 更容易进行契约测试;

  • 不同服务使用同一份定义。

风险是:

  • Schema修改后必须同步生成代码;

  • 团队需要维护接口版本;

  • 不能绕过Schema直接修改响应结构。

两种方案都可以使用,关键是项目必须明确哪一份文件具有最高优先级。

三、不要让Codex同时维护多份相同定义

一个常见问题是,同一个用户结构被写在多个地方:

interface User {
  id: number;
  name: string;
}

OpenAPI中又写一遍:

User:
  type: object
  properties:
    id:
      type: integer
    name:
      type: string

前端项目再写一遍:

type UserResponse = {
  id: number;
  name: string;
};

这些定义最开始可能完全一致,但后续任何一次修改都可能漏掉其中一个位置。

更稳妥的方式是建立生成流程:

OpenAPI Schema
→ 生成后端类型
→ 生成前端客户端
→ 生成接口Mock
→ 执行契约测试

或者:

后端类型与路由
→ 自动生成OpenAPI
→ 前端根据OpenAPI生成客户端

不要让 Codex 每次手动复制字段。

四、使用Schema校验真实返回值

即使 TypeScript 编译通过,也不能保证运行时返回值一定符合文档。

例如:

return {
  id: user.id,
  status: undefined
};

类型可能因为错误断言而通过,但真实 JSON 中字段可能缺失。

可以在接口出口增加运行时 Schema 校验。

伪代码如下:

const UserResponseSchema = z.object({
  id: z.number(),
  name: z.string(),
  status: z.enum(["active", "disabled"])
});

const response = UserResponseSchema.parse({
  id: user.id,
  name: user.name,
  status: user.status
});

return response;

这样,如果接口返回内容与约定不一致,问题会在服务端测试或预发布阶段暴露,而不是等前端运行时报错。

五、状态码也属于接口契约

很多文档只描述成功返回值,却忽略错误状态。

例如登录接口可能包含:

200:登录成功
400:参数格式错误
401:账号或密码错误
403:账号被禁用
429:请求过于频繁
500:服务异常

如果文档只写 200,前端就无法稳定处理其他情况。

让Codex生成接口文档时,可以明确要求:

请为当前接口补充完整契约:

1. 请求参数;
2. 必填与可选字段;
3. 成功响应;
4. 错误状态码;
5. 每种错误的返回结构;
6. 字段示例;
7. 兼容性说明。

错误结构也应尽量统一:

{
  "code": "USER_DISABLED",
  "message": "当前账号不可用",
  "traceId": "req-8f21a7"
}

六、接口示例必须可以通过Schema验证

有些文档中的示例只是为了好看,并不符合真实定义。

例如Schema规定:

id:integer
createdAt:date-time

示例却写成:

{
  "id": "1001",
  "createdAt": "today"
}

这类示例会误导前端和测试人员。

建议在CI中增加验证:

OpenAPI语法检查
→ Schema完整性检查
→ 示例数据校验
→ 客户端生成测试

如果示例无法通过Schema,就不允许合并。

七、使用契约测试检查前后端是否一致

契约测试关注的不是内部实现,而是接口是否符合约定。

例如前端依赖:

{
  "id": 1001,
  "status": "active"
}

契约测试可以验证:

  • id始终存在;

  • id类型为数字;

  • status只允许指定值;

  • 错误响应包含统一字段;

  • 删除字段时必须升级版本。

可以要求Codex补充:

请根据OpenAPI为当前接口生成契约测试。

重点验证:

- 请求参数类型;
- 必填字段;
- 成功响应结构;
- 错误响应结构;
- 状态码;
- 示例数据;
- 已有字段不能被意外删除。

八、删除字段要经过兼容周期

接口新增字段通常风险较低,删除或改名风险更高。

例如将:

user_name

改为:

username

如果直接删除旧字段,仍然使用旧版本的客户端会立即出错。

更合理的流程是:

第一阶段:同时返回user_name和username
第二阶段:文档标记user_name已废弃
第三阶段:统计旧字段使用情况
第四阶段:新版本正式删除旧字段

OpenAPI中可以标记:

user_name:
  type: string
  deprecated: true

Codex修改字段名称时,不应只调整当前代码,还要输出兼容性影响。

九、为接口定义版本策略

当接口发生不兼容变化时,需要考虑版本管理。

常见方式包括:

/api/v1/users
/api/v2/users

或者通过请求头指定版本。

但版本也不能无限增加。

建议记录:

  • 当前支持哪些版本;

  • 每个版本的差异;

  • 旧版本停止维护时间;

  • 哪些客户端仍在使用;

  • 是否提供迁移说明。

小型项目不一定需要复杂的多版本系统,但重大破坏性修改必须有明确过渡方式。

十、把接口规则写入AGENTS.md

长期项目可以加入:

# API契约规则

- 接口结构必须有唯一可信来源
- 不允许手动维护多份重复类型
- 修改接口后必须同步更新OpenAPI
- 请求和响应示例必须通过Schema校验
- 所有错误状态码必须有明确说明
- 删除或改名字段必须提供兼容周期
- 不允许使用any绕过接口类型
- 修改公共接口后必须执行契约测试
- OpenAPI变更必须进入代码审查

这样,Codex修改接口时会同时考虑文档、类型和兼容性,而不是只让当前请求运行成功。

十一、在CI中增加文档一致性检查

建议将接口检查加入自动化流程:

代码检查
→ 生成OpenAPI
→ 检查是否产生未提交差异
→ 校验Schema
→ 验证示例
→ 生成客户端
→ 执行契约测试

如果重新生成的OpenAPI与仓库中的文件不一致,说明开发者修改了接口,却没有提交最新文档。

这种检查比上线后依靠人工发现更加可靠。

十二、让Codex输出接口变更报告

任务结束时,可以要求:

本轮接口变化:

- 新增status字段
- 新增403错误响应
- username改为必填

兼容性:

- 未删除已有字段
- 旧客户端仍可使用
- 无需升级接口版本

同步内容:

- 已更新OpenAPI
- 已更新前端类型
- 已更新Mock数据
- 已补充契约测试

尚未验证:

- 移动端旧版本兼容情况

这样可以快速判断此次修改是否只是内部调整,还是会影响外部调用者。

十三、Plus适合哪些API文档任务?

如果主要使用Codex完成以下工作,Plus通常可以满足多数需求:

  • 为单个接口生成文档;

  • 补充请求与响应Schema;

  • 修复Swagger字段错误;

  • 生成简单客户端类型;

  • 增加接口示例;

  • 编写基础契约测试。

这些任务通常可以按照单个模块拆分完成。

十四、哪些情况可以评估Pro?

如果长期工作包含以下场景,可以根据实际使用强度评估Pro:

  • 同时维护多个服务的API;

  • 一个改动需要同步多个仓库;

  • 经常生成客户端和契约测试;

  • 需要连续分析后端、前端与文档差异;

  • 大型项目包含多个接口版本;

  • Codex已经参与主要开发与交付流程;

  • 当前使用空间经常影响完整验证。

对于多服务、跨仓库和需要持续保持上下文的工程场景,Pro更适合高频工作流。

但更高的使用方案不能代替接口契约。如果项目没有唯一Schema和自动检查,生成再多文档也会继续出现不同步问题。

总结

ChatGPT充值后,Codex生成的API文档与实际接口对不上,通常不是文档工具完全失效,而是接口类型、OpenAPI、前端调用和测试之间缺少统一来源。

通过Code First或Schema First建立唯一契约,结合运行时Schema校验、契约测试、版本策略和CI检查,可以减少字段错误、状态码缺失和文档过期问题。

对于单接口和中小型文档任务,Plus通常已经够用。对于多服务、多版本、需要连续同步代码、文档和客户端的高频工程场景,Pro更符合复杂工作流。

真正可靠的API文档,不是发布时看起来完整,而是在接口发生变化后,代码、类型、示例和测试都能自动保持一致。

CSDN文章描述

本文介绍ChatGPT充值后使用Codex时,如何通过OpenAPI、Schema First、运行时校验、契约测试和CI自动同步,解决API文档与实际接口不一致的问题,并分析ChatGPT Plus与Pro的适用场景。

更多推荐