LangChain 1.0 入门(五):提示词工程、partial变量、ChatPromptTemplate、Hub模板库

系列文章

LangChain 1.0 入门(一):Runnable 统一接口全解析(含完整代码+逐行输出解读)

LangChain 1.0 入门(二):LangChain 全模型标准化接入最佳实践(小白参数详解版)

LangChain 1.0 入门(三):稳定性双核心------重试机制+速率限速器参数详解与实战

LangChain 1.0 入门(四): Messages 深度解析------大模型对话上下文核心单元

LangChain 1.0 入门(五):提示词工程、partial变量、ChatPromptTemplate、Hub模板库


前言

提示词工程(Prompt Engineering)是大模型应用开发的核心环节,手写字符串拼接提示词难以维护、无法迭代调优。LangChain‑Core 的 Prompt 模板体系,就是把提示词工程代码化、工程化。本文先讲解提示词工程基础方法论,再结合 RAG知识库问答、代码助手、企业客服、Agent 系统指令真实业务场景,讲解API、核心参数、partial半成品模板、对话模板、LangSmith Hub模板仓库、生产踩坑与最佳实践,附带完整可运行Python示例。

环境依赖:langchain‑core>=0.2.x,LangChain1.0生态;适配RAG、智能客服、内部助手、文档解析业务。
导入提醒:LangChain1.0全部从langchain_core导入,废弃旧路径langchain.prompts

python 复制代码
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate

一、提示词工程(Prompt Engineering)基础介绍

1.1 什么是提示词工程

提示词工程,指通过设计、编写、调优输入给大模型的指令文本,引导大模型按照预期的格式、逻辑、约束输出结果,而不是单纯写一句提问。

大模型本身不理解业务,它的行为完全由输入提示词来定义:你告诉它是什么角色、要做什么事、遵循什么规则、输出什么格式,模型就会对应产出内容。

传统方式:直接硬编码字符串写Prompt,适合Demo;

工程化方式:使用模板组件管理Prompt,适合线上业务系统。

1.2 高质量提示词五大核心要素

一套生产可用的提示词通常包含5部分,这也是我们写模板时需要拆解的模块:

  1. 角色设定(Role):AI是什么身份,例如:后端代码评审专家、企业知识库客服、技术文档摘要助手;
  2. 任务指令(Instruction):明确告诉模型要完成的具体工作,不能模糊;
  3. 上下文输入(Context):外部输入信息,用户问题、检索知识库、待处理文档、代码片段;
  4. 约束规则(Constraints):边界条件,禁止编造、输出格式、字数限制、语气风格;
  5. 输出示例(Few‑shot):给1~2个输入输出样例,引导模型对齐输出格式。

反面案例(差的提示词):帮我分析这段代码

  • 没有角色,没有约束,输出不可控;

正面案例(高质量提示词):

复制代码
你是Python后端代码评审专家【角色】
任务:对传入代码做安全与性能评审,输出问题清单和修复代码【指令】
待评审代码:{code_snippet}【上下文】
约束:只输出Markdown格式,不做无关闲聊,没有问题就输出"代码无明显风险"【约束】

1.3 提示词工程面临的工程痛点

手工写Prompt在项目迭代中会遇到现实问题,这就是PromptTemplate要解决的问题:

  1. 提示词五大要素混杂在业务代码,角色、规则散落在各个接口,修改一处要改多处;
  2. 部分内容固定不变(角色、约束规则),部分内容每次请求动态变化(用户问题、检索上下文),每次调用重复拼接;
  3. Few‑shot示例很长,硬编码在业务代码可读性极差;
  4. 无法版本管理提示词,调优Prompt只能改代码发布;
  5. RAG、Agent场景,system系统指令反复复制粘贴,容易漏写某一条约束,造成模型输出异常;
  6. 很难复用社区已经调优好的成熟提示词。

Prompt模板的本质:把提示词工程的五大要素进行拆分管理,固定内容预填充,动态内容做变量插值。

二、为什么要使用Prompt模板?

在项目中直接使用f‑string拼接提示词,生产环境痛点:

  1. 系统角色、输出格式散落在业务各处,修改Prompt需要多处改代码;
  2. RAG场景,系统指令固定,用户问题、检索上下文每次动态变化,重复传参极易漏参;
  3. 对话模型需要维护system/human/ai消息数组,字符串拼接极易出错;
  4. Prompt无法版本管理,无法复用社区经过调优的成熟提示词;
  5. 变量内容包含换行、特殊符号,手动拼接容易出现格式错乱。

Prompt模板核心目标:提示词与业务逻辑解耦,模板可复用、可维护、可版本管理,实现提示词工程落地

三、PromptTemplate 普通字符串模板

