掘金 人工智能 前天 17:03
LangChain 设计原理分析⁵ | PromptTemplate 模板系统与上下文注入机制
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入剖析了 LangChain 的 Prompt 模板系统,详细介绍了 PromptTemplate 和 FewShotPromptTemplate 的核心功能,包括变量绑定、格式化、示例注入以及动态样例选择器的应用。文章还探讨了如何通过封装类实现自定义格式逻辑,以及 PromptTemplate 作为 Runnable 模块与其他 LangChain 组件(如 LLM、解析器、输入转换器)的灵活组合方式。最终强调了 PromptTemplate 在保证提示一致性、提高管理效率和构建复杂 AI 应用中的重要价值。

⭐ LangChain 的 PromptTemplate 是一个标准化模板系统,用于生成语言模型输入文本,核心功能是通过占位变量构造提示内容,将动态上下文注入,并实现不同输入场景下的统一模板管理与复用。其基本用法是“模板 + 输入变量 = 生成文本”。

⭐ FewShotPromptTemplate 允许在正式提示前注入一组“训练样例”,以提高模型理解和生成准确性,适用于文本分类、函数映射、意图识别等任务。其工作机制是将样例模板渲染后与用户输入部分(suffix)拼接而成。

⭐ LangChain 支持通过 SemanticSimilarityExampleSelector 等动态样例选择器,根据输入内容检索最相关的示例,从而实现基于输入动态选择最相似示例,大大提升上下文精度,尤其适用于需要精细化上下文的场景。

⭐ 尽管新版本 PromptTemplate 不再直接支持 format_func,但可以通过封装类实现自定义格式控制逻辑,例如封装对话历史、实现动态模板切换,为 Prompt 的生成增加更复杂的行为和灵活性。

⭐ PromptTemplate 本身是一个 Runnable 模块,可与 LLM、解析器、输入转换器等其他 LangChain 组件灵活组合,构建端到端的 AI 应用链路。这种“一切皆可组合”的设计哲学是 LangChain 的核心优势之一。

本文深入讲解 LangChain 中的 Prompt 模板系统,探索变量绑定、FewShot 示例构建、格式化策略等关键能力,帮助你构建灵活可控的提示内容生成逻辑。


一、PromptTemplate 是什么?

PromptTemplate 是 LangChain 中用于生成语言模型 输入文本 的标准化模板系统。

它的主要作用是:


二、基础使用:变量绑定与格式化

PromptTemplate 的核心能力是“模板 + 输入变量 = 生成文本”。

from langchain_core.prompts import PromptTemplateprompt = PromptTemplate.from_template("你是谁?我是{identity}。")print(prompt.format(identity="LangChain"))# 输出:你是谁?我是LangChain。

也可使用 input_variablestemplate 分开定义:

from langchain_core.prompts import PromptTemplateprompt = PromptTemplate(    input_variables=["agent", "topic"],    template="请 {agent} 用一句话总结关于 {topic} 的内容。")print(prompt.format(agent="LLM", topic="LangChain"))# 输出:请 LLM 用一句话总结关于 LangChain 的内容。

三、进阶功能:FewShotPromptTemplate(示例注入式提示构造)

FewShotPromptTemplate 是 LangChain 中用于构造 带有示例上下文(Few-Shot Examples) 的提示模板系统。它的作用是:在正式提示之前,插入一组“训练样例”,让模型更好地理解输入模式,提高生成准确性,常用于分类、问答、意图识别等任务。


✅ 工作机制

它的生成逻辑等价于三段拼接:

[样例1模板渲染]  [样例2模板渲染]  ...  +  [Suffix(真正的Prompt部分)]

从而构造出如下结构:

输入:狗输出:动物输入:苹果输出:水果输入:西瓜输出:

✅ 示例代码解析

from langchain.prompts import FewShotPromptTemplate, PromptTemplate# 定义训练样例examples = [    {"input": "狗", "output": "动物"},    {"input": "苹果", "output": "水果"},]# 定义样例模板:每个样例如何格式化为字符串example_prompt = PromptTemplate.from_template("输入:{input}\n输出:{output}")# 构造 FewShotPromptTemplateprompt = FewShotPromptTemplate(    examples=examples,  # 样例数据列表    example_prompt=example_prompt,  # 样例模板    suffix="输入:{input}\n输出:",  # 正式 Prompt(将在样例之后接上)    input_variables=["input"]  # 最终用户提供的变量(传给 suffix))# 渲染 Promptprint(prompt.format(input="西瓜"))

