# Prompt 工程实践总结

> Site index: <https://blog.suxiong.me/llms.txt>

Original: [Prompt 工程实践总结](https://blog.suxiong.me/blog/prompt-engineering-best-practices)

Author: Suxiong

Date: 2026-02-02

工程师越来越依赖 AI 来加速我们的日常工作流程。这些 AI 工具可以自动补全、修复 bug，甚至生成整个模块或 MVP。然而 AI 输出的质量在很大程度上取决于你提供的 prompt 质量。换句话说，prompt engineering 已经成为了一项必备技能。本文从实用角度系统性地探讨如何为常见开发任务制作有效的 prompt。

Tags: Prompt / 工程实践 / 总结

工程师越来越依赖 AI 来加速我们的日常工作流程。这些 AI 工具可以自动补全、修复 bug，甚至生成整个模块或 MVP。然而 AI 输出的质量在很大程度上取决于你提供的 prompt 质量。换句话说，prompt engineering 已经成为了一项必备技能。本文从实用角度系统性地探讨如何为常见开发任务制作有效的 prompt。

AI 并非无所不能，因为他们对你的具体项目没有任何预先了解，只能依靠你提供的上下文。你提供的信息越多，输出的质量就越好。我总结了 10 种常见的 prompt 模式，以下是一份速查表：

| 技巧 (Technique)                      | 提示词模板 (Prompt template)                                      | 目的 (Purpose)             |
| ----------------------------------- | ------------------------------------------------------------ | ------------------------ |
| 1. 角色设定 (Role Prompting)            | "你是一名资深 {编程语言} 开发人员。请为了 {目标} 审查此函数。"                         | 模拟专家级的代码审查、调试或重构。        |
| 2. 明确上下文设置 (Explicit Context Setup) | "问题如下：{摘要}。代码在下方。它本该执行 {预期行为}，但实际上却在执行 {实际行为}。为什么？"          | 清晰地描述问题，以避免通用的、肤浅的回答。    |
| 3. 输入/输出示例 (Input/Output Examples)  | "当给定 {输入} 时，此函数应返回 {预期输出}。你能编写或修复这段代码吗？"                     | 通过示例展示意图来引导助手。           |
| 4. 迭代链式提问 (Iterative Chaining)      | "首先，生成组件的骨架。接下来，我们将添加状态。然后处理 API 调用。"                        | 将大任务分解为步骤，以避免提示词过于庞大或模糊。 |
| 5. 模拟调试 (Debug with Simulation)     | "逐行遍历该函数。变量的值分别是什么？哪里可能会出错？"                                 | 让助手模拟运行时行为并暴露隐藏的 Bug。    |
| 6. 功能蓝图规划 (Feature Blueprinting)    | "我正在构建 {功能}。需求如下：{要点列表}。使用的技术栈：{技术栈}。请搭建初始组件的脚手架并解释你的选择。"    | 以 AI 主导的规划和脚手架搭建来启动功能开发。 |
| 7. 代码重构指导 (Code Refactor Guidance)  | "重构此代码以改进 {目标}，例如 {例如：可读性、性能、惯用风格}。请使用注释解释所做的更改。"            | 让 AI 的重构符合你的目标，而不是随意的更改。 |
| 8. 寻求替代方案 (Ask for Alternatives)    | "你能用函数式风格重写这个吗？递归版本会是什么样子？"                                  | 探索多种实现路径并扩展你的工具箱（技能库）。   |
| 9. 橡皮鸭调试法 (Rubber Ducking)          | "这是我认为此函数的作用：{你的解释}。我有遗漏什么吗？这是否揭示了任何 Bug？"                   | 让 AI 挑战你的理解并发现不一致之处。     |
| 10. 约束锚定 (Constraint Anchoring)     | "请避免使用 {例如：递归} 并坚持使用 {例如：ES6 语法，无外部库}。针对 {例如：内存} 进行优化。函数如下：" | 防止 AI 越界或引入不兼容的模式。       |

## 好用 Prompt 的核心原则

向 AI 编程工具发送 prompt，有点像与一位只懂字面意思、但有时又很博学的合作者进行沟通。为了获得有用的结果，你需要清晰地设定背景，并引导 AI 了解你想要什么以及希望如何实现。

### 提供丰富的上下文

始终假设 AI 除了你提供的信息外，对你的项目一无所知。请包含相关的细节，例如编程语言、框架和库，以及涉及的具体函数或代码片段。如果遇到错误，请提供准确的报错信息，并描述代码的预期功能。具体性和上下文决定了你得到的是模糊的建议，还是精确、可执行的解决方案。

在实践中，这意味着你的提示词可能包含简短的背景设定，例如："我有一个使用 Express 和 Mongoose 的 Node.js 函数，本应通过 ID 获取用户，但抛出了 TypeError。代码和报错信息如下……"。你提供的铺垫越多，AI 需要猜测的内容就越少。

### 明确你的目标或问题

模糊的提问只会导致模糊的回答。不要问"为什么我的代码跑不通？"这类问题，而要精准指出你需要什么样的分析。例如："这个 JavaScript 函数返回了 undefined，而不是预期的结果。基于下方的代码，你能帮我找出原因并修复它吗？"这样的提问更有可能获得有用的答案。

一个用于调试的提示词公式是："当输入为 \[示例输入] 时，预期行为是 \[预期行为]，但实际行为却是 \[当前行为]。Bug 出在哪里？"同样，如果你需要优化代码，请指明具体的优化方向（例如："我该如何提升这个排序函数处理 1 万条数据时的运行时性能？"）。具体性能够引导 AI 的关注点。

### 拆解复杂任务

当实现新功能或解决多步骤问题时，不要把整个问题塞进一个巨大的提示词里。通常更有效的做法是将工作拆分成更小的块，并进行迭代。例如，"首先，生成一个产品列表页面的 React 组件骨架。接下来，我们将添加状态管理。然后，我们将集成 API 调用。" 每个提示词都建立在前一个的基础上。

通常不建议一次性要求生成整个庞大的功能；相反，应从一个高层目标开始，然后迭代地请求每个部分。这种方法不仅能让 AI 的回复保持专注和可控，而且也反映了人类增量构建解决方案的方式。

### 包含输入/输出示例或预期行为

如果你能用例子说明你想要什么，那就这么做。例如，"给定数组 `[3,1,4]`，此函数应返回 `[1,3,4]`。" 在提示词中提供具体的例子有助于 AI 理解你的意图并减少歧义。这就好比给初级开发人员一个快速测试用例——它明确了需求。

在提示工程术语中，这有时被称为"少样本提示（few-shot prompting）"，即你向 AI 展示一个可遵循的模式。哪怕只有一个正确行为的例子，也能显著引导模型的回复。

### 利用角色或人设

一个在许多广为流传的提示词案例中普及的强大技巧是，要求 AI "扮演（act as）"特定的角色或人设。这可以影响回答的风格和深度。例如，"扮演一名资深 React 开发人员，审查我的代码中潜在的 Bug"或"你是一名 JavaScript 性能专家。优化以下函数。"

通过设定角色，你引导（prime）助手采用相关的基调——无论是作为严格的代码审查员、面向初级开发者的热心老师，还是寻找漏洞的安全分析师。社区分享的提示词已经证明了这种方法的成功，例如"扮演 JavaScript 错误处理程序并帮我调试此函数。数据未能从 API 调用中正确渲染。" 在我们自己的使用中，我们仍然必须提供代码和问题细节，但角色扮演提示词可以产生更结构化和专家级的指导。

### 迭代并完善对话

提示工程是一个交互过程，而非一锤子买卖。开发者通常需要审视 AI 的第一次回答，然后提出后续问题或进行修正。如果解决方案不太对，你可以说："那个方案使用了递归，但我更倾向于迭代方法——你能不用递归再试一次吗？"或者，"很好，现在你能改进变量命名并添加注释吗？"

AI 会记住聊天会话中的上下文，因此你可以逐步引导它达到预期的结果。关键在于将 AI 视为一个你可以指导的伙伴——在第一次尝试时，进展比完美更重要。

### 保持代码清晰和一致

最后一个原则虽然有点间接，但对于基于你的代码上下文工作的工具来说非常重要。即使在 AI 介入之前，也要编写干净、结构良好的代码和注释。有意义的函数和变量名、一致的格式以及文档字符串（docstrings），不仅让你的代码更容易被人类理解，也给了 AI 更强的线索来了解你在做什么。

如果你展示了一致的模式或风格，AI 将会延续它。把这些工具当作极其专注的初级开发人员——它们会从你的代码和注释中捕捉每一个暗示。

牢记这些核心原则，让我们深入探讨具体的场景。我们将从调试开始，这也许是最直接的用例：你有行为异常的代码，你希望 AI 帮你找出原因。

## DEBUG 代码的 PROMPT 指南

以下是如何系统地编写 prompt，以便寻求帮助来发现并修复 Bug：

### 清晰地描述问题和症状

在提示词的开头，先描述出了什么问题以及代码本该实现什么功能。务必包含确切的报错信息或异常行为表现。

例如，不要只是笼统地说"我的代码跑不通"，你可以这样写提示词：

> "我有一个 JavaScript 函数，本该计算数组中数字的总和，但它返回的是 NaN（非数字），而不是实际的总和。代码如下：\[附上代码]。对于像 \[1,2,3] 这样的数字数组，它应该输出一个数字（总和），但我得到的却是 NaN。导致这个 Bug 的原因可能是什么？"

这条提示词明确了编程语言、预期行为、观察到的错误输出，并提供了代码上下文——这些都是至关重要的信息。提供结构化的背景信息（代码 + 报错 + 预期结果 + 已尝试的方法）能为 AI 提供一个坚实的分析起点。相比之下，像"为什么我的函数不起作用？"这样笼统的提问效果甚微——在缺乏背景信息的情况下，模型只能给出最宽泛的猜测。

### 针对棘手的 Bug，采用逐步或逐行分析的方法

对于更复杂的逻辑 Bug（即没有抛出明显的错误信息，但输出结果是错的），你可以提示 AI 逐步检查代码的执行过程。

例如："请逐行检查这个函数，并追踪每一步 total 变量的值。它的累加不正确——逻辑哪里出错了？"

这是一个典型的"橡皮鸭调试"提示词——你本质上是在要求 AI 模拟人类使用打印语句（print）或调试器进行调试的过程。这类提示词通常能揭示一些微妙的问题，比如变量未重置或条件逻辑错误，因为 AI 会详细列出每一步的状态。如果你怀疑代码的某个特定部分，可以聚焦提问："解释一下这里的 filter 调用在做什么，它是否可能排除了不该排除的项目。"让 AI 扮演解释者的角色，往往能在解释的过程中让 Bug 浮出水面。

> **"橡皮鸭"** 这个概念最早出现在经典编程书籍《程序员修炼之道》中。书中讲述了一个程序员随身携带一只橡皮鸭，每当代码调试不通时，就会强迫自己向这只鸭子详细解释每一行代码。

### 尽可能提供最小可复现示例

有时你的实际代码库很大，但 Bug 可以通过一小段代码来演示。如果你能提取或简化出仍然能复现问题的代码，请这样做并将其提供给 AI。这不仅能让 AI 更容易集中注意力，还能迫使你理清问题（这本身通常就是一个有益的练习）。

例如，如果你在一个深层嵌套的函数调用中遇到 TypeError，试着用几行可以分享的代码来复现它。目标是用最少的代码隔离 Bug，假设哪里出了问题，进行测试，然后迭代。你可以通过这样说来让 AI 参与其中："这是一个精简后的示例，它仍然会触发错误 \[附上代码片段]。为什么会出现这个错误？"通过简化，你消除了干扰，帮助 AI 准确定位问题。（这个技巧反映了许多资深工程师的建议：如果你无法立即找到 Bug，就简化问题空间。如果你向 AI 展示一个更小的案例，它就能协助进行分析。）

### 提出聚焦的问题和追问

在提供了背景信息后，直接提出你的需求往往非常有效。例如："导致这个问题的原因可能是什么，我该如何修复它？" 这能引导 AI 既进行诊断又提出解决方案。如果 AI 的初次回答不清楚或帮助有限，请毫不犹豫地进行追问。你可以说："这个解释很有道理。你能演示一下如何修复代码吗？请提供修正后的代码。"

在聊天场景中，AI 拥有对话历史记录，因此它可以直接输出修改后的代码。如果你使用的是像 VS Code 中的 Copilot 或 Cursor 这样的行内工具（而非聊天界面），你可以在代码上方写一行注释，比如 `// BUG: 返回 NaN，修复此函数`，然后看它如何自动补全——但通常来说，交互式聊天能提供更透彻的解释。

另一种追问模式是：如果 AI 给出了修复方案但你不明白其中的原理，可以问："你能解释一下为什么这个改动能解决问题吗？" 这样你不仅能为下次积累经验，还能再次核实 AI 的推理是否站得住脚。

## 重构代码的 PROMPT 指南

代码重构就在不改变功能的前提下，让代码更整洁、更高效或更符合语言习惯。但"更好"具体意味着什么。以下是如何编写代码重构提示词的方法：

### 明确陈述你的重构目标

光说"重构这段代码"太过于宽泛了。你是想提高可读性？降低复杂度？优化性能？还是想换一种编程范式或类库？AI 需要一个明确的目标。一个好的提示词会界定任务范围，例如："重构以下函数以提高其可读性和可维护性（减少重复代码，使用更清晰的变量名）。" 或者"优化此算法的速度——在处理大量输入时它太慢了。"

通过阐明具体目标，你能帮助模型决定采用哪种转换方式。例如，告诉它你关注性能，可能会引导它使用更高效的排序算法或缓存机制；而关注可读性，则可能引导它将函数拆分为更小的模块或添加注释。如果你有多个目标，请一一列出。

Strapi 指南中的一个提示词模板甚至建议列举出具体问题："我希望解决的问题：1) \[性能问题]，2) \[代码重复]，3) \[使用了过时的 API]。" 这样一来，AI 就确切知道需要修复什么。请记住，它并不会天生就知道你认为代码中的哪些部分是问题——你必须告诉它。

### 提供必要的代码上下文

在进行重构时，你通常需要在提示词中包含需要改进的代码片段。重要的是要包含你想要重构的完整函数或部分，有时如果相关的话，还需要包含一些周围的上下文（比如该函数的用法或相关代码，这可能会影响重构的方式）。

此外，务必提及编程语言和框架，因为所谓的"地道（idiomatic）"代码在不同环境下差异很大，比如 Node.js 与 Deno 的风格不同，React 类组件与函数式组件也不同。

例如："我有一个写成类的 React 组件。请把它重构为使用 Hooks 的函数式组件。" 这样 AI 就会应用典型的步骤（使用 useState, useEffect 等）。如果你只是说"重构这个 React 组件"而不阐明风格，AI 可能不知道你特指想要用 Hooks。

如果相关，请包含版本或环境细节。例如，"这是一个 Node.js v14 代码库"或"我们使用的是 ES6 模块"。这会影响 AI 是否使用特定的语法（如 import/export 对比 require），这是正确重构的一部分。如果你想确保它不引入不兼容的内容，请明确提及你的约束条件。

### 鼓励在提供代码的同时给出解释

从 AI 主导的重构中学习（并验证其正确性）的一个好方法是要求它解释所做的更改。

例如："请建议代码的重构版本，并解释你所做的改进。" 这甚至被内置在我们引用的提示词模板中："……建议重构后的代码并解释你的改动。"

当 AI 提供解释时，你可以评估它是否理解了代码并达到了你的目标。解释可能会说："我将两个类似的循环合并为一个以减少重复，并使用字典来加快查找速度"等等。如果解释中有哪里听起来不对劲，那就是一个需要仔细检查代码的警示信号（red flag）。简而言之，利用 AI 的解释能力作为一种安全保障——这就像是让 AI 对它自己的重构工作进行了一次代码审查。

### 使用角色扮演来设定高标准

如前所述，要求 AI 扮演代码审查员或资深工程师的角色非常有效。对于重构，你可以说："扮演一位经验丰富的 TypeScript 专家，重构这段代码以符合最佳实践和现代标准。"

这通常不仅能带来表面的修改，还能带来更有深度的改进，因为 AI 会努力符合"专家"的人设。一个来自提示词指南的流行案例是让 AI 扮演导师："扮演一位指导初级开发者的经验丰富的 Python 开发人员。提供解释并编写文档字符串（docstrings）。重写代码以对其进行优化。"

那个案例的结果是，AI 使用了更高效的数据结构（集合 set 来去重），并为一个原本使用循环的函数提供了一行代码的解决方案。角色扮演不仅帮助它进行了重构，还帮助它解释了为什么新方法更好（在该案例中，使用 set 是众所周知的去重优化手段）。

## 实现新功能的 PROMPT 指南

这里的挑战通常在于，这些任务往往是开放式的——实现同一个功能有许多种方法。针对代码生成的提示词工程，其核心在于引导 AI 生成符合你需求和代码风格的代码。以下是实现这一目标的策略：

### 从高层指令入手，然后逐层深入

首先，用通俗易懂的语言概述你想构建的内容，最好将其拆解为更小的任务（这类似于我们之前提到的拆解复杂任务的建议）。

例如，假设你想在现有的 Web 应用中添加一个搜索栏功能。你可以首先这样编写提示词：

> "请列出一个计划，在我的 React 应用中添加搜索功能，用于按名称过滤产品列表。产品数据是从 API 获取的。"

AI 可能会给你一个分步计划：

1. 添加一个用于搜索查询的输入框。
2. 添加状态（state）来保存查询内容。
3. 根据查询内容过滤产品列表。
4. 确保过滤不区分大小写，等等。

一旦你有了这个计划（你也可以在 AI 的帮助下完善它），就可以通过针对性的提示词来逐个攻克这些要点。

例如：

> "好的，实现第一步：创建一个 SearchBar 组件，包含一个能更新 searchQuery 状态的输入框。"

接着是：

> "实现第三步：给定 searchQuery 和一个产品数组，过滤产品（按名称进行不区分大小写的匹配）。"

通过拆分功能，你可以确保每个提示词都具体明确，且 AI 的回复易于管理。这也契合了迭代式开发的理念——你可以在构建过程中逐一测试每个部分。

### 提供相关的上下文或参考代码

如果你要在现有项目中添加功能，向 AI 展示该项目中类似功能的实现方式会有极大的帮助。例如，如果你已经有一个与你想要构建的组件类似的组件，你可以说：

> "这是一个现有的 UserList 组件（附上代码……）。现在创建一个类似的 ProductList 组件，但要包含一个搜索栏。"

AI 会识别出这些模式（比如你使用的特定库或代码风格惯例）并加以应用。打开相关文件或在提示词中引用它们，能提供上下文，从而获得更符合项目具体情况且风格一致的代码建议。

另一个技巧是：如果你的项目使用特定的编码风格或架构（比如用 Redux 管理状态，或某种 CSS 框架），请提出来。

> "我们使用 Redux 进行状态管理——请将搜索状态集成到 Redux store 中。"

训练有素的模型随后会生成符合 Redux 模式等的代码。本质上，你是在教 AI 了解你的项目环境，以便它能定制输出结果。有些助手甚至可以利用你的整个代码仓库作为上下文；如果使用这类工具，请确保将它指向仓库中类似的模块或文档。

如果是开始新项目但你有偏好的方法，你也可以提出来：

> "我想用函数式编程风格来实现这个功能（无外部状态，使用数组方法）。"

或者：

> "确保遵循 MVC 模式，将逻辑放在控制器中，而不是视图中。"

这些通常是资深工程师会提醒初级工程师的细节，而在这里，你就是那个指导 AI 的资深工程师。

### 使用注释和 TODO 作为行内提示词

当直接在 IDE 中使用 Copilot 工作时，一个有效的工作流是写一条注释来描述你需要的一段代码，然后让 AI 自动补全它。

例如，在 Node.js 后端中，你可以写：

```javascript
// TODO: 验证请求负载（确保提供了姓名和电子邮件）
```

然后开始写下一行。Copilot 通常能捕捉到你的意图，并生成执行该验证的代码块。这之所以有效，是因为你的注释实际上就是一个自然语言提示词。不过，如果 AI 误解了意图，要做好编辑生成代码的准备——一如既往，务必验证其正确性。

### 提供预期的输入/输出或用法示例

这就好比我们之前讨论过的，如果你要求 AI 实现一个新函数，附带一个简短的使用示例或简单的测试用例会非常有帮助。

例如："在 JavaScript 中实现一个 `formatPrice(amount)` 函数，它接收一个数字（如 2.5）并返回格式化为美元的字符串（如 $2.50）。例如，`formatPrice(2.5)` 应该返回 `'$2.50'`。"

通过提供这个示例，你限制了 AI 生成与之逻辑一致的函数。如果没有这个示例，AI 可能会假设其他的格式或货币单位。这种差异虽然细微，但可能至关重要。

在 Web 开发背景下的另一个例子："实现一个 Express 中间件来记录请求。例如，对 `/users` 发起 GET 请求时，应该在控制台打印 `'GET /users'`。" 这清楚地表明了输出应该是什么样子。在提示词中包含预期行为，就像是设定了一个测试用例，AI 会努力去满足它。

### 当结果不符合预期时，增加细节或约束条件重写提示词

生成新功能的第一次尝试往往不会一步到位，这很常见。也许代码能运行，但写法不地道（not idiomatic），或者遗漏了某个需求。

与其感到沮丧，不如把 AI 当作一个交了初稿的初级开发者——现在你需要给出反馈。

例如："这个方案可行，但我更希望你使用内置的数组 filter 方法，而不是 for 循环。" 或者，"你能把生成的组件重构为使用 React Hooks 的形式吗？不要用类组件，我们的代码库全是函数式组件。"

你也可以添加新的约束条件："另外，确保函数在 O(n) 或更好的时间复杂度下运行，因为 n 的值可能很大。"

这种迭代式的提示非常强大。有一个真实案例：一位开发者要求大语言模型（LLM）生成代码，用 JS Canvas 库画一个冰淇淋筒，但模型一直输出不相关的内容，直到开发者用更具体的细节和上下文完善了提示词才成功。

经验教训是，不要尝试一次失败后就放弃。找出提示词中缺少了什么或哪里被误解了，并加以澄清。这就是提示词工程的精髓——每一次微调都能引导模型更接近你的构想。

## 常见的坏味道 PROMPT 并如何避免

### 模糊的提示词 (The Vague Prompt)

这是典型的"它跑不通，请修好它"或"写点能实现 X 功能的东西"，但缺乏足够的细节。我们之前见过一个例子，问"为什么我的函数不起作用？"只能得到毫无用处的回答。模糊的提示词迫使 AI 去猜测上下文，结果往往是通用的建议或不相关的代码。

**解决方法**：增加上下文和细节。如果你发现自己提出的问题得到的回答像"神奇八号球"（Magic 8-ball，指模棱两可、碰运气的回答）一样（比如"你检查过 X 吗？"），请停下来，补充更多细节（报错信息、代码片段、预期结果与实际结果的对比等）重新组织你的问题。一个好的做法是读一遍你的提示词并自问："这个问题是否适用于几十种不同的场景？"如果是，那就太模糊了。要把它写得足够具体，以至于它只能适用于你的场景。

### 过载的提示词 (The Overloaded Prompt)

这是相反的问题：要求 AI 一次性做太多事情。例如，"生成一个完整的 Node.js 应用，包含身份验证、React 前端和部署脚本。"或者即使在较小的范围内，"一次性修复这 5 个 Bug 并添加这 3 个功能。" AI 可能会尝试去做，但你很可能会得到一个混乱或不完整的结果，或者它可能会忽略请求中的某些部分。即使它处理了所有内容，回复也会很长，难以验证。

**解决方法**：拆分任务，分清轻重缓急。正如我们之前强调的，一次只做一件事。这使得发现错误变得更容易，并确保模型保持专注。如果你发现自己在指令中写了一大段话，里面包含多个"并且 (and)"，请考虑将其拆分为单独的提示词或按顺序执行的步骤。

### 缺失问题 (Missing the Question)

有时用户会提供大量信息，但从未明确提出问题或说明他们需要什么。例如，扔出一大段代码片段，然后只说"这是我的代码"。这会让 AI 感到困惑——它不知道你想要什么。

务必包含一个清晰的请求，例如"找出上述代码中的所有 Bug"、"解释这段代码的作用"或"完成代码中的 TODO"。提示词应该有明确的目的。如果你只提供文本而没有问题或指令，AI 可能会做出错误的假设（比如总结代码而不是修复代码）。确保 AI 知道你为什么要给它看这段代码。即使只是简单地加上"这段代码有什么问题？"或"请继续实现这个函数"，也能给它指明方向。

### 模糊的成功标准 (Vague Success Criteria)

这是一个微妙的问题——有时你可能要求优化或改进，但你没有定义"成功"是什么样子的。例如，"让这个函数更快。"以什么指标衡量更快？如果 AI 不知道你的性能约束，它可能会进行无关紧要的微优化，或者使用一种理论上更快但实际上差别不大的方法。或者"让代码更整洁"——"整洁"是主观的。我们之前的处理方式是明确陈述目标，如"减少重复"或"改进变量命名"等。

**解决方法**：量化或限定改进目标。例如，"优化此函数以在线性时间内运行（当前版本是二次方时间）"或"重构此代码以移除全局变量并改用类"。基本上，要明确你通过重构或新功能要解决什么问题。如果你把问题留得太开放，AI 可能会去解决一个你并不关心的问题。

### 忽略 AI 的澄清或输出 (Ignoring AI's Clarification or Output)

有时 AI 可能会回复一个澄清性的问题或假设。例如："你是使用 React 类组件还是函数式组件？"或"我假设输入是一个字符串——请确认。"如果你忽略这些并只是重申你的请求，你就错过了一个改进提示词的机会。AI 正在发出信号，表明它需要更多信息。务必回答它的问题或完善你的提示词以包含这些细节。

此外，如果 AI 的输出明显偏离（比如它误解了问题），不要只是原封不动地重试相同的提示词。花点时间调整你的措辞。也许你的提示词中有一个模棱两可的短语或遗漏了某些关键内容。把它当作一次对话——如果人类误解了，你会换一种方式解释；对 AI 也要这样做。

### 风格多变或不一致 (Varying Style or Inconsistency)

如果你不断改变提问方式或一次性混合不同的格式，模型可能会感到困惑。例如，在指令中在第一人称和第三人称之间切换，或者以令人困惑的方式混合伪代码和实际代码。

尽量在单个提示词中保持一致的风格。如果你提供示例，请确保它们清晰地划分开来（使用 Markdown 的三重反引号标记代码，使用引号标记输入/输出示例等）。一致性有助于模型正确解析你的意图。另外，如果你有偏好的风格（比如 ES6 对比 ES5 语法），请始终如一地提及它，否则模型可能会在一个提示词中建议一种方式，而在稍后的提示词中建议另一种方式。

### 像"上面的代码"这样模糊的引用 (Vague references like "above code")

在使用聊天界面时，如果你说"上面的函数"或"之前的输出"，请确保引用是清晰的。如果对话很长，你说"重构上面的代码"，AI 可能会跟丢，或者选择了错误的代码片段进行重构。

更稳妥的做法是再次引用（粘贴）代码，或者具体指名你想要重构的函数。模型的注意力窗口是有限的，虽然许多大语言模型（LLM）可以参考对话的先前部分，但再次给予明确的上下文有助于避免混淆。如果距离上次展示代码已经过了一段时间（或隔了几条消息），这点尤为重要。

## 重写提示词的战术方法

最后，这是当事情出错时重写提示词的战术方法：

1. **确定 AI 回复中缺失或错误的地方**。它是否解决了一个错误的问题？它是否产生了报错或不合适的解决方案？例如，也许你要求用 TypeScript 解决，但它给了纯 JavaScript。或者当你明确想要迭代解法时，它写了一个递归解法。精准定位差异所在。

2. **在新的提示词中添加或强调该要求**。你可以说，"解决方案应该是 TypeScript，而不是 JavaScript。请包含类型注解。"或者，"我提到我想要一个迭代解法——请避免递归，改用循环。"有时，在提示词中字面意义地使用"注意："或"重要："这样的短语来强调关键约束很有帮助（模型没有情感，但它确实会将某些措辞视为重要性的指示）。例如："重要：不要为此使用任何外部库。"或"注意：代码必须在浏览器中运行，所以不要使用 Node 特有的 API。"

3. **如果需要，进一步拆解请求**。如果 AI 在复杂的请求上反复失败，试着先要求一小部分。或者问一个可能澄清局面的问题："你明白我说的 X 是什么意思吗？"模型可能会复述它认为你的意思，如果错了，你可以纠正它。这就是元提示 (meta-prompting)——讨论提示词本身——有时可以解决误解。

4. **如果对话陷入僵局，考虑重新开始**。有时经过多次尝试后，对话可能会进入一种混乱状态。开始一个新的会话（或暂时清除聊天历史），并根据之前的失败经验，用更完善的请求从头开始提示，这通常会有所帮助。模型不介意重复，而全新的上下文可以消除之前消息中积累的任何混淆。

通过意识到这些坏味道及其解决方案，你将能更快地在操作过程中调整提示词。针对开发者的提示词工程在很大程度上是一个迭代的、反馈驱动的过程。

## 结尾

提示词工程（Prompt Engineering）既是一门艺术，也是一门科学——它正迅速成为开发者的必备技能。通过编写清晰、富含上下文的提示词，你本质上是在教 AI 你需要什么，就像向同事解释问题一样。

Happy prompting, and happy coding!
