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:

1
帮我改一下登录页面

问题:

  • 没说清楚改什么功能
  • 没提技术栈和框架
  • 没有边界约束(是否改后端?是否改样式?)
  • 没有质量要求(要测试吗?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 的输出质量就越高。