PipelinePromptTemplate的替代品
·
一、背景
Pipeline 设计初衷
设计目的:为了模块化重用提示词零件
-
把大提示词拆成小零件
-
零件可以在不同提示词中复用
-
自动组合零件成完整提示词
-
# 原始思想:像搭积木一样组合提示词 PipelinePromptTemplate( final_prompt=最终模板, pipeline_prompts=[("零件1", 零件1), ("零件2", 零件2)] # 可重用的零件 )
为什么被废弃
核心原因:过度设计,手写更简单
-
增加了不必要的复杂性
-
手写组合代码更直观易懂
-
维护成本高,调试困难
-
不符合 Python 的"简单优于复杂"哲学
二、两种替代方案
根据官方文档有两种替代方案
PipelinePromptTemplate — 🦜🔗 LangChain documentation
方案1:手写方式(便于理解)
from functools import partial
from langchain_core.prompts import ChatPromptTemplate
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.example_selectors.ngram_overlap import NGramOverlapExampleSelector
from langchain_community.vectorstores import Chroma,FAISS
from langchain.prompts import PromptTemplate,PipelinePromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate,AIMessagePromptTemplate
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain_openai import ChatOpenAI,OpenAIEmbeddings
import os
chat = ChatOpenAI(
model="Qwen/Qwen2.5-72B-Instruct",
temperature=0.3,
openai_api_key=os.getenv('OPENAI_API_KEY'),
openai_api_base="https://api.siliconflow.cn/v1"
)
# 1. 定义各个零件
hello_prompt = PromptTemplate.from_template('hello\n')
question_prompt = PromptTemplate.from_template('给我讲个{adj}的关于{content}的笑话\n')
partial_question = question_prompt.partial(adj='冷', content='特朗普') # 预设参数
bye_prompt = PromptTemplate.from_template('bye')
# 2. 定义最终模板结构
final_template = '''{hello}{question}{bye}'''
final_prompt = PromptTemplate.from_template(final_template)
# 3. 手动组合各个零件
finalstr = final_prompt.format(
hello=hello_prompt.format(), # 渲染hello零件
question=partial_question.format(), # 渲染question零件(已预设参数)
bye=bye_prompt.format() # 渲染bye零件
)
# 4. 发送给模型
result = chat.invoke(finalstr)
print(result.content)
运行结果
hello
给我讲个冷的关于特朗普的笑话
bye
你好!这里有一个关于特朗普的冷笑话:
为什么特朗普的书永远不会在图书馆的“小说”区出现?
因为即使是图书馆也认为特朗普的故事太过离谱,只能放在“非小说”区。
希望这个笑话能让你会心一笑。再见!
进程已结束,退出代码为 0
方案2:官方推荐的循环方式
from functools import partial
from langchain_core.prompts import ChatPromptTemplate
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.example_selectors.ngram_overlap import NGramOverlapExampleSelector
from langchain_community.vectorstores import Chroma,FAISS
from langchain.prompts import PromptTemplate,PipelinePromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate,AIMessagePromptTemplate
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain_openai import ChatOpenAI,OpenAIEmbeddings
import os
chat = ChatOpenAI(
model="Qwen/Qwen2.5-72B-Instruct",
temperature=0.3,
openai_api_key=os.getenv('OPENAI_API_KEY'),
openai_api_base="https://api.siliconflow.cn/v1"
)
# 1. 定义零件字典
prompts = {
"hello": PromptTemplate.from_template('hello\n'),
"question": PromptTemplate.from_template('给我讲个{adj}的关于{content}的笑话\n').partial(adj='冷', content='特朗普'),
"bye": PromptTemplate.from_template('bye')
}
# 2. 逐步构建输入:按顺序渲染每个零件,结果存入字典供后续使用
input_dict = {}
for key, prompt in prompts.items():
# 对每个提示词零件调用invoke()执行渲染,to_string()转换为纯文本
input_dict[key] = prompt.invoke(input_dict).to_string()
# 第一次循环: input_dict = {"hello": "hello\n"}
# 第二次循环: input_dict = {"hello": "hello\n", "question": "给我讲个冷的关于特朗普的笑话\n"}
# 第三次循环: input_dict = {"hello": "hello\n", "question": "...", "bye": "bye"}
# 3. 最终组合:用最终模板格式化所有零件
final_prompt = PromptTemplate.from_template("{hello}{question}{bye}")
print(final_prompt.format(**input_dict))
chain = final_prompt | chat # 创建执行管道:先渲染模板,再调用聊天模型
# 4. 执行管道
result = chain.invoke(input_dict) # input_dict包含所有已渲染的零件文本
print(result.content)
运行结果
hello
给我讲个冷的关于特朗普的笑话
bye
你好!这里有一个关于特朗普的冷笑话:
为什么特朗普的书永远不会沉到水底?
因为它们总是被浮夸的封面(泡沫)所拯救。
再见!希望你今天过得愉快!
进程已结束,退出代码为 0
因为temperature设为了0.3所以两次输出的内容有一定随机性,结果不同
但构建的提示词是一样的
三、总结
| 方面 | PipelinePromptTemplate | 替代方案 |
|---|---|---|
| 思想 | 模块化重用零件 | ✅ 保留 |
| 复杂度 | 高,需要学习特定类 | ✅ 低,用基础语法 |
| 灵活性 | 受限 | ✅ 高,可自定义逻辑 |
| 调试 | 困难 | ✅ 容易 |
结论:Pipeline 思想很好,但实现方式从"专用类"回归到"基础语法",体现了简单优于复杂的设计原则!
更多推荐


所有评论(0)