要说清楚一点:这里的“接口”指的是软件服务对外提供的 API 接口,不是硬件引脚那种接口。做小项目的时候,很多人把接口设计和异常处理当成“写代码的边角料”,觉得接口嘛,能调通就行;异常嘛,try-catch 包一下就行。结果项目一旦跑起来,调用方问“这个字段什么时候为空”“报错时返回什么状态码”,你才发现当初省下的时间全变成了沟通成本和技术债。
这是小项目实战系列的第二篇,主题就是“让 AI 帮你补齐接口设计和异常处理”。我的立场很明确:AI 不是替你写代码的自动生成器,而是一个特别擅长“枚举边界情况”和“穷举设计方案”的结对搭档。你负责判断业务约束,AI 负责把那些你没想到的角落翻出来,把散落的异常场景整理成体系。这篇文章我用自己的真实小项目做例子,从怎么提问、怎么定契约、怎么设计错误码,到怎么让 AI 交叉评审,完整走一遍。适合正在做小型 Web 服务、又不想在接口文档和异常处理上花太多精力的人参考。
1. 为什么我会把接口设计这件事交给 AI?先说说我的判断
1.1 AI 适合做“穷举”,不适合直接拍板
我见过不少团队用 AI 写接口,做法是丢一句“帮我写个用户注册接口”,然后 AI 呼啦啦生成一大堆代码,看起来像模像样,但真要上线就发现:
- 没有限流和参数上限,容易被刷
- 响应结构和状态码不统一,前端要针对每个接口单独适配
- 异常处理是“catch Exception 然后返回 500”,日志里什么都查不到
问题出在哪?出在把 AI 当成了“最终决策者”。接口设计这件事,本质上不是写代码,而是两件事的叠加:第一是枚举,把所有可能需要被暴露的操作、参数、校验规则、异常情况都列出来;第二是决策,从这些候选项里挑出符合业务约束的那一组。
AI 在“枚举”这件事上非常强,因为它的知识库里见过大量接口设计模式,能帮你把“忘了写分页上限”“忘了定义幂等键”“忘了区分业务异常和系统异常”这些盲区补上。但“决策”必须由人来拍板,因为只有你知道这个项目是内部工具还是对外开放,流量预期是多少,团队能维护到什么程度。
1.2 重新定义分工:AI 出方案,我做选择和权衡
拿我最近重写的那个订单查询服务来说。业务本身不复杂:根据订单号查详情,根据用户昵称或订单状态查列表。但如果直接上手写,很容易陷入“写完能用就行”的状态。我的做法是分两轮:
第一轮,让 AI 只做“方案发散”,不写代码。我给它一段业务描述和调用场景,要求它列出所有候选接口方法、路径、参数、返回结构,包括各种备选方案和它们各自的适用场景。第二轮,我再把筛选后的方向告诉它,让它补全字段级约束、错误码、边界策略。
这样一轮下来,AI 给出的是“地图而不是答案”。我从地图里挑路,而不是被 AI 直接带跑。有个很实际的好处:当你让 AI 列出候选项时,它会顺带把各种“行业内惯例”也列出来。比如分页查询的 page_size 上限、订单号格式校验、查询列表的超时设置,这些如果靠人想,很容易漏,因为它们是“平时不会碰到、一旦碰到就出问题”的知识。
所以我的判断是:接口设计里最耗时、最需要经验的部分,恰恰是 AI 最能补的部分。人只需要守住业务边界和架构底线,剩下的枚举活、整理活、文档活,都可以扔给 AI。
提示:让 AI 做接口设计时,不要一句“帮我设计一个订单接口”就完事。它需要上下文:谁在用这个接口,数据从哪里来,最核心的业务规则是什么,未来可能有哪些扩展。上下文越是具体,AI 补出来的东西越接近可用状态。这部分我在第 4 节会给出可以直接套用的提示词模板。
2. 用一个真实小项目拆解:AI 补齐接口设计的完整链路
2.1 项目背景:订单查询服务重写,顺便把接口规范统一
我手头这个项目是给团队内部运营用的订单查询工具,原先嵌在后台系统里,接口散落在各个业务模块中:查订单详情用的路径是get_order_detail,查列表用的是order_list,参数命名也不统一。这次我借着重写的机会,把它抽成独立服务,同时把接口规范统一起来。
技术栈我选的是 Python FastAPI,原因很简单:类型提示天然友好,自动生成 OpenAPI 文档,适合作为 AI 输出代码的目标框架。数据库是 PostgreSQL,订单表就是最普通的业务表,没有特殊难点。
重写时我对 AI 说的第一句话不是“帮我写接口”,而是“帮我梳理出这个服务应该对外提供哪些接口”。我给它喂了这么一段背景:
这是一个面向内部运营团队的订单查询服务。订单数据存在 PostgreSQL,按 order_id 主键索引,同时有 user_id、status、created_at 三个常用查询字段。服务只读不写。团队内部约有 20 个调用方,包括 Web 后台和数据导出工具。请列出这个服务应该提供的接口候选清单,包括路径、请求方法、参数、响应结构,并说明每个接口解决什么业务场景。
AI 返回的候选清单比我预想的全面得多,概括下来有这么几类:
- 单条查询:
GET /api/v1/orders/{order_id},按主键精确查详情 - 条件列表查询:
GET /api/v1/orders?status=xxx&user_id=xxx&page=1&page_size=20,支持分页 - 批量查询:
POST /api/v1/orders/query,用于支持传入一组订单号,一次性返回多条 - 统计查询:
GET /api/v1/orders/stats,按状态分组返回数量,给运营后台展示用 - 导出查询:
POST /api/v1/orders/export,返回导出的异步任务 ID,避免长请求阻塞
这些接口不一定全部保留,但 AI 替我列出来之后,我再逐条判断“这个有没有人用”“现在要不要做”,决策效率高很多。最后保留了前三个,统计接口因为后台有现成报表暂时不做,导出接口因为小项目用不到异步任务,改为简单的同步 CSV 下载。
| AI 候选方案 | 我的取舍 | 原因 |
|---|---|---|
| GET 单条查询 | 保留 | 主键查询是刚需 |
| GET 条件列表查询 | 保留 | 运营日常使用最频繁 |
| POST 批量查询 | 保留 | 数据导出工具需要,避免 N+1 次请求 |
| GET 统计查询 | 暂不实现 | 已有报表系统覆盖 |
| POST 异步导出 | 改为同步下载 | 数据量不大,引入异步任务会增加维护成本 |
2.2 让 AI 补“接口契约细节”,而不仅仅是路径
第一轮明确了“有哪些接口”,第二轮就要让 AI 把每个接口的契约细节补齐。这里有个容易忽略的点:接口契约不只是路径和参数,还包括字段的校验规则、响应结构、错误场景、幂等性、分页策略。如果只让 AI 生成def get_order(order_id)这样的函数签名,那和手写没什么区别,AI 也没发挥出它的价值。
我用的提示词大概是这个方向:
为上述订单查询接口生成 OpenAPI 3.0 定义片段。要求:每个字段标注类型、是否必填、取值范围、校验规则;分页参数 page 从 1 开始,page_size 取值范围 1~100,超过上限按 100 处理;order_id 统一采用 20 位数字字符串;响应结构使用统一的 { code, message, data, trace_id } 格式;对于列表接口,data 内包含 items、total、page、page_size 四个字段。
AI 补出来的列表接口定义里,有一个细节让我印象很深:它对status参数的处理不是简单的字符串,而是列出了一个枚举:pending / paid / shipped / completed / cancelled,然后提醒我“如果业务状态未来会扩展,建议这里用字符串而不是枚举类型,避免接口升级时需要迁移”。这是个很典型的“行业惯例知识”——后来的调用方果然传了一批我没想到的自定义状态值,如果当初用了枚举类型,接口直接就挂了。
对这个接口的最终设计,我整理成了一张契约表:
| 项 | 规则 |
|---|---|
| 路径 | /api/v1/orders |
| 方法 | GET |
| 查询参数 | status(可选,字符串)、user_id(可选,字符串)、page(默认 1)、page_size(默认 20,最大 100) |
| 排序 | 默认按 created_at 倒序 |
| 响应结构 | { code, message, data, trace_id } |
| 分页字段 | data.items、data.total、data.page、data.page_size |
| 主键校验 | order_id 为 20 位数字字符串,不匹配返回参数错误 |
我个人的经验是:契约细节这一轮,是最不值得人肉去写的一轮,但也是必须让 AI 有足够上下文的一轮。你告诉它的约束越明确,它输出的方案就越贴近真实需求。不要嫌提示词写得长,在这个阶段多写两行字,后面少改十次代码。
2.3 给 AI 喂“行业惯例”,它才知道怎么补盲区
很多人在用 AI 做接口设计时觉得“AI 生成的也不怎么样”,原因往往不是 AI 能力不行,而是你没告诉它行业惯例。举个直观的例子:如果我直接说“帮我写个列表查询接口”,AI 大概率会写一个分页接口出来,但它不一定会主动处理:
- page_size 上限(防止有人传 100000 把数据库打爆)
- 游标分页还是偏移分页的选择依据(偏移分页在深分页时性能差)
- 查询超时限制(防止慢查询拖垮服务)
- 列表字段脱敏(订单涉及用户信息,内部工具也不能随便暴露)
- 响应中的 trace_id(方便链路排查)
这些规则在大多数项目的接口规范文档里都有,但它们属于“约定俗成”的隐性知识。你要做的,是在提示词里显式地把这些“行业惯例”列为约束条件,让 AI 在生成时逐条对照。
我在第 2 轮提示词里会加一句固定的尾巴:
请假设输出代码要用于生产环境。因此需要考虑:输入参数校验、分页上限、超时控制、日志埋点、响应体统一封装。不要省略这些处理。
就是这句话,让 AI 从“能跑的代码”升级成了“能上线的代码”。我自己实测下来,这个步骤贡献了至少一半的项目质量提升。
3. 异常处理怎么“补齐”?让 AI 枚举边界场景的实战方法
3.1 别让异常处理变成“随缘 try-catch”
先说我见过的最常见的异常处理写法:
try: order = db.query(Order).filter(Order.order_id == order_id).first() return OrderDetailSchema.from_orm(order) except: return {"code": 500, "message": "系统错误"}这段代码问题很多,但最要命的是它把“订单不存在”“数据库连接超时”“参数格式错误”全部变成了一句话:系统错误。结果就是调用方收到错误后完全不知道该不该重试、该不该找客服、是它自己的问题还是服务端的问题。
异常处理这件事,我认为它真正的难点不在写 catch,而在提前想清楚系统可能会遇到哪些异常,这些异常分别应该以什么方式暴露给调用方。这一步,AI 的“穷举能力”能帮上大忙。
3.2 用 AI 生成“异常分类清单”
我在项目里做异常处理时,第一步不是写代码,而是让 AI 穷举异常场景。我给它的是之前定好的三个接口契约,加一句:
针对这些接口,列出所有可能出现的异常情况。对每个异常,给出:触发场景、错误码、HTTP 状态码、调用方应该采取的处理策略(重试 / 提示用户 / 反馈管理员)。
AI 给出了一份分类清单,整理后大概是这样的表格:
| 异常类型 | 触发场景 | 错误码 | HTTP 状态码 | 处理策略 |
|---|---|---|---|---|
| 参数错误 | 必填字段缺失、格式错误、page_size 超上限 | 10001 | 400 | 提示调用方修改请求 |
| 订单不存在 | order_id 在数据库中无记录 | 10002 | 404 | 提示用户核对订单号 |
| 服务内部错误 | 数据库连接失败、未预期的异常 | 10500 | 500 | 反馈管理员,可短暂重试 |
| 上游依赖超时 | 内部用户服务响应超时(若有依赖) | 10503 | 503 | 可重试,建议指数退避 |
| 并发冲突 | 同一订单被同时操作(本服务只读,但为将来写操作设计) | 10003 | 409 | 提示用户稍后重试 |
这张表的价值在于:它让团队在写任何一行异常处理代码之前,就对“系统哪些地方会出问题”达成了一致。调用方也知道收到 10001 时去查参数,收到 10503 时去查依赖服务。
当然,AI 给的清单不是拿来就直接用的。我当时就砍掉了一项“上游依赖超时”,因为这个小项目根本没依赖外部用户服务;我也补了一项“数据为空列表”的处理——这个不是异常,但 AI 在枚举时把空列表和异常混在了一个维度里,需要人工把它拿出来。
3.3 错误码体系与全局异常处理框架
有了分类清单,下一步才是让 AI 生成代码。我的要求是:错误码用枚举值定义,所有接口统一走全局异常处理器,禁止在业务代码里到处散落 error 判断。
AI 生成的 FastAPI 全局异常处理框架,裁剪后大概长这样:
class ErrorCode(enum.Enum): PARAM_ERROR = (10001, "参数错误", 400) ORDER_NOT_FOUND = (10002, "订单不存在", 404) CONFLICT = (10003, "操作冲突,请稍后重试", 409) INTERNAL_ERROR = (10500, "系统内部错误", 500) SERVICE_UNAVAILABLE = (10503, "服务暂不可用,请稍后重试", 503) class BizException(Exception): def __init__(self, error_code: ErrorCode, detail: str = ""): self.code = error_code self.detail = detail @app.exception_handler(BizException) async def biz_exception_handler(request, exc: BizException): return JSONResponse( status_code=exc.code.value[2], content={ "code": exc.code.value[0], "message": exc.detail or exc.code.value[1], "data": None, "trace_id": request.state.trace_id, }, ) @app.exception_handler(Exception) async def unhandled_exception_handler(request, exc: Exception): logger.error(f"unhandled exception, trace_id={request.state.trace_id}", exc_info=exc) return JSONResponse( status_code=500, content={ "code": ErrorCode.INTERNAL_ERROR.value[0], "message": "系统内部错误,请稍后重试", "data": None, "trace_id": request.state.trace_id, }, )这个框架里有一点很重要,也是我在实际操作中让 AI 反复调整的:未知异常要记录完整堆栈,但返回给调用方的 message 必须是模糊的“系统内部错误”。如果把底层异常信息直接透传出去,内部库表结构、SQL 语句都可能泄露给调用方,这在任何项目里都是安全红线。
另外一个细节是 trace_id。这个项目的请求入口是一个中间件,为每个请求生成uuid4的 trace_id,然后塞进request.state。后续所有日志、异常响应都带这个 ID。线上排查问题时,调用方只需要把 trace_id 贴给你,你就能把这一条请求的完整日志拉出来。这个小改动,成本极低,但排障效率提升非常明显。
4. 给 AI 的提示词模板:从“能用”到“好用”的三个关键
4.1 模板结构:任务、背景、约束、输出格式
第 2 节和第 3 节里我反复提到提示词怎么组织,这里把通用模板完整分享出来。我用过很多次,无论让 AI 做接口设计、补异常处理,还是让它评审代码,都可以套这个结构:
任务:<你要 AI 具体做什么,越具体越好> 背景:<项目是什么技术栈、业务场景是什么、谁在用、数据从哪来> 约束:<业务规则、行业惯例、不能做什么、必须做什么> 输出格式:<表格 / 代码片段 / OpenAPI 定义 / 清单,需要明确> 例子:<如果有的话,给一个你期望的输出样例>以“让 AI 给订单详情接口补异常处理”为例:
任务:为订单详情接口实现异常处理逻辑,并列出所有需要考虑的异常场景。 背景:FastAPI 项目,接口是 GET /api/v1/orders/{order_id},通过 order_id 查询 PostgreSQL 订单表,order_id 是 20 位数字字符串。 约束:响应统一使用 { code, message, data, trace_id } 结构;错误码使用 ErrorCode 枚举;数据库异常必须记日志但不能在响应中暴露 SQL 信息;订单不存在返回 10002。 输出格式:先给异常场景清单,再给 handler 代码。这个模板的关键在于“约束”这一栏。很多人用 AI 写代码时觉得它“自由发挥太多”,其实就是因为约束给少了。AI 默认情况下会倾向于产出“在代码比赛里能拿高分”的答案——考虑各种边界情况、加各种扩展点,但对小项目来说,那往往就是过度设计。
4.2 场景一:让 AI 评审现有异常处理代码
AI 不止能在“从无到有”时帮你,在“已有代码评审”时也能帮上大忙。我有一次写完一段批量查询接口的异常处理,心里没底,直接把代码贴给 AI:
你是这个项目的资深开发者。以下是我写的批量查询接口异常处理代码,请重点检查:1) 是否吞掉了不该吞的异常;2) 错误码使用是否一致;3) 有没有漏掉该记的日志;4) 调用方拿到错误后能否判断下一步行动。请逐条指出问题,并说明理由。
AI 指出了两个我完全没想到的问题:
第一,我在一处except ValueError里直接把异常信息拼进 message 返回,但同一个异常既可能来自“参数格式错误”,也可能来自“内部解析错误”,调用方无法区分是它的问题还是我的问题。正确做法是:参数校验在入口处完成,内部解析错误走系统异常通道。
第二,批量查询里有一行except Exception: continue,这行我在写的时候觉得“跳过单条问题不影响整体”,但 AI 提醒我:如果一个订单号持续触发异常,调用方看到的响应是“成功但少了这一条”,没人知道数据不完整。这里应该记录失败明细,并在响应里返回一个partial_fail标志。
这两个问题都不是那种一眼能看出的语法错误,而是需要“调用方视角”才能发现的逻辑漏洞。AI 在这类评审场景里的价值,不在于它会写代码,而在于它“见多识广”,能拿你写的东西去对照行业里踩过的坑。
4.3 场景二:让 AI 生成测试用例,反向验证异常处理
代码写完、异常框架搭好之后,我习惯让 AI 再生成一轮测试用例。目的不是为了凑覆盖率,而是为了验证我定下的错误码和调用方处理策略真的生效。
提示词:
为订单详情接口生成 pytest 测试用例。覆盖以下场景:1) 订单号格式非法;2) 订单号合法但不存在;3) 正常返回订单详情;4) 数据库查询抛出超时异常,验证返回 10500 而不是 500;5) 请求带 trace_id 时,响应中回传相同的 trace_id。每个用例给出断言点和预期响应体。
AI 生成的测试里,有一个用例刚好帮我抓出一个真实 bug:数据库查询超时的场景,我的全局异常处理器把OperationalError接住了并返回了code: 10500, status: 500,但我契约里写的是“服务内部错误”对应 10500,而数据库超时属于“依赖不可用”,应该返回 10503 和 503。如果不是测试用例反向逼我重新审视错误码映射表,这个问题上线后会在某个数据库抖动时段才暴露出来。
注意:让 AI 生成测试用例时,不要只说“帮我写测试”,而是要把你期望的“异常策略”也告诉它。否则 AI 会默认按“异常都能被 catch 住”来写,生成的用例测不出错误码映射的问题。
5. 多 AI 协作评审:接口方案落地前的最后一道防线
5.1 为什么“一个 AI 干活”不够,要配置多个角色
我在这个项目里用 AI 的方式,后期基本是“多 AI 协作”——不是同时开一堆窗口瞎聊,而是给不同 AI 安排不同角色,用不同的视角审查同一份接口方案。原因很简单:同一个 AI 生成方案时,思路是连贯的,视角是单一的。它设计接口时觉得自己把异常处理想全了,但再让它用“测试工程师”的视角去挖,往往又能挖出新的问题。
我把这个协作分成三个角色:
| 角色 | 职责 | 关键提示词方向 |
|---|---|---|
| 设计 AI | 产出接口契约、错误码、异常分类清单 | 明确业务场景、要求输出 OpenAPI 定义 |
| 评审 AI | 检查契约中的矛盾、遗漏、语义冲突 | 要求逐条对照行业惯例,只挑毛病不改代码 |
| 测试 AI | 基于契约生成边界测试用例和 mock 数据 | 要求覆盖所有错误码、异常场景和参数边界 |
有意思的是,三个角色用同一个 AI 模型也能生效,只要切换提示词里的“角色设定”和“任务目标”。当然,如果你手头有不止一个 AI 工具或者不同模型,让它们交叉评审效果更好,因为不同模型的训练数据和擅长方向确实有差异。
5.2 评审发现的真实问题:状态码冲突与重试策略错误
这个项目里,评审 AI 确实抓到了几个实际的问题。举两个印象最深的:
第一个是状态码冲突。设计 AI 在定义“并发冲突”时用了 10003、HTTP 409;但在另一个接口的输入校验里,它又用 10003 表示“订单状态参数不合法”。同一个错误码,两个完全不同的语义,调用方拿到 10003 根本不知道发生了什么。评审 AI 在交叉核对错误码表时发现了这个冲突,我才意识到:错误码编号必须全局唯一,且定义好后要像数据库表结构一样做变更管理。
第二个是重试策略错误。列表查询接口,设计 AI 在“数据库连接超时”这条异常里写了“调用方可重试”,但评审 AI 指出来:对于只读查询接口,数据库超时通常意味着数据库本身压力很大,这时候调用方一股脑重试,只会把数据库拖得更垮。正确策略应该是“限制重试次数 + 增加退避时间”,或者直接不自动重试,留给用户判断。这条评审意见直接改掉了我们在接口文档里给调用方的建议。
我把多 AI 协作的完整流程固定成了这样:
- 设计 AI 产出一版接口契约和异常分类清单
- 评审 AI 逐条找漏洞:错误码冲突、边界遗漏、语义不一致
- 测试 AI 根据最终的契约生成测试用例
- 测试用例如果暴露了新问题,回到第 1 步形成循环
- 人工拍板,把最终契约同步给调用方
这套流程不是每次都从头跑到尾。小项目时间紧的时候,我会把第 2 和第 3 步合成一轮完成,但“评审”和“测试”一定不会省。尤其是接口契约这种东西,哪怕只漏掉一个字段校验,调用方对接时就要多等一轮沟通。
6. AI 生成的接口代码里,最容易踩的四个坑
6.1 幻觉接口:AI 编出不存在的依赖
AI 生成代码时,偶尔会“一本正经地调用一个不存在的函数或服务”。我在让 AI 给订单服务补“列表查询里关联用户昵称”的功能时,它生成了一段await user_service.get_batch_users(user_ids),但我们的项目里根本没有user_service这个模块,团队也没对外依赖任何用户服务。
应对方法是在约束里加一句白名单:只允许使用以下模块和函数,如果某项功能需要引入外部依赖,请先列出依赖清单让我确认。这样能很大程度避免 AI 自由发挥出项目里不存在的组件。
6.2 过度设计:小项目被 AI 塞进一堆中间件
小项目最容易犯的毛病,就是 AI 为了“可扩展性”主动引入一堆高级组件。我有一次让 AI 生成一个批量导出接口,它竟然给我设计了一个“Redis 缓存 + 消息队列 + 定时任务”的方案,理由是“数据量大了以后可以异步处理”。对于只有几千条订单的团队内部工具,这完全是负资产。
对付过度设计,我给提示词里加了一条硬性约束:
这是小规模内部工具项目,日请求量预计低于一万。禁止引入 Redis、消息队列、网关、微服务拆分等中间件。所有方案必须基于现有技术栈实现。
这条约束加上之后,AI 的输出立刻“接地气”了,批量导出老老实实变成了同步下载接口。说实话,AI 会有这种“过度设计”倾向不奇怪,它参考的很多大项目最佳实践本身就自带这些组件。你要做的是明确告诉它项目的规模边界。
6.3 错误码与 HTTP 状态码的语义冲突
我在第 5 节提到过错误码冲突,这里再展开一种情况:业务错误码和高层架构的状态码相互矛盾。比如某个场景要求“订单不存在返回 404”,但你的 Web 框架或网关在全局层面把所有 404 都当成“路由不存在”处理,导致调用方收到 404 后第一反应是“我这个接口路径是不是拼错了”,而不是“订单号有问题”。
这种冲突在小项目里很隐蔽,尤其在用 API 网关做统一鉴权的项目里。我的建议:在接口契约文档里,单独用一页列出“业务错误码 vs HTTP 状态码映射规则”,并且明确写清楚哪些错误码允许透传,哪些错误码会被网关拦截替换。这块内容也可以让 AI 去生成初稿,但一定要人工逐条核对。
6.4 异常被全局处理器“假装处理”
最后这个坑最阴。全局异常处理器可以让你少写很多 try-catch,但它也容易让人产生“异常都处理好了”的错觉。常见的问题是:
- 全局处理器把所有异常都接住了,返回了“系统内部错误”,但没有记录任何日志。线上出了事,日志里只有一堆 500 响应,没有堆栈,无从排查。
- 全局处理器把 404、422 之类框架自动抛出的异常也包装成“系统内部错误”,导致参数校验失败这种调用方自己的问题,被错误地归类成了服务端故障。
- 未处理异常和业务异常共用同一个错误码,运维监控里没法区分“用户输错了”和“系统崩了”。
我现在给自己定的一个规矩是:全局异常处理器的代码里,不允许出现空的 except 分支,每一个分支要么有日志、要么有明确的错误码,二者至少占一个。这个规矩也可以直接写进提示词约束里,让 AI 生成框架时代码里自带完整的日志埋点。
回到最开始说的:接口设计和异常处理,看上去是编码问题,本质上是设计问题。AI 在我这个项目里干的最有价值的事,不是帮我写出了多少行代码,而是逼着我在动手之前就开始想“有哪些候选方案、哪些边界情况、每种错误调用方该怎么处理”。把这些想清楚,代码反而是水到渠成的事。如果你手头正好有个小项目要做接口,我建议你按我上面这个顺序试一遍:先让 AI 列候选接口,再让它补契约,再让它枚举异常,最后找一个“挑刺型”的 AI 来评审。这一圈走完,你拿到的接口规范,大概率比你团队里很多老项目的更完整。