☰
给AI写规格说明书:从模糊需求到精确约束的六个维度
2026/10/14 5:45:55 网站建设 项目流程

1. 为什么“给AI写规格说明书”和给人写完全是两码事

很多人第一次尝试让AI帮忙写代码或者做系统设计时,都会遇到一个很尴尬的局面:你觉得自己已经说得很清楚了,但AI产出的东西要么跑偏,要么缺胳膊少腿,要么在细节上自作主张。于是你开始怀疑是不是模型不够强,换了一个又一个工具,结果发现换汤不换药。问题大概率不在模型身上,而在于你给它的那份“需求描述”根本算不上规格说明书。

给人写规格说明书,读者是有常识、有上下文、会主动追问的工程师。你写一句“用户登录后跳转到首页”,对方不会问你“首页是哪个页面”“登录失败怎么办”“token存哪里”。但AI不一样,它没有你们团队的隐性知识,不知道你们的技术栈约定,不了解你们的产品调性,更不会在动手之前先来找你确认。它只会基于你给的文字做最大概率的合理推测,而“最大概率的合理推测”往往就是最平庸、最泛化的那种实现。

所以给AI写规格说明书,本质上是在做一件事:把原本存在于你脑子里、团队默契里、历史代码里的隐性约束,全部显性化成AI可以直接消费的结构化文本。这件事的难度不在于写多少字,而在于你能不能识别出哪些信息是AI“不知道但必须知道”的。

我自己的经验是,一份能让AI产出可用结果的规格说明书,通常需要覆盖六个维度:角色与边界、输入与输出、状态与流转、异常与兜底、约束与偏好、验收与自检。缺了任何一个维度,AI都会在那个维度上自由发挥,而自由发挥的结果十有八九不是你想要的。

下面这张表是我总结的“人类规格书”和“AI规格书”的核心差异,你可以对照看看自己平时写的东西落在哪一边:

维度给人看的规格书给AI看的规格书
读者假设有领域常识,会主动追问零上下文,不会追问
容错空间模糊处可由人补全模糊处由模型猜测
结构要求逻辑清晰即可需要显式分节、编号、标签
异常处理可口头补充必须逐条写明
技术约束团队默认约定必须显式声明
验收标准可事后评审最好前置为自检清单

理解了这层差异,后面的内容才有落脚点。接下来我会按实际写一份规格说明书的完整流程来展开,每一步都告诉你为什么要这样写,以及不这样写会出什么问题。

2. 角色设定与边界划定:让AI知道自己是谁、不做什么

2.1 角色描述不是客套话,是约束条件

很多人写AI规格书时,开头喜欢写一句“你是一个资深工程师”,然后就直接进入需求。这句话不能说没用,但它的作用非常有限。因为“资深工程师”这个标签太宽泛了,AI无法从中推断出你希望它用什么语言、什么架构风格、什么命名习惯来做事。

有效的角色描述应该包含三层信息:技术身份、经验取向、行为偏好。技术身份告诉AI它该用什么工具集思考,经验取向告诉它遇到取舍时往哪个方向倾斜,行为偏好告诉它输出时该注意什么。

举个例子,如果你要做一个数据处理脚本,角色描述可以这样写:

你是一名专注于数据清洗与ETL流程的后端开发者,习惯用Python处理结构化数据,偏好用pandas做批量转换、用pydantic做数据校验。你在写代码时优先考虑可读性和可测试性,而不是极致性能。遇到不确定的字段含义时,你会先在注释中标注假设,而不是自行编造映射关系。

这段描述里,“Python + pandas + pydantic”是技术身份,“优先可读性而非性能”是经验取向,“不确定时标注假设而非编造”是行为偏好。三条加起来,AI在后续生成代码时就有了明确的决策依据。

2.2 边界划定:明确写出“不要做什么”

比“要做什么”更容易被忽略的是“不要做什么”。AI有一个很强的倾向,就是帮你“补全”你没提到的东西。你觉得它很智能,但补出来的往往是你不需要的。

