Prompt Template提示词模板

发布时间:2026/7/20 17:57:23
Prompt Template提示词模板 Prompt是与LLM交互的输入用于定义任务目标、背景和输出要求其设计质量直接影响模型效果。在实际业务中输入具有动态性固定Prompt难以复用且适配性有限。为此LangChain引入Prompt Template将静态字符串抽象为可复用模板并通过变量填充在运行时生成Prompt从而提升灵活性与可维护性。有关Prompt的更多内容详见提示词工程指北。PromptTemplate基础文本模板PromptTemplate是最基础的模板类型适用于生成纯文本形式的Prompt其核心能力是通过变量替换实现动态内容生成。PromptTemplate的具体使用见LangChain PromptTemplate 全解析。from langchain_core.prompts import PromptTemplateprompt PromptTemplate.from_template(“请生成一段话{task}”)prompt_text prompt.invoke({“task”: “介绍良好阅读习惯的重要性”}).textresponse chat_model.invoke(prompt_text)print(response.content)这种方式适用于结构简单的单轮任务。但随着任务复杂度提升仅使用PromptTemplate会逐渐暴露出结构不清晰、可控性不足的问题。ChatPromptTemplate对话模板在对话模型场景中直接拼接文本Prompt往往不够清晰因此LangChain提供了ChatPromptTemplate用于按角色组织Prompt结构。from langchain_core.prompts import ChatPromptTemplatechat_prompt ChatPromptTemplate.from_messages([(“system”, “你是一名文言文写作助手输出一段自然流畅的文字”),(“human”, “请完成任务{task}”)])messages chat_prompt.invoke({“task”: “介绍良好阅读习惯的重要性”})response chat_model.invoke(messages)print(response.content)通过显式区分system和human角色可以让Prompt结构更加清晰同时也更贴合对话模型的训练方式。不过当Prompt进一步复杂化时这种方式仍然存在复用困难的问题。https://superml.dev/langchain-prompt-templateMessagePromptTemplate消息模板组件为了支持更复杂的Prompt设计LangChain提供了MessagePromptTemplate将Prompt拆分为更细粒度的组件。from langchain_core.prompts import (ChatPromptTemplate,SystemMessagePromptTemplate,HumanMessagePromptTemplate)chat_prompt ChatPromptTemplate.from_messages([SystemMessagePromptTemplate.from_template(“你是一个擅长写说明性文字的助手输出必须为一段完整的表述”),HumanMessagePromptTemplate.from_template(“请生成一段话{task}”)])messages chat_prompt.invoke({“task”: “介绍良好阅读习惯的重要性”})response chat_model.invoke(messages)print(response.content)在这种方式下不同角色的Prompt可以独立定义并按需组合适用于复杂系统和团队协作开发。但即使结构清晰模型在输出格式上的稳定性仍难以完全保证。FewShotPromptTemplate少样本提示当需要模型稳定输出特定格式或风格时仅依赖Prompt往往不够。FewShotPromptTemplate通过提供示例引导模型模仿既有格式以示例替代规则使输出更加稳定和可预测。关于相关概念及更详细的使用说明可参考Langchain学习入门。简单示例如下from langchain_core.prompts import PromptTemplate, FewShotPromptTemplateexample_template PromptTemplate.from_template(“单词{word}, 英文翻译{translation}”)examples_data [{“word”: “苹果”, “translation”: “apple”},{“word”: “快乐”, “translation”: “happy”}]few_shot_template FewShotPromptTemplate(example_promptexample_template,examplesexamples_data,prefix“请给出一个单词及其英文翻译以下是示例”,suffix“单词{input_word}英文翻译”,input_variables[“input_word”])prompt_text few_shot_template.invoke({“input_word”: “计算机”}).to_string()print(prompt_text)response chat_model.invoke(prompt_text)print(response.content)在对话场景中也可以使用基于消息结构的FewShotChatMessagePromptTemplatefrom langchain_core.prompts import (ChatPromptTemplate,FewShotChatMessagePromptTemplate,)examples [{“input”: “你好”, “output”: “Hello”},{“input”: “谢谢你的帮助”, “output”: “Thank you for your help”},]example_prompt ChatPromptTemplate.from_messages([(“human”, “{input}”),(“ai”, “{output}”),])few_shot_prompt FewShotChatMessagePromptTemplate(example_promptexample_prompt,examplesexamples,)final_prompt ChatPromptTemplate.from_messages([(“system”,“你是一个翻译助手将中文翻译成英文。只输出翻译结果不要提供额外解释。”),few_shot_prompt,(“human”, “{input}”),])chain final_prompt | chat_modelprint(chain.invoke({“input”: “今天天气很好”}).content)print(chain.invoke({“input”: “请稍等一下”}).content)partial方法Prompt部分填充通过模板实现动态生成Prompt后常会遇到固定变量反复传递的问题如目标语言、角色设定或业务背景手动处理既繁琐又易出错。此时可用partial方法预先填入这些固定内容相当于提前构建好一部分Prompt。这样便可通过一个通用模板衍生多个可直接使用的版本简单又高效。from langchain_core.prompts import ChatPromptTemplatetemplate ChatPromptTemplate.from_messages([(“system”, “将以下文本翻译为{target_lang}保留原意”),(“human”, “{text}”)])zh_translator template.partial(target_lang“中文”)en_translator template.partial(target_lang“英文”)result_zh zh_translator.invoke({“text”: “Hello world”})result_en en_translator.invoke({“text”: “你好世界”})print(result_zh.to_messages())print(result_en.to_messages())2.4 Output Parser输出解析器LLM默认返回的是纯字符串而实际开发中为了进行后续处理通常需要结构化数据。为此必须先对模型的输出结果进行解析借助解析器将文本转换为特定的数据结构。在LangChain中这类解析器被定义为Output Parser并提供了多种实现以适配不同的输出格式。解析器名称 作用StrOutputParser 将模型输出直接解析为字符串JsonOutputParser 将模型输出解析为JSON格式的结构化数据CommaSeparatedListOutputParser 将逗号分隔的文本解析为Python列表XMLOutputParser 将模型输出解析为XML格式的结构化数据关于Output Parser的更多介绍见How to Master Output Parsers下面通过一个完整示例演示不同解析器的使用方式from langchain_core.prompts import PromptTemplatefrom langchain_core.output_parsers import (StrOutputParser,JsonOutputParser,CommaSeparatedListOutputParser,XMLOutputParser)1. 字符串解析器StrOutputParser最基础用法str_prompt PromptTemplate.from_template(“用一句话介绍什么是{name}”)str_chain str_prompt | chat_model | StrOutputParser()print(“StrOutput:”, str_chain.invoke({“name”: “LLM”}))2. JSON解析器JsonOutputParser结构化输出json_parser JsonOutputParser()json_prompt PromptTemplate(template“用一句话介绍什么是{name}。\n{format_instructions}”,input_variables[“name”],partial_variables{“format_instructions”: json_parser.get_format_instructions()})json_chain json_prompt | chat_model | json_parserprint(“JSON Output:”, json_chain.invoke({“name”: “LLM”}))3. 列表解析器CommaSeparatedListOutputParser列表结构list_parser CommaSeparatedListOutputParser()list_prompt PromptTemplate(template“列出{name}的3个特点。\n{format_instructions}”,input_variables[“name”],partial_variables{“format_instructions”: list_parser.get_format_instructions()})list_chain list_prompt | chat_model | list_parserprint(“List Output:”, list_chain.invoke({“name”: “LLM”}))4. XML解析器XMLOutputParser层级结构xml_parser XMLOutputParser()xml_prompt PromptTemplate(template“用XML格式输出什么是{name}。\n{format_instructions}”,input_variables[“name”],partial_variables{“format_instructions”: xml_parser.get_format_instructions()})xml_chain xml_prompt | chat_model | xml_parserprint(“XML Output:”, xml_chain.invoke({“name”: “LLM”}))2.5 Runnable的调用方式Runnable是LangChain中的核心执行抽象代表任何可接收输入并产生输出的可执行单元。可以把它理解为一个标准化的接口无论LLM、提示词模板、输出解析器、检索器、工具还是LangGraph定义的工作流只要遵循这一接口规范就都成为了Runnable。这种统一让不同组件可以像积木一样自由拼接和编排从而构建复杂的应用。在LangChain 1.x中这一抽象被进一步统一Prompt、Model、Parser、Retriever以及Tool等核心组件均被明确定义为Runnable。由于遵循相同的输入输出规范一个组件的输出可以直接成为下一个组件的输入实现模块间的无缝衔接与灵活组合。更详细的说明可阅读深入解析Runnable接口的统一、组合与流式处理。统一的执行抽象建立之后核心问题便转向调用方式。Runnable为此提供了一组标准方法以覆盖不同的使用场景方法 说明invoke 同步单次调用stream 流式输出batch 批量处理ainvoke 异步单次调用astream 异步流式输出abatch 异步批量处理下面通过简单示例来介绍这些调用方式的实际用法import asynciodef run_invoke():response chat_model.invoke(“你好”)print(“ invoke ”)print(response.content)print(response.response_metadata)def run_stream():print(“\n stream ”)for chunk in chat_model.stream(“写一篇500字文章”):print(chunk.content, end“”, flushTrue)def run_batch():print(“\n batch ”)responses chat_model.batch([“翻译hello”,“翻译world”,“翻译apple”])for r in responses:print(r.content)async def run_async():print(“\n ainvoke ”)response await chat_model.ainvoke(“异步调用”)print(response.content)print(\n astream ) async for chunk in chat_model.astream(讲一个简短故事): print(chunk.content, end, flushTrue) print() print(\n abatch ) responses await chat_model.abatch([ 异步翻译cat, 异步翻译dog ]) for r in responses: print(r.content)ifname “main”:run_invoke()run_stream()run_batch()asyncio.run(run_async())2.6 Bind方法bind方法解决了一个常见需求同一个模型在不同任务中往往需要不同的运行参数。例如做数学计算时希望输出稳定写文案时又希望富有变化。如果每次都重新实例化模型来切换参数既繁琐又低效。bind的作用就是在一个模型实例上临时附加一组运行参数比如temperature、max_tokens或stop等然后返回一个绑定了这些参数的新对象。该方法不会修改原始模型而是在其基础上生成一个绑定了特定参数的副本从而允许在不重新实例化模型的前提下灵活切换调用行为。这一机制常用于根据任务需求动态调整模型策略例如精确策略绑定temperature0.0, max_tokens200提升输出稳定性与确定性适用于信息抽取、数学计算等对准确性要求较高的任务创意策略绑定temperature0.9, max_tokens1000增强随机性与表达空间适用于写作、对话生成等需要开放创造力的任务。示例bind 生成不同策略的实例原模型不受影响precise_strategy chat_model.bind(temperature0.3, max_tokens200)creative_strategy chat_model.bind(temperature0.9, max_tokens1000)result_precise precise_strategy.invoke(“12*9?”)result_creative creative_strategy.invoke(“写一首关于夏天的诗”)print(“ 精确策略 ”)print(result_precise.content)print(“\n 创意策略 ”)print(result_creative.content)3 核心组件3.1 Chains与LCEL在LangChain中Chain可以理解为一条处理任务的流水线。数据会按照预先设定的步骤依次经过提示词模板、LLM和输出解析器等组件处理最终输出结果。关于Chain的详细介绍可参考LangChain最详细教程之Chains。LCELLangChain Expression Language用于以声明式方式描述这一结构将各组件组合为可执行表达式而不改变底层执行逻辑。最常见的写法是使用管道符|chain prompt | chat_model | parser该表达式自左向右执行prompt生成输入传递至chat_model进行推理再由parser完成结构化处理对应完整的Chain流程。可以理解为Chain定义执行结构LCEL负责表达结构|用于连接各Runnable组件并传递数据流。LangChain中Chains与LCEL的关系可以参考深度拆解LangChain Chains与LCEL。在实现层面参与组合的组件都需要实现Runnable接口。多个组件通过|连接后新的Chain本身仍然是一个Runnable因此既可以继续与其他组件组合也可以通过invoke、stream和batch等方式执行任务。示例from langchain_openai import ChatOpenAIfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.documents import Documentfrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.runnables import RunnableLambdaMath Chainmath_prompt ChatPromptTemplate.from_template(“请计算下面数学问题{input}”)math_chain (math_prompt| chat_model| StrOutputParser())print(math_chain.invoke({“input”: “25乘以8等于多少”}))MultiPrompt / Router Chaintranslate_prompt ChatPromptTemplate.from_template(“请翻译下面内容\n{input}”)summary_prompt ChatPromptTemplate.from_template(“请总结下面内容\n{input}”)translate_chain (translate_prompt| chat_model| StrOutputParser())summary_chain (summary_prompt| chat_model| StrOutputParser())def router(x):text x[“input”]if “翻译” in text or “translate” in text.lower():return translate_chainreturn summary_chainrouter_chain RunnableLambda(router)print(router_chain.invoke({“input”: “Technology makes life better.”}))StuffDocumentsChainprompt ChatPromptTemplate.from_template(“请总结下面内容\n{context}”)docs [Document(page_content“LangChain是一个LLM开发框架。”),Document(page_content“它支持Prompt、Chain和Agent。”)]context “\n”.join([doc.page_content for doc in docs])stuff_chain (prompt| chat_model| StrOutputParser())print(stuff_chain.invoke({“context”: context}))