学习如何创建可复用、动态的提示(prompts),并将 AI 的响应解析为结构化数据。这是构建生产级 AI 应用所必备的核心技能。
学习目标
- 使用变量创建动态且可复用的提示模板
- 针对不同场景选用合适的提示模板类型
- 将非结构化的 AI 输出解析为结构化数据(如 JSON、列表等)
- 通过验证后的输出构建可靠的应用程序
本中级教程的前置知识
本教程假设你已具备以下条件:
- 已完成第 5 课(LangChain 环境配置)或已安装 LangChain
- 具备中级 Python 编程能力
- 对提示工程(prompt engineering)有基本理解
- 熟悉 JSON 及常用数据结构
什么是 LangChain 提示模板?------ 基础概念
提示模板是一种包含变量的可复用提示,这些变量可以在运行时动态填充。与其将提示硬编码,不如创建一个能根据输入自动调整的模板。
🔑 为什么要使用模板?
- 可复用性:一次编写,多次使用,适配不同输入
- 一致性:确保整个应用中提示结构统一
- 可维护性:只需在一个地方修改提示内容
- 动态内容:轻松注入用户数据、上下文或变量
如何创建基础的 LangChain 提示模板?------ Python 示例
简单变量替换
最基本的模板会将占位符替换为实际值。下面这个例子展示了一个可用于 LLM 的翻译提示模板:
python
from langchain_core.prompts import PromptTemplate
# 创建一个简单模板
template = """你是一个乐于助人的助手,负责将 {input_language} 翻译成 {output_language}。
原文:{text}
译文:"""
# 创建提示模板对象
prompt = PromptTemplate(
input_variables=["input_language", "output_language", "text"],
template=template
)
# 使用模板
formatted_prompt = prompt.format(
input_language="English",
output_language="Spanish",
text="Hello, how are you?"
)
print(formatted_prompt)
输出结果:
你是一个乐于助人的助手,负责将 English 翻译成 Spanish。
原文:Hello, how are you?
译文:
说明:模板会将 {input_language}、{output_language} 和 {text} 替换为你提供的实际值。注意:这一步仅生成提示文本,并未真正执行翻译。若要获得翻译结果,还需将此提示发送给 LLM。
完整示例:模板 + LLM
下面展示如何将模板与 LLM 结合,真正完成翻译任务:
python
from langchain_core.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 创建模板
template = """你是一个乐于助人的助手,负责将 {input_language} 翻译成 {output_language}。
原文:{text}
译文:"""
prompt = PromptTemplate(
input_variables=["input_language", "output_language", "text"],
template=template
)
# 初始化 LLM(需在 .env 文件中设置 GOOGLE_API_KEY)
model = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
google_api_key=os.getenv("GOOGLE_API_KEY")
)
# 构建链:模板 → LLM
chain = prompt | model
# 执行链(这将真正进行翻译!)
response = chain.invoke({
"input_language": "English",
"output_language": "Spanish",
"text": "Hello, how are you?"
})
print(response.content)
# 输出:"Hola, ¿cómo estás?"
聊天提示模板(Chat Prompt Templates)
对于聊天模型(chat models),应使用 ChatPromptTemplate 来处理消息格式。聊天模型要求消息具有特定的角色结构(system、human、assistant),因此 ChatPromptTemplate 是与之正确通信的关键:
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 创建包含 system 和 human 消息的聊天模板
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个{role},负责协助完成{task}。"),
("human", "{user_input}"),
])
# 格式化模板
messages = chat_template.format_messages(
role="编程导师",
task="Python 编程",
user_input="如何读取一个 CSV 文件?"
)
# 与模型交互
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
google_api_key=os.getenv("GOOGLE_API_KEY") # 显式设置 API 密钥
)
response = llm.invoke(messages)
print(response.content)
📋 消息角色说明:
- "system":设定 AI 的行为、性格或约束条件,相当于给助手下达指令
- "human":用户的输入或问题
- "assistant":AI 的历史回复(用于对话上下文)
✨ ChatPromptTemplate 的优势:
- 自动为聊天模型格式化消息结构
- 支持在任意消息类型中使用动态变量
- 轻松构建对话式应用
- 在不同聊天模型提供商之间保持一致性
高级模板模式
部分模板(Partial Templates)
预先填充部分变量,其余变量保持动态。适用于某些值固定(如当前日期、系统配置或默认值),而其他值随每次调用变化的场景:
python
from langchain_core.prompts import PromptTemplate
from datetime import datetime
# 包含多个变量的模板
template = """日期:{date}
用户:{user_name}
任务:{task}
请完成以下请求:{request}"""
# 创建部分模板,预填日期
prompt = PromptTemplate(
input_variables=["user_name", "task", "request"],
template=template,
partial_variables={"date": datetime.now().strftime("%Y-%m-%d")}
)
# 此时只需提供剩余变量
formatted = prompt.format(
user_name="Alice",
task="代码审查",
request="请根据最佳实践审查以下 Python 函数"
)
print(formatted)
🔑 何时使用部分模板?
- 时间戳:自动在日志或报告中加入当前日期/时间
- 系统信息:预填环境、版本或配置详情
- 用户上下文:一次性设置用户偏好,多次复用
- 默认值:提供合理的默认选项,同时允许覆盖
💡 专业技巧:部分模板非常适合从通用模板派生专用版本。例如,先创建一个通用邮件模板,再通过部分填充生成支持、销售或通知等不同场景的专用模板。
模板组合(Template Composition)
将多个模板组合成复杂提示。这种模式允许你构建模块化、可复用的提示组件,并根据不同用例灵活搭配:
python
from langchain_core.prompts import PromptTemplate
# 定义可复用的模板组件
persona_template = "你是一位拥有{years}年经验的{expertise}专家。"
task_template = "你的任务是{action}以下{content_type}:"
format_template = "请将你的回答格式化为{format}。"
# 组合模板
full_template = f"""
{persona_template}
{task_template}
{format_template}
内容:{{content}}
"""
# 创建完整提示
prompt = PromptTemplate(
input_variables=["expertise", "years", "action", "content_type", "format", "content"],
template=full_template
)
# 使用组合模板
result = prompt.format(
expertise="Python",
years="10",
action="优化",
content_type="代码",
format="带解释的改进建议列表",
content="def calculate_sum(numbers): total = 0; for n in numbers: total = total + n; return total"
)
print(result)
🧩 为何使用模板组合?
- 模块化:为提示的不同部分创建可复用的构建块
- 一致性:确保应用内所有提示结构统一
- 灵活性:根据不同场景自由组合组件
- 可维护性:修改一个组件即可影响所有使用它的提示
💡 真实场景示例:
设想构建一个客服系统,需要不同组合:
- 技术支持:persona_template + technical_task + detailed_format
- 销售咨询:persona_template + sales_task + friendly_format
- 投诉处理:persona_template + empathy_task + solution_format
- 共享同一"人设"组件,但任务和格式组件各不相同!
LangChain 输出解析器教程:结构化数据的逐步指南
为什么需要输出解析器?
LLM 返回的是非结构化文本,但应用程序通常需要结构化数据。输出解析器能将自由文本转换为以下可用格式:
- JSON
- 结构化对象
- 列表
- 枚举项
- 布尔值(是/否决策)
- 自定义格式
列表输出解析器(List Output Parser)
解析逗号分隔或编号列表。该解析器会自动指示 LLM 以逗号分隔格式返回结果,然后将其拆分为 Python 列表:
python
from langchain_core.output_parsers import CommaSeparatedListOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 初始化解析器
list_parser = CommaSeparatedListOutputParser()
# 创建带格式指令的提示
prompt = PromptTemplate(
template="列出 5 个{category}。\n{format_instructions}",
input_variables=["category"],
partial_variables={"format_instructions": list_parser.get_format_instructions()}
)
# 构建链
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
google_api_key=os.getenv("GOOGLE_API_KEY")
)
chain = prompt | llm | list_parser
# 获取解析后的列表
result = chain.invoke({"category": "Python Web 框架"})
print(result) # ['Django', 'Flask', 'FastAPI', 'Pyramid', 'Tornado']
📋 工作原理:
- 解析器自动向提示中添加格式指令
- LLM 返回逗号分隔的项
- 解析器拆分响应并清理空白字符
- 返回可直接使用的干净 Python 列表
✨ 适用场景:
- 生成想法或建议列表
- 从文本中提取多个项目
- 创建分类或标签
- 任何需要多个简单输出的任务
结构化输出解析器(Structured Output Parser)
解析带验证的复杂结构化数据。该解析器使用 ResponseSchema 对象定义期望结构,并自动指示 LLM 以 JSON 格式返回数据:
python
from pydantic import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser # 注意:这个还在
from langchain_core.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
import os
from dotenv import load_dotenv
load_dotenv()
# 1. 用 Pydantic 定义你的输出结构(替代 ResponseSchema)
class ProductInfo(BaseModel):
name: str = Field(description="产品名称")
price: float = Field(description="价格,单位为美元")
features: list[str] = Field(description="主要功能列表")
in_stock: bool = Field(description="是否有库存")
# 2. 创建解析器
parser = PydanticOutputParser(pydantic_object=ProductInfo)
# 3. 构建提示(自动注入格式指令)
prompt = PromptTemplate(
template="从以下文本中提取产品信息。\n{format_instructions}\n\n文本:{product_description}",
input_variables=["product_description"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 4. 调用链
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
google_api_key=os.getenv("GOOGLE_API_KEY")
)
chain = prompt | llm | parser
result = chain.invoke({
"product_description": "新款 iPhone 15 Pro 售价 999 美元,采用钛金属设计、A17 Pro 芯片和升级版相机系统,目前门店有售。"
})
print(result) # 返回 ProductInfo 对象,可直接访问属性
# 输出:name='iPhone 15 Pro' price=999.0 features=['钛金属设计', 'A17 Pro 芯片', '升级版相机系统'] in_stock=True
注意: ResponseSchema 和 StructuredOutputParser (0.3版本以前的写法,1.0版本已经弃用,改为更加现代化的方式)。在1.0版本中,推荐使用更加现代化的方式来实现结构化输出解析器。PydanticOutputParser 是一个基于 Pydantic 模型的解析器,它可以将 LLM 的响应解析为符合定义的 Pydantic 模型的实例。
🔑 核心特性:
- 结构定义:为每个字段指定名称和描述
- 类型灵活:支持字符串、数字、列表和布尔值
- 自动指令:解析器明确告诉 LLM 如何格式化响应
- JSON 输出:返回 Python 字典形式的数据
💡 典型用例:
- 数据提取:从非结构化文本中抽取结构化信息
- 表单处理:将自然语言转换为表单字段
- API 响应:生成可供 API 使用的结构化数据
- 数据库记录:创建可直接插入数据库的记录
高级:Pydantic 输出解析器(Pydantic Output Parser)
对于生产级应用,推荐使用 Pydantic 实现类型安全与验证。Pydantic 提供最强大的解析能力,包括自动类型转换、验证和清晰的错误信息。
🔍 为何选择 Pydantic 输出解析器?
- 类型安全:自动类型检查与转换
- 验证机制:内置字段验证,支持自定义规则
- 错误处理:解析失败时提供清晰的错误信息
- IDE 支持:完整的自动补全与类型提示
- 生产就绪:已在企业级应用中广泛验证
💡 核心组件:
- BaseModel:用类型定义数据结构
- Field():添加描述和验证规则
- PydanticOutputParser:将 LLM 输出转换为类型化对象
- format_instructions:自动生成提示指令
python
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_google_genai import ChatGoogleGenerativeAI
from pydantic import BaseModel, Field
from typing import List
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 定义数据模型
class Recipe(BaseModel):
name: str = Field(description="食谱名称")
prep_time: int = Field(description="准备时间(分钟)")
servings: int = Field(description="可供几人食用")
ingredients: List[str] = Field(description="所需食材列表")
difficulty: str = Field(description="难度等级:easy, medium 或 hard")
# 创建解析器
parser = PydanticOutputParser(pydantic_object=Recipe)
# 创建提示
prompt = PromptTemplate(
template="""从以下文本中提取食谱信息。
{format_instructions}
文本:{recipe_text}""",
input_variables=["recipe_text"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 使用链
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
temperature=0, # 降低随机性以提高结构稳定性
google_api_key=os.getenv("GOOGLE_API_KEY")
)
chain = prompt | llm | parser
# 解析食谱
result = chain.invoke({
"recipe_text": "这道简单的培根蛋面仅需 20 分钟即可完成,可供 4 人食用。你需要意大利面、鸡蛋、培根、帕玛森奶酪和黑胡椒。"
})
print(f"食谱:{result.name}")
print(f"耗时:{result.prep_time} 分钟")
print(f"份量:{result.servings} 人")
print(f"食材:{', '.join(result.ingredients)}")
print(f"难度:{result.difficulty}")
🎯 高级特性:
- 自定义验证器:通过 @validator 添加自定义验证逻辑
- 默认值:为可选字段设置默认值
- 嵌套模型:支持复杂的嵌套数据结构
- 枚举(Enums):限制字段只能取特定值
💡 带验证的示例:
python
from typing import List
from pydantic import BaseModel, Field, field_validator # ← 注意这里导入的是 field_validator
class Recipe(BaseModel):
name: str = Field(description="食谱名称")
prep_time: int = Field(description="准备时间(分钟)", gt=0, le=480) # 1~480 分钟
ingredients: List[str] = Field(description="食材列表", min_length=1) # ⚠️ 注意:min_items → min_length
@field_validator('name')
def name_must_not_be_empty(cls, v: str) -> str:
if not v.strip():
raise ValueError('食谱名称不能为空')
return v.title() # 自动首字母大写
最佳实践
提示模板(Prompt Templates)
- 保持模板聚焦单一任务
- 使用描述性强的变量名
- 在提示中包含示例
- 用边界情况测试模板
输出解析器(Output Parsers)
- 始终包含格式指令
- 优雅处理解析错误
- 复杂结构优先使用 Pydantic
- 使用前务必验证输出
💡常见模式
- 数据提取:模板 + StructuredOutputParser → 从非结构化文本中提取结构化数据
- 分类任务:带选项的模板 + EnumOutputParser → 对输入进行分类
- 多步处理:串联多个模板与解析器 → 构建复杂工作流
🎉下一步:构建复杂工作流
干得漂亮!你已经掌握了 LangChain 的提示模板与输出解析器------这是构建动态、结构化 AI 应用的基石。这些技能将为你学习更复杂的 LangChain 模式打下坚实基础。
准备进阶了吗?在下一课中,你将学习如何使用 LangChain Chains 构建复杂工作流,将多个步骤组合成强大的 AI 流水线。