nestjs+langchain:Prompt Template

书接上文

一、Prompt Template

介绍与分类

Prompt Template 是LangChain中的一个概念,接收用户输入,返回一个传递给LLM的信息(即提示词prompt)。

在应用开发中,固定的提示词限制了模型的灵活性和适用范围。所以,prompt template 是一个模板化的字符串 ,你可以将 变量插入到模板 中,从而创建出不同的提示。调用时:

  • 以 字典 作为输入,其中每个键代表要填充的提示模板中的变量。

  • 输出一个 PromptValue 。这个 PromptValue 可以传递给 LLM 或 ChatModel,并且还可以转换为字符串或消息列表。

有几种不同类型的提示模板:

🔥 PromptTemplate :LLM提示模板,用于生成字符串提示。

🔥 ChatPromptTemplate :聊天提示模板,用于组合各种角色的消息模板,传入聊天模型。

  • XxxMessagePromptTemplate :消息模板词模板,包括:SystemMessagePromptTemplateHumanMessagePromptTemplate、AIMessagePromptTemplate、ChatMessagePromptTemplate等

  • PipelinePrompt :管道提示词模板,用于把几个提示词组合在一起使用。

  • 自定义模板 :允许基于其它模板类来定制自己的提示词模板。

具体使用:PromptTemplate

使用说明

PromptTemplate类,用于快速构建 包含变量 的提示词模板,并通过 传入不同的参数值 生成自定义的提示词。

主要参数介绍:

  • template:定义提示词模板的字符串,其中包含 文本 和 变量占位符(如{name}) ;

  • input_variables: 列表,指定了模板中使用的变量名称,在调用模板时被替换;

  • partial_variables:字典,用于定义模板中一些固定的变量名。这些值不需要在每次调用时被替换。

两种实例化方式

1. 使用构造方法

agents.service.ts

js 复制代码
//1.引入
import { PromptTemplate } from '@langchain/core/prompts';

/**
   * 演示 PromptTemplate 的使用
   */
  async demonstratePromptTemplate(): Promise<void> {
    // 2. 定义模板
    // inputVariables 定义了需要传入的参数名
    const promptTemplate = new PromptTemplate({
      template: '请简要描述{topic}的应用。',
      inputVariables: ['topic'],
    });

    // 3. 使用模板生成提示词 (format)
    // format 方法返回格式化后的字符串
    const prompt_1 = await promptTemplate.format({ topic: '机器学习' });
    const prompt_2 = await promptTemplate.format({ topic: '自然语言处理' });

    // 4. 打印结果 
    console.log('提示词1:', prompt_1);
    console.log('提示词2:', prompt_2);

    // 5. (可选) 直接将格式化的提示词发送给 LLM
    // 注意:invoke 通常接收 Message 对象数组,所以我们需要将格式化后的字符串包装成 HumanMessage
    const messages = [new HumanMessage(prompt_1)];
    const response = await this.llm.invoke(messages);
    console.log('LLM 响应:', response.content);
  }
makefile 复制代码
输出结果:
提示词1: 请简要描述机器学习的应用。
提示词2: 请简要描述自然语言处理的应用。
LLM 响应: 机器学习作为人工智能的核心分支,通过数据驱动模型实现自动化决策与预测,其应用已渗透到...
2. fromTemplate

agents.service.ts

js 复制代码
const promptTemplate = PromptTemplate.fromTemplate(
      '请给我一个关于{topic}的{type}解释。',
    );

    const prompt = await promptTemplate.format({
      type: '详细',
      topic: '量子力学',
    });

    console.log('提示词1:', prompt);
erlang 复制代码
 输出结果:
 提示词1: 请给我一个关于量子力学的详细解释。
 LLM 响应: 量子力学是描述微观世界(如原子、亚原子粒子等尺度)行为的核心物理理论,...

两种新的结构形式

1. 部分提示词模版
js 复制代码
 // 1. 定义模板 + 预填充部分变量(partialVariables)
    const template = new PromptTemplate({
      template: '请评价{product}的优缺点,包括{aspect1}和{aspect2}。',
      inputVariables: ['product', 'aspect2'], // 必须传的变量
      partialVariables: { aspect1: '电池续航' }, // 预填充变量
    });

    const prompt = await template.format({
      product: '智能手机',
      aspect2: '拍照质量',
    });
2. 链式调用 .partial()
js 复制代码
 // 1. 先用 fromTemplate 传入「纯字符串模板」
    const baseTemplate = PromptTemplate.fromTemplate(
      '请评价{product}的优缺点,包括{aspect1}和{aspect2}。',
    );
    // 2. ✅ 关键:await 等待 partial 完成
    const template = await baseTemplate.partial({
      aspect1: '电池续航',
    });

    // 3. 正常 format
    const prompt = await template.format({
      product: '智能手机',
      aspect2: '拍照质量',
    });

⚠在nestji中使用langchain时,给模板变量赋值的方法只有format()

具体使用:ChatPromptTemplate

使用说明

ChatPromptTemplate是创建 聊天消息列表 的提示模板。它比普通 PromptTemplate 更适合处理多角

色、多轮次的对话场景。

特点: 支持 System / Human / AI 等不同角色的消息模板对话历史维护

参数类型: 列表参数格式是tuple类型

元组的格式为:(role: str | type, content: str | listdict | listobject),其中 role 是:字符串(如 "system" 、 "human" 、 "ai" )

两种实例化方式

1.使用构造方法

agents.service.ts

js 复制代码
import {
  ChatPromptTemplate,
  HumanMessagePromptTemplate,
  SystemMessagePromptTemplate,
} from '@langchain/core/prompts';

