AI Coding Agent Prompt Engineering 指南:写出高质量编程任务
AI Coding Agent Prompt Engineering 指南:写出高质量编程任务
简介
AI Coding Agent(Claude Code、Codex、OpenCode、Cursor 等)与通用聊天 AI 最大的不同在于:它们需要精确的指令来执行代码操作。一个模糊的 prompt 可能导致 Agent 迷失方向、做无用功甚至引入 Bug。
本文总结了一套经过验证的编程 Agent Prompt 方法论,涵盖任务描述框架、边界约束、质量门禁和调试技巧,适用于所有 AI 编程代理。
前置要求
- 至少使用过一种 AI Coding Agent(Claude Code、Codex CLI 等)。
- 了解基本的编程概念(函数、类、测试、依赖管理)。
- 建议先阅读 fnos 中
CLAUDE.md-配置与最佳实践.md 了解项目级上下文配置。
详细步骤
1. 一个糟糕的 Prompt 长什么样
先看反例,理解为什么需要好的 prompt:
问题:
- 没说清楚改什么功能
- 没提技术栈和框架
- 没有边界约束(是否改后端?是否改样式?)
- 没有质量要求(要测试吗?lint 要过吗?)
- 没有验收标准(怎么样算改好了?)
2. P.A.C.T. 任务描述框架
推荐使用 P.A.C.T. 四要素来构造每个任务 prompt:
| 要素 |
含义 |
问题引导 |
| Purpose |
任务目的 |
为什么要做这个改动?解决什么问题? |
| Action |
具体行动 |
需要增加、修改、删除哪些文件? |
| Constraint |
约束条件 |
不能改什么?必须遵守什么规范? |
| Test |
验证标准 |
如何验证改动是正确的? |
P.A.C.T. 模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ## 任务:[简短标题]
### Purpose - 背景:[改动的原因和上下文] - 目标:[期望达到的效果]
### Action - 需要修改的文件:[文件路径列表] - 需要添加的文件:[新文件列表] - 具体实现:[关键的技术方案描述]
### Constraint - 不要修改:[禁止触碰的文件/目录] - 必须遵守:[代码风格、命名规范、架构约定] - 依赖:如果依赖尚未完成,使用 mock 并标注 TODO
### Test - 运行命令:`npm run test:api` 验证 - 验收条件:[具体的可检查标准] - 提交前输出:`git diff --stat`
|
实战示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ## 任务:实现订单状态数量统计接口
### Purpose 管理后台需要一个仪表盘展示今日订单数据概览。 目前订单数据已完整存储,缺少一个聚合统计的 API。
### Action 1. 在 `server/routes/orders.ts` 中新增 `GET /api/orders/statistics` 2. 在 `server/services/order-stats.ts` 中实现统计逻辑 3. 返回 JSON: { total, pending, processing, shipped, completed, cancelled }
### Constraint - 不要修改 `server/models/` 下的 ORM 模型文件 - 使用 Prisma 的 `groupBy` 和 `count` 聚合,不要手动遍历 - SQL 查询必须在数据库层面完成聚合,不在内存里做
### Test - 运行 `npm run test:api -- --grep "order statistics"` 验证 - 手动 curl: `curl http://localhost:3000/api/orders/statistics` - 提交前运行 `npm run lint` 和 `npm run test`
|
3. 边界约束:最重要的部分
AI Agent 最常犯的错误不是”写的代码不对”,而是”改了不该改的文件”。边界约束是最值得花时间写清楚的部分。
文件级边界
1 2 3 4 5
| ### Constraint - 【禁止】修改 `database/migrations/` 下的迁移文件 - 【禁止】修改 `src/types/` 下的公共类型定义 - 【禁止】格式化不相关的文件(除非特别要求) - 【谨慎】修改 `package.json` 必须说明理由
|
架构级边界
1 2 3 4 5
| ### Constraint - 不要在 API 层直接操作数据库,统一走 Service 层 - 不要在客户端存储敏感信息(Token 必须用 httpOnly cookie) - 所有异步操作必须处理 Error 边界 - 新增数据库字段必须写 migration,不要手动改表
|
质量级边界
1 2 3 4 5
| ### Constraint - 所有新增函数必须有 TypeScript 类型标注 - 函数不超过 50 行,超过则拆分 - 不允许使用 `any` 类型 - 错误信息必须是中文,对用户友好
|
4. 分阶段 prompt:复杂功能拆解
大功能不要一次写完,而是分阶段推进。每个阶段的 prompt 都遵循 P.A.C.T. 框架:
阶段 1:调研与设计
1 2 3 4 5 6 7 8 9
| ## 任务:调研订单导出方案的可行实现
阅读现有代码结构,回答以下问题: 1. 目前有无导出相关的代码? 2. 数据库中最适合导出的表结构和字段? 3. 推荐的技术方案?(ExcelJS / CSV / PDF) 4. 主要风险和复杂度评估?
请阅读 src/server/ 和 prisma/schema.prisma 后给出分析。
|
阶段 2:实现核心逻辑
1 2 3 4 5 6 7 8 9 10 11
| ## 任务:实现订单导出 Service
基于阶段 1 的方案分析,在 src/services/export-service.ts 中实现: 1. 查询订单数据(支持日期范围过滤) 2. 生成 Excel 文件(使用 exceljs 库) 3. 返回文件流
约束: - 单次导出最大行数 10000 - 列头使用中文 - 日期格式 YYYY-MM-DD HH:mm:ss
|
阶段 3:补充测试
1 2 3 4 5 6 7 8 9 10 11
| ## 任务:为订单导出 Service 编写测试
参考 tests/services/ 下的现有测试风格。
要求: 1. 正常导出路径:测试文件生成成功 2. 空数据路径:导出空的 Excel 表头 3. 超过 10000 行时:返回错误 4. Mock 掉 ExcelJS 和 Prisma
运行:npm run test:export
|
阶段 4:Code Review
1 2 3 4 5 6 7 8 9 10
| ## 任务:审查 export-service.ts 的代码质量
检查以下方面: 1. 错误处理是否覆盖了所有边界情况 2. 大文件导出是否有流式处理 3. 内存使用情况评估 4. 类型安全——是否有隐式 any 5. 与现有 OrderService 的耦合度
如发现问题,标注行号和建议修改方案,不要直接改代码。
|
5. 多 Agent 协作的 prompt 技巧
为不同角色定制 prompt
1 2 3 4 5 6 7 8 9
| ## 【实现者任务】实现订单列表 API
你在 agent-order-api worktree 中工作,只修改 server/ 和 tests/api/。 不要修改 web/ 下的前端代码。
### Constraint - 使用 Prisma 查询,paginate 参数: page, pageSize - 返回格式: { data: Order[], total: number, page: number } - 排序默认按 created_at DESC
|
1 2 3 4 5 6 7 8 9 10
| ## 【审查者任务】审查订单列表 API
你在 agent-order-review worktree 中工作。 不要修改任何业务代码。
请检查 server/orders*.ts 中的: 1. 输入验证是否完整(page 负数?pageSize 超过上限?) 2. 是否有 SQL 注入风险(Prisma 已经防注入,但 raw query 呢?) 3. 性能:全表扫描还是走了索引? 4. 错误信息是否暴露了内部细节?
|
6. 修复 Bug 的 prompt 技巧
修复 Bug 时,让 Agent 先理解问题再动手:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ## 任务:修复登录页面在 iOS 上键盘弹起时白屏
### 症状 iOS 15/16 Safari,点击输入框后键盘弹起,页面顶部白屏约 200px。
### 排查步骤 1. 先查看 web/login/ 下的相关组件 2. 查找是否有 `100vh` 或 `window.innerHeight` 的使用 3. 读取现有 CSS 中的媒体查询和 viewport 设置
### 行动 找到根因后,描述你发现的方案和修改建议,不要直接改代码。 等我确认方案后再执行修改。
|
核心原则:先诊断,再开药方,最后动手术。
7. 修复与验证循环
Agent 完成修改后,在 prompt 中包含验证命令:
1 2 3 4 5 6 7
| ### 完成后的验证
1. 运行 `npm run test:api -- --grep "order export"` 2. 如果测试失败,分析失败原因并修复 3. 重复直到测试通过 4. 最终运行 `npm run lint` 确保无格式问题 5. 输出最终的 `git diff --stat`
|
8. 跨语言/框架的 prompt 注意事项
| 语言/框架 |
特殊注意事项 |
| TypeScript |
指定 strict 模式、是否允许 any、类型定义文件位置 |
| Python |
指定类型检查工具 (mypy/pyright)、虚拟环境路径 |
| React |
指明 Hooks 规则、组件模式(函数式/类)、状态管理方案 |
| Node.js |
运行时版本、模块系统 (ESM/CJS)、包管理器 (npm/pnpm/yarn) |
| Go |
GOPATH/mod 模式、错误处理约定、测试框架 |
| Rust |
异步运行时 (tokio/async-std)、错误处理方式 (anyhow/thiserror) |
代码示例
Python 项目 prompt 模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ## 任务:添加用户注册 API
### Purpose 支持新用户通过邮箱注册。
### Action 在 app/routes/auth.py 中新增 `POST /api/auth/register` 输入: { email, password, name } 输出: { id, email, name, created_at }
### Constraint - 密码使用 bcrypt 哈希,不要明文存储 - 邮箱格式验证使用 pydantic(已有 EmailStr) - 不要修改 app/models/user.py 的模型定义 - 代码风格遵循 PEP 8,使用 snake_case - 类型注解必须完整,运行 mypy 验证
### Test 1. 运行: `python -m pytest tests/test_auth.py -x -v` 2. curl 验证新注册端点 3. 确认密码在数据库中是哈希值,不是明文
|
重构任务 prompt 模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ## 任务:重构订单查询逻辑
### Purpose 当前 OrderService 中的查询方法有大量重复的过滤代码, 需要抽取为可复用的 QueryBuilder。
### Action 1. 在 src/services/builders/ 下创建 OrderQueryBuilder 类 2. 支持链式调用: `.byStatus().byDateRange().byUserId()` 3. 重构 OrderService 中的 findOrders/findPendingOrders 方法
### Constraint - 保持现有 API 接口不变(方法签名和返回类型一致) - 不修改测试文件(测试可以通过即说明重构成功) - 每个方法不超过 30 行 - 不允许使用 lodash 等额外依赖
### Test - 运行: npm run test:services 确认全部通过 - 运行: npm run typecheck 确保类型正确
|
紧急热修复 prompt 模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ## 紧急修复:Token 过期后页面无限重定向
### 严重程度 P0 生产问题,影响所有已登录用户。
### 现象 Access Token 过期后,刷新页面触发 OAuth 刷新流程, 刷新失败后重定向到登录页,然后立即再次触发刷新 → 死循环。
### 根因 LoginPage 组件挂载时无条件调用 refreshToken(), 没有检查是否已经在流程中。
### 修复方案 在 LoginPage 中添加状态标记 `isRefreshing`,防止重入。
### 约束 - 只修改 web/pages/LoginPage.tsx,不动其他文件 - 不引入新依赖 - 修改后运行: npm run test:e2e -- --grep "login"
|
常见问题
1. Agent 不遵守 prompt 中的约束怎么办?
逐步收紧:
1 2 3 4
| ## 纠正 我发现在 `src/types/user.ts` 中新增了字段。 请在打开的约束 `【禁止】改公共类型定义` 下恢复此改动。 如果必须改,请先说明需要改的字段和理由。
|
如果 Agent 反复违规,考虑在 CLAUDE.md 中写入该约束,让它每次加载项目时就记住。
2. Agent 生成了大量无用代码或过度工程?
在 prompt 中明确”最小改动原则”:
1 2 3 4 5
| ### Constraint - 遵循最小改动原则:只改动实现需求必需的代码 - 不要提前抽象或引入设计模式 - 不要在非必要处添加装饰器、工厂、适配器等 - 不要添加日志埋点(有专门的日志方案)
|
3. prompt 太长导致上下文窗口不够怎么办?
把固定信息放在 CLAUDE.md 或 .claude/instructions/ 中,prompt 中只写”增量指令”:
1 2 3 4 5 6
| ## 任务 如 CLAUDE.md 所述,新增 `GET /api/orders/statistics` 接口。
### 本次特定约束 - 只使用 Prisma 聚合查询,不要新增索引 - 运行 pnpm test:api 验证
|
4. 如何让 Agent 在一次对话中完成多个子任务?
使用编号列表分解:
1 2 3 4 5 6 7 8 9
| ## 任务清单
请按顺序完成以下子任务,每完成一个输出"✅ 已完成: [子任务名]":
1. 在 server/routes/orders.ts 中新增统计接口 2. 在 server/services/order-stats.ts 中实现统计逻辑 3. 在 tests/api/orders.test.ts 中补充测试 4. 运行 npm run test:api 确认通过 5. 输出最终的 git diff --stat
|
5. Agent 回答中大量出现「假设」「可能」「应该」等不确定性词汇?
在 prompt 中明确要求确定性输出:
1 2 3 4 5
| ## 回答要求 - 如果有不确定的地方,直接说出不完全确认,然后给出你的最佳判断 - 用「是/否」回答二选一问题 - 给出具体的代码行号和文件路径 - 如果方案有多个选择,列出优劣对比后推荐一个
|
6. 同一个任务重复多次 Agent 的表现不一致?
这是 Agent 的固有特性。缓解方法:
- 在 CLAUDE.md 中固化关键约束
- 使用多阶段 prompt(设计→实现→审查→提 PR)
- 审查 Agent 的输出时关注逻辑而非风格
小结
好的 AI Coding Agent Prompt = 清楚的上下文 + 精确的边界 + 可验证的标准。
1 2 3 4 5 6 7
| P.A.C.T. 框架: ┌─────────────────────────────────────┐ │ Purpose ─ 为什么做 │ │ Action ─ 做什么、改哪里 │ │ Constraint ─ 不能做什么 │ │ Test ─ 怎么算完成 │ └─────────────────────────────────────┘
|
核心心法:**给 Agent 的 prompt 不是”对 AI 说话”,而是”对同事写任务单”**。内容越精确、边界越清晰、验收标准越可衡量,Agent 的输出质量就越高。