比如你让它写一个用户注册接口,你只说了“接收邮箱和密码,存入数据库”。它可能会自动帮你加上:密码强度校验、邮箱格式校验、重复注册检查、验证码发送、注册成功后的欢迎邮件、日志记录、限流……这些东西单拎出来都是合理的,但如果你当前阶段只想先跑通主流程,这些“贴心”的补充就会变成负担。

所以边界划定要显式写出来。我通常会用这样的格式:

  • 本次范围内:接收邮箱和密码,做基本非空校验,写入用户表,返回用户ID
  • 本次范围外:不做密码强度校验、不发验证码、不发邮件、不做限流、不写操作日志
  • 后续可能扩展但当前不实现:邮箱唯一性检查、密码加密存储

这样写的好处是,AI知道哪些是它该操心的,哪些是它不该碰的。你可能会问,密码加密存储怎么能不做?这就是边界划定的意义——也许当前只是一个内部原型,也许加密逻辑在另一层统一处理,总之你明确说了不做,AI就不会自作主张。

2.3 用“假设清单”替代“隐含前提”

还有一个很实用的技巧,就是在规格书开头单独列一个“假设清单”。把你认为理所当然、但AI可能不知道的前提全部写出来。比如:

  • 假设运行环境是Python 3.11,已安装pandas 2.x
  • 假设数据库是PostgreSQL 15,连接信息通过环境变量传入
  • 假设输入数据中时间字段统一为UTC时间戳
  • 假设调用方已经完成了身份认证,本模块不处理鉴权

这些假设写出来之后,AI在生成代码时就不会去重复实现这些已经存在的东西,也不会因为不知道环境而选择错误的库版本。我踩过的一个坑就是没有声明Python版本,结果AI用了一个3.12才有的语法特性,在3.10环境上直接报错。从那以后,假设清单成了我每份规格书的标配。

3. 输入输出契约:把“大概这样”变成“必须这样”

3.1 输入定义要细到字段级别

“接收用户信息”这种描述对AI来说等于没说。它需要知道:字段名是什么、类型是什么、是否必填、取值范围是什么、默认值是什么、字段之间有没有依赖关系。

我通常会用表格来定义输入,因为表格的约束感比段落强得多。比如一个订单创建接口的输入定义:

字段名类型必填说明示例
user_idstring是用户唯一标识,UUID格式"a1b2c3d4-..."
itemsarray是商品列表,至少1项见下方items结构
coupon_codestring否优惠券码,为空表示不使用"SAVE10"
remarkstring否备注,最长200字符"尽快发货"

items数组内部还要继续定义:

字段名类型必填说明
sku_idstring是商品SKU编号
quantityinteger是数量,最小1,最大99

这样定义之后,AI在生成校验逻辑时就有据可依,不会漏掉某个字段,也不会把可选字段当成必填。

3.2 输出定义要包含成功和失败两条路径

很多人只定义成功时的返回结构,失败时的返回就交给AI自由发挥。结果就是AI可能返回一个字符串错误信息,也可能抛异常,也可能返回一个包含error字段的对象,风格完全不统一。

正确的做法是把成功和失败都定义清楚。成功路径定义返回数据的结构,失败路径定义错误码、错误信息格式、以及不同错误场景对应的错误码。

场景HTTP状态码错误码错误信息模板
参数缺失400INVALID_PARAM"缺少必填字段: {field}"
用户不存在404USER_NOT_FOUND"用户 {user_id} 不存在"
库存不足409OUT_OF_STOCK"商品 {sku_id} 库存不足"
系统内部错误500INTERNAL_ERROR"服务暂时不可用,请稍后重试"

这张表写出来之后,AI生成的错误处理代码就会和你的预期高度一致,而不是每个接口一套风格。

3.3 用示例代替长篇描述

有时候一段文字描述不如一个具体示例来得清楚。特别是涉及嵌套结构、复杂映射关系的时候,给一个完整的输入输出示例,AI的理解准确率会大幅提升。

