AI生成接口文档,应先从当前项目找出路由、字段校验、权限和测试响应,再整理成可调用的契约。不要从接口名称猜参数,也不要把追踪ID当成幂等键。先让AI列出证据和冲突,再核对成功、失败与重复请求,才能减少前后端联调时的反复确认。
有本地代码与测试文件时,可以用墨刀AI客户端分析项目并整理接口文档,把路由、Schema、错误处理与最近变更放在同一个任务中。下面保留从盘点到交付的流程,并用一份成员导入契约串起字段表、cURL、响应和OpenAPI,帮助你检查这些产物是否说的是同一件事。

为什么接口文档要以代码和测试为证据
手写文档最常见的失真有三种:文档写了新字段但代码没有;代码改变了错误码但文档没更新;示例能成功,却没有说明鉴权、幂等、分页和失败恢复。AI如果只读一份旧文档,会把这些错误放大成一份看似完整的说明。
因此,墨刀AI客户端处理接口文档时,应优先读取当前分支的路由注册、控制器或处理函数、请求/响应模型、校验规则、错误定义、测试脚本和最近变更,再把人工文档作为背景或补充。没有证据的字段要标记为“待确认”,不要为了填满表格而猜测。
准备本地项目:给AI一张接口证据地图
建议先建立一个接口文档任务目录,或者在已有项目中明确以下入口:
| 证据位置 | 重点读取内容 | 文档产物 |
|---|---|---|
| 路由/控制器 | HTTP方法、路径、处理入口、版本前缀 | 接口清单、调用顺序和权限入口 |
| Schema/DTO/类型 | 字段类型、必填、枚举、默认值和嵌套结构 | 请求与响应字段表 |
| 校验/错误定义 | 错误码、错误消息、状态码、业务失败条件 | 错误处理和排查说明 |
| 认证中间件 | 登录方式、角色、权限、令牌和租户范围 | 鉴权、权限和安全注意事项 |
| 测试与样例 | 真实请求、响应、边界数据和失败场景 | 可复制的联调示例与验证依据 |
| 变更记录 | 新增、删除、废弃、兼容和迁移说明 | 版本差异和升级提醒 |
如果项目使用多个服务,先让AI输出服务、路由和版本的清单,再选择一个业务域深入;不要在第一轮把所有微服务混成一张巨大表格。关于本地文件边界,可参考墨刀AI本地项目怎么用。
第一步:生成接口清单,而不是直接写长文
接口文档的第一产物应该是一张可核对的清单,至少包括:接口ID、方法、路径、版本、模块、鉴权、稳定性、状态和证据文件。让研发先确认“有没有漏接口、有没有把内部接口当公开接口”,再生成详细章节。 下表沿用一个成员管理模块说明清单如何写;其中角色、稳定性和路径要替换为自己项目核实后的结果。
| 接口ID | 方法与路径 | 用途 | 鉴权/状态 | 证据 |
|---|---|---|---|---|
| MEMBER-001 | POST /v1/members/import | 批量导入成员 | 管理员;草稿 | 路由、控制器、接口测试 |
| MEMBER-002 | GET /v1/members | 分页查询成员 | 团队成员;稳定 | 路由、Schema、前端调用 |
| MEMBER-003 | DELETE /v1/members/{id} | 移除成员 | 管理员;需审计 | 控制器、权限测试、审计日志 |
清单中的“状态”很重要。把内部调试接口、已废弃接口、实验版本和公开联调接口区分开,能避免其他团队误用。若状态无法从代码和变更中确认,输出“需要负责人确认”,不要自行判断。
第二步:生成字段表,把规则写在字段旁边
字段表不应只列名称和类型。联调最需要的是必填、来源、格式、枚举、默认值、脱敏、空值和错误条件:
| 位置与字段 | 类型/必填 | 要从项目核实的规则 | 常见遗漏 |
|---|---|---|---|
| 请求体 team_id | string/是 | 团队是否存在,调用人是否有该团队管理权限 | 只校验已登录,没有校验所属团队 |
| 请求体 role | string/是 | 允许的枚举,作用于整批还是单个成员 | 文档写了默认值,实现却要求必填 |
| 请求体 members | array/是 | 成员字段、数量、邮箱格式、重复项和整批失败规则 | 只定义数组,没有定义数组元素 |
| 请求头 Idempotency-Key | string/按接口约定 | 键的作用域、有效期、同键不同请求体如何处理 | 把网络重试变成两次写入 |
| 响应头 X-Request-ID | string/由服务生成 | 用于关联一次请求的日志与问题反馈 | 误以为有追踪ID就具备幂等性 |
对于嵌套数组、金额、时间、时区、文件和富文本,要求AI提供最小有效值、最大边界值和非法示例。不要让“可选”掩盖“空字符串是否等同于未传”的差异。
第三步:补齐鉴权、错误、幂等和分页
一份接口文档是否能减少联调来回,往往取决于这些非成功路径:
- 鉴权:需要什么令牌、角色、团队或项目权限,权限不足返回什么。
- 错误:状态码、业务错误码、可展示消息、重试建议和排查字段。
- 幂等:重复提交如何判定,网络重试会不会创建多份数据。
- 分页:页码还是游标、默认和最大条数、排序稳定性和总数语义。
- 限流:频率限制、响应头、退避方式和恢复时间。
- 版本:兼容策略、废弃时间、字段新增和删除规则。
让AI从错误定义和测试脚本中找证据,找不到时列成待确认项。不要依据常见框架习惯自动编造错误码或重试规则。
一份从请求到响应都能对齐的接口文档
下面以“管理员批量导入团队成员”为例,把文档中最容易分离的几部分放在一起。例子约定整批成功或整批拒绝,同批成员使用同一角色;最多100名成员、幂等键保留24小时是这份契约的设计条件,不是所有接口的通用规则。地址使用保留测试域名,实践时替换成自己的测试服务与真实约定。
1. 先固定输入、权限和一次操作的结果
POST /v1/members/import接收团队ID、角色和成员列表。调用人需持有有效令牌,并有目标团队的管理权限。role只接受viewer或editor;members包含1至100项,每项必须有合法邮箱和1至80个字符的姓名。请求中的邮箱不能重复,目标团队也不能已存在其中任一邮箱。任一条件不满足时,不导入其他成员。
把下面内容保存为request.json。它应同时作为文档示例、契约中的example和测试夹具,避免三处各写一份逐渐失去同步。
{
"team_id": "tm_1001",
"role": "viewer",
"members": [
{
"email": "lin@example.com",
"name": "林同学"
},
{
"email": "zhou@example.com",
"name": "周同学"
}
]
}
2. 用可复制的cURL暴露缺失条件
将地址与令牌替换为自己的测试环境后执行。命令采用Bash续行写法;Windows PowerShell可使用curl.exe,将参数合并为一行后执行。成功请求的必要条件要写在命令中,包括方法、Content-Type、认证和幂等键。
curl --request POST 'https://api.example.test/v1/members/import' \
--header 'Authorization: Bearer YOUR_TEST_TOKEN' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: import-team1001-20261010-001' \
--data-binary @request.json
Idempotency-Key由调用方为这一批操作生成。网络断开后的重试保持键与请求内容相同;换一批成员或修改角色时使用新键。本例在同一调用人、团队和路径下保留键24小时,同键同内容返回原业务结果,不再次新增;同键不同内容返回409。X-Request-ID则由服务为每次HTTP请求返回,便于查日志,不负责防止重复创建。
3. 成功、校验失败与重试冲突分别返回什么
成功状态码为200,返回实际导入数量和成员ID;本例数量应为2,ID数量也应为2。不能只检查HTTP成功就忽略业务结果。
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-ID: req_1001
{
"imported_count": 2,
"member_ids": [
"mem_101",
"mem_102"
]
}
如果第二个邮箱不合法,返回400,指出出错字段,整批没有写入。调用方修改输入后再提交,不应自动反复重试同一非法请求。
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Request-ID: req_1002
{
"code": "INVALID_REQUEST",
"message": "成员邮箱格式不正确",
"field": "members[1].email"
}
| HTTP状态/业务码 | 含义 | 调用方下一步 |
|---|---|---|
| 400/INVALID_REQUEST | 字段、格式、数量或批内重复邮箱不合法 | 根据field定位输入;修正后再提交 |
| 401/UNAUTHENTICATED | 令牌缺失或无效 | 重新获取有效凭据,不展示为“导入成功” |
| 403/FORBIDDEN | 没有目标团队管理权限 | 核对团队和权限,重复点击不能解决 |
| 409/IDEMPOTENCY_CONFLICT | 同一个键对应不同请求内容 | 先确认原批次结果;新操作使用新键 |
| 409/MEMBER_EXISTS | 某成员已经在目标团队,整批拒绝 | 核对已有成员并调整批次,不把其余成员当已成功 |
这张表中的条件应在服务代码与测试中逐条对应。项目若采用部分成功,响应就必须另外定义每项结果和重试范围;不能只把“整批拒绝”四个字删掉,保留同一份成功示例。
4. 将同一份约定整理成OpenAPI
OpenAPI 3.1.0规范允许用结构化定义描述路径、参数、请求体、响应与安全方案。下面的JSON可保存为member-import.openapi.json,导入支持该版本的校验或文档工具。它与上面的路径、字段和响应一致;邮箱是否已存在、幂等键的存储以及整批事务仍需服务端实现,Schema本身不会替你执行这些业务规则。
完整OpenAPI契约,可复制保存
{
"openapi": "3.1.0",
"info": {
"title": "团队成员导入契约练习",
"version": "1.0.0",
"description": "用于说明文档字段、示例与契约如何保持一致;不是墨刀公开服务。"
},
"servers": [
{
"url": "https://api.example.test"
}
],
"paths": {
"/v1/members/import": {
"post": {
"operationId": "importMembers",
"summary": "原子批量导入团队成员",
"description": "调用人必须为目标团队管理员。同一请求中邮箱不能重复;任一成员已存在则整批拒绝。幂等键按调用人、团队和路径分区,保留24小时;同键同内容重试返回原业务结果,同键不同内容返回409。",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"description": "调用方生成的批次键;网络重试保持不变,新批次使用新键。"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ImportRequest"
},
"example": {
"team_id": "tm_1001",
"role": "viewer",
"members": [
{
"email": "lin@example.com",
"name": "林同学"
},
{
"email": "zhou@example.com",
"name": "周同学"
}
]
}
}
}
},
"responses": {
"200": {
"description": "全部成员导入成功,或同键同内容重放原业务结果。",
"headers": {
"X-Request-ID": {
"$ref": "#/components/headers/RequestId"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ImportResponse"
},
"example": {
"imported_count": 2,
"member_ids": [
"mem_101",
"mem_102"
]
}
}
}
},
"400": {
"description": "INVALID_REQUEST:请求格式、字段、数组数量或批内重复邮箱不合法;没有写入。",
"$ref": "#/components/responses/BadRequest"
},
"401": {
"description": "UNAUTHENTICATED:令牌缺失或无效;没有写入。",
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"description": "FORBIDDEN:没有目标团队管理权限;没有写入。",
"$ref": "#/components/responses/Forbidden"
},
"409": {
"description": "IDEMPOTENCY_CONFLICT:同键不同内容;MEMBER_EXISTS:邮箱已在团队中。两种情况都不新增成员。",
"$ref": "#/components/responses/Conflict"
}
}
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer"
}
},
"headers": {
"RequestId": {
"description": "本次HTTP请求的追踪标识,不用于去重。",
"schema": {
"type": "string"
}
}
},
"schemas": {
"ImportRequest": {
"type": "object",
"additionalProperties": false,
"required": [
"team_id",
"role",
"members"
],
"properties": {
"team_id": {
"type": "string",
"minLength": 1
},
"role": {
"type": "string",
"enum": [
"viewer",
"editor"
]
},
"members": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"email",
"name"
],
"properties": {
"email": {
"type": "string",
"format": "email"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
}
}
}
}
}
},
"ImportResponse": {
"type": "object",
"additionalProperties": false,
"required": [
"imported_count",
"member_ids"
],
"properties": {
"imported_count": {
"type": "integer",
"minimum": 1,
"maximum": 100
},
"member_ids": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"uniqueItems": true,
"items": {
"type": "string"
}
}
}
},
"ApiError": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"enum": [
"INVALID_REQUEST",
"UNAUTHENTICATED",
"FORBIDDEN",
"IDEMPOTENCY_CONFLICT",
"MEMBER_EXISTS"
]
},
"message": {
"type": "string"
},
"field": {
"type": "string"
}
}
}
},
"responses": {
"BadRequest": {
"description": "请求无效,整批没有写入。",
"headers": {
"X-Request-ID": {
"$ref": "#/components/headers/RequestId"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
},
"example": {
"code": "INVALID_REQUEST",
"message": "成员邮箱格式不正确",
"field": "members[1].email"
}
}
}
},
"Unauthorized": {
"description": "令牌缺失或无效,没有写入。",
"headers": {
"X-Request-ID": {
"$ref": "#/components/headers/RequestId"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
},
"example": {
"code": "UNAUTHENTICATED",
"message": "请提供有效的测试令牌"
}
}
}
},
"Forbidden": {
"description": "没有目标团队管理权限,没有写入。",
"headers": {
"X-Request-ID": {
"$ref": "#/components/headers/RequestId"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
},
"example": {
"code": "FORBIDDEN",
"message": "没有该团队的成员管理权限"
}
}
}
},
"Conflict": {
"description": "幂等键冲突或成员已经存在,没有新增成员。",
"headers": {
"X-Request-ID": {
"$ref": "#/components/headers/RequestId"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
},
"example": {
"code": "IDEMPOTENCY_CONFLICT",
"message": "该幂等键已用于不同的请求内容"
}
}
}
}
}
}
}检查时先让工具解析文件,再用同一份request.json和响应样本核对Schema。解析通过只表示结构可读;还要分别验证成功、非法邮箱、无权限、同键重试和同键不同内容,才能知道实现是否遵守契约。
契约确认后,若后端尚未就绪,可以按接口契约生成本地Mock,让前端先联调成功、空列表与服务失败三种响应,再与真实接口核对。
AI生成API文档提示词模板
| 部分 | 可复用写法 |
|---|---|
| 范围 | 只分析【服务/目录/分支】中的公开业务接口,不包含内部调试路由和已废弃版本。 |
| 证据优先级 | 以当前路由、处理函数、Schema、错误定义和接口测试为准;人工文档用于补充,冲突必须列出。 |
| 输出结构 | 先给接口清单,再按接口输出用途、权限、请求、响应、错误、幂等、分页、示例、版本和变更说明。 |
| 示例规则 | 只使用项目中的脱敏测试数据,给出一个最小成功示例和至少一个失败示例。 |
| 格式 | 输出为可评审 Markdown;如果建议 OpenAPI 结构,先说明字段来源与无法确认的部分。 |
| 限制 | 不修改源码,不执行生产请求,不虚构未找到的字段、状态码或鉴权规则。 |
Markdown适合阅读与评审,OpenAPI适合描述结构化契约。可以先让AI把已确认字段整理成OpenAPI文本,再用团队工具解析、校验并与测试响应比较;生成一段定义文本,与工具已经支持一键发布接口文档,是两件不同的事。
接口变更时,让AI生成差异说明
接口文档最容易在发布后失效。每次变更可以让客户端比较基线和当前分支,输出:
- 新增:新接口、新字段、新枚举和新错误。
- 修改:类型、必填、默认值、权限、状态码和业务语义变化。
- 废弃:旧接口或字段的替代方式、迁移时间和兼容窗口。
- 风险:可能影响的调用方、前端页面、脚本和测试。
- 验证:需要更新的契约测试、集成测试、示例和监控。
把差异说明与代码提交或版本号关联,联调人员就能快速知道自己需要更新什么。若项目使用Git,可以先查看AI生成的差异,再将确认后的文档放进评审目录,不要直接覆盖历史版本。
联调前的接口文档验收清单
| 检查项 | 通过标准 |
|---|---|
| 路径和方法 | 能在当前代码和路由注册中找到,版本前缀一致 |
| 鉴权与权限 | 成功、未登录、无权限和跨团队场景均有说明 |
| 字段规则 | 必填、类型、枚举、空值、长度、默认值和脱敏明确 |
| 错误处理 | 常见状态码、业务码、消息和重试边界可观察 |
| 数据语义 | 时间、金额、时区、分页、排序和一致性说明清楚 |
| 示例可复现 | 使用脱敏测试数据,响应与实际测试或运行结果一致 |
| 版本与差异 | 新增、修改、废弃和兼容窗口有负责人确认 |
验收时最好用一个真实的联调请求逐项走过文档。如果字段表写得很完整,但示例无法运行,仍然不能算交付完成。

