从零学会规范写 Prompt|LangChain 双模板详解 + 3 套可复用业务案例源码
📅 2026/7/23 7:38:33
👁️ 阅读次数
📝 编程学习
一、本章学习目标
结合前序 DeepSeek 模型调用、消息角色配置、对话历史存储知识点,本章吃透 Prompt 标准化管理方案,学完具备以下能力:
- 认知 Prompt 对大模型输出效果的决定性作用
- 熟练区分并使用
PromptTemplate、ChatPromptTemplate两套模板 - 掌握模板变量注入,实现提示词复用与解耦
- 独立开发商品文案、学习规划、智能客服三大实用案例
- 使用
MessagesPlaceholder挂载、截断多轮对话历史
二、Prompt 基础认知
1. 什么是 Prompt
Prompt 就是给到大模型的整套指令集合,包含角色定位、工作任务、约束规则、业务入参。
- 极简写法:
一句话介绍 LangChain 框架 - 企业标准写法:
你是专业电商运营,根据商品信息撰写详情文案 约束:150字以内、突出用户收益、禁止夸大宣传2. 为什么要用 Prompt 模板?
原生使用f-string硬拼接字符串写提示词,存在诸多痛点:代码臃肿冗余、变量拼接易出错、后期修改维护成本高。
模板核心优势:固定提示文本与动态业务变量分离,一处编写多处复用,迭代维护更简单。
三、两大核心提示模板详解
3.1 PromptTemplate(纯文本模板)
适用场景:无 system/user 角色区分,单纯文本生成需求
基础示例
from langchain_core.prompts import PromptTemplate 定义模板,{}标记变量占位符 tpl = PromptTemplate.from_template("商品{product_name},卖点:{selling_points},撰写一句宣传广告语") 填充变量渲染文本 prompt = tpl.invoke({"product_name": "罗技鼠标", "selling_points": "静音、灵敏、无延迟"}) 取出渲染后的字符串 print(prompt.text)3.2 ChatPromptTemplate(对话模型首选)
当前主流大模型(DeepSeek/GPT/通义千问)均采用system、human、ai结构化消息交互,该模板为项目开发标配。
基础示例
from langchain_core.prompts import ChatPromptTemplate tpl = ChatPromptTemplate.from_messages([ ("system", "身份:电商文案师,文案简洁写实,拒绝浮夸话术"), ("human", "商品{product_name},卖点{selling_points},编写商品介绍文案") ]) prompt = tpl.invoke({"product_name": "罗技鼠标", "selling_points": "静音、灵敏、无延迟"}) 向模型传参必须传递完整 prompt 对象,不要单独截取字符串3.3 两种模板核心对比
| 模板名称 | 输出格式 | 角色支持 | 推荐使用场景 |
|---|---|---|---|
| PromptTemplate | 纯文本字符串 | 无原生角色区分 | 简单单次文本生成、无对话交互 |
| ChatPromptTemplate | 结构化消息数组 | 原生支持系统/用户/AI 消息 | 聊天机器人、Agent、所有正式业务项目 |
3.4 高质量 Prompt 编写四要素
- 角色:限定 AI 身份,固定回答风格
- 任务:清晰描述需要 AI 完成的工作内容
- 约束:限制字数、格式、禁用词汇,规避输出跑偏
- 入参标注:明确各个变量含义,让 AI 精准识别业务数据
四、实战案例
公共封装:模型工厂 model_factory.py
消除每个文件重复的模型初始化代码,统一管理 DeepSeek 配置
# utils/model_factory.py import os from dotenv import load_dotenv from langchain.chat_models import init_chat_model def get_deepSeek_model(temperature: float = 0.7): load_dotenv() model = init_chat_model( model="deepseek-v4-flash", model_provider="openai", base_url=os.getenv("DEEPSEEK_BASE_URL"), api_key=os.getenv("DEEPSEEK_API_KEY"), temperature=temperature ) return model案例1:商品文案自动生成
from langchain_core.prompts import ChatPromptTemplate from utils.model_factory import get_deepSeek_model model = get_deepSeek_model(temperature=0.5) prompt_tpl = ChatPromptTemplate.from_messages([ ("system", "资深电商运营,文案贴合用户体验,不使用虚假宣传"), ("human", """ 商品名称:{product_name} 商品卖点:{selling_points} 目标用户:{target_user} 要求:文案150字以内,重点描述用户使用后的实际好处""") ]) prompt_val = prompt_tpl.invoke({ "product_name": "无线静音鼠标", "selling_points": "静音按键、蓝牙连接、续航30天、机身轻便", "target_user": "办公、图书馆学习的上班族" }) res = model.invoke(prompt_val) print(res.content)案例2:个性化学习计划生成
from langchain_core.prompts import ChatPromptTemplate from utils.model_factory import get_deepSeek_model model = get_deepSeek_model(temperature=0.5) prompt_tpl = ChatPromptTemplate.from_messages([ ("system", "编程教学规划师,输出落地可执行的学习方案,搭配每日练习"), ("human", """ 学习科目:{topic} 总学习天数:{days}天 每日可用时长:{hours_per_day}小时 自身基础:{level} 需求:按天划分学习内容,同步配套实操练习""") ]) prompt_val = prompt_tpl.invoke({ "topic": "LangChain框架", "days": 3, "hours_per_day": 1, "level": "掌握Python基础语法" }) res = model.invoke(prompt_val) print(res.content)案例3:电商客服智能回复
from langchain_core.prompts import ChatPromptTemplate from utils.model_factory import get_deepSeek_model model = get_deepSeek_model(temperature=0.7) prompt_tpl = ChatPromptTemplate.from_messages([ ("system", "电商客服,回复先安抚用户情绪,客观说明问题并给出解决方案,全文120字以内"), ("human", "用户提问:{user_question},订单状态:{order_status},物流详情:{shipping_info}") ]) prompt_val = prompt_tpl.invoke({ "user_question": "快递三天物流没更新,包裹是不是丢失了?", "order_status": "已发货", "shipping_info": "包裹抵达上海转运中心,暂未更新下级物流节点" }) res = model.invoke(prompt_val) print(res.content)五、MessagesPlaceholder 对话历史占位符
5.1 核心作用
普通变量仅能传入一段文本,MessagesPlaceholder支持批量插入多条历史对话消息,是实现多轮上下文记忆的核心组件;同时支持裁剪历史消息条数,防止上下文超长溢出。
5.2 参数说明
| 参数 | 释义 |
|---|---|
| variable_name | 绑定变量名称,调用入参名称必须保持一致 |
| optional | 默认 False(不传历史会报错);True 代表历史为空也可正常运行 |
| n_messages | 仅读取最近 N 条对话,管控上下文长度 |
5.3 完整可运行示例
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from utils.model_factory import get_deepSeek_model model = get_deepSeek_model(temperature=0.7) chat_tpl = ChatPromptTemplate.from_messages([ ("system", "友好的通用问答助手"), MessagesPlaceholder(variable_name="history", optional=True, n_messages=4), ("human", "{question}") ]) res = model.invoke(chat_tpl.invoke({ "history": [("human", "我叫Alice"), ("ai", "很高兴认识你,Alice")], "question": "请问我的名字是什么?" })) print(res.content)⚠️ 注意:history 入参必须是消息列表格式,禁止直接传入普通字符串
六、本章知识总结 & 常见问题解答
核心总结
- 正式项目优先使用
ChatPromptTemplate,PromptTemplate只用于简单纯文本生成场景 - 模板实现提示词与业务数据解耦,大幅提升代码可维护性
MessagesPlaceholder专门用来托管、截断多轮对话上下文
高频问题答疑
- Prompt 写得越长,回答效果越好?
答:并非越长越好,指令逻辑清晰精简即可,过多的约束条件会造成模型顾此失彼,输出更容易混乱。 - 模型无法严格按照我的指令输出怎么办?
大模型属于概率生成式模型,无法做到 100% 严格执行指令;如果对输出格式、字段有强约束,后续章节会讲解结构化输出、代码校验的解决方案。
💡 码字不易,如果文章对你有帮助,点赞+收藏不迷路,后续持续更新 LangChain 全套实战干货!
编程学习
技术分享
实战经验