别再让AI猜了:AI编程Prompt工程的正确打开方式

用AI写代码的人越来越多,但写出来的代码质量参差不齐。问题往往不在AI,而在你怎么跟它"说话"。一个好的Prompt能让AI输出专业级代码,一个模糊的Prompt只会得到一堆需要返工的半成品。本文系统梳理AI编程场景下的Prompt工程技巧,帮你真正把AI用好。

为什么Prompt这么重要

很多人用AI写代码的体验是这样的:

"帮我写一个用户登录功能"

AI洋洋洒洒写了两百行,结果:用了你不需要的框架、没做输入验证、密码直接明文存储、跟你的项目架构完全不搭。

然后你花半小时修修补补,还不如自己从头写。

问题出在哪? 不是AI不行,而是你给的信息太少。AI只能根据你提供的上下文来"猜"你想要什么。Prompt的本质就是消除歧义、缩小搜索空间

模糊 Prompt → AI 猜测 → 大量返工
精准 Prompt → AI 精确生成 → 微调即用

Prompt的五层信息模型

一个好的编程Prompt应该包含五个层次的信息:

层次 内容 示例
角色 期望AI扮演什么角色 "你是一个资深Go后端工程师"
任务 具体要做什么 "实现一个JWT中间件"
约束 技术栈、风格、限制 "使用gin框架,不引入第三方JWT库"
上下文 项目背景、已有代码 "现有项目结构如下..."
输出格式 期望的输出形式 "给出完整代码+单元测试+使用说明"

不需要每次都写满五层,但信息越完整,结果越精准

反面教材 vs 正面示范

场景一:写一个工具函数

反面

帮我写一个日期格式化函数

AI可能会用你项目里根本不存在的库,写出跟你项目风格完全不同的代码。

正面

用Go写一个日期格式化函数,要求:
- 输入是time.Time和格式字符串
- 支持"2006-01-02"、"2006/01/02 15:04:05"两种预定义格式
- 输入零值时返回空字符串而非报错
- 放在项目已有的 utils/time.go 中,与现有函数风格一致
- 附上表驱动测试

场景二:修复Bug

反面

这段代码有bug,帮我修一下

正面

以下Go代码在并发场景下偶发panic: runtime error: concurrent map writes。
复现路径:10个goroutine同时调用ProcessOrder()。
我的分析是orders map没有加锁保护,请确认并修复。
修复时注意:不要引入全局锁,考虑用sync.Map或分片锁。

[粘贴代码]

场景三:代码重构

反面

优化这段代码

正面

重构以下代码,目标:
1. 提取重复的数据库查询逻辑为独立方法
2. 将硬编码的SQL改为参数化查询
3. 保持所有现有测试通过
4. 遵循项目现有的Repository模式
5. 不要改变公开API的签名

[粘贴代码]

六大核心Prompt技巧

1. 提供示例(Few-Shot)

给AI看你想要的代码风格,比说一百句"风格要好"都管用:

按照以下风格为PaymentService写单元测试:

// 已有测试示例
func TestUserService_CreateUser_Success(t *testing.T) {
    svc := NewUserService(mockRepo, mockLogger)
    user, err := svc.CreateUser(context.Background(), CreateUserReq{
        Name:  "Alice",
        Email: "alice@example.com",
    })
    require.NoError(t, err)
    assert.Equal(t, "Alice", user.Name)
    mockRepo.AssertCalled(t, "Insert", mock.Anything)
}

请为PaymentService.ProcessPayment写类似风格的测试,覆盖:
- 支付成功
- 余额不足
- 网络超时

2. 分步拆解(Chain of Thought)

复杂任务不要一步到位,让AI分步思考:

我需要实现一个分布式限流器。请按以下步骤进行:

第一步:分析需求——每秒最多1000次请求,部署在5个节点上,需要精确限流
第二步:选型——对比令牌桶、滑动窗口、固定窗口三种算法,给出推荐
第三步:设计接口——定义RateLimiter的公开方法签名
第四步:实现核心逻辑——用Go实现选定的算法
第五步:写测试——覆盖正常限流、边界值、并发安全

每一步完成后暂停,等我确认再继续。

3. 指定约束条件

约束越明确,AI越不容易跑偏:

用Python实现一个配置加载器,约束条件:
- Python 3.10+,不使用任何第三方依赖(仅标准库)
- 支持JSON和YAML格式(YAML用简单正则解析,不引入PyYAML)
- 支持环境变量覆盖:ENV_VAR_NAME 覆盖 config.key.name
- 配置值支持类型自动推断(int/float/bool/string)
- 文件不存在时使用默认配置,不抛异常
- 代码不超过150行

4. 利用上下文窗口

把相关代码贴给AI,让它理解项目全貌:

以下是我项目的目录结构和关键接口定义:

[目录结构]
[interfaces.go 内容]
[现有的 user_service.go 内容]

现在请按照相同的模式实现 order_service.go,保持一致的:
- 错误处理风格(自定义Error类型)
- 日志记录方式(slog)
- 依赖注入方式(构造函数参数)
- 测试结构(表驱动 + testify)

5. 反向验证

让AI在生成代码后自己检查:

实现完成后,请:
1. 列出这段代码可能存在的3个边界条件问题
2. 检查是否有并发安全隐患
3. 评估时间复杂度和空间复杂度
4. 如果有问题,直接修复并说明修改了什么

6. 迭代优化

不要期望一次Prompt就完美,学会迭代:

第一轮:生成基础实现
→ "代码可以工作,但错误处理太粗糙,请为每个错误路径添加结构化日志和错误码"

