Python & AI Tutorials Logo
LangChain & LangGraph

4. 使用模板设计可复用的提示词

在第 3 章中,我们构建了一个可工作的流式聊天 CLI,其中提示词直接嵌入在 Python 代码中。这对于快速原型开发是可行的,但随着 AI 应用的增长,硬编码的提示词会变成维护噩梦。想象一下在多个文件中更新相同的提示词逻辑,或者在不重新部署代码的情况下尝试 A/B 测试不同的提示词变体。

本章教你如何使用 LangChain 的模板系统设计可复用、可维护的提示词。你将学习将提示词逻辑与应用代码分离,利用基于角色的消息传递实现更好的 LLM 控制,将提示词外部化到 YAML 文件以便团队协作,以及在执行前验证模板以尽早捕获错误。

本章涵盖的内容(以及不涵盖的内容):

在本章中,我们将手动处理模板和提示词——你将显式地将模板渲染为消息,然后使用 llm.invoke() 将这些消息发送到 LLM。这种动手实践的方法帮助你准确理解模板的作用和工作原理。

在第 6 章中,你将学习 LCEL(LangChain 表达式语言),它允许你使用 | 运算符将模板和 LLM 组合成管道。现在,我们专注于模板基础,不涉及编排层。

在本章结束时,你将拥有一个强大的提示词管理系统,可以从简单的聊天机器人扩展到复杂的多代理工作流。

4.1) 关注点分离:解耦代码与提示词

为什么要将提示词与代码分离?

当你将提示词直接硬编码在应用逻辑中时,会产生紧密耦合,导致几个问题:

维护负担:更改提示词需要修改 Python 代码、运行测试并重新部署。提示词的更改频率通常远高于代码更改,这使得代码修改-测试-重新部署的循环对于本应是简单的文本编辑来说效率极低。

版本控制挑战:当代码和提示词混合在一起时,版本控制变得困难。合并冲突更容易发生,每个冲突都需要手动解决和重构。

协作摩擦:非技术团队成员(产品经理、领域专家)无法直接编辑存在于 .py 文件中的提示词,必须依赖开发人员的帮助。这种依赖使提示词改进周期显著变慢。

测试复杂性:测试不同的提示词变体意味着复制代码、修改字符串并管理多个分支——使实验变得缓慢且容易出错。

将提示词想象成传统应用中的 SQL 查询。你不会在 Python 代码中硬编码 SQL 字符串——你会使用 ORM 或至少集中管理查询。提示词值得同样的架构规范。

LangChain 的模板系统

LangChain 提供 PromptTemplateChatPromptTemplate 类来分离提示词的固定结构和变化的数据。使用 {占位符} 编写一次提示词,然后每次插入不同的值——不再需要使用 f-字符串或字符串拼接重建提示词。

模板语法和用法

占位符语法

模板使用 {变量名} 作为占位符。在运行时,你提供一个具有匹配键的字典:

python
from langchain_core.prompts import PromptTemplate
 
# 使用占位符定义模板
template = PromptTemplate.from_template(
    "Translate {content} from {source_lang} to {target_lang}"
)
 
# 使用字典填充占位符
result = template.invoke({
    "content": "Hello world",
    "source_lang": "English", 
    "target_lang": "Korean"
})
 
print(result.text)

输出:

Translate Hello world from English to Korean

关键规则:

  • 占位符名称必须与字典键完全匹配
  • 必须提供所有占位符(缺少键会引发 KeyError)
  • 额外的字典键会被忽略
  • 使用 invoke() 用你的值渲染模板

PromptTemplate vs ChatPromptTemplate

PromptTemplate: 返回纯字符串(包装在 StringPromptValue 中)

  • 用于简单的文本补全或传统模型
  • 输出: 单个字符串,如 "Summarize: {content}"

ChatPromptTemplate: 返回带有角色的结构化消息(包装在 ChatPromptValue 中)

  • 用于现代聊天模型(GPT-4、Claude、Gemini)
  • 输出: 角色分离的消息(system/user/assistant)
  • 首选选择: 更好地将系统指令与用户输入分开维护

何时使用哪个?

  • 对于聊天模型,默认使用 ChatPromptTemplate——它更清晰、更易维护
  • 仅在简单补全或不需要角色分离时使用 PromptTemplate
python
# PromptTemplate - 单字符串输出
from langchain_core.prompts import PromptTemplate
 
