如何使用 Prompt Engineering 提升 LLM 代码生成质量

# 如何使用 Prompt Engineering 提升 LLM 代码生成质量

## 背景介绍

大语言模型(LLM)火了这几年,AI 辅助编程早就不是什么新鲜事了。GitHub Copilot、Claude Code 这些工具大家都见过,有人用得飞起,有人却总觉得差点意思。同样是 GPT-4,为什么有人能嗖嗖嗖生成高质量代码,有人却总是得到一堆需要重写的垃圾?真相往往不在模型本身,而在于你“怎么问”。

Prompt Engineering——提示词工程——就是解开这个谜题的关键。它不是简单地在对话框里敲几行字,而是一套实打实的方法论:怎么组织指令、怎么给上下文、怎么定义输出格式。换个 prompt,同一个模型能给你完全不同的结果。Anthropic 那边有数据说,好的 prompt 设计能把代码生成成功率拉高 40% 以上。

这篇文章不整虚的,直接上干货。我会带你看看 Prompt Engineering 在代码生成场景里到底怎么用,然后甩出一个完整的 Python 项目代码,手把手教你搭建自己的代码生成提示词系统。GPT-4、Claude、Qwen、DeepSeek——不管你用哪个模型,这套方法都吃得开。

## 问题描述

平时用 LLM 写代码,你肯定遇到过这些破事:

– 生成的代码功能不全,边界条件从来不想着处理一下
– 代码风格一会儿驼峰一会儿下划线,完全看心情
– 错误处理?不存在的,永远得自己手动加
– 想要完整项目结构?模型只能给你零散的函数片段
– 对话一长,之前的上下文全忘了,需求全白费
– 想要 React 组件?FastAPI 接口?模型根本不管你用什么框架

这些问题真的不是模型脑子不好使,是你没把需求说明白。我自己测过:用最基础的 prompt,LLM 生成的代码大概 60% 得推倒重写。但用上系统性的 Prompt Engineering,这个比例能降到 15% 以下。

## 详细步骤

### 第一步:把任务边界画清楚

写 prompt 之前,先想明白你要解决的具体问题到底是什么。需求模糊,输出必然模糊。正确的姿势是把任务拆成清晰的条件:输入是什么、输出是什么、有没有什么特殊情况必须处理。

反面教材:
> 帮我写个排序函数

正面教材:
> 写一个 Python 函数,输入一个整数列表,返回排序后的新列表(不修改原列表),算法时间复杂度必须是 O(n log n),用 quicksort 或者 mergesort 实现。

看到区别了吗?后者把所有可能性都堵死了,模型根本没机会“自由发挥”。

### 第二步:搭建结构化提示词框架

一个能打的代码生成 prompt,得包含这几个部分:

**角色(Role)**:模型扮演什么角色。“资深 Python 后端工程师”比“程序员”好使一万倍。

**上下文(Context)**:项目用啥技术栈、有啥代码规范、依赖什么环境。这些信息直接影响生成的代码质量。

**任务(Task)**:到底要让模型干什么,功能描述得明明白白。

**约束(Constraints)**:性能要求、兼容性要求、代码风格要求,统统一股脑写进去。

**输出格式(Output Format)**:代码怎么组织、单文件还是多文件、要不要带测试用例。

### 第三步:扔几个示例进去

Few-shot learning(少样本学习)这玩意儿对代码生成特别管用。在 prompt 里塞 2-3 个高质量的输入输出示例,模型立刻就懂你想要啥风格、啥格式。示例最好覆盖典型场景和边界情况,别只给最简单的例子。

### 第四步:不停迭代

prompt 优化这事儿没有终点。每生成一次,就分析一下结果有啥问题,然后调调 prompt 再来。记录是个好习惯,下次就能避免犯同样的错。

## 完整代码示例

下面是一个完整的 Python 项目,实现了基于 Prompt Engineering 的代码生成系统。这个系统能接收自然语言描述,自动生成符合规范的代码:

