langchain_core.prompts.PipelinePromptTemplate
类是 LangChain 中用于组合多个提示模板的工具类,允许构建复杂的提示流水线。
本文基于 LangChain 0.3.x,详细介绍 PipelinePromptTemplate
的定义、参数、方法和典型场景,并提供一个独立示例,展示如何使用 PipelinePromptTemplate
结合 ChatOpenAI
处理人工智能主题的问答,示例通过流水线组合上下文、问题和格式指令。
从0.3.22
版本起本类已经弃用,如需迁移至新方案,可以查看:迁移教程
langchain_core.prompts.PipelinePromptTemplate
简介
PipelinePromptTemplate
是 LangChain 的提示模板类,用于将多个子提示模板组合成一个完整的提示。它通过定义输入变量的依赖关系,允许动态填充子模板,并生成最终的提示字符串。特别适合需要复杂提示结构的任务,如多部分问答、RAG 或需要上下文和格式指令的场景。
核心功能:
- 组合多个子提示模板(如
PromptTemplate
或ChatPromptTemplate
)。 - 支持输入变量的层级依赖,动态填充子模板。
- 提供格式化方法,生成最终提示。
- 支持同步和异步格式化,集成到 LCEL 链。
适用场景:
- 构建复杂的多部分提示,如包含上下文、问题和格式指令。
- 在 RAG 应用中组合检索文档和用户查询。
- 分模块设计提示,提高可维护性和复用性。
- 动态生成提示,适应不同输入。
与普通 PromptTemplate
对比:
PromptTemplate
:单一模板,直接格式化输入变量。PipelinePromptTemplate
:组合多个模板,管理变量依赖,适合复杂提示。
类定义和初始化
以下是 PipelinePromptTemplate
的定义,基于 LangChain 源码(langchain_core/prompts/pipeline.py
)和官方文档(PipelinePromptTemplate)。
类签名
class PipelinePromptTemplate(BasePromptTemplate):
def __init__(
self,
final_prompt: BasePromptTemplate,
pipeline_prompts: List[Tuple[str, BasePromptTemplate]],
input_variables: Optional[List[str]] = None,
**kwargs: Any
) -> None
- 参数:
final_prompt
(BasePromptTemplate
):最终的提示模板,包含子模板的占位符。pipeline_prompts
(List[Tuple[str, BasePromptTemplate]]
):子提示模板列表,每个元素是(变量名, 子模板)
,变量名对应final_prompt
中的占位符。input_variables
(Optional[List[str]]
,默认None
):顶级输入变量列表,若未提供,自动从模板推断。**kwargs
:传递给BasePromptTemplate
的其他参数(如metadata
)。
- 功能:
- 将子模板的输出填充到
final_prompt
的占位符。 - 验证变量依赖,确保子模板的输入变量被正确提供。
- 将子模板的输出填充到
初始化示例
from langchain_core.prompts import PromptTemplate, PipelinePromptTemplate
# 子模板
context_template = PromptTemplate.from_template("上下文:{context}")
question_template = PromptTemplate.from_template("问题:{question}")
# 最终模板
final_template = PromptTemplate.from_template("{context}\n{question}")
# 组合
pipeline_prompt = PipelinePromptTemplate(
final_prompt=final_template,
pipeline_prompts=[
("context", context_template),
("question", question_template)
]
)
常用方法
PipelinePromptTemplate
继承自 langchain_core.prompts.base.BasePromptTemplate
,提供以下核心方法。
1. format
def format(self, **kwargs: Any) -> str
- 功能:同步格式化提示,填充所有输入变量,生成最终字符串。
- 输入:
kwargs
,包含所有子模板和最终模板的输入变量。 - 输出:
str
,格式化后的提示字符串。 - 示例:
result = pipeline_prompt.format(context="AI 简介", question="什么是 AI?") print(result) # 输出: # 上下文:AI 简介 # 问题:什么是 AI?
2. format_prompt
def format_prompt(self, **kwargs: Any) -> PromptValue
- 功能:同步格式化提示,返回
PromptValue
(如StringPromptValue
或ChatPromptValue
)。 - 使用场景:与 LLM 链集成。
- 示例:
prompt_value = pipeline_prompt.format_prompt(context="AI 简介", question="什么是 AI?") print(prompt_value.to_string())
3. ainvoke
async def ainvoke(self, input: Dict[str, Any], config: Optional[RunnableConfig] = None) -> PromptValue
- 功能:异步格式化提示,返回
PromptValue
。 - 使用场景:高并发场景。
- 示例:
import asyncio async def run(): result = await pipeline_prompt.ainvoke({"context": "AI 简介", "question": "什么是 AI?"}) print(result.to_string()) asyncio.run(run())
4. validate_variable_mapping
def validate_variable_mapping(self) -> None
- 功能:验证子模板和最终模板的变量依赖,确保所有占位符都有输入。
- 内部调用:初始化时自动运行。
- 示例:
pipeline_prompt.validate_variable_mapping() # 抛出 ValueError 如果变量缺失
使用方式
以下是使用 PipelinePromptTemplate
的步骤。
1. 安装依赖
pip install --upgrade langchain langchain-openai
2. 设置 OpenAI API 密钥
export OPENAI_API_KEY="your-api-key"
或在代码中:
import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
3. 定义子模板和最终模板
from langchain_core.prompts import PromptTemplate
context_template = PromptTemplate.from_template("背景:{context}")
question_template = PromptTemplate.from_template("问题:{question}")
format_template = PromptTemplate.from_template("请按 JSON 格式回答:\n```json\n{format_instructions}\n```")
final_template = PromptTemplate.from_template("{context}\n{question}\n{format_instructions}")
4. 初始化 PipelinePromptTemplate
pipeline_prompt = PipelinePromptTemplate(
final_prompt=final_template,
pipeline_prompts=[
("context", context_template),
("question", question_template),
("format_instructions", format_template)
]
)
5. 集成到链
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
chain = pipeline_prompt | llm
6. 调用链
result = chain.invoke({
"context": "人工智能简介",
"question": "什么是人工智能?",
"format_instructions": '{"question": "string", "answer": "string"}'
})
使用 PipelinePromptTemplate
的示例
以下是一个独立示例,展示如何使用 PipelinePromptTemplate
结合 ChatOpenAI
处理人工智能主题的问答,通过流水线组合上下文、问题和 JSON 格式指令,生成结构化输出。示例灵感来源于复杂提示组合的需求,扩展为带解析器的场景。
准备环境:
- 获取 OpenAI API 密钥:OpenAI Platform。
- 设置环境变量:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai
代码:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate, PipelinePromptTemplate
from langchain_core.output_parsers import JsonOutputParser
# 定义子模板
context_template = PromptTemplate.from_template(
"背景信息:{context}"
)
question_template = PromptTemplate.from_template(
"用户问题:{question}"
)
format_template = PromptTemplate.from_template(
"输出格式:\n```json\n{format_instructions}\n```"
)
# 最终模板
final_template = PromptTemplate.from_template(
"{context}\n{question}\n{format_instructions}"
)
# 初始化 PipelinePromptTemplate
pipeline_prompt = PipelinePromptTemplate(
final_prompt=final_template,
pipeline_prompts=[
("context", context_template),
("question", question_template),
("format_instructions", format_template)
]
)
# 初始化 ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)
# 定义 JSON 解析器
parser = JsonOutputParser()
# 创建问答链
chain = pipeline_prompt | llm | parser
# 测试 PipelinePromptTemplate
print("测试 PipelinePromptTemplate:")
try:
result = chain.invoke({
"context": "人工智能(AI)是模拟人类智能的技术。",
"question": "人工智能的定义是什么?",
"format_instructions": '{"question": "string", "answer": "string"}'
})
print("解析结果:")
print(f"问题: {result['question']}")
print(f"回答: {result['answer']}")
except Exception as e:
print(f"错误: {e}")
# 测试提示格式化
print("\n测试提示格式化:")
formatted_prompt = pipeline_prompt.format(
context="人工智能简介",
question="人工智能有哪些应用?",
format_instructions='{"question": "string", "answer": "string"}'
)
print("格式化提示:")
print(formatted_prompt)
输出示例(实际输出取决于模型和 API 响应):
测试 PipelinePromptTemplate:
解析结果:
问题: 人工智能的定义是什么?
回答: 人工智能(AI)是计算机科学的一个分支,旨在创建能够模拟人类智能的系统,如学习、推理和问题解决。
测试提示格式化:
格式化提示:
背景信息:人工智能简介
用户问题:人工智能有哪些应用?
输出格式:
```json
{"question": "string", "answer": "string"}
代码说明
- 子模板:
context_template
:定义背景信息。question_template
:定义用户问题。format_template
:定义 JSON 格式指令。
- 最终模板:
final_template
:组合子模板的占位符{context}
、{question}
和{format_instructions}
。
- PipelinePromptTemplate:
- 初始化
pipeline_prompt
,映射子模板到最终模板的变量。
- 初始化
- LLM 初始化:
- 使用
ChatOpenAI
调用gpt-3.5-turbo
,设置temperature=0.7
。
- 使用
- 解析器:
- 使用
JsonOutputParser
解析模型输出为字典。
- 使用
- 问答链:
- LCEL 链组合
pipeline_prompt
、llm
和parser
,生成结构化输出。
- LCEL 链组合
- 测试:
- 测试链调用,输出解析结果。
- 测试
format
方法,展示格式化提示。
- 错误处理:
- 使用
try-except
捕获 API 或解析错误。
- 使用
运行要求:
- 有效的 OpenAI API 密钥:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai
- 网络连接:访问
https://api.openai.com
。
注意事项
- API 密钥:
- 确保
OPENAI_API_KEY
已设置:echo $OPENAI_API_KEY
- 或在代码中设置:
llm = ChatOpenAI(api_key="your-api-key")
- 确保
- 变量依赖:
- 确保子模板的输入变量在
final_prompt
中有对应:pipeline_prompt.validate_variable_mapping()
- 检查变量:
print(pipeline_prompt.input_variables) # ['context', 'question', 'format_instructions']
- 确保子模板的输入变量在
- 提示设计:
- 子模板应简洁,避免重复逻辑:
context_template = PromptTemplate.from_template("背景:{context}")
- 最终模板应清晰组合子模板:
final_template = PromptTemplate.from_template("{context}\n{question}")
- 子模板应简洁,避免重复逻辑:
- 模型选择:
- 使用支持结构化输出的模型(如
gpt-3.5-turbo
):llm = ChatOpenAI(model="gpt-3.5-turbo")
- 开源模型(如
ChatOllama
)可能需要优化:from langchain_ollama import ChatOllama llm = ChatOllama(model="llama3")
- 使用支持结构化输出的模型(如
- 性能优化:
- 缓存:启用
InMemoryCache
:from langchain_core.caches import InMemoryCache llm.cache = InMemoryCache()
- 异步调用:使用
ainvoke
:result = await chain.ainvoke(inputs)
- 限制 token:设置
max_tokens
:llm = ChatOpenAI(max_tokens=512)
- 缓存:启用
- 错误调试:
- 变量缺失:
- 检查输入:
print(inputs)
- 验证模板:
print(pipeline_prompt.input_variables)
- 检查输入:
- API 错误:
- 检查密钥:
print(os.environ.get("OPENAI_API_KEY"))
- 增加超时:
llm = ChatOpenAI(timeout=30)
- 检查密钥:
- 格式错误:
- 检查输出:
print(response.content)
- 结合
RetryWithErrorOutputParser
:from langchain.output_parsers import RetryWithErrorOutputParser retry_parser = RetryWithErrorOutputParser(parser=JsonOutputParser(), llm=llm)
- 检查输出:
- 变量缺失:
常见问题
Q1:如何处理复杂子模板?
A:定义多级子模板,确保变量依赖清晰:
sub_template1 = PromptTemplate.from_template("子上下文:{sub_context}")
sub_template2 = PromptTemplate.from_template("主上下文:{sub_context_output}")
pipeline_prompt = PipelinePromptTemplate(
final_prompt=final_template,
pipeline_prompts=[("sub_context_output", sub_template1), ("context", sub_template2)]
)
Q2:如何支持异步调用?
A:使用 ainvoke
:
import asyncio
async def run():
result = await chain.ainvoke(inputs)
print(result)
asyncio.run(run())
Q3:如何与 RAG 结合?
A:添加检索文档子模板:
retrieved_template = PromptTemplate.from_template("检索文档:{docs}")
pipeline_prompt = PipelinePromptTemplate(
final_prompt=final_template,
pipeline_prompts=[("docs", retrieved_template), ("question", question_template)]
)
Q4:如何支持开源模型?
A:使用 ChatOllama
:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3")
chain = pipeline_prompt | llm | parser
总结
langchain_core.prompts.PipelinePromptTemplate
是 LangChain 中构建复杂提示的核心工具,核心功能包括:
- 定义:组合多个子提示模板,管理变量依赖。
- 初始化:配置
final_prompt
和pipeline_prompts
。 - 常用方法:
format
(字符串)、format_prompt
(PromptValue)、ainvoke
(异步)。 - 适用场景:复杂问答、RAG、多部分提示。