template1 = PromptTemplate.from_template("Summarize: {content}")
result1 = template1.invoke({"content": "LangChain is a framework..."})  
print(result1)

输出:

text='Summarize: LangChain is a framework...'
python
# ChatPromptTemplate - 基于角色的消息
from langchain_core.prompts import ChatPromptTemplate
 
template2 = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant"),
    ("user", "{question}")
])
result2 = template2.invoke({"question": "What is LangChain?"})
print(result2)

输出:

messages=[SystemMessage(content='You are a helpful assistant'), HumanMessage(content='What is LangChain?')]

模板定义一次。你可以使用不同的值重复使用它,而无需修改模板定义。PromptTemplate.invoke()ChatPromptTemplate.invoke() 都返回准备直接发送到 LLM 的提示词值。

从字符串格式化到模板

让我们将硬编码的提示词重构为使用模板。这是第 3 章的"之前"版本:

python
# 硬编码方法(第 3 章风格)
from langchain_openai import ChatOpenAI
 
llm = ChatOpenAI(model="gpt-4o-mini")
 
user_input = "Explain quantum computing"
# 提示词逻辑与代码混合
prompt = f"You are a helpful assistant. Answer this question: {user_input}"
 
response = llm.invoke(prompt)
print(response.content)

现在使用模板——使用我们将在本章中练习的分步方法:

python
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
 
# 模板单独定义
template = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("user", "{user_input}")
])
 
# 应用逻辑 - 分步执行
llm = ChatOpenAI(model="gpt-4o-mini")
 
user_input = "Explain quantum computing"
 
# 步骤 1: 将模板渲染为消息
messages = template.invoke({"user_input": user_input})
 
# 步骤 2: 将消息发送到 LLM
response = llm.invoke(messages)
print(response.content)

发生了什么变化?

  1. 模板定义: 提示词结构在 template 中定义一次,与执行逻辑分离。
  2. 占位符语法: {user_input} 是一个在运行时填充的占位符。
  3. 分步执行: 我们显式地渲染模板(template.invoke()),然后将结果发送到 LLM(llm.invoke())。这个两步过程帮助你理解模板实际做什么。
  4. 可复用性: 相同的 template 可以用于任何用户问题,无需修改。
  5. 消息结构: template.invoke() 返回 LLM 期望的格式正确的 ChatPromptValue

为什么使用分步方法?

在本章中,你会反复看到这种模式:

python
messages = template.invoke(inputs)  # 步骤 1: 渲染模板
response = llm.invoke(messages)     # 步骤 2: 发送到 LLM

我们有意使用这种两步方法进行学习——它准确显示了模板的作用:将输入数据转换为结构化消息。在第 6 章中,你将学习真实世界的生产模式:使用 LCEL 管道组合这些步骤(template | llm)。但首先分别理解每个步骤可以建立坚实的基础。

模板验证

模板可以尽早捕获错误。如果你引用了不存在的占位符,LangChain 会在进行 API 调用之前引发错误:

python
template = PromptTemplate.from_template("Summarize: {text}")
 
# 这将失败 - 缺少 'text' 键
try:
    template.invoke({"content": "Some text"})  # 错误的键名
except KeyError as e:
    print(f"Template error: {e}")

输出:

Template error: "Input to PromptTemplate is missing variables {'text'}.  Expected: ['text'] Received: ['content']

这种验证发生在模板渲染时,而不是在 LLM 执行期间——为你节省时间和 API 成本。

4.2) 角色感知提示词模板(System、User、Assistant)

理解消息角色

现代 LLM(GPT-4、GPT-5、Claude、Gemini)通过消息角色理解对话结构。每条消息都有一个特定的角色,告诉模型如何解释它。

三个核心角色:

System: 定义 AI 应该如何行为

  • 目的: 设置 AI 的个性、专业知识和操作规则
  • 示例: "你是一个编写简洁代码示例的 Python 专家"
  • 何时应用: 在开始时设置一次,影响所有响应
  • 可以理解为: AI 的指令手册

User: 代表人类输入

  • 目的: 提出问题或发出请求
  • 示例: "如何在 Python 中读取文件?"
  • 何时应用: 每次人类发送消息时
  • 可以理解为: 你提出的问题

Assistant: 代表 AI 之前的响应

  • 目的: 提供对话历史
  • 示例: "你可以使用 open() 函数读取文件"
  • 何时应用: 当你需要多轮对话时
  • 可以理解为: AI 对之前答案的记忆

