RETRIEVAL-AUGMENTED GENERATION · 04
理解 Prompt Template 的动态变量、Zero-shot 方法和基础 LCEL 调用链。
- PromptTemplate
- Zero-shot
- LCEL
本文目录
- 9.1 项目中的 Prompt 包含固定与动态内容
- 9.2 Prompt 与 PromptTemplate 的区别
- 9.3 PromptTemplate 的动态变量
- 9.4 数据流
- 十、Zero-shot(零样本)
- 10.1 概念
- 10.2 为什么可以先尝试 Zero-shot?
- 10.3 重要边界
- 十一、LLM + PromptTemplate + Zero-shot 示例
- 11.1 创建模板
- 11.2 分步执行
- 十二、prompt | llm、Chain 与 LCEL
- 12.1 | 的基础理解
- 12.2 执行整条 Chain
- 12.3 Chain 是什么?
- 12.4 LCEL 是什么?
- 十三、完整基础示例
- 十四、易错点汇总
- 易错点 1:RAG 就是 LangChain
- 易错点 2:RAG 会修改或训练大模型
- 易错点 3:LangChain 自己完成 Embedding、存储和生成
- 易错点 4:Embedding Model 也会回答问题
- 易错点 5:invoke() 就是调用大模型
- 易错点 6:PromptTemplate 就是最终 Prompt
- 易错点 7:多轮历史全部写成 SystemMessage
- 易错点 8:Zero-shot 表示模型没训练过
- 易错点 9:prompt | llm 表示同时执行
- 十五、面试表达
- 15.1 为什么需要 RAG?
- 15.2 为什么 RAG 项目常用 LangChain?
- 15.3 LangChain 是什么?
- 15.4 LLM、Chat Model 和 Embedding Model 有什么区别?
- 15.5 invoke() 是什么?
- 15.6 Prompt 与 PromptTemplate 有什么区别?
- 15.7 什么是 Zero-shot?
- 十六、今日学习总结
PromptTemplate 与 Zero-shot
9.1 项目中的 Prompt 包含固定与动态内容
一个 RAG Prompt 可能包含:
固定内容 动态内容
──────── ────────
模型的身份 本次检索到的资料
回答规则 当前用户问题
没有依据时如何处理 其他运行时数据
如果每次都手写并拼接完整 Prompt,代码会重复、难维护,也容易遗漏规则。
因此,我们希望提前定义结构:
你是企业知识库客服。
请只根据提供的资料回答;资料中没有答案时,请回答“不知道”。
知识库内容:
{context}
用户问题:
{question}
其中 {context} 和 {question} 是运行时才填入的变量。
9.2 Prompt 与 PromptTemplate 的区别
概念 含义 状态
Prompt 已经可以交给模型的完整提示词 动态内容已经填好 PromptTemplate 带固定结构和变量占位符的模板 还需要填入动态数据
类比短信模板:
模板:尊敬的 {name},您的订单 {order_id} 已发货。
填入数据后:尊敬的张三,您的订单 9527 已发货。
9.3 PromptTemplate 的动态变量
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"请把下面内容翻译成{language}:{text}"
)
这里有两个动态变量:
{language}
{text}
填充变量:
prompt_value = prompt.invoke({
"language": "英文",
"text": "今天天气很好",
})
print(prompt_value.text)
得到的完整 Prompt 类似:
请把下面内容翻译成英文:今天天气很好
此时只执行了模板填充,还没有调用模型。
9.4 数据流
输入数据
{
"language": "英文",
"text": "今天天气很好"
}
↓
PromptTemplate
↓
填充 {language} 和 {text}
↓
完整 Prompt
↓
LLM
↓
模型答案
十、Zero-shot(零样本)
10.1 概念
Zero-shot 指:
Prompt 中不提供任务示例,只说明任务要求,然后让模型直接完成任务。
例如:
请判断下面评论的情感属于:正面、负面、中性。
评论:这家餐厅的菜很好吃。
请只输出分类结果。
这里提供了任务、类别和待处理内容,但没有提供任何“输入应该对应什么输出”的演示样例,所以属于 Zero-shot。
10.2 为什么可以先尝试 Zero-shot?
现代大模型已经具备较强的通用能力。总结、翻译、简单分类、关键词提取等任务,经常仅凭清晰指令就能完成。
因此,简单任务可以先尝试 Zero-shot。如果结果不稳定、模型误解标准或输出格式不符合要求,再考虑其他提示策略。
10.3 重要边界
Zero-shot 中的“零”是 Prompt 里有 0 个任务示例,不是说模型没有经过训练。
本文到此只掌握 Zero-shot 的概念和写法,不展开 Few-shot 代码。
十一、LLM + PromptTemplate + Zero-shot 示例
任务:对商品评论进行情感分类,只允许输出“正面、负面、中性”。
11.1 创建模板
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template(
"""
请判断下面评论的情感属于:
正面、负面、中性。
评论:
{review}
请只输出分类结果。
"""
)
{review} 是动态变量。这个 Prompt 中没有任务示例,因此使用的是
Zero-shot 提示方式。
11.2 分步执行
prompt_value = prompt.invoke({
"review": "这家餐厅味道非常不错,下次还会再来。"
})
response = llm.invoke(prompt_value)
print(response)
数据流:
评论文本
↓
PromptTemplate 填入 {review}
↓
生成完整 Prompt
↓
LLM
↓
“正面”
llm 的具体初始化会因模型服务和接口类型不同而变化;今天的重点是理解
PromptTemplate 到模型的核心数据流。
十二、prompt | llm、Chain 与 LCEL
12.1 | 的基础理解
LangChain 可以把组件连接起来:
chain = prompt | llm
暂时把 | 理解成:
把前一个组件的输出,作为后一个组件的输入。
输入字典
↓
prompt
↓
完整 Prompt
↓
llm
↓
模型结果
12.2 执行整条 Chain
response = chain.invoke({
"review": "这家餐厅味道非常不错,下次还会再来。"
})
这里 chain.invoke() 会执行整条链,而不只是执行 Prompt
或模型中的某一个。
12.3 Chain 是什么?
Chain 可以理解为:
按照数据流把多个组件组合起来形成的执行链。
当前最简单的 Chain 是:
PromptTemplate → LLM
以后 RAG 的数据流会在前面增加检索等组件,但今天不展开其代码。
12.4 LCEL 是什么?
使用 | 组合 LangChain 组件的表达方式属于:
LCEL(LangChain Expression Language,LangChain 表达式语言)
今天只需要知道这个名字,并理解
前一个组件的输出 → 后一个组件的输入,不需要继续深入语法。
十三、完整基础示例
from langchain_core.prompts import PromptTemplate
# 1. 创建带动态变量的提示词模板
prompt = PromptTemplate.from_template(
"""
请判断下面评论的情感属于:
正面、负面、中性。
评论:
{review}
请只输出分类结果。
"""
)
# 2. 把 PromptTemplate 与模型连接成一条 Chain
chain = prompt | llm
# 3. 执行整条 Chain
response = chain.invoke({
"review": "这家餐厅味道非常不错,下次还会再来。"
})
print(response)
不要只背代码,要能翻译成下面的过程:
创建模板
↓
定义动态变量 {review}
↓
prompt | llm 连接两个组件
↓
chain.invoke() 接收输入数据
↓
模板填充变量,生成完整 Prompt
↓
完整 Prompt 进入模型
↓
模型返回分类结果
十四、易错点汇总
易错点 1:RAG 就是 LangChain
错误。RAG 是架构思想,LangChain 是可用来实现它的框架之一。
易错点 2:RAG 会修改或训练大模型
通常不会。RAG 的核心是在生成前检索资料,并把资料作为上下文交给模型。
易错点 3:LangChain 自己完成 Embedding、存储和生成
不准确。真正计算的是对应的 Embedding Model、向量数据库和生成模型;LangChain 主要负责对接和组织。
易错点 4:Embedding Model 也会回答问题
错误。Embedding Model 的主要输出是向量,用于语义计算,不是自然语言答案。
易错点 5:invoke() 就是调用大模型
错误。invoke() 表示执行当前组件一次。调用对象不同,执行的工作也不同。
易错点 6:PromptTemplate 就是最终 Prompt
错误。PromptTemplate 是带变量的模板;填入变量后才形成完整 Prompt。
易错点 7:多轮历史全部写成 SystemMessage
错误。历史消息要保留各自角色:用户用 HumanMessage,AI 回答用 AIMessage;系统规则才使用 SystemMessage。
易错点 8:Zero-shot 表示模型没训练过
错误。它只表示当前 Prompt 中没有提供任务示例。
易错点 9:prompt | llm 表示同时执行
不应这样理解。它表示把组件按顺序组成数据流:Prompt 的输出进入模型。
十五、面试表达
15.1 为什么需要 RAG?
大模型可能不了解企业私有数据,知识也可能过时,并且存在生成幻觉的风险。RAG 会先从外部知识库中检索与问题相关的内容,再把检索结果和用户问题一起交给大模型生成答案,从而让回答获得更相关、可控的知识依据。
15.2 为什么 RAG 项目常用 LangChain?
一个完整的 RAG 系统包含文档加载、文本切分、Embedding、向量存储、Retriever、Prompt 构建和模型调用等多个环节。LangChain 为这些组件提供相对统一的抽象和组合方式,便于组织工作流并降低组件之间的耦合。但 RAG 并不依赖 LangChain,也可以使用原生 Python 或其他框架实现。
15.3 LangChain 是什么?
LangChain 是用于构建大模型应用的开发框架。它不是大模型、向量数据库或 RAG 本身,而是帮助开发者调用、组织和连接模型、检索器、Prompt 等组件。
15.4 LLM、Chat Model 和 Embedding Model 有什么区别?
LLM 接口侧重字符串 Prompt 到生成文本;Chat Model 以带角色的消息列表作为输入,适合聊天和多轮上下文;Embedding Model 把文本转换成向量,用于语义相似度计算和检索,而不负责生成自然语言答案。
15.5 invoke() 是什么?
invoke()表示给当前 LangChain 组件输入数据并执行一次。调用 PromptTemplate 时用于填充模板,调用模型时用于生成结果,调用 Chain 时则会执行整条数据流。
15.6 Prompt 与 PromptTemplate 有什么区别?
Prompt 是已经可以提交给模型的完整提示内容;PromptTemplate 是包含固定结构和动态变量占位符的模板,需要在运行时填入数据后生成完整 Prompt。
15.7 什么是 Zero-shot?
Zero-shot 是指 Prompt 中不提供任务示例,只给出任务要求和待处理内容,让模型直接完成任务。“零”指示例数量为零,不代表模型没有接受过训练。
十六、今日学习总结
今天已经建立了从 RAG 到最基础 LangChain Chain 的完整认知:
- 大模型存在私有知识缺失、知识过时和幻觉等问题。
- RAG 的核心是“先检索,再把资料和问题交给模型生成答案”。
- RAG 包含知识库准备和用户问答两个阶段。
- LangChain 是大模型应用开发框架,可以组织 RAG 的各个组件,但不是实现 RAG 的唯一方式。
- LLM、Chat Model 与 Embedding Model 的输入、输出和职责不同。
- Chat Model 的多轮历史要保留 System、Human、AI 各自的消息角色。
invoke()的通用含义是执行当前组件一次。- PromptTemplate 把固定提示结构与动态数据分开管理。
- Zero-shot 是 Prompt 中没有任务示例。
prompt | llm把模板和模型连接成 Chain;这种组合方式属于 LCEL。
最终应能在脑中还原这条数据流:
输入数据
↓
PromptTemplate 填充动态变量
↓
完整 Prompt
↓
LLM / Chat Model
↓
模型结果
这正是后续继续理解更完整 RAG 工作流的基础。