适用于:非对话大模型、文本生成、摘要、关键词提取等文本处理场景,模板内部使用{变量名}作为占位符。

3.1 from_template 快速创建(调试、原型开发)

自动解析模板中大括号占位符,自动推导input_variables,适合快速验证提示词工程想法。

业务示例场景:文档摘要生成

python 复制代码
from langchain_core.prompts import PromptTemplate

# 业务:对输入文档片段做内容摘要,max_words控制摘要字数
prompt_template = PromptTemplate.from_template(
    """【角色】文档摘要助手
【任务指令】请对下面文档片段做内容摘要
【约束】摘要控制在{max_words}字以内,保留核心技术信息,不要冗余描述
【待处理文档】
{document_content}
【输出摘要】:"""
)

# format填充业务变量,渲染出最终prompt字符串
formatted_prompt = prompt_template.format(
    max_words=150,
    document_content="""LangChain‑Core是LangChain1.0的核心基础库,提供Prompt模板、消息结构、LCEL链式原语,不绑定任何大模型,可以对接各类国产以及海外大模型,用于快速搭建LLM应用。"""
)

print(formatted_prompt)

3.2 显式对象实例化(生产环境推荐)

手动显式声明input_variables,代码可读性强,启动阶段校验模板合法性。

PromptTemplate核心参数表

参数 说明
input_variables 必填变量列表,.format()必须传入;一般为用户输入、检索文档、业务数据
template 原始提示词模板字符串,使用{var}占位插值,存放角色、指令、约束、占位上下文
partial_variables 预填静态固定变量;模板定义阶段赋值,后续可以被.partial()覆盖
validate_template 布尔,校验占位符和变量是否匹配,开发环境建议True
template_format 模板语法,默认f‑string;可选mustache

业务示例:内部技术文档关键词提取

python 复制代码
from langchain_core.prompts import PromptTemplate

template = PromptTemplate(
    input_variables=["doc_text", "extract_count"],
    template="""
【角色】技术文档关键词提取助手
【任务】从下面技术文档中提取{extract_count}个核心业务关键词
【约束】只输出关键词,逗号分隔,不要多余解释
【文档内容】
{doc_text}
关键词输出:""",
    validate_template=True
)

prompt_text = template.format(
    doc_text="昇腾NPU基于CANN算子库,支持vLLM推理框架,通过Docker容器部署大模型服务。",
    extract_count=4
)

print(prompt_text)

⚠️注意点:

  1. 占位符必须是英文大括号{var},中文全角{}无法识别;
  2. 如果需要输出字面{}符号,写双大括号转义 {``{ }}

四、partial_variables / partial() 半成品模板(生产高频,提示词工程利器)

结合提示词工程五要素来看:

  • 固定不变部分:角色设定、任务指令、约束规则、Few‑shot示例,几乎不会随每次请求变化;
  • 动态变化部分:用户query、检索上下文、待处理文档,每次请求都不一样。

partial能力:提前填充角色、指令、约束这些固定提示词片段,得到半成品模板;只把动态业务内容留给后续format传入。避免每次调用重复传入一大段系统提示词。

两种用法:

  1. 构造对象:partial_variables={...}静态预填固定值;
  2. 运行时.partial(**kwargs):支持覆盖旧值,支持传入函数做动态变量

4.1 静态partial_variables 模板定义时预填

业务场景:企业内部技术问答助手,角色、输出约束固定,仅用户问题动态传入

python 复制代码
from langchain_core.prompts import PromptTemplate

template = PromptTemplate(
    input_variables=["user_query"],
    template="""
【角色】公司内部技术知识库问答助手
【任务】回答员工技术问题
{answer_rule}

用户提问:{user_query}
回答:
""",
    partial_variables={
        "answer_rule": """【约束】
1. 只基于已有知识库内容回答,不知道直接回复"知识库未收录该问题"
2. 条理清晰分点作答,不要编造信息
3. 技术问题优先给出可执行操作步骤"""
    }
)

# format 仅需要传入动态的 user_query
prompt = template.format(user_query="昇腾环境如何安装vLLM?")
print(prompt)

4.2 .partial() 运行时覆盖预填变量

同一套模板,不同业务场景动态切换提示词约束;对内技术人员输出详细,对外业务人员输出通俗。

python 复制代码
# 覆盖预设回答规则,切换面向普通业务人员模式
prompt = template.partial(answer_rule="""【约束】
1. 语言通俗易懂,尽量少用专业术语
2. 不知道直接回复"知识库未收录该问题"
""").format(user_query="昇腾环境如何安装vLLM?")
print(prompt)

4.3 partial高级用法:传入函数生成动态变量

重要:partial_variables静态字典不支持函数 ;只有.partial()支持传入函数。