系统消息:控制机制

系统消息告诉 AI 它是谁以及应该如何操作——在任何用户交互之前。

你可以控制什么:

  1. 专业知识: "你是一名高级 Python 开发人员"
  2. 输出格式: "始终以 JSON 格式响应"
  3. 行为规则: "如果不确定,说'我不知道'"
  4. 响应风格: "简洁且技术性"

为什么这很重要:

没有系统消息 → 通用、冗长的响应

有系统消息 → 一致、定制的行为

系统消息的实际应用

让我们通过比较有无系统消息的相同问题来看看系统消息的真实影响。注意响应的变化有多大——不仅在长度上,而且在语气、复杂性和教学方法上。

没有系统消息:

python
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
 
template = ChatPromptTemplate.from_messages([
    ("user", "What is Python?")
])
 
llm = ChatOpenAI(model="gpt-4o-mini")
messages = template.invoke({})
response = llm.invoke(messages)
print(response.content)

输出:

Python is a high-level, interpreted programming language known for its readability and simplicity. 
It was created by Guido van Rossum and first released in 1991. 
Python emphasizes code readability, allowing programmers to express concepts in fewer lines of code compared to languages such as C++ or Java.
 
Key features of Python include:
...

有系统消息:

python
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
 
# 使用系统消息控制角色和输出风格
template = ChatPromptTemplate.from_messages([
    ("system", """你是一位拥有 15 年教学经验的高级 Python 讲师。
你的学生是从未编程过的完全初学者。
 
教学风格:
- 使用简单的日常类比
- 避免技术术语
- 展示日常生活中的实际例子
- 鼓励和耐心"""),
    ("user", "What is Python?")
])
 
llm = ChatOpenAI(model="gpt-4o-mini")
messages = template.invoke({})
response = llm.invoke(messages)
print(response.content)

输出:

Great question! Think of Python like a really helpful tool in your toolbox. 
Just like a hammer or a screwdriver helps you build or fix things around the house, Python helps you create software or automate tasks on a computer.
 
Imagine you wanted to bake a cake. 
You need a recipe to follow, right? In this analogy, Python is like that recipe. 
It tells the computer what steps to take to achieve a goal, whether it's doing math, organizing files, or even running a game.
...

区别:

没有系统消息:

  • AI 使用其默认行为: 礼貌、信息丰富,但通用
  • 响应是百科全书式和正式的——针对广泛受众优化
  • 没有一致的角色: 每个响应的语气和风格可能不同
  • 没有约束: AI 自己决定详细程度或技术性

有系统消息:

  • AI 遵循你的具体指令: 你定义的角色、风格和规则
  • 响应是一致和可预测的——每个答案都符合你的要求
  • 保持清晰的角色: 充当你分配的角色(教师、专家、助手)
  • 应用明确的约束: 你设置的输出格式、语言级别和行为边界

关键见解: 没有系统消息,你得到 AI 的默认模式。有系统消息,你得到你的 AI——根据你的应用需求定制。系统消息将 AI 从通用工具转变为专门的助手,每次都完全按照你想要的方式行为。

User 和 Assistant 角色:构建对话

单个问题(仅 User):

python
template = ChatPromptTemplate.from_messages([
    ("system", "You are a Python expert."),
    ("user", "{question}")
])
 
llm = ChatOpenAI(model="gpt-4o-mini")
messages = template.invoke({"question": "How do I read a CSV?"})
response = llm.invoke(messages)

对于独立问题效果很好。

带上下文的多轮对话(User + Assistant):

没有历史:

python
template = ChatPromptTemplate.from_messages([
    ("system", "You are a Python expert."),
    ("user", "How does it work?")  # "it" = ???
])

AI 不知道"it"指的是什么。

有历史:

python
template = ChatPromptTemplate.from_messages([
    ("system", "You are a Python expert."),
    ("user", "What's the pandas library?"),
    ("assistant", "Pandas is a data analysis library."),
    ("user", "How does it work?")  # 现在 "it" = pandas
])

对话历史(之前的用户问题 + 助手响应)提供了上下文。AI 现在理解"it"指的是 pandas。

示例:构建带历史的对话

现在让我们构建一个记住之前交流的示例。这个函数维护对话历史,并在每个新问题中将其传递给 AI:

