关于 AI 驱动开发(AIDD)实践

基于 Web Nexus 所属项目的 Claude 实践经验总结

Back

摘要

随着 AI 编码助手(如 Claude Code、Cursor、Copilot、Kiro 等)的快速发展,软件开发正在经历一场范式转变。本文基于 Web Nexus 项目的实践经验,系统性地总结了 AI 驱动开发(AI-Driven Development, AIDD)的最佳实践,涵盖项目配置架构、文档组织策略、Agent 系统设计、工具链集成等核心领域,为企业级项目的 AIDD 实践提供参考框架。

核心理念

AIDD 的本质

AI 驱动开发不是简单地使用 AI 工具写代码,而是构建一个可持续、可扩展、可审计的 AI 辅助开发生态系统。

AI 驱动开发(AI-Driven Development, AIDD) 是一种将 AI 工具深度集成到软件开发全生命周期的方法论。与传统的"AI 辅助编码"不同,AIDD 强调:

  • 系统化集成:AI 不是可选工具,而是开发流程的核心组成部分
  • 上下文感知:AI 理解项目架构、编码规范、业务逻辑
  • 自动化决策:AI 参与架构设计、代码审查、测试生成等高级任务
  • 持续学习:项目知识通过文档和记忆系统不断积累

三大支柱

  1. 约束驱动(Constraint-Driven)

    • 通过明确的规则和约束引导 AI 行为
    • 将隐性知识显性化为可执行的规则
    • 用约束替代重复的人工审查
  2. 上下文优先(Context-First)

    • 为 AI 提供充分的项目上下文
    • 分层组织项目知识(架构、规范、模式)
    • 动态加载相关文档和示例
  3. 人机协作(Human-AI Collaboration)

    • AI 执行重复性和机械性任务
    • 人类负责决策和创造性工作
    • 建立清晰的责任边界

核心价值主张

对开发者

  • ⚡ 减少 70% 的样板代码编写时间
  • 🎯 专注于业务逻辑而非语法细节
  • 📚 自动遵循项目规范和最佳实践
  • 🔍 实时获取最新技术文档

对团队

  • 📖 知识沉淀为可执行的指导文件
  • 🔄 新成员快速上手项目规范
  • ✅ 自动化质量检查减少人工审查
  • 🚀 加速功能交付周期

对项目

  • 🏗️ 一致的代码风格和架构模式
  • 🛡️ 强制执行安全和性能规范
  • 📊 可追溯的开发决策历史
  • 🔧 易于维护和演进的代码库

架构体系

AIDD 架构采用分层设计,每一层都有明确的职责和接口。

┌─────────────────────────────────────────────────────────┐
│  Layer 1: 项目记忆层(Project Memory)                   │
├─────────────────────────────────────────────────────────┤
│  CLAUDE.md + AGENTS.md + docs/ + .claude/               │
│  职责:定义项目规范、架构模式、开发约束                    │
└────────────────────────┬────────────────────────────────┘
┌────────────────────────┴────────────────────────────────┐
│  Layer 2: 专用 Agent 层(Specialized Agents)            │
├─────────────────────────────────────────────────────────┤
│  web-nexus-dev + code-reviewer + tester                 │
│  职责:专业领域的 AI 助手,具备深度技术栈知识              │
└────────────────────────┬────────────────────────────────┘
┌────────────────────────┴────────────────────────────────┐
│  Layer 3: Skills/Commands 层(Skills Layer)             │
├─────────────────────────────────────────────────────────┤
│  Speckit Workflow + Custom Commands                     │
│  职责:可复用的工作流和命令,串联开发生命周期               │
└────────────────────────┬────────────────────────────────┘
┌────────────────────────┴────────────────────────────────┐
│  Layer 4: MCP 工具服务器层(MCP Servers)                 │
├─────────────────────────────────────────────────────────┤
│  职责:外部知识源集成,提供实时文档和工具                   │
└────────────────────────┬────────────────────────────────┘
┌────────────────────────┴────────────────────────────────┐
│  Layer 5: 工作流与钩子层(Workflows & Hooks)             │
├─────────────────────────────────────────────────────────┤
│  PostToolUse + PreCommit + Custom Hooks                 │
│  职责:自动化触发质量检查和格式化                          │
└─────────────────────────────────────────────────────────┘

Layer 1: 项目记忆层

初始化 Claude.md,管理 Claude 的内存

核心价值: 提供持久化的项目知识,确保 AI 理解项目上下文

