langchain中的提示词模板PromptTemplate、ChatPromptTemplate、格式化适配器、PromptValue

张开发
2026/6/9 7:24:16 15 分钟阅读
langchain中的提示词模板PromptTemplate、ChatPromptTemplate、格式化适配器、PromptValue
文章目录PromptTemplatePromptTemplate示例ChatPromptTemplateChatPromptTemplate示例FewShotPromptTemplateFewShotPromptTemplate示例ChatPromptTemplate和ChatPromptTemplate的区别baseMessage属于promptTemplate吗?PromptValuetemplate、model、value之间是什么关系?自定义格式化转换器自动调用和手动调用的区别?有人问了为什么一个简单的提示词还需要弄个模板呢?其实不然通过不通的模板不但方便定义而且有利于大模型准确的理解。注这篇笔记说的都是提示词相关的内容所以有时prompt会省略掉例如说template就表示promptTemplate。运行机制1、定义模板2、传入数据并格式化3、输出标准化(重)在 LangChain 等框架中生成的不仅仅是字符串而是一个PromptValue对象。作用这个对象是一个“变形金刚”。如果传给普通模型LLM它调用 .to_string() 变成纯文本。如果传给聊天模型ChatModel它调用 .to_messages() 变成 [HumanMessage(…)] 列表。常见的提示词模板有哪些?1、PromptTemplate2、ChatPromptTemplate3、FewShotPromptTemplate如下表模板类型核心作用适用场景PromptTemplate通用字符串格式化单次任务、简单文本生成ChatPromptTemplate结构化对话消息聊天机器人、多轮对话、AgentFewShotPromptTemplate注入示例数据需要给模型看例子才能做对的复杂任务PromptTemplatePromptTemplate示例fromlangchain.promptsimportPromptTemplate# 注意看模板的结尾冒号和换行符是关键# 我们人为制造了一个“填空题”的语境template_str 你是一个专业的翻译助手。 请将以下中文翻译成英文。 中文{input_text} 英文# --- 关键点在这里戛然而止强迫 LLM 续写英文promptPromptTemplate.from_template(template_str)# 生成结果...英文 - LLM 看到后会自然地接下去写 Hello WorldChatPromptTemplateChatPromptTemplate示例fromlangchain.promptsimportChatPromptTemplate# 我们不再拼接长字符串而是定义“消息块”chat_promptChatPromptTemplate.from_messages([(system,你是一个专业的翻译助手负责将中文翻译成英文。),# 设定人设/指令(human,{input_text})# 用户输入# 不需要写 (ai, )模型会自动在这里开始生成])# 生成结果[SystemMessage(...), HumanMessage(你好)]# - ChatModel 收到后知道该输出 AIMessage 了FewShotPromptTemplateFewShotPromptTemplate示例fromlangchain.promptsimportFewShotPromptTemplate,PromptTemplatefromlangchain_core.promptsimportPromptTemplate# 1. 定义示例数据 (Examples)# 这就是“少样本”的核心我们预先准备好几组标准的“输入-输出”对examples[{document:这部电影的特效简直炸裂视觉盛宴但是剧情有点拖沓结尾让人摸不着头脑。,summary_json:{\n \主题\: \电影评论\,\n \核心观点\: \特效好但剧情差\,\n \情感\: \混合\,\n \评分\: 6\n}},{document:这款手机的电池续航能力太差了充满电只能用半天。而且充电速度也很慢完全不推荐购买。,summary_json:{\n \主题\: \电子产品评论\,\n \核心观点\: \续航差充电慢\,\n \情感\: \负面\,\n \评分\: 2\n}},{document:昨天的会议主要讨论了下一季度的市场预算分配问题大家一致同意增加在数字营销方面的投入。,summary_json:{\n \主题\: \会议纪要\,\n \核心观点\: \增加数字营销预算\,\n \情感\: \中立\,\n \评分\: null\n}}]# 2. 定义示例模板 (Example Prompt)# 告诉 LangChain 如何把上面字典里的数据拼成一个字符串example_promptPromptTemplate(input_variables[document,summary_json],template文档内容{document}\n标准摘要{summary_json})# 3. 构建 FewShotPromptTemplate# 这是核心类它会自动把 examples 和 example_prompt 组合起来prefix你是一个专业的数据分析师。请阅读下方的“待处理文档”并严格按照示例中的格式输出 JSON 摘要。 注意不要输出任何多余的解释文字只输出 JSON。 以下是几个示例suffix待处理文档{input_document} 标准摘要promptFewShotPromptTemplate(examplesexamples,# 传入示例列表example_promptexample_prompt,# 传入示例的格式化模板prefixprefix,# 头部指令suffixsuffix,# 尾部输入包含变量 {input_document}input_variables[input_document]# 声明用户需要传入的变量)# # 4. 模拟用户输入批量/多文档场景# user_input 文档 A苹果发布了新款 Vision Pro售价 3500 美元虽然技术很先进但价格让很多人望而却步。 文档 B特斯拉的股价今天上涨了 5%因为马斯克宣布了新的全自动驾驶测试计划。 # 5. 生成最终提示词final_prompt_valueprompt.format(input_documentuser_input)# 打印出来看看效果模拟发送给模型前的样子print(------- 发送给模型的最终内容 -------)print(final_prompt_value)解读当你运行这段代码时FewShotPromptTemplate 会自动执行以下拼接逻辑**1、Prefix前缀**先输出通用的指令“你是一个分析师…”。**2、Examples示例循环**它会自动遍历 examples 列表利用 example_prompt 把每一组示例格式化成文本拼在指令后面。文档内容电影…标准摘要{JSON}…文档内容手机…标准摘要{JSON}…**3、Suffix后缀**最后放上你的 user_input待处理文档并以 标准摘要 结尾。 为什么这对“批量/多文档”很有用格式锁定通过示例模型会模仿示例中的 JSON 结构即使你的 user_input 包含多个文档文档 A 和 文档 B模型也会倾向于按照示例的风格把它们整合成一个结构化的输出。逻辑示范示例中展示了如何处理“混合情感”电影评论这教会了模型在面对复杂情况时该怎么做而不仅仅是简单的正面/负面。动态性你可以随时更换 examples 列表。比如针对“医疗文档”你可以换成一组医疗相关的示例而不需要修改核心代码逻辑。这就是 Few-Shot 的威力用示例代替复杂的规则说明。ChatPromptTemplate和ChatPromptTemplate的区别维度LLM (续写型) 的 PromptTemplateChatModel (交互型) 的 ChatPromptTemplate思维模式剧本编剧模式我要怎么写开头演员才会顺着我的剧本演下去对话管理模式我要给系统什么规则用户说了什么模板结构单一大字符串包含所有指令和输入。消息列表由 System, Human, AI 等模块组成。关键技巧结尾诱导模板通常以Answer:或\n结尾利用模型的续写本能。角色隔离利用system角色来强行注入指令模型会无条件服从。如果写错如果结尾没写好例如以句号结尾模型可能会自己接一句废话或者直接停止。如果把指令写在human里模型可能会觉得这是用户在自言自语而不是在下达命令。baseMessage属于promptTemplate吗?不属于。baseMessage是数据单元promptTemplate是模板工具他们相互协作将消息定义的更加清楚更加结构化。PromptValue提示值。实际就是发给大模型前的最后一站了。template、model、value之间是什么关系?如下这个例子讲的太好了1、PromptTemplate 是工厂负责生产内容。2、Model 是客户有的客户只收现金String有的客户只收刷卡List[Message]。3、PromptValue 就是“万能支付卡”。你拿着这张卡PromptValue去付款。如果客户要现金它就提现to_string。如果客户要刷卡它就刷卡to_messages。自定义格式化转换器场景主流的大模型都支持提示词转换但是假如某个大模型不支持提示词转换怎么办那么我们完全可以自己做一个提示词转换工具。例如就复用PromptValue这个类。实现两个方法即可to_string()to_messages()1、自定义提示词模板fromtypingimportList,Anyfromlangchain_core.prompt_valuesimportBasePromptValuefromlangchain_core.messagesimportBaseMessage,HumanMessage,SystemMessage# 1. 定义自定义的 PromptValueclassMyCustomPromptValue(BasePromptValue):# 这里定义你的数据源比如一段文本和一个特殊的指令头text:strspecial_header:str[SPECIAL_MODE]# 核心方法 A适配“普通文本模型”# 当这个 PromptValue 传给一个只认字符串的模型时会调用这个方法defto_string(self)-str:returnf{self.special_header}\n\n{self.text}# 核心方法 B适配“聊天模型”# 当这个 PromptValue 传给 ChatModel 时会调用这个方法defto_messages(self)-List[BaseMessage]:# 这里你可以随意定义消息的结构# 比如把特殊头放在 SystemMessage 里正文放在 HumanMessage 里return[SystemMessage(content系统已激活特殊模式。),HumanMessage(contentf{self.special_header}{self.text})]# (可选) 如果你需要序列化比如保存链条可能需要实现这个def__str__(self):returnself.to_string()2、调用并测试# 实例化你的自定义 PromptValuemy_valueMyCustomPromptValue(text你好世界,special_header[DEBUG])# 测试变身成字符串 (给普通模型看)print(--- 字符串格式 ---)print(my_value.to_string())# 输出: [DEBUG]# 你好世界# 测试变身成消息 (给聊天模型看)print(\n--- 消息格式 ---)formsginmy_value.to_messages():print(f{msg.type}:{msg.content})# 输出:# system: 系统已激活特殊模式。# human: [DEBUG] 你好世界自动调用和手动调用的区别?自动调用不需要显示的格式化(1)定义模板(2)定义调用链chainprompt|model model.invoke(你好)手动调用需要手动格式化不需要定义调用链了直接invoke(1)手动格式化(2)不需要定义调用链prompt_value手动格式化的内容model.invoke(你好)

更多文章