python
llm = ChatOpenAI(model="gpt-4o-mini")
 
def chat_with_history(user_input: str, history: list):
    messages = [("system", "You are a Python expert.")]
    
    # 添加历史
    for msg in history:
        messages.append((msg["role"], msg["content"]))
    
    # 添加当前输入
    messages.append(("user", user_input))
    
    # 使用 mustache 格式避免内容包含 {花括号} 时出错
    template = ChatPromptTemplate.from_messages(messages, template_format="mustache")
    
    formatted = template.format()
    response = llm.invoke(formatted)
    return response.content
 
# 使用
history = []
 
# 第 1 轮
resp1 = chat_with_history("What's a Python dictionary?", history)
print(resp1)
 
history.append({"role": "user", "content": "What's a Python dictionary?"})
history.append({"role": "assistant", "content": resp1})
 
# 第 2 轮 - 使用上下文
resp2 = chat_with_history("Show an example.", history)
print(resp2)

消息顺序规则

LLM 期望特定的对话结构: System → User → Assistant → User → Assistant → ...

为什么是这个顺序?

这种模式反映了自然的人机对话:

  1. System 首先出现(可选): 因为它设置了适用于整个对话的行为规则,所以必须在任何交互开始之前定义。就像你在某人开始工作之前向他们简要介绍,而不是在任务中间。

  2. User 然后 Assistant 交替: 在真实对话中,人类说话(User),AI 响应(Assistant),人类跟进(User),AI 再次响应(Assistant)。这种轮流模式是 AI 训练的方式,所以它期望这种结构。

  3. 必须以 User 结束: AI 生成对最后一条 User 消息的响应。如果对话以 Assistant 结束,AI 就没有什么可以响应的。

有效示例:

python
# System + 单个 User
[("system", "..."), ("user", "...")]
 
# System + 对话
[("system", "..."), ("user", "..."), ("assistant", "..."), ("user", "...")]

有问题的模式:

python
# Assistant 在 User 之前 - AI 对上下文感到困惑
[("system", "..."), ("assistant", "..."), ("user", "...")]
# AI 看到一个没有问题的响应。它可能会虚构这是在回答什么问题,
# 导致不相关或混乱的响应。
python
# 两条连续的 User 消息 - 缺少 AI 响应
[("system", "..."), ("user", "..."), ("user", "...")]
# AI 不知道要响应哪条 User 消息,或者可能会笨拙地合并它们。
# 失去对话流程。
python
# 以 Assistant 结束 - 没有什么可以响应的
[("system", "..."), ("user", "..."), ("assistant", "...")]
# 对话已完成。AI 没有什么可以生成的,因为没有待处理的 User 问题。
# 可能会产生错误或空响应。

关键点: 这些模式并不总是导致硬错误,但它们会混淆 AI,因为它们打破了它训练的对话逻辑。AI 可能会生成响应,但它们将不可靠或无意义。始终遵循预期模式以获得可预测的行为。

超越简单历史:生产模式(预览)

重要说明: 你刚刚学到的对话历史模式是一个很好的基础,但生产系统使用更复杂的方法。

原始历史的问题:

简单地将所有对话历史传递给 AI 有局限性:

  1. 令牌浪费: 每条消息(即使是旧消息)都计入你的令牌限制和成本
  2. 失去焦点: AI 可能会被不相关的早期对话分散注意力
  3. 没有明确的任务: AI 从历史中推断要做什么,而不是接收明确的指令

更好的方法:

生产系统将上下文与指令分离:

简单历史方法(我们刚学的):

python
messages = [
    ("system", "You are a Python expert."),
    ("user", "What's a dictionary?"),
    ("assistant", "A dictionary is a key-value data structure."),
    ("user", "Show an example.")
]

生产方法(在后续章节中):

python
messages = [
    ("system", "You are a Python expert."),
    ("user", """上下文: 用户之前询问了 Python 字典,并了解到它们是键值结构。
 
任务: 提供一个演示字典用法的代码示例。""")
]

区别:

  • 原始历史: AI 看到完整对话并弄清楚要做什么
  • 生产模式: AI 接收总结的上下文 + 明确的指令

分离的好处:

  • 更少的令牌(更低的成本,更快的响应)
  • 更可靠的行为(明确的指令)
  • 更好的控制(你决定什么上下文重要)