比如你要描述一个数据转换逻辑,与其写“将源数据的create_time字段从毫秒时间戳转换为ISO 8601格式字符串”,不如直接给一个示例:

输入:

{"create_time": 1700000000000, "name": "test"}

输出:

{"create_time": "2023-11-14T22:13:20Z", "name": "test"}

示例的好处是消除了歧义。文字描述里“ISO 8601格式”可能有多种写法,但示例只有一种,AI会直接照着示例的格式来。

注意:示例要覆盖边界情况。比如空值、超长字符串、特殊字符等,最好各给一个示例,否则AI可能只处理正常情况。

4. 状态流转与异常兜底:AI最容易糊弄过去的地方

4.1 状态机要显式画出所有合法迁移

如果你的系统涉及状态变化,比如订单从“待支付”到“已支付”到“已发货”,那状态流转必须显式定义。AI在没有明确指示的情况下,往往会实现一个“万能更新接口”,允许任意状态跳到任意状态,这在业务上通常是灾难。

我习惯用一张状态迁移表来定义:

当前状态允许迁移到触发条件副作用
待支付已支付支付成功回调扣减库存、发送通知
待支付已取消用户取消或超时释放库存
已支付已发货管理员操作生成物流单
已发货已完成用户确认收货无
已支付已退款退款审核通过返还库存、退款

这张表写出来之后,AI在实现状态更新逻辑时就会去校验当前状态是否允许迁移,而不是无脑更新。

4.2 异常兜底要逐条列出,不能靠AI“合理推测”

异常处理是AI最容易偷懒的地方。如果你不写,它可能只处理最明显的那个异常,其他一律往上抛。但实际生产中,每个异常都需要有明确的处理策略。

我通常会把异常分成三类来写:

第一类:可预期且可恢复的异常。比如网络超时、第三方接口返回限流。这类异常的处理策略是重试,但要写明重试次数、重试间隔、退避策略。

第二类:可预期但不可恢复的异常。比如参数校验失败、资源不存在。这类异常的处理策略是直接返回错误,但要写明返回什么错误码、什么信息。

第三类:不可预期的异常。比如空指针、类型错误。这类异常的处理策略是捕获后记录日志,返回统一的内部错误,不暴露堆栈信息给调用方。

每一类下面再列出具体的异常场景和处理方式。这样AI在生成代码时,就会按照你的分类去写try-catch,而不是把所有异常混在一起。

4.3 并发和幂等:不写就等着出问题

如果你的接口可能被并发调用,那并发控制必须写进规格书。AI默认生成的代码通常没有并发保护,因为它假设一切按顺序发生。

需要写明的并发相关信息包括:是否存在竞态条件、用什么机制保证一致性(乐观锁、悲观锁、分布式锁、唯一约束)、幂等键是什么、重复请求如何处理。

比如一个支付回调接口,规格书里应该写:

该接口可能被支付平台重复调用。以支付平台的transaction_id作为幂等键,首次处理时记录该ID,后续相同ID的请求直接返回成功,不重复执行业务逻辑。使用数据库唯一约束保证并发情况下的幂等性。

这段话写进去,AI就知道要加唯一索引、要先查后写、要处理唯一约束冲突。不写的话,它大概率就是一个简单的“查到就更新”,并发下直接出问题。

5. 技术约束与风格偏好:让产出直接能进代码库

5.1 技术栈约束要具体到版本和库

“用Python写”和“用Python 3.11 + FastAPI + SQLAlchemy 2.0 + Pydantic v2写”是两个完全不同的约束。前者AI可能给你Flask,也可能给你Django,还可能给你一个纯脚本。后者才能保证产出和你的项目无缝对接。

除了语言和框架,还要写明:包管理工具(pip/poetry/uv)、代码格式化工具(black/ruff)、类型检查要求(mypy严格模式)、测试框架(pytest/unittest)。这些信息看起来琐碎,但决定了AI产出的代码能不能直接放进你的项目里跑。