典型场景:注入当前时间、链路TraceId,丰富提示词上下文信息。

python 复制代码
from datetime import datetime
from langchain_core.prompts import PromptTemplate

def get_current_datetime():
    """获取当前服务时间,模板渲染时自动执行"""
    return datetime.now().strftime("%Y‑%m‑%d %H:%M:%S")

base_template = PromptTemplate(
    input_variables=["question"],
    template="""
【请求时间】{server_time}
【角色】业务咨询助手
用户业务咨询:{question}
回答:"""
)

# partial传入函数,渲染时自动调用执行
partial_tpl = base_template.partial(server_time=get_current_datetime)
final_prompt = partial_tpl.format(question="如何查询接口调用报错日志?")
print(final_prompt)

input_variables 与 partial变量对比

项目 input_variables partial_variables / .partial()
是否必须format传入 ✅必须 ❌不需要
填入时机 .format()每次业务调用 模板定义 / 运行时.partial()
是否支持覆盖 ✅后调用覆盖先前值
是否支持函数 ✅仅.partial()支持函数
提示词工程对应模块 上下文、用户输入 角色、任务指令、约束规则、Few‑shot示例

✅生产最佳实践:RAG、Agent把角色、任务、约束规则全部放到partial预填;业务调用只传用户输入和检索结果,减少漏参bug。

五、ChatPromptTemplate对话消息模板(项目首选)

现在绝大多数LLM都是对话接口,接收消息数组,天然对应提示词工程的模块拆分:

  • system:存放角色、全局任务指令、约束规则(提示词工程核心固定部分)
  • human:存放用户输入、待处理上下文
  • ai:Few‑shot示例,历史对话回复

ChatPromptTemplate.from_messages()组装消息列表,每条消息内部同样支持{变量}插值。

关键区分:

  • PromptTemplate.format() 返回字符串;
  • ChatPromptTemplate.format_messages() 返回消息对象列表,直接喂给聊天模型model.invoke(messages)
    业务示例场景:代码审查助手
python 复制代码
from langchain_core.prompts import ChatPromptTemplate

chat_template = ChatPromptTemplate.from_messages([
    ("system", """
【角色】后端Python代码评审专家
【任务】对代码做安全、异常捕获、资源泄漏、代码规范评审
【约束】输出Markdown格式,列出风险点,给出修改后的完整代码
"""),
    ("human", "待评审代码片段:\n```python\n{code_snippet}\n```"),
    ("ai", "【问题摘要】1.缺少异常捕获;2.文件句柄未做安全关闭"), # Few‑shot输出示例
    ("human", "{user_follow_command}")
])

messages = chat_template.format_messages(
    code_snippet="""
def read_file(file_path):
    f = open(file_path,"r")
    return f.read()
""",
    user_follow_command="请输出修复之后完整可运行代码,同时逐条说明改动点"
)

# 打印消息结构
for msg in messages:
    print(f"\n【角色】{msg.type}")
    print(f"【内容】\n{msg.content}")

# response = model.invoke(messages)

元组简写映射:

  • ("system", "内容")SystemMessage
  • ("human", "内容")HumanMessage
  • ("ai", "内容")AIMessage

ChatPromptTemplate同样支持.partial()预填system里面的角色、约束规则,RAG开发中非常高频。

六、LangSmith Hub 拉取社区成熟Prompt模板

提示词工程不一定全部从零手写,大量经过调优的提示词存放在LangSmith Hub,RAG、文本分类、摘要、Agent提示词直接拉取使用,支持版本标记,方便迭代提示词。

官网:https://smith.langchain.com/hub

前置准备:

  1. 注册LangSmith账号,获取LANGSMITH_API_KEY
  2. 安装依赖:pip install langsmith python‑dotenv
  3. .env配置环境变量。

业务示例:拉取官方标准RAG提示词,官方模板内部已经封装好角色、任务、约束规则

python 复制代码
import os
from dotenv import load_dotenv
from langsmith import Client

load_dotenv()
client = Client(api_key=os.getenv("LANGSMITH_API_KEY"))

# 拉取官方RAG提示模板 rlm/rag‑prompt,线上不要每次请求拉取,应用启动阶段拉取一次
prompt = client.pull_prompt("rlm/rag‑prompt")

formatted_prompt = prompt.format(
    context="""vLLM是一款高性能大模型推理服务框架,支持PagedAttention,大幅提升吞吐量,可以在昇腾NPU上通过vLLM‑Ascend适配部署。""",
    question="vLLM推理框架核心优势是什么?"
)

print(formatted_prompt)
# response = model.invoke(formatted_prompt)