你将在哪里学到这个:

  • 第 8 章: 管理对话状态和内存
  • 第 11 章: 上下文检索(将 RAG 与对话内存结合)
  • 第 16 章: 基于对话上下文的动态路由

现在,理解原始历史是必不可少的——它是这些高级模式的基础。但请记住:你刚学到的是一个教学工具,而不是最终解决方案。

4.3) 外部化提示词:管理模板文件(.yaml)

为什么要外部化提示词?

随着 AI 应用的增长,在 Python 代码中管理提示词变得笨拙。将提示词外部化到 YAML 文件提供:

非技术协作: 产品经理、领域专家和提示词工程师可以编辑 YAML 文件,而无需接触 Python 代码或理解编程概念。

版本控制清晰: 单独跟踪提示词更改和代码更改。不再有提示词调整和逻辑更新一起出现的混合提交。

特定环境的提示词: 开发、预发布和生产的不同提示词,无需更改代码。

A/B 测试: 通过加载不同的文件测试提示词变体——无需更改代码。

将 YAML 提示词文件视为传统应用中的配置文件——它们定义行为,而无需更改代码或重新部署。

什么是 YAML?

YAML 是一种人类可读的数据格式,通常用于配置文件。如果你以前从未见过 YAML,可以将其视为 JSON 的更清晰替代品——它使用缩进而不是括号,更易于阅读和编辑。

YAML 提示词结构

LangChain 为提示词定义了标准的 YAML 文件结构。让我们看看示例:

示例 1: 没有变量的提示词

当提示词不需要任何运行时值时,将 input_variables 设置为空列表:

yaml
# prompts/system_prompt.yaml
_type: prompt
input_variables: []
template: |
  You are a helpful assistant.
  Please answer in a friendly and encouraging tone.

| 符号允许你编写多行文本,并保留换行符。

示例 2: 带变量的提示词

当提示词需要运行时值时,在 input_variables 中列出它们:

yaml
# prompts/user_prompt.yaml
_type: prompt
input_variables:
  - user_input
template: |
  User question: {user_input}
  Please provide a clear answer.

在运行时,{user_input} 占位符会被实际值替换。

关键组件:

  • _type: prompt: 标识这是一个提示词模板
  • input_variables: 列出模板中使用的所有占位符(如果没有则为空列表 [])
  • template: 带有 {占位符} 的实际提示词文本

加载和使用 YAML 提示词

基本加载:

现在让我们加载我们创建的 YAML 文件并将它们与 LLM 一起使用:

python
from langchain_core.prompts import load_prompt, ChatPromptTemplate
from langchain_openai import ChatOpenAI
 
# 从 YAML 文件加载提示词
system_prompt_template = load_prompt("prompts/system_prompt.yaml")
user_prompt_template = load_prompt("prompts/user_prompt.yaml")
 
# 将加载的提示词组合成聊天模板
chat_template = ChatPromptTemplate.from_messages([
    ("system", system_prompt_template.template),
    ("user", user_prompt_template.template)
])
 
llm = ChatOpenAI(model="gpt-4o-mini")
 
# 步骤 1: 使用运行时值渲染模板
messages = chat_template.invoke({"user_input": "What is LangChain?"})
 
# 步骤 2: 发送到 LLM
response = llm.invoke(messages)
print(response.content)

验证加载的模板:

在使用模板之前,验证它是否正确加载:

python
from langchain_core.prompts import load_prompt
 
# 加载模板
user_prompt_template = load_prompt("prompts/user_prompt.yaml")
 
# 检查它期望什么变量
print("Input variables:", user_prompt_template.input_variables)
 
# 查看模板文本
print("Template:", user_prompt_template.template)

输出:

Input variables: ['user_input']
Template: User question: {user_input}
Please provide a clear answer.

常见的 YAML 错误

错误 1: 不一致的缩进

YAML 要求一致的缩进(通常是 2 个空格)。每个级别必须使用相同的间距量:

错误:

yaml
_type: prompt
input_variables:
- user_input      # 错误: 列表项应该缩进
  - question      # 错误: 混合缩进级别

正确:

yaml
_type: prompt
input_variables:
  - user_input    # 正确: 两个项目在同一缩进级别
  - question

错误 2: 占位符不匹配

template 中的占位符必须与 input_variables 匹配:

错误:

yaml
input_variables:
  - user_input
template: "Question: {question}"  # 'question' 不在 input_variables 中!

正确:

yaml
input_variables:
  - user_input