关键文件:

  • CLAUDE.md: 高层概览,快速导航
  • .claude/rules/*.md: 模块化的详细规则(架构、编码规范、工作流等)
  • AGENTS.md: Agent 使用指南和最佳实践

设计原则:

  • 模块化: 拆分多个独立文件,按主题组织
  • 自动加载: Claude Code 自动读取 .claude/rules/ 目录
  • 上下文效率: 90% 的上下文使用效率提升

管理 Claude 的内存 - Claude Code Docs

了解如何通过不同的内存位置和最佳实践在会话中管理 Claude Code 的内存。

Claude Code 可以在会话中记住您的偏好设置,例如样式指南和工作流中的常用命令。

确定内存类型

Claude Code 在分层结构中提供四个内存位置,每个位置都有不同的用途:

内存类型位置用途用例示例共享对象
项目内存./CLAUDE.md./.claude/CLAUDE.md项目的团队共享说明项目架构、编码标准、常见工作流通过源代码控制的团队成员
项目规则./.claude/rules/*.md模块化、特定主题的项目说明特定于语言的指南、测试约定、API 标准通过源代码控制的团队成员
用户内存~/.claude/CLAUDE.md所有项目的个人偏好设置代码样式偏好、个人工具快捷方式仅您(所有项目)
项目内存(本地)./CLAUDE.local.md个人的项目特定偏好设置您的沙箱 URL、首选测试数据仅您(当前项目)

启动 Claude Code 时,所有内存文件都会自动加载到其上下文中。层次结构中较高位置的文件优先级更高,并首先加载,为更具体的内存提供基础 CLAUDE.local.md 文件会自动添加到 .gitignore,使其成为不应签入版本控制的私有项目特定偏好设置的理想选择。

CLAUDE.md 导入

CLAUDE.md 文件可以使用 @path/to/import 语法导入其他文件。以下示例导入 3 个文件:

See @README for project overview and @package.json for available npm commands for this project.

# Additional Instructions
- git workflow @docs/git-instructions.md

允许相对路径和绝对路径。特别是,导入用户主目录中的文件是团队成员提供不签入存储库的个人说明的便捷方式。导入是 CLAUDE.local.md 的替代方案,在多个 git 工作树中效果更好。

# Individual Preferences
- @~/.claude/my-project-instructions.md

为了避免潜在的冲突,导入不会在 markdown 代码跨度和代码块内进行评估。

This code span will not be treated as an import: `@anthropic-ai/claude-code`

导入的文件可以递归导入其他文件,最大深度为 5 跳。您可以通过运行 /memory 命令查看加载了哪些内存文件。

Claude 如何查找内存

Claude Code 递归读取内存:从当前工作目录开始,Claude Code 向上递归到(但不包括)根目录 / 并读取它找到的任何 CLAUDE.md 或 CLAUDE.local.md 文件。当在大型存储库中工作时,这特别方便,您在 foo/bar/ 中运行 Claude Code,并在 foo/CLAUDE.mdfoo/bar/CLAUDE.md 中都有内存。

Claude 还会发现当前工作目录下的子树中嵌套的 CLAUDE.md。它们不是在启动时加载,而是仅在 Claude 读取这些子树中的文件时才包含。

使用 /memory 直接编辑内存

在会话期间使用 /memory 斜杠命令在系统编辑器中打开任何内存文件,以进行更广泛的添加或组织。

设置项目内存

假设您想设置一个 CLAUDE.md 文件来存储重要的项目信息、约定和常用命令。项目内存可以存储在 ./CLAUDE.md./.claude/CLAUDE.md 中。

使用以下命令为您的代码库引导 CLAUDE.md:

> /init

提示:

  • 包含常用命令(构建、测试、lint)以避免重复搜索
  • 记录代码样式偏好和名约定
  • 添加特定于您的项目的重要架构模式
  • CLAUDE.md 内存可用于与您的团队共享的说明和您的个人偏好

使用 .claude/rules/ 的模块化规则

对于较大的项目,您可以使用 .claude/rules/ 目录将说明组织到多个文件中。这允许团队维护专注、组织良好的规则文件,而不是一个大型 CLAUDE.md。

基本结构

在项目的 .claude/rules/ 目录中放置 markdown 文件:

your-project/
├── .claude/
│   ├── CLAUDE.md           # Main project instructions
│   └── rules/
│       ├── code-style.md   # Code style guidelines
│       ├── testing.md      # Testing conventions
│       └── security.md     # Security requirements

.claude/rules/ 中的所有 .md 文件都会自动加载为项目内存,优先级与 .claude/CLAUDE.md 相同。

特定于路径的规则

规则可以使用带有 paths 字段的 YAML 前置事项限定到特定文件。这些条件规则仅在 Claude 处理与指定模式匹配的文件时适用。


paths: src/api/**/*.ts

# API Development Rules

- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation comments

没有 paths 字段的规则会无条件加载,适用于所有文件。

Glob 模式

paths 字段支持标准 glob 模式:

模式匹配
**/*.ts任何目录中的所有 TypeScript 文件
src/**/*src/ 目录下的所有文件
*.md项目根目录中的 Markdown 文件
src/components/*.tsx特定目录中的 React 组件

您可以使用大括号有效地匹配多个模式:

paths: src/**/*.{ts,tsx}

# TypeScript/React Rules

这会扩展为匹配 src/**/*.tssrc/**/*.tsx。您也可以用逗号组合多个模式:

paths: {src,lib}/**/*.ts, tests/**/*.test.ts

子目录

规则可以组织到子目录中以获得更好的结构:

.claude/rules/
├── frontend/
│   ├── react.md
│   └── styles.md
├── backend/
│   ├── api.md
│   └── database.md
└── general.md

所有 .md 文件都会被递归发现。

符号链接

.claude/rules/ 目录支持符号链接,允许您在多个项目中共享常见规则:

# Symlink a shared rules directory
ln -s ~/shared-claude-rules .claude/rules/shared

# Symlink individual rule files
ln -s ~/company-standards/security.md .claude/rules/security.md

符号链接会被解析,其内容会正常加载。循环符号链接会被检测并妥善处理。

用户级规则

