一、为什么前端要关心提示词模板

从 Vue、React 转到 Agent 开发,最容易踩的坑不是模型能力不够,而是把提示词当成一段随手拼接的字符串。前端同学对字符串模板并不陌生,但提示词模板和普通模板有本质区别:它需要支持变量注入、多轮消息结构、部分填充、输出格式约束,还要能被复用和测试。

LangChain 的 Prompt Template 就是把这套东西工程化的产物。理解它,等于理解了 Agent 的“输入层”。

二、PromptTemplate:最基础的字符串模板

最常用的是 PromptTemplate,它接收一个模板字符串和一组变量,最终渲染成一段文本。

from langchain_core.prompts import PromptTemplate

prompt = PromptTemplate.from_template(
    "你是一名资深前端工程师,请用通俗的语言解释 {concept},并给出一个 {framework} 中的示例。"
)

text = prompt.format(concept="虚拟 DOM", framework="React")
print(text)

这里有两个关键点:

  • 变量用花括号声明:{concept}、{framework} 会被自动识别为输入变量,可以通过 prompt.input_variables 查看。
  • 渲染与调用分离:模板只负责生成文本,不负责调用模型,这让它可以被单独测试和复用。

如果模板里本身需要出现花括号(比如输出 JSON 示例),要用双花括号转义:{{"name": "Tom"}}。

三、ChatPromptTemplate:面向多轮对话的消息模板

现代大模型基本都是对话式接口,输入是消息列表而不是单段文本。这时应该用 ChatPromptTemplate,它由多条消息组成,每条消息带角色。

from langchain_core.prompts import ChatPromptTemplate

chat_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一名前端技术顾问,回答要简洁、准确,必要时给出代码。"),
    ("human", "我在 {framework} 中遇到了 {problem},该怎么排查?"),
])

messages = chat_prompt.format_messages(framework="Vue 3", problem="组件重复渲染")
for m in messages:
    print(m.type, m.content)

渲染结果是 SystemMessage 和 HumanMessage 组成的列表,可以直接传给模型。相比手写字典,这种写法更清晰,也更容易做角色约束。

常见角色对应关系:

角色说明典型用途
system系统设定角色、语气、输出格式约束
human用户输入问题、指令、上下文
ai模型历史回复多轮对话上下文
placeholder占位符动态插入历史消息列表

四、MessagesPlaceholder:把对话历史塞进模板

做多轮对话时,历史消息是动态的,数量不固定。用 MessagesPlaceholder 可以在模板中预留一个位置,运行时把整个消息列表填进去。

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个耐心的前端导师。"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{question}"),
])

messages = prompt.format_messages(
    history=[
        ("human", "什么是闭包?"),
        ("ai", "闭包是函数与其词法作用域的组合。"),
    ],
    question="那它和内存泄漏有什么关系?",
)

这一步是 Agent 记忆能力的基础:只要把历史消息维护好,模板就能自动拼出完整的上下文。

五、Few-shot 示例模板

当模型输出不稳定时,给几个示例往往比反复改措辞更有效。LangChain 提供了 FewShotChatMessagePromptTemplate。

from langchain_core.prompts import (
    ChatPromptTemplate,
    FewShotChatMessagePromptTemplate,
)

examples = [
    {"input": "按钮点击没反应", "output": "检查事件绑定与阻止冒泡逻辑"},
    {"input": "页面首屏很慢", "output": "检查打包体积与关键资源加载顺序"},
]

example_prompt = ChatPromptTemplate.from_messages([
    ("human", "{input}"),
    ("ai", "{output}"),
])

few_shot = FewShotChatMessagePromptTemplate(
    example_prompt=example_prompt,
    examples=examples,
)

final_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是前端问题诊断助手,回答保持一句话。"),
    few_shot,
    ("human", "{input}"),
])

示例会被展开成多组 human/ai 消息,插在系统提示之后、真实问题之前。

六、部分填充与模板组合

有些变量是固定的,比如角色设定或当前日期。可以用 partial 先填一部分,剩下的运行时再补。

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是 {role},今天是 {date}。"),
    ("human", "{question}"),
])

partial_prompt = prompt.partial(role="前端架构师", date="2026-11-05")
messages = partial_prompt.format_messages(question="如何设计组件库的目录结构?")

模板还可以用 + 或管道组合,把多个片段拼成一个完整提示词,便于按模块维护。

七、输出格式约束:让模型返回可解析结果

Agent 需要结构化输出,否则后续代码无法处理。常见做法是在提示词中明确要求 JSON,并配合解析器。

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个信息抽取助手,只输出 JSON,不要输出多余文字。"),
    ("human", "从下面的描述中抽取技术栈和问题类型:{text}"),
])

messages = prompt.format_messages(text="Vue 项目打包后白屏,怀疑是路由模式配置问题")

更稳妥的方式是使用 with_structured_output 或 JsonOutputParser,把格式约束交给框架处理,减少模型自由发挥的空间。

八、前端视角的类比与常见坑

用前端经验来类比,会更容易上手:

  • PromptTemplate 类似字符串模板函数,输入变量输出文本。
  • ChatPromptTemplate 类似组件树,消息是子节点,角色是 props。
  • MessagesPlaceholder 类似 slot,运行时插入动态内容。
  • partial 类似给组件设置默认 props。

几个高频坑:

  1. 花括号未转义:模板里写 JSON 示例时忘记双花括号,导致变量解析报错。
  2. 变量名拼错:format_messages 时缺少变量会直接抛异常,建议提前校验 input_variables。
  3. 系统提示过长:把所有规则堆在 system 里,反而稀释了关键约束,应按职责拆分。
  4. 忽略消息顺序:示例、历史、当前问题顺序错乱,会显著影响输出质量。

九、小结

提示词模板是 Agent 的输入契约。掌握 PromptTemplate、ChatPromptTemplate、MessagesPlaceholder、Few-shot 和 partial 这几件工具,就能把零散的提示词变成可维护、可测试的工程资产。下一节会在此基础上,把这些模板接入模型调用与链式流程。

Logo

更多推荐