template: "Question: {user_input}"

如果占位符与声明的变量不匹配,LangChain 将引发错误。

4.4) 执行前预览和验证模板

为什么要预览模板?

提示词工程是迭代的。你调整措辞、调整结构、添加示例——每次迭代都会消耗 API 令牌和时间。在执行前预览模板可以让你:

节省时间和金钱: 在进行昂贵的 API 调用之前捕获错误。

验证正确性: 确保变量正确填充,格式符合预期。

高效调试: 查看发送到 LLM 的确切提示词,所有变量都已填充,格式已应用。

将模板预览视为打印调试——你在执行前检查中间状态以验证正确性。

基本模板预览

检查模板结构:

在将模板与 LLM 一起使用之前,检查其结构并预览它如何使用示例数据渲染:

python
from langchain_core.prompts import ChatPromptTemplate
 
template = ChatPromptTemplate.from_messages([
    ("system", "You are a {role}."),
    ("user", "{user_input}")
])
 
# 预览模板结构
print("Input variables:", template.input_variables)
print("Message count:", len(template.messages))
 
# 使用示例数据预览
prompt_value = template.invoke({
    "role": "Python programming expert",
    "user_input": "What is Python?"
})
 
print("\nPreview:")
for msg in prompt_value.to_messages():
    print(f"{msg.type}: {msg.content}")

输出:

Input variables: ['role', 'user_input']
Message count: 2
 
Preview:
system: You are a Python programming expert.
human: What is Python?

这显示了将发送到 LLM 的确切内容,允许你在执行前验证提示词。

验证模板:捕获缺失的变量

最常见的模板错误是缺少必需的变量。这是一个可重用的验证函数,可以捕获缺失的变量:

python
from langchain_core.prompts import ChatPromptTemplate
 
def preview_template(template: ChatPromptTemplate, inputs: dict):
    """使用给定的输入预览模板,捕获错误。"""
    try:
        prompt_value = template.invoke(inputs)
        
        print("TEMPLATE PREVIEW")
        print("=" * 60)
        
        for i, msg in enumerate(prompt_value.to_messages(), 1):
            print(f"Message {i} ({msg.type.upper()}):")
            print(msg.content)
            print("-" * 60)
                
    except KeyError as e:
        print(f"ERROR: {e}")
        print(f"Required variables: {template.input_variables}")
 
# 使用
template = ChatPromptTemplate.from_messages([
    ("system", "You are a {role}."),
    ("user", "{user_input}")
])
 
# 有效输入
preview_template(template, {
    "role": "Python programming expert",
    "user_input": "What is Python?"
})
 
# 缺失变量
preview_template(template, {
    "user_input": "What is Python?"  # 缺少 'role'
})

输出:

TEMPLATE PREVIEW
============================================================
Message 1 (SYSTEM):
You are a Python programming expert.
------------------------------------------------------------
Message 2 (HUMAN):
What is Python?
------------------------------------------------------------
 
ERROR: "Input to ChatPromptTemplate is missing variables {'role'}.
Expected: ['role', 'user_input'] Received: ['user_input']
...
Required variables: ['role', 'user_input']

验证工作流:

这是典型的模板验证过程:

错误

有效

定义模板

加载示例数据

验证输入

修复模板/数据

预览消息

准备好了吗?

使用 LLM 执行

这个迭代过程有助于在昂贵的 LLM 调用之前捕获错误。

执行前检查清单

在将模板发送到生产之前:

  • 所有 input_variables 都在 YAML/模板中声明
  • 示例数据渲染没有错误
  • 多行提示词正确显示
  • 占位符与变量名完全匹配
  • 使用边缘情况测试(空字符串、长文本)

章节总结:

你已经学会使用 LangChain 的模板系统设计可维护、可复用的提示词:

  1. 关注点分离: 将提示词与代码解耦,以便更容易维护和迭代
  2. 角色感知模板: 使用 system、user 和 assistant 消息进行结构化的 LLM 交互,具有适当的指令层次结构
  3. 外部化提示词: 在 YAML 文件中管理提示词,以便非技术协作和版本控制
  4. 预览和验证: 在执行前尽早捕获错误并验证模板

下一步:

在第 5 章中,你将看到模板如何在预览代理示例中实现自主决策。然后在第 6 章中,你将学习 LCEL(LangChain 表达式语言),使用 | 运算符将这些模板组合成强大的管道。