您可以在 ~/.claude/rules/ 中创建适用于所有项目的个人规则:

~/.claude/rules/
├── preferences.md    # Your personal coding preferences
└── workflows.md      # Your preferred workflows

用户级规则在项目规则之前加载,使项目规则具有更高的优先级。

.claude/rules/ 的最佳实践:

  • 保持规则专注:每个文件应涵盖一个主题(例如 testing.mdapi-design.md
  • 使用描述性文件名:文件名应指示规则涵盖的内容
  • 谨慎使用条件规则:仅在规则确实适用于特定文件类型时添加 paths 前置事项
  • 使用子目录组织:分组相关规则(例如 frontend/backend/

组织级内存管理

组织可以部署适用于所有用户的集中管理的 CLAUDE.md 文件。

要设置组织级内存管理:

  1. 在上面 内存类型表 中显示的托管策略位置创建托管内存文件。
  2. 通过您的配置管理系统(MDM、组策略、Ansible 等)部署,以确保在所有开发人员计算机上一致分发。

内存最佳实践

  • 具体明确:"使用 2 空格缩进"比"正确格式化代码"更好。
  • 使用结构来组织:将每个单独的内存格式化为项目符号,并在描述性 markdown 标题下分组相关内存。
  • 定期审查:随着项目的发展更新内存,以确保 Claude 始终使用最新的信息和上下文。
  • 放在项目根目录

配置层级(参考 settings.json 的模式):

  • 用户级:~/.claude/ 目录
  • 项目级:项目根目录或 .claude/ 目录

最佳实践建议:

  • 保持 CLAUDE.md 简洁,只包含高层概述和关键规则
  • 使用 Skills 系统 拆分详细的主题指南
  • 使用 Plugins 组织更复杂的扩展功能

解决 Claude.md 过大的推荐方案:

  1. 使用 Skills 系统:将不同主题的规则拆分为独立的 skill 文件,通过 /skill-name 按需调用
  2. 使用 Plugin 系统:将规则组织为插件,包含 commands、agents 等模块化结构
  3. 保持 CLAUDE.md 精简:只放高层概述和关键规则,详细内容通过 skills 或让 Claude 按需读取其他文档文件
  4. 可以在 ~/.claude/rules/ 中创建适用于所有项目的个人规则:

Layer 2: 定义 Project SubAgent

核心价值: 针对不同开发场景提供专业化的 AI 助手

核心理念: "专业的人做专业的事"

问题:
  通用 AI Agent 在处理复杂任务时的局限性:
  - 缺乏领域专业知识
  - 工具选择不够精准
  - 上下文理解不够深入

解决方案:
  为不同开发场景创建专用 Agent:
  - 后端架构 → service-copilot
  - 前端开发 → nexthub-dev
  - 日常开发 → 通用 Agent

创建自定义子代理 - Claude Code Docs

在 Claude Code 中创建和使用专门的 AI 子代理,用于特定任务工作流和改进的上下文管理。

子代理是处理特定类型任务的专门 AI 助手。每个子代理在自己的上下文窗口中运行,具有自定义系统提示、特定的工具访问权限和独立的权限。当 Claude 遇到与子代理描述相匹配的任务时,它会委托给该子代理,该子代理独立工作并返回结果。子代理帮助你:

  • 保留上下文,通过将探索和实现保持在主对话之外
  • 强制执行约束,通过限制子代理可以使用的工具
  • 跨项目重用配置,使用用户级子代理
  • 专门化行为,使用针对特定领域的聚焦系统提示
  • 控制成本,通过将任务路由到更快、更便宜的模型(如 Haiku)

Claude 使用每个子代理的描述来决定何时委托任务。创建子代理时,请写一个清晰的描述,以便 Claude 知道何时使用它。Claude Code 包括几个内置子代理,如

探索计划通用。你也可以创建自定义子代理来处理特定任务。本页涵盖内置子代理如何创建你自己的完整配置选项使用子代理的模式示例子代理

Layer 3: 添加项目技术栈所需的 MCP

核心价值: 提供外部工具和服务的集成能力

通过 MCP 将 Claude Code 连接到工具 - Claude Code Docs

Claude Code 可以通过 **Model Context Protocol (MCP)** 连接到数百个外部工具和数据源,这是一个用于 AI 工具集成的开源标准。MCP 服务器为 Claude Code 提供对您的工具、数据库和 API 的访问权限。

连接 MCP 服务器后,您可以要求 Claude Code:

  • 从问题跟踪器实现功能:“添加 JIRA 问题 ENG-4521 中描述的功能,并在 GitHub 上创建 PR。”
  • 分析监控数据:“检查 Sentry 和 Statsig 以检查 ENG-4521 中描述的功能的使用情况。”
  • 查询数据库:“根据我们的 PostgreSQL 数据库,找到使用功能 ENG-4521 的 10 个随机用户的电子邮件。”
  • 集成设计:“根据在 Slack 中发布的新 Figma 设计更新我们的标准电子邮件模板”
  • 自动化工作流:“创建 Gmail 草稿,邀请这 10 个用户参加关于新功能的反馈会议。“

Layer 4: 添加项目技术栈所需的 Skills

核心价值: 可复用的任务模板,通过 /skill-name 快速调用

Agent Skills - Claude Code Docs

在 Claude Code 中创建、管理和共享技能以扩展 Claude 的功能。包括自定义斜杠命令。

技能扩展了 Claude 能做的事情。创建一个包含说明的 SKILL.md 文件,Claude 就会将其添加到其工具包中。Claude 在相关时使用技能,或者你可以使用 /skill-name直接调用一个技能。

对于内置命令(如 /help 和 /compact),请参阅交互模式自定义斜杠命令已合并到技能中。 .claude/commands/review.md 中的文件和 .claude/skills/review/SKILL.md 中的技能都会创建 /review 并以相同方式工作。你现有的 .claude/commands/ 文件继续工作。技能添加了可选功能:支持文件的目录、控制你或 Claude 是否调用它们的前置元数据,以及 Claude 在相关时自动加载它们的能力。

Claude Code 技能遵循 **Agent Skills** 开放标准,该标准适用于多个 AI 工具。Claude Code 使用额外功能扩展了该标准,如调用控制子代理执行动态上下文注入

Layer 5: 工作流与钩子层

核心价值: 自动化开发流程,强制执行质量标准

工作流示例:

添加新端点工作流:
  1. 阅读相关文件了解现有实现
  2. 确认修改不会破坏现有功能
  3. 实施代码变更
  4. 添加单元测试和集成测试
  5. 运行 make lint, make typecheck, make test
  6. 手动验证功能
  7. 提交代码(使用 /commit)

数据库迁移工作流:
  1. 修改 SQLAlchemy 模型
  2. 生成迁移: make migrate-create
  3. 审查迁移文件
  4. 应用迁移: make migrate
  5. 验证数据库状态
  6. 更新相关测试

全栈功能开发工作流:
  1. @service-copilot 规划后端 API
  2. 实施后端端点和测试
  3. @nexthub-dev 创建前端页面
  4. 集成 Admin API
  5. 浏览器自动化测试验证
  6. /review-pr 代码审查

利用 Claude Code Plugin 快速初始化

插件让你能够使用可在项目和团队中共享的自定义功能来扩展 Claude Code。

Claude Code Plugin Docs

插件可以包含:自定义代理、Skills/Command、钩子、MCP 服务器和 LSP 服务器。

常见错误:不要将 commands/agents/skills/hooks/ 放在 .claude-plugin/ 目录内。只有 plugin.json 应该在 .claude-plugin/ 内。所有其他目录必须位于插件根级别。

目录位置用途
.claude-plugin/插件根仅包含 plugin.json 清单(必需)
commands/插件根作为 Markdown 文件的斜杠命令
agents/插件根自定义代理定义
skills/插件根带有 SKILL.md 文件的代理 Skills
hooks/插件根hooks.json 中的事件处理程序
.mcp.json插件根MCP 服务器配置
.lsp.json插件根用于代码智能的 LSP 服务器配置

有关所有插件组件的完整技术规范,请参阅插件参考

Claude Code 官方插件仓库


实践模式

文档驱动开发(Documentation-Driven Development)

核心理念: 文档是项目的"单一真相来源"(Single Source of Truth)

传统方式:
  代码 → 文档(经常过时)
  问题: 文档滞后,AI 无法获取最新信息

AIDD 方式:
  文档 ↔ 代码(同步更新)
  优势: AI 始终理解最新架构和规范

实施步骤:

1. 建立文档结构:
   CLAUDE.md (主导航)
   .claude/rules/ (详细规则)
   docs/ (架构文档、PRD)

2. 定义硬性规则:
   - 第三方库版本管理
   - 架构约束
   - 安全要求

3. 编写代码示例:
   - 每个规则配代码示例
   - 展示正确和错误的做法

4. 持续更新:
   - 架构变更 → 立即更新文档
   - 新功能 → 添加到文档
   - 重构 → 更新相关章节

示例:添加新功能的文档流程:

场景: 添加 Rate Limit Cooldown 功能

步骤 1: 更新架构文档
  文件: .claude/rules/rate-limit-cooldown.md
  内容:
    - 功能概述
    - 配置方法
    - API 端点
    - 故障排查

步骤 2: 更新主导航
  文件: CLAUDE.md
  添加: "详细的 Rate Limit Cooldown 实现见 .claude/rules/rate-limit-cooldown.md"

步骤 3: 实施代码
  AI 参考文档实施功能

步骤 4: 验证一致性
  代码实现 ↔ 文档描述
  确保完全一致

上下文效率优化

问题: AI 上下文窗口有限,如何最大化利用?

解决方案: 模块化 + 按需加载

优化前:
  单一 AGENTS.md: 2384 行
  问题: 加载慢,信息密度低

优化后:
  AGENTS.md: 392 行(导航)
  .claude/rules/: 12 个专题文件
  效果: 90% 上下文效率提升

模块化原则:

1. 单一职责:
   每个文件只关注一个主题

2. 合理粒度:
   100-700 行为宜

3. 清晰索引:
   主文件提供导航

4. 交叉引用:
   相关文件互相链接

Agent 协作模式

模式 1: 规划-实施分离

流程:
  @service-copilot 规划
  → Handoff: Start Implementation
  → 通用 Agent 实施

优势:
  - 规划阶段深度分析
  - 实施阶段专注执行
  - 职责清晰,效率高

模式 2: 前后端协作

流程:
  @nexthub-dev 发现需要新 API
  → Handoff: Backend Integration
  → @service-copilot 设计 API
  → 通用 Agent 实施后端
  → @nexthub-dev 集成前端

优势:
  - 前后端需求对齐
  - API 设计符合前端需求
  - 减少返工

模式 3: 测试驱动协作

流程:
  /tdd 生成测试
  → 通用 Agent 实施代码
  → /review-pr 代码审查
  → /e2e 端到端验证

优势:
  - 质量保证
  - 自动化验证
  - 持续改进

安全优先原则

核心理念: 安全检查自动化,主动防御而非被动修复

实施策略:
  1. 代码生成时:
     - AI 自动应用安全最佳实践
     - 避免 OWASP Top 10 漏洞

  2. 代码审查时:
     - /security-review 自动触发
     - 检测注入攻击、XSS、CSRF

  3. 部署前:
     - 运行安全扫描
     - 验证依赖库无已知漏洞

示例规则:
  - 所有 admin 端点必须有 require_admin
  - 所有用户输入必须验证和清理
  - 敏感数据必须加密存储
  - API Key 必须哈希存储

性能与效率优化

上下文窗口优化

问题: AI 上下文窗口有限(200K tokens),如何高效利用?

优化策略:

1. 模块化文档:
   优化前: 单一文件 2384 行
   优化后: 12 个模块文件
   效果: 90% 上下文效率提升

2. 按需加载:
   - Claude Code 自动加载 .claude/rules/
   - 只加载相关模块
   - 避免加载无关信息

3. 文档压缩:
   - 使用代码示例代替长篇描述
   - 使用 YAML 格式代替自然语言
   - 删除冗余信息

4. 交叉引用:
   - 主文件提供导航
   - 详细内容在专题文件
   - 避免重复内容

实测数据:

优化前:
  CLAUDE.md: 37 KB
  AGENTS.md: 58 KB
  总计: 95 KB
  上下文利用率: 40%

优化后:
  CLAUDE.md: 37 KB(更新)
  AGENTS.md: 10 KB(优化)
  .claude/rules/: 12 个文件
  总计: ~60 KB(有效内容)
  上下文利用率: 85%

效率提升技巧:

1. 使用 Skills 快捷方式:
   - /commit 代替手动 git 操作
   - /review-pr 代替手动代码审查
   - /tdd 强制测试驱动开发

2. 使用专用 Agent:
   - 后端任务 → @service-copilot
   - 前端任务 → @nexthub-dev
   - 避免使用通用 Agent 处理复杂任务

3. 利用 Handoffs:
   - 规划 → 实施 → 测试
   - 自动切换 Agent
   - 减少上下文切换

4. 自动化工作流:
   - pre-commit hook 自动 lint
   - post-tool-call hook 自动测试
   - 减少手动操作

常见陷阱与解决方案

文档陷阱

陷阱 1: 文档过时

问题: 代码更新了,文档没更新,AI 使用过时信息

症状:

- AI 生成的代码不符合当前架构
- AI 引用已删除的文件或函数
- AI 使用已废弃的 API

解决方案:

1. 建立文档更新流程:
   代码变更 → 立即更新文档
   重构 → 更新相关章节
   新功能 → 添加到文档

2. 使用 /doc-updater skill:
   自动更新 codemaps 和文档
   生成 docs/CODEMAPS/*
   更新 README

3. 代码审查检查:
   PR 必须包含文档更新
   检查文档与代码一致性

陷阱 2: 文档过于冗长

问题: 文档太长,AI 上下文窗口利用率低

症状:

- AI 响应慢
- AI 遗漏重要信息
- 上下文溢出

解决方案:

1. 模块化拆分:
   单一文件 → 多个专题文件
   每个文件 100-700 行

2. 使用代码示例:
   长篇描述 → 简洁代码示例
   自然语言 → YAML 格式

3. 删除冗余:
   重复内容 → 交叉引用
   过时信息 → 删除

Agent 使用陷阱

陷阱 3: 使用错误的 Agent

问题: 用通用 Agent 处理复杂任务,效率低下

症状:

- Agent 响应慢
- 生成的代码不符合最佳实践
- 缺乏领域专业知识

解决方案:

决策树:
  后端架构/数据库/性能 → @service-copilot
  Next.js/前端/浏览器 → @nexthub-dev
  简单代码修改 → 通用 Agent

示例:
  ✗ 错误: 用通用 Agent 设计数据库架构
  ✓ 正确: 用 @service-copilot 设计数据库架构

  ✗ 错误: 用 @service-copilot 调试 hydration 错误
  ✓ 正确: 用 @nexthub-dev 调试 hydration 错误

陷阱 4: 忽略 Handoffs

问题: 不使用 Handoffs,手动切换 Agent,效率低

症状:

- 需要重新描述上下文
- Agent 之间信息丢失
- 工作流不连贯

我需要继续添加第7章的内容,但要注意分段输出。让我继续添加解决方案和更多陷阱。

解决方案:

使用 Handoffs:
  规划完成 → 点击 "Start Implementation"
  前端需要后端 → 点击 "Backend Integration"
  需要测试 → 点击 "Test in Browser"

优势:
  - 自动预填充提示
  - 保留上下文
  - 工作流连贯

MCP 工具陷阱

陷阱 5: 不使用 Context7 MCP

问题: 依赖训练数据中的旧知识,使用过时 API

症状:

- 生成的代码使用已废弃的 API
- 参数签名不匹配
- 导入路径错误

解决方案:

文档优先原则:
  1. 总是先查询 Context7 MCP
  2. 验证 API 签名和参数
  3. 使用最新文档生成代码

示例:
  ✗ 错误: 直接生成 Starlette 代码
  ✓ 正确: 先查询 Context7 MCP,再生成代码

  # 正确流程
  1. resolve-library-id(libraryName="Starlette")
  2. query-docs(query="WebSocket implementation")
  3. 基于最新文档生成代码

总结与行动指南

核心要点回顾

AIDD 的五大支柱:

1. 项目记忆系统:
   - 模块化文档架构
   - 90% 上下文效率提升
   - 持续更新机制

2. 专用 Agent 系统:
   - 领域专业化
   - Handoffs 工作流
   - 高效协作模式

3. MCP 工具集成:
   - 文档优先原则
   - 运行时验证
   - 浏览器自动化

4. Agent Skills:
   - 可复用任务模板
   - 标准化工作流
   - 快速调用机制

5. 自动化工作流:
   - 质量保证
   - 安全检查
   - 性能优化

最后的建议

给团队领导者:

1. 投资基础设施:
   - 文档系统是核心
   - 不要急于求成
   - 持续优化迭代

2. 培养 AI 思维:
   - 鼓励团队使用 AI 工具
   - 分享最佳实践
   - 建立学习文化

3. 衡量和优化:
   - 跟踪效率指标
   - 识别瓶颈
   - 持续改进

给开发者:

1. 拥抱 AI 工具:
   - 学习使用专用 Agent
   - 掌握 Skills 快捷方式
   - 利用 MCP 工具

2. 贡献知识:
   - 更新文档
   - 分享经验
   - 创建新 Skills

3. 保持好奇:
   - 探索新工具
   - 尝试新模式
   - 推动创新

三阶段方法论

原视频链接

第一阶段:研究。我会把所有相关的东西都提供给 AI,包括架构图、文档、Slack 对话记录。

这一点我其实已经反复强调过很多次了,但核心只有一句话:尽可能把所有与你即将做出的修改相关的上下文一次性带进来,然后再使用智能代理去分析整个代码库,梳理系统的组成部分以及它们之间的依赖关系。

这绝对不是一次性完成的过程。我通常会不断追问,比如缓存是怎么处理的?失败场景是如何应对的?如果它的分析有误,我会直接纠正;如果它缺少关键信息,我就补充上下文。每一轮交互,都会让它的分析更加精细。

这一阶段的产出是一份完整的研究文档:系统里目前都有哪些东西、它们之间是如何相互连接的、你即将做出的改动会影响到哪些部分。原本需要花上好几个小时甚至更久的探索过程,被压缩成了几分钟的阅读时间。

我知道 Dex 之前也提到过这一点,但我还是要强调:这里的人工检查点(human checkpoint)至关重要。这是整个流程中投入产出比最高的时刻,你需要把分析结果与现实系统进行对照,在这里发现错误的话就能避免之后发生的灾难性后果。

第二阶段:制定可以“照着做”的实现计划。已经有了可靠研究结论的前提下,我们开始制定一份极其详细的实现计划,包括真实的代码结构、函数签名、类型定义、数据流等。

这份计划的目标,是做到任何一名开发者都可以直接照着执行。我常把它比作“数字填色”:你可以把它交给团队里最初级的工程师,对他说“照着这个来做”。只要他逐行照抄,最终结果就应该是正确可用的。

大量关键的架构决策,正是在这一阶段完成的。我们会在这里确保复杂逻辑是正确的,业务需求遵循良好实践,服务边界清晰,职责划分干净,同时避免任何不必要的耦合。之所以能在问题发生之前就识别它们,是因为我们曾经亲身踩过这些坑。而 AI 并没有这种经验,它会把代码中看到的每一种模式,都当作“必须遵守的约束”。

这一阶段真正的“魔法”,在于评审速度。我们可以在几分钟之内完成对整个方案的验证,并且清楚地知道接下来到底会构建出什么。而如果我们想跟上代码生成的速度,就必须以同样快的速度理解自己正在做的事情。

第三阶段:实现。最后才是实现,一旦我们有了清晰的研究结论和明确的实现计划,这一步反而应该是最简单的,而这正是我们希望看到的结果。

当 AI 有一份清楚、具体的规格说明可以遵循时,上下文就会保持干净且聚焦。我们避免了冗长对话导致的复杂度螺旋。相比五十轮不断“进化”的代码修改,现在只需要三次高度聚焦的输出,而且每一步都会在进入下一阶段前完成验证。没有被放弃的方案,没有相互冲突的模式,也不会再出现那种“等等,其实应该这样”的瞬间,没有留下遍地的死代码。

在我看来,这种方法真正的好处是:你可以把大量工作交给后台运行的智能体来完成。因为所有真正困难、需要动脑子的事情,已经提前由你完成了。智能体只需要按照计划开始实现。你可以去处理别的事情,回来时只需要快速评审结果,因为你检查的只是“它是否遵循了计划”,而不是试图弄清楚它是不是凭空“发明”了什么。

我们不是用 AI 来替我们思考,而是用它来加速机械性的工作,同时保持我们对代码的理解能力。研究更快了,规划更全面了,实施也更干净了。但思考、综合和判断,仍然是我们的责任。

还记得我之前说的那个 AI 无法处理的授权系统重构吗?现在我们实际上已经开始推进它,并且取得了一些实质性的进展。但这并不是因为我们找到了更好的提示词,恰恰相反,我们发现,连研究、规划、实现这些阶段都无法一开始就交给 AI。最终,我们不得不亲自下场,手工完成这次修改:不借助 AI,只是阅读代码、理解依赖关系,然后一步步改动,看哪里会出问题。

说实话,这次人工迁移过程非常痛苦,但至关重要。它揭示了所有隐藏的约束条件、必须遵守的不变式,以及一旦授权逻辑发生变化,哪些服务会直接崩溃。这些信息,是任何自动化代码分析都不可能替我们挖掘出来的。

然后,我们把这个手动迁移的拉取请求纳入了研究过程,让它作为后续所有研究工作的基础。即便如此,由于不同实体之间仍然存在差异,我们还是需要不断追问:这个该怎么处理、哪些数据是加密的哪些不是,每一次都要补充额外的上下文,并经过多轮迭代。

直到这时,我们才有可能生成一份“或许能一次成功”的计划。注意,这里的关键词是“或许”。我们仍然在持续验证、不断调整,并持续发现新的边界情况。

这套三阶段方法并不是什么魔法。它之所以能奏效,只是因为我们曾经亲手完成过一次迁移。在把理解写进流程之前,我们必须先赢得这种理解。

我依然认为,并不存在所谓的银弹。没有更好的提示词,没有万能的模型,甚至也不是写得更漂亮的规格文档。真正重要的,始终是那件最朴素、也最困难的事情:足够深入地理解你的系统,理解到你可以安全地对它做出修改为止。

那为什么还要折腾这一整套流程呢?为什么不干脆一直和 AI 反复迭代,直到“能用”为止?反正模型迟早会变得足够强,最后不就都能跑起来了吗?

在我看来,“能跑”本身并不够。通过测试的代码和能在生产环境长期稳定运行的代码之间,是有本质区别的;今天还能工作的系统,和未来还能被别人安全修改的系统,也是两回事。

这中间存在一个认知鸿沟。当 AI 可以在几秒钟内生成成千上万行代码时,理解这些代码却可能要花你几个小时;如果系统足够复杂,可能需要几天;甚至在极端情况下,你可能永远都无法真正理解它。

软件,终究是一项人类的事业

还有一个我觉得几乎没人认真讨论过的问题:每一次为了跟上生成速度而跳过思考,我们失去的并不只是对代码的理解。我们正在逐渐丧失一种能力:识别问题的能力,那种会提醒你“等等,这里开始变复杂了”的直觉,如果你长期不真正理解自己的系统,是会慢慢退化的。

模式识别(pattern recognition)来源于经验。我一眼就能看出某种架构是危险的,那是因为我就那个曾经凌晨三点还在被它折磨的人;当我坚持推动更简单的方案时,是因为我曾经接手并维护过别人留下的复杂系统。

AI 只会生成你让它生成的东西,它并不会内化那些来自失败的教训。

三阶段方法,正是用来弥合这道鸿沟的。它把“理解”压缩成一系列可以在生成速度下被快速审查的产出物。如果没有这一层,我们只是在用一种自己无法理解的速度,不断累积复杂度。

AI 确实彻底改变了我们写代码的方式,但坦率地说,我并不认为但它并没有改变软件失败的根本原因。每一代人都会遭遇属于自己的软件危机。Dijkstra 那一代,通过建立软件工程这门学科来应对;而我们这一代,面对的是无限规模的代码生成。

答案并在于下一个工具或新的方法论,而在于重新记起一个我们早就知道的事实:软件始终是一项人类的事业。困难的从来不是敲代码,而是在一开始就知道该敲什么。

最终能够走得更远的开发者,并不只是那些生成代码最多的人,而是那些仍然理解自己在构建什么、能够看清系统接缝、敢于质疑问题本身是否正确的人。

我想用一个问题来结束今天的分享,这个问题并不是“我们会不会使用 AI”,那早已是既定事实。

真正的问题是: 当 AI 写下大部分代码的时候,我们是否仍然理解自己的系统?

从清晰的计划开始:先写方案,再写代码

不要只是把“愿望”一股脑丢给 LLM,应先定义问题,再规划解决方案。

一个非常常见的错误,是在提示语还很模糊的情况下,直接让 AI 生成代码。在我的工作流中(以及许多成熟实践中),第一步并不是写代码,而是和 AI 一起头脑风暴,产出一份详细的规格说明,然后再整理出清晰的分步计划。

对于一个新项目,我通常会先描述整体想法,并让 LLM 不断向我反问,直到需求、边界条件和潜在的边缘情况都被充分挖掘出来。最终,我们会把这些内容整理成一份完整的 spec.md,其中包含:功能需求、架构决策、数据模型,甚至测试策略。这份规格文档会成为整个开发过程的基石。

接下来,我会把这份 spec 交给一个具备推理能力的模型,让它生成项目计划:把实现过程拆解成逻辑清晰、粒度合适的小任务或里程碑。某种意义上,这是一个“迷你版设计文档 / 项目计划”。我通常会多次迭代这份计划——亲自修改,再让 AI 批判性地审视、优化——直到它足够完整、连贯,然后才进入真正的编码阶段。

这种前期投入乍看之下有点慢,但回报极高。正如 Les Orchard 所说,这就像是“15 分钟完成一次瀑布式设计”,一个快速而结构化的规划阶段,让后续编码变得异常顺畅。

有了清晰的规格和计划,当我们真正“释放”代码生成能力时,人和 AI 都非常清楚:我们要做什么,以及为什么要这么做。简而言之,先规划能让你和 AI 站在同一页上,避免无效反复。很多人会跳过这一步,但如今有经验的 LLM 开发者,已经把高质量的 spec / plan 当成整个工作流的核心。

把工作拆分成小而可迭代的块

范围管理是一切的关键:给 LLM 可控的小任务,而不是一次性塞进整个代码库。

我学到的一个重要教训是:不要让 AI 一次性输出大量、整体性的代码。相反,应把项目拆成一系列小步骤或“工单”,逐个完成。这本来就是良好的软件工程实践,但在引入 AI 之后变得尤为重要。

LLM 在聚焦型任务上表现最好:实现一个函数、修复一个 bug、添加一个小功能。比如在完成规划后,我会直接对代码生成模型说:“好,我们来实现计划里的第 1 步。”完成后测试,再进入第 2 步,如此循环。每一个 chunk 都足够小,小到 AI 能在上下文中处理干净,而你也能真正理解它生成的代码。

这种方式能有效防止模型“跑偏”。如果一次性要求太多,模型往往会迷失方向,生成一堆“纠缠在一起的代码垃圾”,非常难以维护。很多开发者都有类似体验:让 LLM 一口气生成一个完整应用,结果代码风格不统一、逻辑重复,“就像 10 个程序员各干各的,彼此完全没沟通”。我自己也踩过这个坑,解决方法只有一个:停下来,退一步,把问题切小。

每一轮迭代,我们都在已有上下文的基础上,增量式地推进。这也非常适合测试驱动开发(TDD):每一步都可以同步编写或生成测试(后面会详细讲)。

不少编码 Agent 工具已经显式支持这种“分块”工作流。例如,我有时会生成一个结构化的“prompt plan”文件,里面包含每个任务对应的一条提示语,让 Cursor 这类工具按顺序逐条执行。核心原则只有一个:避免大跃进。通过小步快跑,我们大幅降低灾难性错误的概率,也能更快纠偏。LLM 在快速、受限的任务上非常擅长,要顺势而为。

提供充足的上下文和明确的指导

LLM 的质量上限,取决于你提供的上下文质量。把相关代码、文档和约束条件都给它。

在处理真实代码库时,我会确保 AI 拥有完成任务所需的一切信息:相关源码、技术约束、已知坑点、推荐或禁止的方案。现代工具在这方面已经很强了:比如 Claude 的 Projects 模式可以直接导入整个 GitHub 仓库;Cursor、Copilot 会自动把当前打开的文件放进上下文。但我通常还会做得更多。

如果我怀疑模型缺乏某些关键信息,就会通过 MCP(比如 Context7),或干脆手动把重要模块、API 文档粘进对话里。资深 LLM 用户普遍强调这种“上下文打包(context packing)”的重要性,比如在编码前来一次完整的“信息倾倒”,包括:

高层目标与不变量

正确解法的示例

明确警告哪些方案不要用

如果任务本身比较棘手,我甚至会提前告诉 AI 哪些朴素解法性能不行,或者给它一个外部参考实现。如果使用的是冷门库或全新 API,我会直接贴官方文档或 README,避免它“蒙着眼睛飞”。

所有这些前置上下文,都会显著提升输出质量,因为模型不需要猜测,而是基于事实和约束进行生成。

现在也有不少工具能自动化上下文整理,比如 gitingest、repo2txt,它们可以把代码库的关键部分导出成一个文本文件,让 LLM 一次性读入。对于大型项目来说,这是救命工具。原则很简单:不要让 AI 在信息不完整的情况下工作。一个 bug 如果涉及四个模块,就把这四个模块都给它。当然要注意 token 限制,但如今前沿模型的上下文窗口已经非常大(几万 token),合理利用即可。我通常只选取与当前任务相关的代码,并明确告诉 AI 哪些内容可以忽略,以节省上下文空间。

我个人也很看好 Claude Skills 这个方向:它把原本脆弱、一次性的提示,封装成可复用的“技能”,把指令、脚本和领域知识模块化。当请求匹配某个 Skill 时,工具可以自动应用这些能力,效果远好于通用 prompt。这让我们从一次性交互,走向可复用、可沉淀的工程流程。

目前社区已经有不少 Skills 集合,我很喜欢的一个例子是 frontend-design skill,它能终结 LLM UI 里泛滥的“紫色设计风”。在官方工具全面支持之前,也已经有一些可行的变通方案。

最后,在 prompt 里用明确的注释和规则引导 AI。例如,我会在代码前加一句:“这是 X 的当前实现,我们需要扩展它来做 Y,但一定不要破坏 Z。”这种小提示非常有效。LLM 本质上是“字面主义者”,你给什么指令,它就照着执行。上下文越清晰,幻觉和跑偏就越少,生成的代码也越贴合项目实际。

Written by

DS-Dev

At

Wed Jan 28 2026