第 4 章:Prompt 工程与输出控制
章节定位
上一章你已经把 Prompt、Model 和 Parser 串成了一条最小链路。这一章要解决更关键的问题:为什么同样是喂给模型一个主题,不同的提示词会得到完全不同的结果。
Prompt 工程不是“写得更像人说话”,而是让模型更稳定、更可控、更符合你的应用目标。对于 AI 学习助手 来说,这一章决定了它是一个偶尔靠谱的聊天机器人,还是一个可持续演进的学习产品。
配套示例
- 目录:
examples/chapter-04 - 入口:
examples/chapter-04/main.py - 依赖:
examples/chapter-04/requirements.txt - 运行:
cd examples/chapter-04 && python3 main.py
示例层级与边界
- 层级:
教学版 - 本章重点:通过对比 Prompt 来理解输出控制,重点是方法论,不是接某个真实模型平台。
- 不要误判:示例没有覆盖线上 prompt 管理、版本实验或安全护栏,它只是帮助你建立稳定输出的意识。
本章目标
- 理解 Prompt 工程的基本原则
- 学会为不同任务设计不同的提示词
- 学会用约束提升输出稳定性
- 学会把输出控制成适合程序处理的格式
- 为后续 RAG、Agent 和 LangGraph 的提示词设计打基础
前置知识
学习本章前,你应该已经知道:
- 什么是 LLM 应用
- Prompt、Message、Output Parser 的基本概念
AI 学习助手 V1的链式结构
如果你还没有做过上一章的最小链,建议先回到上一章,因为这里的很多结论都建立在“链式应用已经存在”的前提上。
核心概念
什么是 Prompt 工程
Prompt 工程不是玄学,也不是“多写几句话让模型听懂”。它的本质是:
- 明确任务
- 提供必要上下文
- 设定输出边界
- 降低模型自由发挥的空间
你希望模型完成的是“在可控范围内完成任务”,而不是“尽量聪明地随便回答”。
为什么 Prompt 会影响工程质量
模型输出不稳定,很多时候不是模型“不行”,而是提示词给得太松。常见问题包括:
- 任务没说清楚
- 角色没定义
- 输出格式没限定
- 输入和上下文混在一起
- 没有明确告诉模型不要做什么
如果你希望后续页面可以直接渲染结果,就必须从一开始就把这些问题处理掉。
什么叫“可控输出”
可控输出意味着模型的结果可以被程序可靠使用。
例如 AI 学习助手 不是只要一段长文,而是最好能输出类似下面的结构:
- 标题
- 学习目标
- 核心概念
- 建议顺序
- 练习建议
这样前端页面、卡片组件、列表区块才好渲染。
分模块讲解
4.1 Prompt 的基本设计原则
写 Prompt 时,优先遵循四个原则:
明确任务
不要只说“请介绍一下 LangChain”,而要明确:
- 面向谁
- 讲到什么深度
- 输出什么结构
- 不能输出什么
给出上下文
如果模型需要知道用户的背景,就直接说明:
- 读者是初学者
- 目标是学习路线而不是百科解释
- 输出应尽量简洁
限制输出
输出限制很重要。你要明确告诉模型:
- 字数范围
- 段落数
- 是否需要列表
- 是否需要 JSON
指定格式
如果输出会被程序使用,格式必须提前定义。否则你后面会在解析阶段花更多时间。
4.2 Few-shot 与角色设定
角色设定
角色设定的作用不是“让模型更有戏感”,而是帮助模型进入合适的任务语境。
例如:
- 你是一个教程编辑
- 你是一个初学者学习助手
- 你是一个结构化输出生成器
这些设定本质上是在约束语言风格和任务边界。
Few-shot
Few-shot 的作用是给模型一个输出样例,让它模仿结构,而不是完全靠猜。
对于 AI 学习助手 来说,Few-shot 特别适合用在:
- 学习计划生成
- 摘要模板
- FAQ 结构
- 练习题格式
4.3 输出控制为什么是工程问题
很多人以为 Prompt 工程只是写文案,其实它直接影响后续工程环节:
- Parser 是否稳定
- 前端是否容易渲染
- 是否方便存档
- 是否能做回归测试
如果输出格式总是变,整个项目都会变得难维护。
4.4 如何为 AI 学习助手 设计 Prompt
本章建议你把 Prompt 分成三层:
任务层
说明要完成什么。例如:
- 生成学习摘要
- 生成课程路径
- 生成练习建议
约束层
说明不要做什么。例如:
- 不要输出无关闲聊
- 不要写太长
- 不要省略结构
格式层
说明结果怎么输出。例如:
- 使用 Markdown 小标题
- 使用固定列表项
- 使用 JSON 字段
这个分层会让你的 Prompt 更清晰,也更容易后续迭代。
最小示例说明
下面是一个面向 AI 学习助手 的 Prompt 思路示例。重点不在某个 SDK 版本,而在结构设计。
python
from langchain_core.prompts import PromptTemplate
template = """
你是一个中文 LangChain 学习助手。
目标读者:初学者
任务:围绕主题 {topic} 输出一份学习摘要
要求:
1. 先给出学习目标
2. 再列出核心概念
3. 再给出学习顺序
4. 最后给出 3 个练习建议
5. 不要输出与主题无关的内容
6. 使用 Markdown 列表
"""
prompt = PromptTemplate.from_template(template)这个示例的价值在于,你可以明显看出 Prompt 中包含了四类信息:
- 身份
- 任务
- 约束
- 输出格式
这比简单一句“请总结一下”可靠得多。
本章实践
建议你为 AI 学习助手 V1 做一次 Prompt 重构。
任务
把上一章的学习助手升级成 AI 学习助手 V2,要求:
- 输出格式固定为 4 个部分
- 每个部分都要简洁
- 输出适合直接放到网页中展示
- 当主题是“RAG 入门”时,输出要更偏向学习路径而不是定义解释
你应该观察什么
- 同一个输入在多次运行时是否更稳定
- 输出结构是否更容易解析
- Prompt 是否减少了歧义
- 输出是否更适合后续页面渲染
推荐做法
先设计 Prompt,再看模型输出,再修订 Prompt。不要一开始就指望模型“自己懂”你想要什么。
常见坑
把 Prompt 写成一大段散文
如果任务、约束、格式混在一起,模型很难稳定遵守。建议采用分层结构,越清楚越好。
只写“请帮我总结”
这种指令太宽泛了。模型可能会给出你想不到的结构,后续也很难统一页面输出。
只追求自然语言流畅,忽略程序可用性
如果结果最终要进入页面、数据库或评估系统,可读性不是唯一标准,可控性更重要。
不区分任务类型
学习助手、问答器、摘要器、路线生成器,它们的 Prompt 设计方式不一样。任务不同,约束也应该不同。
练习题
- 为
AI 学习助手 V2设计一个更严格的 Prompt,要求输出始终是 4 个 Markdown 小节。 - 把一个开放式问题改写成一个结构化任务指令。
- 思考在什么情况下应该加角色设定,什么情况下不需要。
- 尝试设计一个适合“课程路径生成”的 Few-shot 示例。
本章总结
这一章解决的是“让模型输出更可控”这个核心问题。你应该已经看到,Prompt 工程不是修辞练习,而是 AI 应用工程的一部分。
本章结束后,你应该能做到:
- 根据任务设计提示词
- 根据读者和使用场景设置输出约束
- 让输出更适合程序处理和页面展示
- 把
AI 学习助手的结构稳定下来,为后续章节继续演进
学完本章,你现在应该会
- 把一个模糊需求改写成包含任务、约束和输出格式的 Prompt
- 判断什么场景需要角色设定,什么场景只需要明确任务描述
- 让
AI 学习助手 V2的输出更稳定、更适合页面展示 - 用多次运行对比 Prompt 调整前后的输出差异
最小验收 checklist
- [ ] 我写出了一个固定输出 4 个部分的 Prompt
- [ ] 我能指出 Prompt 里的身份、任务、约束、格式分别在哪
- [ ] 我至少比较过一次“改 Prompt 前”和“改 Prompt 后”的输出区别
- [ ] 我知道本章目标不是写华丽提示词,而是提高结果可控性
建议你动手改一版
- 给
AI 学习助手 V2增加一个“不知道就明确说明”的约束 - 为“RAG 入门”和“Prompt 工程”两个主题分别调 Prompt,比较哪部分需要通用、哪部分需要定制
- 把输出格式固定为 Markdown 小节标题,测试是否更容易直接进入文档页面
卡住时先回看这里
- 如果你写的 Prompt 总是一大段散文,回看 chapter-04-prompt-engineering.md 里的
## 核心概念 - 如果你不确定实践目标到底是什么,回看 chapter-04-prompt-engineering.md 里的
## 本章实践 - 如果你只顾自然语言流畅没有考虑结构化输出,回看 chapter-04-prompt-engineering.md 里的
## 最小示例说明
下一章预告
下一章我们会进入 RAG 入门。到那时,Prompt 不再只是决定风格和结构,它还会和检索到的课程资料结合,决定模型究竟“看到了什么”和“如何回答”。这会让 AI 学习助手 从生成内容,进一步走向基于资料的学习支持系统。