🧠 核心概念解析

参数名称含义说明
examples提供的示例数据,通常是结构化字典列表
example_prompt每个样例的渲染模板(可嵌套 PromptTemplate)
suffix实际用户输入部分的 Prompt
prefix(可选)在所有样例之前插入前缀
example_separator样例之间的分隔符,默认为两个换行

📦 FewShotPromptTemplate 的使用场景


🧩 进阶用法:动态样例选择器(Selector)

除了手动提供 examples 外,你还可以动态选择最相关的样例:

from langchain_community.embeddings import HuggingFaceEmbeddingsfrom langchain_community.vectorstores import FAISSfrom langchain.prompts.example_selector import SemanticSimilarityExampleSelectorfrom langchain.prompts import FewShotPromptTemplate, PromptTemplate# 1. 定义本地 embedding 模型embedding_model = HuggingFaceEmbeddings(model_name="BAAI/bge-large-zh-v1.5")# 2. 定义示例examples = [    {"input": "狗", "output": "汪汪叫"},    {"input": "苹果", "output": "水果"},    {"input": "猫", "output": "喵喵叫"},    {"input": "钢琴", "output": "乐器"},]# 3. 构建向量相似度选择器 selectorselector = SemanticSimilarityExampleSelector.from_examples(    examples=examples,    embeddings=embedding_model,    vectorstore_cls=FAISS,    k=2)# 4. 构建 Prompt 模板example_prompt = PromptTemplate.from_template("输入:{input}\n输出:{output}")prompt = FewShotPromptTemplate(    example_selector=selector,    example_prompt=example_prompt,    suffix="输入:{input}\n输出:",    input_variables=["input"])# 5. 格式化并查看实际 Promptprint(prompt.format(input="小提琴"))

这可以实现 基于输入动态检索最相似的示例,大大提升上下文精度。


