Prompt 工程实践笔记

这篇笔记记录了日常使用 LLM 过程中总结的 Prompt 编写技巧,不追求学术完整性,只记录真正有用的实战经验。


一、基础原则

清晰 > 聪明

新手写 Prompt 常犯的错误是把 Prompt 写得太”聪明”,用各种暗示和隐喻。实际上模型更擅长理解直白、具体的指令

❌ 差的写法:
"作为一个懂技术的人,帮我优化一下这段代码"

✅ 好的写法:
"请优化以下 Python 代码的性能:
1. 减少不必要的循环
2. 使用更高效的数据结构
3. 保持代码可读性不变
代码如下:..."

角色设定(System Prompt)

给模型一个明确的角色,可以显著提升输出质量:

你是一位有 10 年经验的 Python 后端工程师,熟悉 FastAPI、PostgreSQL 和 Redis。
在回答问题时:
- 优先考虑代码的可维护性和性能
- 遇到安全相关问题主动提示风险
- 代码示例需包含错误处理

二、常用技巧

1. Chain of Thought(思维链)

让模型”先思考再回答”,对复杂推理任务效果显著:

请分步骤解决以下问题,先列出你的思考过程,再给出最终答案:
问题:...

或者直接加一句魔法词:

Let's think step by step.(让我们一步步思考)

2. Few-shot 示例

给模型看几个”输入→输出”的例子,让它理解你想要的格式:

请按照以下格式提取文章中的关键信息:

示例1:
输入:苹果公司于2007年发布了第一代iPhone,改变了智能手机市场。
输出:{"公司": "苹果", "事件": "发布iPhone", "时间": "2007年", "影响": "改变智能手机市场"}

示例2:
输入:特斯拉2023年交付了约180万辆汽车,同比增长38%。
输出:{"公司": "特斯拉", "事件": "汽车交付", "时间": "2023年", "数据": "180万辆,增长38%"}

现在请处理:
输入:...

3. 结构化输出

明确要求 JSON/Markdown 格式,方便后续处理:

prompt = """
分析以下代码并以 JSON 格式返回结果,不要包含任何额外文字:
{
"issues": [{"line": 行号, "type": "bug/style/performance", "description": "问题描述"}],
"score": 1-10的评分,
"summary": "总体评价"
}

代码:
```python
{code}

“””


### 4. 约束输出长度

请用不超过 100 字总结以下文章的核心观点:…

```
请给出 3 个具体的优化建议,每条不超过一句话:...

三、System Prompt 设计

System Prompt 是 Agent 和 Chatbot 的”灵魂”,设计时需要考虑以下几个维度:

一个好的 System Prompt 包含:

1. 角色定义 → 你是谁?有什么专长?
2. 任务范围 → 你能做什么?不做什么?
3. 行为规范 → 遇到边界情况怎么处理?
4. 输出格式 → 回答的结构是什么?
5. 语气风格 → 正式/轻松?详细/简洁?

实际示例 —— 技术客服机器人:

你是「代码助手」,一个专注于编程问题解答的 AI 助手。

【能力范围】
- 回答 Python、JavaScript、SQL 相关问题
- 帮助调试代码、解释错误信息
- 提供代码优化建议

【行为规范】
- 对于不确定的内容,明确说明"我不确定,建议查阅官方文档"
- 代码示例必须可以直接运行
- 不回答与编程无关的问题,礼貌引导用户聚焦技术问题

【回答格式】
1. 先用一句话直接回答核心问题
2. 如有必要,提供代码示例
3. 最后补充注意事项或延伸阅读

【语气】简洁、专业,避免过多废话

四、提示词版本管理

当 Prompt 用于生产环境时,需要像管理代码一样管理提示词:

# prompts.py
PROMPTS = {
"v1.0": {
"system": "你是一个助手...",
"user_template": "请处理:{input}"
},
"v1.1": {
"system": "你是一个专业助手,回答时注意...", # 优化了角色描述
"user_template": "请按照JSON格式处理:{input}" # 增加格式要求
}
}

CURRENT_VERSION = "v1.1"

好处:

  • 方便 A/B 测试不同版本的效果
  • 出现问题时可以快速回滚
  • 通过 Git 追踪 Prompt 的演进历史

五、常见踩坑记录

踩坑1:否定指令不如正面指令有效

❌ "不要使用 for 循环"
✅ "使用列表推导式或 map/filter 函数"

踩坑2:上下文过长导致”遗忘”

当对话历史很长时,模型可能忽略早期的系统指令。解决方案:

  • 在用户消息末尾重申关键约束
  • 定期总结对话内容,压缩历史

踩坑3:过度依赖单次 Prompt

复杂任务用单个 Prompt 搞定,往往质量不稳定。更好的做法是拆分为多步骤:

  1. 第一次调用:分析需求,列出步骤
  2. 第二次调用:执行具体步骤
  3. 第三次调用:检查和优化输出

踩坑4:忘记处理模型拒绝回答的情况

response = llm.invoke(prompt)

# 别直接用 response,先检查
if "无法" in response or "抱歉" in response:
# 走降级逻辑
response = fallback_handler(prompt)

六、评估 Prompt 质量

判断一个 Prompt 好不好,看这三个指标:

指标 说明
准确率 输出是否符合预期?
稳定性 多次运行结果是否一致?
鲁棒性 边界输入时是否优雅降级?

建议维护一个测试集,每次修改 Prompt 后跑一遍,防止在一个场景改好了,另一个场景又坏掉。


小结

Prompt 工程的本质是和模型建立共识——你需要用模型能理解的方式,清晰表达你的意图。

经验越多,越能感受到哪些描述是”模型友好”的,哪些是在”靠运气”。多记录、多测试、多迭代,是提升 Prompt 质量最可靠的路径。