第二轮:增强健壮性
→ "补充单元测试,重点覆盖错误路径和边界条件"

第三轮:补充测试
→ "检查代码中是否有可以提取为公共方法重复逻辑"

第四轮:重构优化

不同场景的Prompt模板

新功能开发

在[项目/模块]中实现[功能描述]。

技术栈:[语言+框架+版本]
已有接口:[粘贴相关接口定义]
设计要求:
- [功能点1]
- [功能点2]
- [异常处理策略]
- [性能要求]

输出要求:
- 完整可运行的代码
- 单元测试覆盖核心逻辑
- 关键决策的注释说明

Bug修复

Bug描述:[具体现象]
复现步骤:[1. 2. 3.]
期望行为:[应该怎样]
实际行为:[实际怎样]
环境:[OS/语言版本/框架版本]
相关代码:
[粘贴代码]

请:
1. 分析根因
2. 给出修复方案
3. 实现修复代码
4. 编写回归测试确保不再复现

代码审查

请审查以下代码,关注:
1. 安全漏洞(注入、越权、敏感信息泄露)
2. 并发安全(竞态条件、死锁)
3. 错误处理(是否有被吞掉的错误)
4. 性能问题(N+1查询、不必要的内存分配)
5. 可维护性(命名、职责划分、代码重复)

按严重程度从高到低排列问题,每个问题给出:
- 问题描述
- 具体位置(行号或代码片段)
- 修复建议(附代码)

[粘贴代码]

API设计

设计一个[功能]的RESTful API,要求:
- 遵循RESTful规范和项目现有API风格
- 给出每个接口的:方法、路径、请求体、响应体、状态码
- 包含错误响应格式(统一错误码)
- 考虑分页、过滤、排序
- 给出OpenAPI 3.0规范

现有API风格参考:
[粘贴一个现有API的示例]

进阶技巧

让AI扮演审查者

你是一位有10年经验的后端架构师。请审查我的实现,重点检查:
- 是否遵循SOLID原则
- 是否有过度设计或设计不足
- 异常处理是否完整
- 是否考虑了可观测性(日志、指标、追踪)

[粘贴代码]

利用否定指令

告诉AI不要做什么和告诉它要做什么一样重要:

实现用户注册功能,注意:
- 不要使用ORM,用原生SQL
- 不要引入新的第三方依赖
- 不要修改现有的数据库schema
- 不要在handler层直接操作数据库
- 不要返回完整的用户对象给前端(脱敏处理)

对比方案

我需要实现一个任务队列。请对比以下三种方案的优劣:
1. 基于Redis List + BRPOP
2. 基于PostgreSQL SKIP LOCKED
3. 基于NATS JetStream

评估维度:吞吐量、持久化、复杂度、运维成本、团队学习曲线。
我的项目背景:Go语言,日均任务量约50万,已有Redis和PostgreSQL基础设施。
给出你的推荐和理由。

生成文档和注释

为以下代码生成:
1. 函数级别的godoc注释(遵循Go文档规范)
2. 复杂逻辑的行内注释(解释Why,不解释What)
3. 一个使用示例(Example函数格式)

不要为显而易见的代码加注释。

[粘贴代码]

常见误区

误区一:Prompt越长越好

。过长的Prompt会稀释重点信息。关键是把约束条件上下文给清楚,而不是堆砌废话。

误区二:一次Prompt搞定一切

。复杂任务应该拆分为多轮对话。第一轮搭框架,第二轮补细节,第三轮做优化。每次让AI聚焦一件事。

误区三:完全信任AI的输出

。AI生成的代码必须经过审查。特别关注:

  • 安全问题(AI经常忽略)
  • 并发安全(AI倾向于写单线程代码)
  • 错误处理(AI经常吞掉错误或用panic代替)
  • 第三方依赖版本(AI可能用过时API)

误区四:不给项目上下文

。AI不了解你的项目。把目录结构、接口定义、编码规范贴给它,结果会好一个量级。

误区五:用自然语言描述代码结构

。直接贴代码比用文字描述"有一个UserServiceImpl类继承了BaseService..."高效得多。

工具链配合

Prompt工程不是孤立的,配合工具效果更好:

工具 配合方式
Cursor / Qoder 自动加载项目上下文,减少手动粘贴
Copilot Chat 选中代码直接提问,上下文自动带入
Claude Code 终端Agent模式,自动读取项目文件
自定义系统Prompt 预设项目规范,所有对话自动继承

设置项目级系统Prompt

很多工具支持项目级别的系统Prompt(如Cursor的.cursorrules),可以预设:

你是一个Go后端工程师,项目技术栈:
- Go 1.22 + Gin + sqlc + slog
- 遵循项目现有的分层架构:handler → service → repository
- 错误处理使用自定义AppError类型
- 所有公开方法必须有单元测试
- 日志使用结构化日志,包含trace_id
- 不使用全局变量,依赖通过构造函数注入

这样每次对话都自动继承这些约束,不用反复说明。

总结

AI编程的Prompt工程,本质是把隐性知识显性化的过程。

你脑子里有很多"理所当然"的约束——项目风格、技术选型、编码规范、异常处理策略——这些信息AI不知道。Prompt的作用就是把这些信息传递给AI。

记住这个公式:

好的Prompt = 明确的任务 + 充分的约束 + 相关的上下文 + 期望的输出格式

不需要每次都写得很长,但要养成多给一句约束的习惯。多一句"不要用ORM",就能避免AI引入你不想要的依赖;多一句"保持测试通过",就能避免AI破坏现有功能。

从今天开始,别再让AI猜了。