四、进阶控制:自定义格式逻辑(替代 format_func

在 LangChain 新版本中,PromptTemplate 已不再支持传入 format_func 参数。但我们依然可以通过封装、继承等方式实现自定义的 Prompt 格式控制逻辑,特别适用于构建动态 Prompt、多语言切换、对话历史注入等复杂场景。


✅ 1. 封装类实现“自定义格式器”

你可以为 PromptTemplate 写一个包装器,对格式化结果进行二次加工:

from langchain.prompts import PromptTemplateclass UppercasePrompt:    def __init__(self, template: PromptTemplate):        self.template = template    def format(self, **kwargs) -> str:        base = self.template.format(**kwargs)        return base.upper()# 示例用法template = PromptTemplate.from_template("你好,{name}!")prompt = UppercasePrompt(template)print(prompt.format(name="tom"))# 输出:你好,TOM!

✅ 2. 拼接上下文:封装对话历史逻辑

适用于多轮对话中,把历史问答作为 Prompt 的一部分注入:

from langchain_core.prompts import PromptTemplateclass ChatHistoryPrompt:    def __init__(self, prompt_template: PromptTemplate):        self.prompt = prompt_template    def format(self, user_input: str, history: list[dict]) -> str:        history_text = "\n".join(f"用户:{h['q']}\n助手:{h['a']}" for h in history)        full_input = f"{history_text}\n用户:{user_input}\n助手:"        return self.prompt.format(input=full_input)# 用法prompt_template = PromptTemplate.from_template("{input}")history_prompt = ChatHistoryPrompt(prompt_template)chat_history = [    {"q": "今天天气好吗?", "a": "很晴朗。"},    {"q": "那我适合出门吗?", "a": "当然适合。"}]print(history_prompt.format(user_input="那我还要带伞吗?", history=chat_history))

📤 输出:


✅ 3. 动态模板切换(根据输入结构)

适用于根据不同任务切换 Prompt 模板结构:

from langchain_core.prompts import PromptTemplateclass TaskPrompt:    def __init__(self):        self.qa = PromptTemplate.from_template("问:{question}\n答:")        self.summary = PromptTemplate.from_template("请总结以下内容:{text}")    def format(self, task_type: str, **kwargs) -> str:        if task_type == "qa":            return self.qa.format(**kwargs)        elif task_type == "summary":            return self.summary.format(**kwargs)        else:            raise ValueError("未知的任务类型")# 使用示例prompt = TaskPrompt()print(prompt.format(task_type="qa", question="LangChain 是什么?"))# 输出:问:LangChain 是什么?print(prompt.format(task_type="summary",                    text="PromptTemplate系统本质上是一个可编程的模板引擎,"                         "允许用户在模板注入逻辑中引入复杂行为(如动态示例切换、多语言支持、上下文拼接等)。"))# 输出:请总结以下内容:PromptTemplate系统本质上是一个可编程的模板引擎,允许用户在模板注入逻辑中引入复杂行为(如动态示例切换、多语言支持、上下文拼接等)。

五、与其他模块组合:PromptTemplate 本身是 Runnable

PromptTemplate 在 LangChain 中不仅仅是一个字符串格式化工具,它本身就是一个可执行模块,继承自 RunnableSerializable,因此你可以像拼积木一样将其与模型、解析器、分支、回退等模块灵活组合。

这也是 LangChain 的核心哲学之一:一切都是 Runnable,一切皆可组合。


✅ 基础用法:PromptTemplate 与 LLM 拼接

import osfrom langchain.prompts import PromptTemplatefrom langchain_openai import ChatOpenAIprompt = PromptTemplate.from_template("请解释一下:{input}")# 或者使用环境变量llm = ChatOpenAI(    temperature=0.7,    model="glm-4.5",    openai_api_key=os.getenv("ZAI_API_KEY"),    openai_api_base="https://open.bigmodel.cn/api/paas/v4/")# 组合两个 Runnable,构成一个完整链路chain = prompt | llmprint(chain.invoke({"input": "月亮"}))

📌 说明:

    invoke({"input": ...}) 会自动传入模板所需字段输出为 ChatMessage 对象,通常为 AIMessage(content=...)


✅ 输入转换:配合 RunnableLambda 进行字段重构

我们可以通过 RunnableLambda 对输入数据结构进行预处理,例如将外部问答表单结构转换为 Prompt 所需的 {input} 字段:

from langchain_core.runnables import RunnableLambdacontext_injector = RunnableLambda(lambda d: {"input": d["question"]})chain = context_injector | prompt | llm# 原始数据不符合 Prompt 模板格式input_data = {"question": "什么是日照金山?"}print(chain.invoke(input_data))

✅ 常用于从工具接收参数、网页表单输入、数据库字段等“非标准格式”转为 Prompt 所需格式。


✅ 中间加工:组合 Parser、后处理、工具调用等模块

你可以在 Prompt → LLM 之间插入处理模块,例如代码高亮、参数注解、消息格式转换等:

from langchain_core.runnables import RunnableLambdapost_processor = RunnableLambda(lambda msg: msg.content.upper())chain = prompt | llm | post_processorprint(chain.invoke({"input": "用10个英文单词概括一下介绍一下LLM"}))


✅ 与其他模块协同:Retry / Fallback / Tagging / LangSmith

所有 Runnable 都支持:

你可以构建一个“具备鲁棒性与可观测性”的 Prompt 执行链:

robust_chain = (prompt | llm).with_config(tags=["分类任务"])print(robust_chain.invoke({"input": "苹果"}))

✅ 并行执行多个 Prompt:构造多路提示结构(如对比测试)

from langchain_core.runnables import RunnableParallelprompt1 = PromptTemplate.from_template("请用10到20个中文汉字解释:{input}")prompt2 = PromptTemplate.from_template("请用10到20个英文单词解释:{input}")multi_chain = RunnableParallel({    "中文回答": prompt1 | llm,    "英文回答": prompt2 | llm})print(multi_chain.invoke({"input": "黑洞"}))

六、总结与工程价值

PromptTemplate 是提示工程的基础设施,具备以下价值:

在构建复杂的 Agent、RAG 或多轮对话系统时,PromptTemplate 是最基本的构建砖块。


接下来我们将进入 LangChain 的 Memory 设计体系,理解如何构建支持上下文记忆的链,支持多轮会话与历史引用等高级功能。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangChain PromptTemplate 提示工程 AI模型 语言模型
相关文章