const chatPromptTemplate = new ChatPromptTemplate({
  // 👇 这里必须用 promptMessages,不是 messages!
  promptMessages: [
    SystemMessagePromptTemplate.fromTemplate(
      '你是一个AI助手,你的名字叫{name}',
    ),
    HumanMessagePromptTemplate.fromTemplate('我的问题是{question}'),
  ],
  // 手动声明输入变量
  inputVariables: ['name', 'question'],
});

// TS 中 invoke 是异步方法,必须 await
const res = await chatPromptTemplate.invoke({
  name: '小智',
  question: '1+2等于几',
});
console.log('提示词1:', res.messages);
css 复制代码
输出结果:
提示词1: [
  SystemMessage {
    "content": "你是一个AI助手,你的名字叫小智",
    "additional_kwargs": {},
    "response_metadata": {}
  },
  HumanMessage {
    "content": "我的问题是1+2等于几",
    "additional_kwargs": {},
    "response_metadata": {}
  }
]
2.fromMessages

agents.service.ts

js 复制代码
const chatPromptTemplate = ChatPromptTemplate.fromMessages([
      ['system', '你是一个AI助手,你的名字叫{name}'],
      ['human', '我的问题是{question}'],
]);

// 调用
const res = await chatPromptTemplate.invoke({
  name: '小智',
  question: '1+2等于几',
});
console.log('提示词1:', res.messages);
复制代码
输出结果同上

模板调用的几种方式

invoke/formatMessages异步(必须 await) ,只有 format同步

通用模板:

js 复制代码
// 1. 定义通用聊天模板 
const chatPromptTemplate = ChatPromptTemplate.fromMessages([ 
    ["system", "你是专业的{role}助手"], 
    ["human", "请解答:{question}"] ]
);
1.invoke:返回 ChatPromptValue
js 复制代码
const res = await chatPromptTemplate.invoke({
      role: '编程',
      question: '什么是NestJS',
});
2.format:返回纯文本字符串
js 复制代码
const res = chatPromptTemplate.format({
      role: '编程',
      question: '什么是NestJS',
});
3.formatMessages:返回消息对象数组BaseMessage[]
js 复制代码
const res = await chatPromptTemplate.formatMessages({
      role: '编程',
      question: '什么是NestJS',
});

插入消息列表:MessagesPlaceholder

当你不确定消息提示模板使用什么角色,或者希望在格式化过程中 插入消息列表 时,该怎么办? 这就需要使用 MessagesPlaceholder,负责在特定位置添加消息列表。

js 复制代码
// 创建聊天模板
const chatPromptTemplate = ChatPromptTemplate.fromMessages([
  ['system', '你是一个AI助手,你的名字叫{name}'],
  // 消息占位符
  new MessagesPlaceholder('msgs'),
]);

// 准备调用参数
const result = await chatPromptTemplate.invoke({
  name: '小智',
  msgs: [
    new HumanMessage('我的问题是:1 + 2 * 3 = ?'),
    new AIMessage('1 + 2 * 3 = 7'),
  ],
});

少量样本示例的提示词模板

在构建prompt时,可以通过构建一个 少量示例列表 去进一步格式化prompt,这是一种简单但强大的指导生成的方式,在某些情况下可以 显著提高模型性能。少量示例提示模板可以由 一组示例一个负责从定义的集合中选择 一部分示例 的示例选择器构建。

前者:使用ChatPromptTemplate

后者:使用Example selectors(示例选择器)

每个示例的结构都是一个 字典 ,其中 键 是输入变量, 值 是输入变量的值。

ChatPromptTemplate实现

js 复制代码
// 1. 定义示例
const examples = [
  { input: '2+2', output: '4', description: '加法运算' },
  { input: '5-2', output: '3', description: '减法运算' },
];

// 2. 把示例转为「用户提问 + AI回答」对话对
const exampleMessages = examples.flatMap((example) => [
  new HumanMessage(`算式:${example.input},请计算并说明`),
  new AIMessage(`结果:${example.output},说明:${example.description}`),
]);

// 3. 构建聊天模板,插入少样本对话
const prompt = ChatPromptTemplate.fromMessages([
  ['system', '你是数学专家,参考对话示例回答问题,格式和示例保持一致'],
  // 插入所有少样本对话
  ...exampleMessages,
  // 用户新问题
  ['human', '算式:{input},请计算并说明'],
]);

// 4. 调用模板生成提示词
const messages = await prompt.invoke({ input: '2*5' });
const response = await this.llm.invoke(messages);
console.log(response.content);
复制代码
输出结果:
结果:10,说明:乘法运算
相关推荐
用户5191495848451 小时前
Windows 渗透测试载荷加载器 POC 工具集
人工智能·aigc
袋鱼不重1 小时前
我的神奇同事,AI 用多了居然写了个 Open In Codex
前端·后端·ai编程
大树881 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
用户8356290780511 小时前
使用 Python 操作 Word 内容控件
后端·python
像我这样帅的人丶你还1 小时前
啥? 前端也要会干Java?🛵🛵🛵
后端
Hommy881 小时前
【剪映小助手】添加贴纸接口(Add Sticker)
后端·github·剪映小助手·视频剪辑自动化·剪映api
通信小呆呆2 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
施小赞2 小时前
普通 RAG vs GraphRAG 核心对比
人工智能·ai
EAIReport2 小时前
RuoYi-AI 企业级AI开发平台实战详解
人工智能
HelloWorld__来都来了2 小时前
【每日学术速报】2026-06-15
人工智能·具身智能