AI Coding Agent 时代的核心技能:如何写好 Software Spec
从 Vibe Coding 到 Spec-Driven Development——当代码不再是源头,意图才是。
引言:为什么你写给 AI 的"需求文档"比以往任何时候都重要
2025-2026 年,AI coding agent 经历了一场质变。Claude Code、Codex CLI、Cursor、Kiro——这些工具不再只是补全下一行代码的自动完成器,它们已经进化为能理解整个代码仓库、执行多文件修改、运行测试并自主迭代的 自主代理(autonomous agent)。Google 的 Addy Osmani 在其广泛流传的工作流分享中将这种新模式定义为"AI-augmented software engineering"——AI 增强的软件工程,而非 AI 自动化的软件工程。
这个区分至关重要。开发者的角色正在从"写代码的人"转变为"指挥 AI 写代码的人"。而指挥的核心载体,就是 Software Spec(软件规格说明书)。
GitHub 在 2025 年 9 月开源了 Spec Kit 工具包,正式提出了 Spec-Driven Development(SDD,规格驱动开发) 的方法论。AWS 推出了内置 SDD 工作流的 Kiro IDE。Martin Fowler 的技术博客也开始系统性地探讨 SDD 的定义、工具和局限。一个清晰的行业共识正在形成:在 AI agent 时代,specification 正在取代 code 成为"源头真相"(source of truth)。
本文将结合 2025-2026 年最新的行业实践,系统讲解:Software Spec 是什么、为什么重要、怎么写好、以及一个可以直接拿去用的最佳模板。
一、Software Spec 的定义
在 AI coding agent 的语境下,Software Spec 有一个比传统软件工程更具体的含义。Martin Fowler 网站上的 SDD 系列文章给出了一个精准的定义:
Spec 是一种结构化的、以行为为导向的制品(artifact),使用自然语言描述软件功能,并作为 AI coding agent 的工作指引。
换一种更直觉的说法:Spec 是你和 AI 之间的"合同"。 它精确描述你要什么、不要什么、约束条件是什么,让 AI 在最少的来回沟通中产出最接近你预期的代码。
如果你有后端工程经验,可以这样理解:产品经理给你的 PRD 如果模糊不清,你要反复确认、返工。AI coding agent 就是你的"超级初级工程师"——执行力极强、速度极快,但它不会主动补全你没说清楚的部分。Spec 写得越好,AI 的产出越接近你脑中的画面。
Spec ≠ Prompt
这里要澄清一个常见的混淆。Spec 不是一次性的 prompt。Prompt 是一条消息,发完就消失在聊天历史里;Spec 是一个持久化的、版本控制的文档,它锚定在你的代码仓库中,跨会话存在,随项目演进而更新。
正如 Addy Osmani 所建议的:把 spec 保存为项目中的 SPEC.md 文件,让它成为你和 AI 都可以随时查阅的参考。当对话历史变长或需要重启 agent 时,spec 文件就是防止 AI “失忆"的锚点。
二、为什么 Spec 在 AI Agent 时代变得更重要了
1. AI 没有隐含上下文
你和同事合作时,对方知道团队的技术栈、代码风格、业务背景。AI 什么都不知道——除非你告诉它。每一个你觉得"显而易见"的假设,对 AI 来说都是需要被显式声明的约束条件。
2. AI 的"创造性"是双刃剑
当 spec 有空白地带时,AI 不会停下来问你,它会自己填补——而它填补的方式往往不是你想要的。你说"写一个用户认证模块”,它可能给你搞一个 JWT + OAuth2 + 社交登录的全套方案,而你只需要一个 API key 验证。Overengineering 是 AI 的默认模式。
3. “指令诅咒”(Curse of Instructions)
研究表明,当你往 prompt 中塞入过多指令时,模型对每一条指令的遵循率会显著下降。这被称为"指令诅咒"。这意味着你不能把所有需求、约束、风格要求都堆到一条消息里——你需要一个结构化的、分层的 spec 来管理这些信息。
4. Spec 是你验收 AI 产出的标尺
如果没有明确的 spec,你甚至不知道该用什么标准来判断 AI 写的代码好不好。Spec 给了你一个 checklist,让你可以系统性地验收而不是凭感觉。
5. Spec 让多 Agent 协作成为可能
当你使用 sub-agent 或并行 agent 时,每个 agent 需要知道自己负责的范围和边界。Spec 就是这个边界的定义。没有 spec,多个 agent 会互相踩脚、产出冲突的代码。
三、Spec 的核心组成部分:六大领域
GitHub 的 AI 团队分析了超过 2,500 个 agents.md 文件后,发现了一个清晰的模式:最有效的 spec 覆盖六个核心领域。 这个发现同样适用于所有 AI coding agent 的 spec 编写。
1. 命令(Commands)
把可执行命令放在 spec 的早期位置——不只是工具名称,而是带标志和参数的完整命令。Agent 会频繁引用这些命令。
- 构建: `npm run build`(编译 TypeScript,输出到 dist/)
- 测试: `npm test`(运行 Jest,提交前必须通过)
- 代码检查: `npm run lint --fix`(自动修复 ESLint 错误)
2. 测试(Testing)
如何运行测试、使用什么框架、测试文件放在哪里、覆盖率要求是什么。
3. 项目结构(Project Structure)
源代码在哪里、测试放哪里、文档归哪里。必须显式说明:
- `src/` — 应用源代码
- `tests/` — 单元测试和集成测试
- `docs/` — 项目文档
4. 代码风格(Code Style)
一个真实的代码示例比三段文字描述更有效。 命名规范、格式化规则、以及你期望的好代码长什么样。
5. Git 工作流(Git Workflow)
分支命名、提交信息格式、PR 要求。Agent 如果你说清楚了,是完全能遵循这些的。
6. 边界(Boundaries)
Agent 绝对不能碰的东西——密钥文件、vendor 目录、生产环境配置、特定文件夹。GitHub 研究发现,“不要提交密钥"是最常见也最有效的约束。
用三级系统来表达边界:
- ✅ 始终执行: 提交前运行测试,遵循命名规范
- ⚠️ 先确认: 数据库 schema 变更,添加新依赖
- 🚫 绝不: 提交密钥,修改 node_modules/,修改 CI 配置
四、Spec 的工作流:四阶段门控模型
GitHub 的 Spec Kit 提出了一个经过实战验证的四阶段工作流。这个模型的核心思想是:在每个阶段设置人工检查点,直到当前阶段被验证后才进入下一阶段。
阶段 1:Specify(定义意图)
提供一个高层描述——你在构建什么、为什么要构建。这不是关于技术栈或架构,而是关于用户旅程、体验和成功标准。谁会使用这个功能?它解决什么问题?用户如何与它交互?
让 AI agent 把你的高层描述扩展为一个详细的规格说明。这个 spec 就成为你和 AI 共同构建的第一个制品。
实操建议: 利用 Claude Code 的 Plan Mode(Shift+Tab),在只读模式下让 agent 分析代码库并创建详细计划,不写任何代码,直到你确认计划无误。
阶段 2:Plan(技术设计)
现在进入技术层面。你提供期望的技术栈、架构和约束条件,agent 生成一个全面的技术方案。如果团队有标准化的技术选型,这里是说明的地方。如果有合规要求或遗留系统集成需求,也在这里声明。
阶段 3:Tasks(任务分解)
Agent 把 spec 和 plan 分解为具体的、可独立完成和测试的工作单元。不是"构建认证系统”,而是"创建一个验证邮箱格式的用户注册端点"。每个任务都应该小到可以独立实现和验证——这本质上是 TDD 思想在 AI agent 工作流中的映射。
阶段 4:Implement(执行)
Agent 逐个(或并行)执行任务。你不再需要 review 千行代码的巨大 diff,而是审查解决特定问题的小变更。Agent 知道要构建什么(spec)、如何构建(plan)、当前在做什么(task)。
这个门控工作流解决了"纸牌屋代码"的问题——那种看起来能运行但一推就倒的脆弱 AI 产出。
五、最佳实践:来自行业前沿的经验
实践 1:先让 AI 起草,再由你精炼
不要试图从零写一个完美的 spec。更有效的做法是:给 AI 一个清晰的高层目标,让它生成一个详细的 spec 草稿,然后你来 review 和修正。这利用了 AI 擅长扩展细节的优势,同时你保持方向控制权。
具体做法:开始新项目时,告诉 agent:
“你是一位 AI 软件工程师。为 [项目 X] 起草一个详细的规格说明,涵盖目标、功能列表、约束条件和分步计划。”
然后审阅它的产出,纠正任何偏差或 hallucination,保存为 SPEC.md。
实践 2:结构化是王道
使用 Markdown 标题或 XML 标签来分隔 spec 的不同部分,因为 AI 模型处理结构化文本远比自由格式散文更好。Anthropic 的工程团队也推荐把 prompt 组织成不同的区块(如 <background>、<instructions>、<constraints>、<output_format>)。
关键原则:“精简"不一定意味着"短”。 如果某个细节很重要,不要省略,但要确保它放在正确的位置。
实践 3:写"不做什么"比写"做什么"更重要
这是大多数人最容易忽略的部分,却是对 AI agent 最有效的控制手段。因为 AI 添加你不想要的东西的返工成本,远高于它漏掉你想要的东西(那你只需要追加要求)。
好的"不做"清单示例:
- 这个版本不需要支持模糊搜索
- 不要添加缓存层,这是 V1
- 不要修改现有的
memory_store.py,只新增文件 - 不要引入当前
requirements.txt中没有的新依赖
实践 4:一个代码示例胜过三段文字
当你想让 AI 遵循特定的代码风格或架构模式时,直接贴一个示例文件作为参考,比用文字描述高效得多。比如:
## 代码风格参考
遵循 src/handlers/digest.py 的结构模式。
实践 5:模块化——分而治之
不要把所有东西塞进一个巨大的 prompt。按组件或模块拆分 spec,每次只给 AI 当前任务需要的部分。研究证实,指令越多,模型对每条指令的遵循率越低(指令诅咒效应)。
高级技巧:创建一个"扩展目录"(Extended TOC)。 让 agent 为你的 spec 生成一个浓缩摘要,每个章节只保留关键点。这个摘要可以常驻在 prompt 中作为"心智地图",而细节按需提供。
实践 6:Spec 是活文档,不是一次性制品
当 AI 在实现中做出了设计决策,或者你决定砍掉某个功能,要更新 spec。把 spec 提交到 Git,做版本控制。spec 不只是给 AI 看的——它帮助你作为开发者保持对项目的全局掌控。
实践 7:声明技术栈的具体版本
说"React 18 with TypeScript, Vite, and Tailwind CSS",不要说"React 项目"。包含版本号和关键依赖。模糊的 spec 产出模糊的代码。
实践 8:验收标准要可测试
最好的验收标准可以直接转化为测试用例:
## 验收标准
1. 发送 /recall 无参数 → 返回使用说明
2. 发送 /recall <存在的关键词> → 返回 1-3 条结果,含时间戳和摘要
3. 发送 /recall <不存在的关键词> → 返回友好的无结果提示
如果你能让 AI 同时生成测试代码,那就更好了——形成一个自动验证循环。
六、最佳 Software Spec 模板
综合 GitHub Spec Kit 的四阶段模型、Addy Osmani 的 PRD+SRS 混合方法、Kiro 的三文档结构、以及 2,500+ agents.md 文件的分析结论,以下是一个适用于主流 AI coding agent(Claude Code、Codex CLI、Cursor 等)的实战模板:
# [Feature/Project Name] — Software Spec
## 1. 目标与背景(Why & What)
### 目标
一句话概述:[这个功能/项目要解决什么问题]
### 背景
- 用户是谁:[目标用户画像]
- 用户痛点:[没有这个功能时用户遇到什么问题]
- 成功标准:[做完后,怎么定义"成功"]
### 范围
- 这是一个 [全新项目 / 现有项目的新功能 / Bug 修复]
- 当前版本:V[x],专注于 [核心价值],不追求完美
---
## 2. 技术约束(Constraints)
### 技术栈
- 语言: [e.g., Python 3.11]
- 框架: [e.g., python-telegram-bot 21.x]
- 数据库: [e.g., PostgreSQL 15 via Supabase]
- 关键依赖: [e.g., mem0ai SDK 0.1.x]
### 运行环境
- [e.g., Docker container on GCP Cloud Run]
- [e.g., 本地开发环境为 macOS + Python venv]
### 现有架构约束
- 新文件放在: [e.g., src/handlers/]
- 遵循现有模式: [e.g., 参考 src/handlers/digest.py 的结构]
- 入口注册: [e.g., 在 src/main.py 中注册新 handler]
### 已知技术雷区
- [e.g., Mem0 的 search API 每次最多返回 10 条,不支持分页]
- [e.g., python-telegram-bot v21 的 API 有 breaking changes,不要用 v20 的写法]
---
## 3. 命令参考(Commands)
```bash
# 构建
npm run build # 或 python -m build
# 测试
pytest -v # 必须全部通过后才能提交
# 代码检查
ruff check --fix . # 自动修复格式问题
# 本地运行
python -m src.main # 启动开发服务器
4. 接口与数据契约(Interface Contract)
输入
[精确描述输入的形状、来源、格式]
处理逻辑
[核心处理步骤的伪代码或流程描述]
输出
[精确描述输出的形状、格式,包含示例]
异常情况
- 当 [条件 A] 时 → [行为 A]
- 当 [条件 B] 时 → [行为 B]
5. 边界(Boundaries)
✅ 始终执行
- 提交前运行测试
- 遵循现有代码风格
- 新增文件必须有对应的测试文件
⚠️ 需先确认
- 数据库 schema 变更
- 添加新的第三方依赖
- 修改公共 API 接口
🚫 绝不
- 不提交任何密钥或 token
- 不修改 node_modules/ 或 vendor/
- 不修改 CI/CD 配置文件
- 不引入当前依赖清单中没有的新依赖(除非在 ⚠️ 中确认)
功能边界(本版本不做)
- [e.g., 不加缓存层]
- [e.g., 不支持分页]
- [e.g., 不做国际化]
6. 代码风格参考(Style Reference)
[贴一个真实的代码片段作为风格参考,比三段文字描述更有效]
# 参考: src/handlers/digest.py
async def handle_digest(update: Update, context: CallbackContext):
"""处理 /digest 命令,返回今日摘要。"""
user_id = update.effective_user.id
try:
digest = await digest_service.get_daily(user_id)
await update.message.reply_text(
format_digest(digest),
parse_mode="Markdown"
)
except ServiceError as e:
logger.error(f"Digest failed for {user_id}: {e}")
await update.message.reply_text("获取摘要失败,请稍后重试。")
7. 验收标准(Acceptance Criteria)
[用 GIVEN-WHEN-THEN 或直接描述可测试场景]
- 正常流程: [输入 X] → [期望输出 Y]
- 边界情况: [输入为空/异常] → [期望的错误处理]
- 集成验证: [与现有模块的交互是否正常]
- 结构合规: [新代码是否遵循了指定的架构模式]
8. 参考资料(References)
- [相关 API 文档片段]
- [现有代码示例文件路径]
- [设计决策的背景说明]
---
## 七、使用模板的实战示例
用上面的模板,为一个实际项目写一个 spec。以 Telegram bot 的记忆检索功能为例:
```markdown
# /recall 命令 — Software Spec
## 1. 目标与背景
### 目标
为 hey!stalker Telegram bot 实现 /recall 命令,让用户主动从语义记忆中检索信息。
### 背景
- 用户是谁:hey!stalker 的个人用户
- 用户痛点:目前只能被动等 bot 推送信息,无法主动搜索过往记忆
- 成功标准:用户输入关键词后,3 秒内返回 top-3 相关记忆片段
### 范围
- 现有项目的新功能,V1 实现
- 专注于基本搜索,不追求高级语义理解
---
## 2. 技术约束
### 技术栈
- Python 3.11, python-telegram-bot 21.x
- Mem0 via mem0ai SDK, PostgreSQL via Supabase
### 现有架构约束
- 新 handler 放在 src/handlers/recall.py
- 在 src/main.py 注册
- 遵循 src/handlers/digest.py 的结构模式
- Mem0 client 已初始化在 src/clients/mem0.py
### 已知技术雷区
- Mem0 search API 每次最多返回 10 条,limit 参数有效
- python-telegram-bot v21 使用 async handler
---
## 3. 命令参考
```bash
pytest -v tests/
python -m src.main
4. 接口与数据契约
输入
用户在 Telegram 发送: /recall <query_string>
处理逻辑
1. 解析 query_string(/recall 后的文本)
2. 调用 mem0_client.search(query=query_string, user_id=user_id, limit=3)
3. 格式化返回结果
输出格式
📌 记忆 1 (2025-06-15)
关于机器学习的讨论:提到了 transformer 注意力机制的本质...
📌 记忆 2 (2025-06-10)
阅读笔记:Attention Is All You Need 论文的核心贡献...
异常情况
- /recall 无参数 → “用法: /recall <关键词>,例如 /recall 机器学习”
- 无搜索结果 → “没有找到相关记忆,试试换个关键词?”
- Mem0 API 异常 → “记忆检索暂时不可用,请稍后重试。”
5. 边界
🚫 功能边界(本版本不做)
- 不加缓存
- 不加分页
- 不做模糊拼写纠正
- 不修改现有文件(除 main.py 注册路由)
- 不引入新依赖
6. 代码风格参考
参考 src/handlers/digest.py(已在技术约束中指定)
7. 验收标准
- /recall 无参数 → 返回使用说明
- /recall 机器学习(假设已有相关记忆)→ 返回 1-3 条结果,每条含时间戳和摘要
- /recall xyzabc123(不存在的关键词)→ 返回友好的无结果提示
- 新 handler 结构与 digest.py 一致
- tests/test_recall.py 包含上述三个场景的测试
---
## 八、常见陷阱与应对
### 陷阱 1:Spec 太长反而有害
AI 的注意力分布不均匀——开头和结尾被关注的概率高于中间部分。超过一页的 spec,考虑拆分为多个任务,每个任务配一个精炼的 spec。
**应对:** 为长 spec 创建一个 Extended TOC(扩展目录摘要)。每个章节浓缩为 1-2 句话的关键信息,作为 agent 的"心智地图"常驻在上下文中,细节按需提供。
### 陷阱 2:把实现方式写进 Spec
Spec 应该描述 What 和 Why,不是 How。告诉 AI 目标和约束,让它选择实现方式——这才是你用 AI agent 的意义。
**例外:** 当你知道 AI 大概率会选错实现方式时,必须显式指定 How。判断标准:如果一个有经验的工程师第一次接手你的项目,他会不会在这个地方犯错?如果会,AI 也会,那就写进 spec。
### 陷阱 3:一次给太大的任务
即使 spec 写得很好,任务范围太大("实现整个用户系统")时,AI 产出质量会显著下降。分解成小任务,每个任务一个 spec,按依赖关系顺序执行。
### 陷阱 4:写完 Spec 就不管了
Spec 必须是活文档。当 AI 在实现中做出了你未预见的设计决策,或者你改变了需求,必须更新 spec。否则 spec 与代码脱节,它就失去了"源头真相"的意义。
### 陷阱 5:SDD 工具可能过度工程化
Martin Fowler 技术博客上的评测指出了一个实际问题:像 Kiro 和 Spec Kit 这样的工具有时会为一个简单的 bug fix 生成大量 markdown 文件——多个 user story、十几条 acceptance criteria。对于小任务,这是"用大锤砸坚果"。
**应对:** 根据任务规模调整 spec 的详细程度。简单 bug fix 可能只需要几行描述;复杂新功能才需要完整的四阶段流程。Spec 的形式服务于目的,不是目的本身。
---
## 九、SDD 生态现状(2026 年 4 月)
当前 Spec-Driven Development 的工具生态正在快速成型:
**GitHub Spec Kit** 是目前最成熟的开源 SDD 框架。它提供 CLI 工具和模板,支持 Claude Code、Codex、Cursor、Copilot 等主流 agent,通过四阶段门控工作流(Specify → Plan → Tasks → Implement)来结构化开发过程。它是 agent 无关的——你用什么 agent 都可以。
**AWS Kiro** 是一个内置 SDD 工作流的 IDE(基于 VS Code/Code OSS)。它的三文档结构(requirements.md → design.md → tasks.md)更直观,并支持"steering files"作为项目级的持久配置。Kiro 还支持 agent hooks——基于文件变更或提交触发的自动化 agent 任务。
**OpenSpec** 定位为更轻量的替代方案,强调灵活迭代而非严格的阶段门控,更适合 brownfield(已有代码库)场景。
**AGENTS.md** 作为一个开放标准,已被超过 60,000 个开源项目采纳。它不是 SDD 框架,而是一种让 agent 理解项目约定的通用格式——可以理解为"给 AI 读的 README"。
**需要注意的是:** SDD 这个术语目前还没有统一的定义,不同工具的实现差异很大。核心原则——先写 spec 再写代码——是被广泛认可的;但具体到 spec 的结构、详细程度、以及长期维护策略,行业还在探索中。
---
## 十、写好 Spec 对职业发展的价值
如果你正在转型 AI 应用工程方向,spec writing 能力有三重价值:
**第一,直接提升 portfolio 项目质量。** 更好的 spec 意味着更高效地利用 AI agent 产出高质量代码,让你的作品集项目更快达到 demo-ready 状态。
**第二,它就是 prompt engineering 的工程化实践。** 面试中被问到 prompt engineering 经验时,"我使用 spec-driven development 来指挥 AI agent,包括结构化的需求定义、技术约束声明、边界控制和可测试的验收标准"——这比"我会调 temperature"有说服力得多。
**第三,这是 AI 时代工程师的核心能力之一。** 行业趋势是越来越多的团队把 AI coding agent 纳入日常工作流。"能不能有效地指挥 AI 写代码"正在成为与"能不能自己写好代码"同等重要的能力维度。
---
## 参考资料
- Addy Osmani, "How to write a good spec for AI agents", January 2026
- GitHub Blog, "Spec-driven development with AI: Get started with a new open source toolkit", September 2025
- GitHub Blog, "How to write a great agents.md: Lessons from over 2,500 repositories", November 2025
- Martin Fowler (Birgitta Böckeler), "Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl", 2025
- Kiro Documentation, "Specs", 2026
- Zencoder Docs, "A Practical Guide to Spec-Driven Development", 2025