欢迎光临
我们一直在努力

AI Agent白手起家27: LangChain 提示词模板原理与实践

纲要

  • 提示词在大模型应用中的核心地位
  • 提示词模板的工作原理
  • 提示词模板的优势
  • 从自然语言到结构化输出的完整链路
  • 优质提示词的基本要素
  • LangChain 中的两种模板
    • PromptTemplate
    • ChatPromptTemplate
  • 实战:使用 ChatPromptTemplate 构建一个旅游攻略生成器
  • 完整可运行代码
  • 总结

提示词:大模型应用的“控制面板”

对于任何基于大语言模型的应用而言,提示词(Prompt)是最主要的人机交互方式。即便不进行应用开发,我们日常使用 ChatGPT、DeepSeek 等工具时,本质上就是在不断撰写提示词。在 LangChain 的组件体系中,提示词模板被提升到了一个可工程化、可复用的层次,成为连接用户意图与模型能力的核心桥梁。

一个大模型应用的典型 IO 流程如下:

#mermaid-svg-e8cfY7qJblkElhFO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-e8cfY7qJblkElhFO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-e8cfY7qJblkElhFO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-e8cfY7qJblkElhFO .error-icon{fill:#552222;}#mermaid-svg-e8cfY7qJblkElhFO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-e8cfY7qJblkElhFO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-e8cfY7qJblkElhFO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-e8cfY7qJblkElhFO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-e8cfY7qJblkElhFO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-e8cfY7qJblkElhFO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-e8cfY7qJblkElhFO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-e8cfY7qJblkElhFO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-e8cfY7qJblkElhFO .marker.cross{stroke:#333333;}#mermaid-svg-e8cfY7qJblkElhFO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-e8cfY7qJblkElhFO p{margin:0;}#mermaid-svg-e8cfY7qJblkElhFO .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-e8cfY7qJblkElhFO .cluster-label text{fill:#333;}#mermaid-svg-e8cfY7qJblkElhFO .cluster-label span{color:#333;}#mermaid-svg-e8cfY7qJblkElhFO .cluster-label span p{background-color:transparent;}#mermaid-svg-e8cfY7qJblkElhFO .label text,#mermaid-svg-e8cfY7qJblkElhFO span{fill:#333;color:#333;}#mermaid-svg-e8cfY7qJblkElhFO .node rect,#mermaid-svg-e8cfY7qJblkElhFO .node circle,#mermaid-svg-e8cfY7qJblkElhFO .node ellipse,#mermaid-svg-e8cfY7qJblkElhFO .node polygon,#mermaid-svg-e8cfY7qJblkElhFO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-e8cfY7qJblkElhFO .rough-node .label text,#mermaid-svg-e8cfY7qJblkElhFO .node .label text,#mermaid-svg-e8cfY7qJblkElhFO .image-shape .label,#mermaid-svg-e8cfY7qJblkElhFO .icon-shape .label{text-anchor:middle;}#mermaid-svg-e8cfY7qJblkElhFO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-e8cfY7qJblkElhFO .rough-node .label,#mermaid-svg-e8cfY7qJblkElhFO .node .label,#mermaid-svg-e8cfY7qJblkElhFO .image-shape .label,#mermaid-svg-e8cfY7qJblkElhFO .icon-shape .label{text-align:center;}#mermaid-svg-e8cfY7qJblkElhFO .node.clickable{cursor:pointer;}#mermaid-svg-e8cfY7qJblkElhFO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-e8cfY7qJblkElhFO .arrowheadPath{fill:#333333;}#mermaid-svg-e8cfY7qJblkElhFO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-e8cfY7qJblkElhFO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-e8cfY7qJblkElhFO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e8cfY7qJblkElhFO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-e8cfY7qJblkElhFO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e8cfY7qJblkElhFO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-e8cfY7qJblkElhFO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-e8cfY7qJblkElhFO .cluster text{fill:#333;}#mermaid-svg-e8cfY7qJblkElhFO .cluster span{color:#333;}#mermaid-svg-e8cfY7qJblkElhFO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-e8cfY7qJblkElhFO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-e8cfY7qJblkElhFO rect.text{fill:none;stroke-width:0;}#mermaid-svg-e8cfY7qJblkElhFO .icon-shape,#mermaid-svg-e8cfY7qJblkElhFO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e8cfY7qJblkElhFO .icon-shape p,#mermaid-svg-e8cfY7qJblkElhFO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-e8cfY7qJblkElhFO .icon-shape .label rect,#mermaid-svg-e8cfY7qJblkElhFO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e8cfY7qJblkElhFO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-e8cfY7qJblkElhFO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-e8cfY7qJblkElhFO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

提示词模板 + 变量

格式化生成完整 Prompt

大语言模型 ChatModel

自然语言回答

输出解析器 Output Parser

结构化数据 e.g. JSON

  • 提示词模板 将动态内容抽象为变量,将不变的部分固化,类似于填空题。
  • 大模型 接收完整的提示词,进行推理并返回自然语言。
  • 输出解析器 将自然语言转换为程序可读的结构化数据(如 JSON),供下游系统使用。