⚠️生产注意事项:

  1. pull_prompt是网络IO,禁止每次HTTP业务请求调用拉取;应用启动时全局拉取一次缓存;
  2. 使用版本号锁定模板,例如rlm/rag‑prompt:v1,避免官方模板更新导致业务逻辑突变;
  3. include_model=True会附带模型配置,国产大模型建议关闭该参数;
  4. 增加try‑except捕获网络超时异常。

七、LCEL链式调用结合Prompt模板(线上标准写法)

模板不需要手动调用format_messages,直接通过管道符|和模型组成chain,输入字典自动填充模板变量。

python 复制代码
from langchain_core.prompts import ChatPromptTemplate
# from langchain_openai import ChatOpenAI

# llm = ChatOpenAI(model="gpt‑4o‑mini")

# RAG问答模板,partial预填system中角色、任务、约束(提示词工程固定部分)
rag_chat_prompt = ChatPromptTemplate.from_messages([
    ("system", """
【角色】企业内部知识库助手
【任务】基于检索到的上下文回答用户问题
{limit_rule}"""),
    ("human", "参考上下文:\n{context}\n用户问题:{question}")
]).partial(limit_rule="""
【约束】
1. 仅依赖上下文信息回答;
2. 不知道就如实说明,禁止编造知识库不存在信息;
3. 回答分点简洁输出。
""")

# LCEL构建链路
# rag_chain = rag_chat_prompt | llm
# resp = rag_chain.invoke({
#     "context":"检索回来的知识库文本......",
#     "question":"用户实际提问"
# })

八、提示词工程 + PromptTemplate高频踩坑清单

  1. 提示词五要素缺失:只写问题,缺少角色、约束,模型输出不可控;
  2. 变量名大小写敏感,占位符key与传入字典key不一致直接抛出KeyError
  3. 区分format()返回字符串、format_messages()返回消息对象;对话模型误用format会导致报错;
  4. partial_variables静态字典不能放函数;动态函数变量只能用.partial(func=xxx)
  5. 字面输出{ }符号,使用双大括号{``{ }}转义;
  6. .partial()多次调用,后调用的同名变量覆盖前面,可以用来动态切换提示词约束;
  7. Hub拉取模板要做启动缓存,不能每一次请求走网络;
  8. 检索上下文context为大文本时,要做长度截断,防止超出模型上下文窗口;
  9. Few‑shot示例不要硬编码在业务逻辑,放到system消息或者partial预填。

九、业务选型建议表

业务场景 推荐组件
文本摘要、关键词提取、非对话模型 PromptTemplate
对话大模型、RAG问答、智能客服、代码助手 ChatPromptTemplate(优先)
角色、任务、约束规则固定,仅输入动态变化 ChatPromptTemplate + .partial()预填提示词固定片段
复用社区调优Prompt、提示词需要版本管理 LangSmith Hub pull_prompt,启动缓存

十、总结

  1. 提示词工程核心:通过角色、任务指令、上下文、约束规则、Few‑shot示例引导大模型输出符合业务预期;
  2. PromptTemplate用于普通字符串模板;ChatPromptTemplate处理system/human/ai结构化消息,是LLM业务开发首选;
  3. 在模板体系中,partial()专门存放提示词工程的角色、指令、约束规则,input_variables存放动态上下文;实现提示词的模块化;
  4. LangSmith Hub可以复用成熟提示词,但线上必须缓存,规避网络开销;
  5. Prompt模板工程化的核心思想,就是把提示词工程从零散字符串变成可维护、可调试、可版本迭代的业务组件
相关推荐
wno7041 小时前
nginx反向代理设置ssl,支持https
运维·服务器·网络
FreeTinker1 小时前
联想个人云存储:大厂入局NAS赛道,体验如何?
网络
circuitsosk1 小时前
Python 文件读写与上下文管理器:with 语句为什么是最佳选择
java·服务器·python·文件操作·上下文管理器·contextlib
Shawn Dev1 小时前
没有公网 IP,如何让家里的服务器通过域名访问?——Cloudflare Tunnel 实战指南
服务器·网络协议·tcp/ip
智者向内寻求力量1 小时前
【记录】ubuntu 24.04 安装在levnoval PC上之后,蓝牙设备找不到解决方法
linux·服务器·ubuntu
迪康coolmu2 小时前
企业IT运维闭环——工单管理与远程协助一体化实践
java·大数据·运维·网络·数据库·人工智能·安全
halo雨航2 小时前
阿贝云免费服务器申请
运维·服务器
huainingning2 小时前
Linux和Windows系統SCP命令传输文件
linux·运维·服务器
polarislove02142 小时前
Windows安全中心网络盘打开文件提示“打开这些文件可能会对你的计算机有害”的解决方法
网络·windows·安全