我一般会在规格书里单独开一节叫“技术约束”,用列表形式写清楚:

  • 语言:Python 3.11
  • Web框架:FastAPI 0.100+
  • ORM:SQLAlchemy 2.0,使用声明式模型
  • 数据校验:Pydantic v2
  • 包管理:poetry
  • 格式化:ruff format + ruff check
  • 类型检查:mypy --strict
  • 测试:pytest + httpx

5.2 命名和目录结构约定

AI生成的代码经常出现命名风格不统一的问题,因为你不说,它就随机选。所以命名约定要写清楚:文件名用什么风格、类名用什么风格、函数名用什么风格、常量用什么风格、数据库表名和字段名用什么风格。

目录结构也一样。如果你希望代码放在特定的目录下,就在规格书里画出目录树。比如:

src/ api/ routes/ schemas/ core/ config.py exceptions.py models/ services/ tests/

有了这个目录树,AI就知道该把文件放在哪里,不会把所有代码塞进一个文件里。

5.3 注释和文档字符串要求

AI默认生成的注释要么太多(每行都注释),要么太少(完全没有)。你需要明确告诉它注释的粒度:哪些地方必须写注释(复杂逻辑、非显而易见的决策、外部系统交互),哪些地方不需要(自解释的代码)。

文档字符串的格式也要指定。是Google风格、NumPy风格还是Sphinx风格?参数和返回值要不要写类型?异常要不要列出来?这些都说清楚,产出的文档字符串才能和你的项目风格一致。

提示:如果你用的是ruff,可以在规格书里直接写“注释和文档字符串需通过ruff的pydocstyle检查”,这样AI就知道该按什么标准来写。

6. 验收标准与自检清单:让AI自己先过一遍

6.1 把验收标准写成可执行的检查项

“功能正确”这种验收标准对AI没有意义。它需要的是可以逐条勾选的检查项。比如:

  • 所有必填字段缺失时返回400和对应错误码
  • 所有可选字段为空时使用默认值,不报错
  • 输入超长字符串时返回400而不是500
  • 并发相同幂等键请求时只执行一次业务逻辑
  • 数据库操作失败时回滚事务并返回500
  • 所有公开函数都有类型注解和文档字符串
  • 测试覆盖率不低于80%

这些检查项写出来之后,AI在生成代码时会主动去满足它们,而不是等你事后发现缺了再补。

6.2 让AI在输出前做自检

一个很实用的技巧是在规格书末尾加一段“输出前自检”指令,要求AI在给出最终结果之前,先逐条核对验收标准,并说明每条是如何满足的。这样做有两个好处:一是AI在自检过程中会发现自己遗漏的地方并主动补上,二是你拿到结果时已经有了一个对照清单,验收效率大幅提升。

自检指令可以这样写:

在输出最终代码之前,请先逐条核对上述验收标准,对每一条说明你的实现方式。如果某一条无法满足,请明确说明原因,不要跳过。

实测下来,加了这段指令之后,AI产出的完整度明显提升,尤其是异常处理和边界条件这两块,遗漏率大幅下降。

6.3 迭代式规格书:先跑通再细化

最后分享一个我常用的工作方式:不要试图一次性写出完美的规格书。第一版只需要覆盖核心路径和关键约束,让AI先产出一版能跑的东西。然后你拿着这版结果去对照,看哪些地方偏离了预期,把偏离的地方作为补充约束写进规格书,再让AI重新生成。

这个过程通常迭代两到三轮就能收敛。第一轮解决“有没有”的问题,第二轮解决“对不对”的问题,第三轮解决“好不好”的问题。比起憋一份大而全的规格书然后一次性生成,这种迭代方式效率更高,而且每一轮你都能学到AI在哪些地方容易理解偏差,下一轮写规格书时就会更有针对性。

我自己的体会是,写AI规格书这件事,本质上是在训练自己把模糊需求转化为精确约束的能力。这个能力一旦练出来,不仅对AI有效,对跟人协作也同样有效。毕竟,能把事情说清楚,本身就是一种稀缺能力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询