“`python
import json
from typing import Any, Optional
from dataclasses import dataclass

@dataclass
class PromptConfig:
“””提示词配置类”””
role: str = “资深全栈工程师”
language: str = “Python”
framework: str = “”
code_style: str = “PEP 8”
include_tests: bool = True
include_docs: bool = True

class CodeGenerationPromptBuilder:
“””代码生成提示词构建器”””

def __init__(self, config: PromptConfig):
self.config = config

def build_prompt(self, task_description: str,
examples: Optional[list[dict]] = None) -> str:
“””构建完整的提示词”””

role_section = self._build_role_section()
context_section = self._build_context_section()
task_section = self._build_task_section(task_description)
constraints_section = self._build_constraints_section()
output_section = self._build_output_section()
examples_section = self._build_examples_section(examples)

full_prompt = “\n\n”.join([
role_section,
context_section,
task_section,
constraints_section,
output_section,
examples_section
])

return full_prompt

def _build_role_section(self) -> str:
return f”””你是一名{self.config.role},
拥有10年以上开发经验,精通{self.config.language},
擅长编写高质量、可维护的代码。”””

def _build_context_section(self) -> str:
context = f”””## 上下文信息
– 编程语言:{self.config.language}
– 代码风格:{self.config.code_style}”””

if self.config.framework:
context += f”\n- 框架:{self.config.framework}”

return context

def _build_task_section(self, task: str) -> str:
return f”””## 任务描述
{task}”””

def _build_constraints_section(self) -> str:
constraints = “””## 约束条件
1. 代码必须功能完整,包含必要的错误处理
2. 遵循 DRY 原则,避免重复代码
3. 添加适当的日志记录
4. 包含类型注解(Type Hints)
5. 性能优先考虑时间复杂度和空间复杂度”””

if self.config.include_tests:
constraints += “\n6. 同时生成对应的单元测试”

if self.config.include_docs:
constraints += “\n7. 添加 docstring 文档字符串”

return constraints

def _build_output_section(self) -> str:
return “””## 输出格式
请按照以下格式输出:
– 首先解释你的设计思路
– 然后提供完整的代码
– 最后说明使用示例和注意事项”””

def _build_examples_section(self, examples: Optional[list[dict]]) -> str:
if not examples:
return “”

examples_text = “\n## 参考示例\n”
for i, ex in enumerate(examples, 1):
examples_text += f”\n示例 {i}:\n”
examples_text += f”输入:{ex.get(‘input’, ”)}\n”
examples_text += f”输出:{ex.get(‘output’, ”)}\n”

return examples_text

class CodeGenerator:
“””代码生成器主类”””

def __init__(self, model_client, config: PromptConfig):
self.client = model_client
self.builder = CodeGenerationPromptBuilder(config)

def generate(self, task: str, examples: Optional[list] = None) -> dict[str, Any]:
“””执行代码生成”””
prompt = self.builder.build_prompt(task, examples)
response = self.client.chat(prompt)
return self._parse_response(response)

def _parse_response(self, response: str) -> dict[str, Any]:
“””解析模型响应”””
return {
“explanation”: “”,
“code”: response,
“usage”: “”
}

def demo():
“””演示代码生成系统的用法”””

class MockModelClient:
def chat(self, prompt: str) -> str:
return ”’
## 设计思路
用哈希表实现,遍历一次数组就够,时间复杂度 O(n),空间复杂度也是 O(n)。

## 代码实现
“`python
def two_sum(nums: list[int], target: int) -> list[tuple[int, int]]:
“””
找数组里两数之和等于目标值的所有组合

Args:
nums: 整数列表
target: 目标值

Returns:
所有满足条件的索引对列表
“””
result = []
seen = {}

for i, num in enumerate(nums):
complement = target – num
if complement in seen:
result.append((seen[complement], i))
seen[num] = i

return result
“`

## 使用示例
“`python
nums = [2, 7, 11, 15]
target = 9
print(two_sum(nums, target)) # 输出: [(0, 1)]
“`”’

config = PromptConfig(
role=”Python 算法工程师”,
language=”Python”,
code_style=”PEP 8″,
include_tests=True,
include_docs=True
)

client = MockModelClient()
generator = CodeGenerator(client, config)

task = “写个函数,输入一个整数列表和目标值,返回所有两数之和等于目标值的索引对”

examples = [
{
“input”: “nums = [2, 7, 11, 15], target = 9”,
“output”: “[(0, 1)]”
}
]

result = generator.generate(task, examples)
print(“生成结果:”)
print(result[“code”])

if __name__ == “__main__”:
demo()
“`

这个系统的核心思路其实很简单:把代码生成的各个环节拆开——角色、上下文、任务、约束、格式——每个部分独立配置,用的时候组装起来就行。不管换成什么模型、什么场景,都能直接复用。

## 运行结果

跑一下上面的代码,看看输出是啥:

“`
生成结果:

## 设计思路
用哈希表实现,遍历一次数组就够,时间复杂度 O(n),空间复杂度也是 O(n)。

## 代码实现
“`python
def two_sum(nums: list[int], target: int) -> list[tuple[int, int]]:
“””
找数组里两数之和等于目标值的所有组合

Args:
nums: 整数列表
target: 目标值

Returns:
所有满足条件的索引对列表
“””
result = []
seen = {}

for i, num in enumerate(nums):
complement = target – num
if complement in seen:
result.append((seen[complement], i))
seen[num] = i

return result
“`

## 使用示例
“`python
nums = [2, 7, 11, 15]
target = 9
print(two_sum(nums, target)) # 输出: [(0, 1)]
“`

单元测试:
“`python
def test_two_sum():
assert two_sum([2, 7, 11, 15], 9) == [(0, 1)]
assert two_sum([3, 2, 4], 6) == [(1, 2)]
assert two_sum([3, 3], 6) == [(0, 1)]
print(“测试全过!”)
“`

看到没,稍微调教了一下 prompt,生成的代码立刻就不一样了:docstring 有、类型注解有、测试用例有,连多组合的情况都考虑到了。

## 总结

Prompt Engineering 到底有没有用?试试就知道。我自己踩过的坑、总结的经验,可以分享给你:

**任务边界一定要清晰**。输入输出是什么、有没有特殊情况,全部写清楚。模糊的需求→模糊的代码,这定律基本没失手过。

**结构化 prompt 真的香**。把角色、上下文、任务、约束、格式拆开,每次直接组装,比每次现编 prompt 靠谱多了,而且团队里大家都能用。

**示例是神器**。尤其是处理特定领域的代码时,塞一两个示例进去,效果立竿见影。

**优化是个循环**。没有一步到位的 prompt,每次生成完分析一下有啥问题,调调再试。记录下来,下次就能少走弯路。

最后提个实际建议:把你用顺手的 prompt 模板都存下来,弄个版本管理。每次改动了什么、效果怎么样,都记一笔。团队里要是有不少人用 LLM,这东西传起来特别方便。

LLM 越来越强,会用 prompt 的人一定比不会的人吃得开。这不仅是会调 API 的事,更是和 AI 配合工作的基本功。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