Skip to content

第 4 章:Prompt 工程与输出控制

章节定位

上一章你已经把 PromptModelParser 串成了一条最小链路。这一章要解决更关键的问题:为什么同样是喂给模型一个主题,不同的提示词会得到完全不同的结果。

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 设计方式不一样。任务不同,约束也应该不同。

练习题

  1. AI 学习助手 V2 设计一个更严格的 Prompt,要求输出始终是 4 个 Markdown 小节。
  2. 把一个开放式问题改写成一个结构化任务指令。
  3. 思考在什么情况下应该加角色设定,什么情况下不需要。
  4. 尝试设计一个适合“课程路径生成”的 Few-shot 示例。

本章总结

这一章解决的是“让模型输出更可控”这个核心问题。你应该已经看到,Prompt 工程不是修辞练习,而是 AI 应用工程的一部分。

本章结束后,你应该能做到:

  • 根据任务设计提示词
  • 根据读者和使用场景设置输出约束
  • 让输出更适合程序处理和页面展示
  • AI 学习助手 的结构稳定下来,为后续章节继续演进

学完本章,你现在应该会

  • 把一个模糊需求改写成包含任务、约束和输出格式的 Prompt
  • 判断什么场景需要角色设定,什么场景只需要明确任务描述
  • AI 学习助手 V2 的输出更稳定、更适合页面展示
  • 用多次运行对比 Prompt 调整前后的输出差异

最小验收 checklist

  • [ ] 我写出了一个固定输出 4 个部分的 Prompt
  • [ ] 我能指出 Prompt 里的身份、任务、约束、格式分别在哪
  • [ ] 我至少比较过一次“改 Prompt 前”和“改 Prompt 后”的输出区别
  • [ ] 我知道本章目标不是写华丽提示词,而是提高结果可控性

建议你动手改一版

  • AI 学习助手 V2 增加一个“不知道就明确说明”的约束
  • 为“RAG 入门”和“Prompt 工程”两个主题分别调 Prompt,比较哪部分需要通用、哪部分需要定制
  • 把输出格式固定为 Markdown 小节标题,测试是否更容易直接进入文档页面

卡住时先回看这里

下一章预告

下一章我们会进入 RAG 入门。到那时,Prompt 不再只是决定风格和结构,它还会和检索到的课程资料结合,决定模型究竟“看到了什么”和“如何回答”。这会让 AI 学习助手 从生成内容,进一步走向基于资料的学习支持系统。