把API文档交给产品、前端和测试
可按下面的最小目录交付,把人工说明、机器契约与测试数据放在同一版本中。让AI负责补齐缺项与对照差异,负责人确认后再合并。
docs/api/members/
README.md 用途、权限、调用顺序与待确认问题
member-import.openapi.json 已评审的结构化契约
examples/request.json 与文档一致的最小请求
examples/success.json 当前测试环境的成功响应
examples/error.json 当前测试环境的失败响应
changes.md 本次提交、兼容影响与验证结果验收记录至少写明:代码提交号、测试环境、执行日期、请求文件、状态码、响应样本、结论和负责人。把“看过文档”改成“按指定版本调用并核对结果”,交付才有明确完成条件。
产品关心能力边界和业务状态,前端关心字段、错误和示例,测试关心可验证条件,运维关心版本、限流、日志和告警。交接时建议附上接口清单、变更差异、待确认问题、测试证据和负责人,而不是只发一个没有版本号的链接。
需要团队共同评论、管理版本或把接口说明和原型放在一起时,可以把确认后的材料带入墨刀工作台与企业空间;客户端安装与能力边界见墨刀AI客户端使用指南。
AI生成接口文档的七个常见错误
- 只读旧文档,不看当前路由和测试。
- 把内部调试接口混入公开接口清单。
- 只写成功响应,没有错误、权限和重试。
- 把可选字段、空值和默认值混为一谈。
- 示例使用真实密钥、客户数据或不可复现的环境。
- 新增字段写进文档,却没有说明兼容和版本。
- 生成后直接覆盖旧文档,丢失变更和回滚依据。
常见问题
墨刀AI客户端能自动从代码发布API文档吗?
生成API文档后,先由研发对照代码和测试响应核对字段、鉴权与错误码,再按团队流程导出、发布和联调。需要OpenAPI等标准格式时,应另外检查字段结构及项目工具是否支持,不能只把排版后的文字当成可直接导入的定义文件。
接口文档必须使用OpenAPI吗?
不一定。Markdown 适合评审和快速交接,OpenAPI 适合工具链消费。先保证内容以真实代码和测试为证据,再根据团队需要选择格式,不要为了格式而补写不存在的规则。
代码和文档冲突时以谁为准?
先暂停自动生成,列出冲突位置、版本和影响,交给接口负责人确认。代码也可能处于未发布分支,不能脱离版本语境简单地说“代码永远正确”。
如何防止接口文档越写越长?
先用接口清单筛选公开和当前版本,再按调用方需要组织章节。把内部实现细节、历史变更和联调示例分层展示,首屏先给能完成调用所需的信息。
AI生成接口文档的核心,是把真实代码、测试和版本变化翻译成团队可以共同遵守的契约。用墨刀AI客户端先盘点证据,再生成字段、错误、示例和差异,最后用一次真实联调验证,文档才会真正减少沟通成本。需要开始本地项目任务时,可先下载墨刀AI客户端。