这个过程清晰地展示了提示词在整个系统中的关键作用:它既是模型的输入源,也是影响输出质量最重要的可控因素。

提示词模板的工作原理

在没有模板的情况下,我们每次调用模型都要手动拼接完整的提示词,不仅重复劳动,还难以维护和版本控制。提示词模板通过占位符将可变部分抽离:

  • 模板: “{role},请为我规划一个{theme}的旅行攻略,预算{budget}元。”
  • 变量: role=“导游”, theme=“海南”, budget=“10000”
  • 格式化后: “导游,请为我规划一个海南的旅行攻略,预算10000元。”

在 LangChain 中,这一过程通过 format 或 invoke 方法完成,模板会自动处理变量的注入,生成最终提交给模型的字符串或消息列表。

提示词模板的核心优势

  • 复用性:同一个模板可以填入不同的变量值,生成多样化的提示词。
  • 可维护性:集中管理提示词逻辑,修改模板一处即可同步所有调用。
  • 版本控制:模板作为代码的一部分,可以纳入 Git 进行团队协作和历史追溯。
  • 安全性:可对变量进行校验,防止注入恶意内容。

好提示词的要素

优质提示词通常包含以下结构(对非推理模型尤其重要):

  • 角色设定:赋予模型一个专家身份,引导其进入特定领域语境。
  • 背景信息:提供上下文,说明问题的来龙去脉。
  • 明确目标:清晰描述希望达成的结果。
  • 约束条件:指明格式、语气、禁忌等要求。

例如,一个糟糕的提示词:

“帮我做一份旅行攻略。”

而一个高质量的提示词:

“假设你是一名资深导游,我要和两位朋友去海南玩七天,预算一万元。我们不喜欢行程太赶,也不喜欢网红景点,更偏爱有文化底蕴的地方。请推荐景点并附上门票价格。”

后者给出了明确的角色、约束和期望,模型响应质量会显著提升。

LangChain 中的两种模板

LangChain 为不同模型类型提供了对应的模板类:

模板类适用模型输出格式
PromptTemplate 传统 LLMs(纯文本补全) 字符串
ChatPromptTemplate ChatModels(对话型) 消息列表(支持 system, human, ai 等角色)

目前绝大多数模型都已转向 Chat 模式,因此推荐优先使用 ChatPromptTemplate。它支持系统消息、人类消息的独立构建,并将模板变量分别注入。

实战:使用 ChatPromptTemplate 构建旅游攻略生成器

下面通过一个完整示例,展示如何用 LangChain 的提示词模板构建一个可复用的旅行攻略助手。我们将定义一个包含系统角色和用户模板的 ChatPromptTemplate,并调用模型生成结构化回答。

项目结构

├── main.py
└── requirements.txt

依赖安装

pip install langchain-openai langchain-core

完整可运行代码

import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# 1. 初始化模型
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY"),
)

# 2. 定义提示词模板
template = ChatPromptTemplate.from_messages([
("system", "你是一位资深的旅行规划师,擅长制定个性化的旅行方案。"),
("human", (
"我要和{num_people}位朋友去{destination}玩{days}天,"
"总预算{budget}元。我们不喜欢行程太紧凑,也不喜欢网红景点,"
"更偏爱有文化底蕴的景点。请推荐景点并尽量附上门票价格。"
)),
])

# 3. 填入具体变量
prompt = template.invoke({
"num_people": "两",
"destination": "海南",
"days": "7",
"budget": "10000",
})

print("生成的提示词消息:")
print(prompt.to_string())
print("\\n" + "=" * 50 + "\\n")

# 4. 调用模型
response = llm.invoke(prompt)
print("模型回答:")
print(response.content)

if response.usage_metadata:
print("\\nToken 用量:", response.usage_metadata)

运行说明:

  • 需要设置环境变量 OPENAI_API_KEY 为有效的 OpenAI API 密钥。
  • 代码使用 GPT-3.5-turbo 进行演示,成本低且足以完成规划任务。
  • 可根据需要调整模板中的系统消息和人类消息,增加更多约束或角色细节。
  • 若想接入本地模型(如 Ollama),将 ChatOpenAI 替换为 ChatOllama 并修改 base_url 即可,模板部分完全通用。

总结

  • 提示词是连接人类意图和模型能力的唯一通道,其质量直接决定应用效果。
  • LangChain 的提示词模板通过变量和格式化实现了提示词的工程化管理,提升了复用性、可维护性和安全性。
  • ChatPromptTemplate 是目前最推荐的模板类型,支持多角色消息构建,适配绝大多数模型。
  • 好的提示词应包含角色、背景、目标和约束四个要素,这是 AI Agent 开发的基本功。
赞(0)
未经允许不得转载:171主机测评 » AI Agent白手起家27: LangChain 提示词模板原理与实践
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址