书接上文。
一、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
//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);
}
输出结果:
提示词1: 请简要描述机器学习的应用。
提示词2: 请简要描述自然语言处理的应用。
LLM 响应: 机器学习作为人工智能的核心分支,通过数据驱动模型实现自动化决策与预测,其应用已渗透到...
2. fromTemplate
agents.service.ts
const promptTemplate = PromptTemplate.fromTemplate(
'请给我一个关于{topic}的{type}解释。',
);
const prompt = await promptTemplate.format({
type: '详细',
topic: '量子力学',
});
console.log('提示词1:', prompt);
输出结果:
提示词1: 请给我一个关于量子力学的详细解释。
LLM 响应: 量子力学是描述微观世界(如原子、亚原子粒子等尺度)行为的核心物理理论,...
两种新的结构形式
1. 部分提示词模版
// 1. 定义模板 + 预填充部分变量(partialVariables)
const template = new PromptTemplate({
template: '请评价{product}的优缺点,包括{aspect1}和{aspect2}。',
inputVariables: ['product', 'aspect2'], // 必须传的变量
partialVariables: { aspect1: '电池续航' }, // 预填充变量
});
const prompt = await template.format({
product: '智能手机',
aspect2: '拍照质量',
});
2. 链式调用 .partial()
// 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 | list[dict] | list[object]),其中 role 是:字符串(如 "system" 、 "human" 、 "ai" )
两种实例化方式
1.使用构造方法
agents.service.ts
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);
输出结果:
提示词1: [
SystemMessage {
"content": "你是一个AI助手,你的名字叫小智",
"additional_kwargs": {},
"response_metadata": {}
},
HumanMessage {
"content": "我的问题是1+2等于几",
"additional_kwargs": {},
"response_metadata": {}
}
]
2.fromMessages
agents.service.ts
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 是同步
通用模板:
// 1. 定义通用聊天模板
const chatPromptTemplate = ChatPromptTemplate.fromMessages([
["system", "你是专业的{role}助手"],
["human", "请解答:{question}"] ]
);
1.invoke:返回 ChatPromptValue
const res = await chatPromptTemplate.invoke({
role: '编程',
question: '什么是NestJS',
});
2.format:返回纯文本字符串
const res = chatPromptTemplate.format({
role: '编程',
question: '什么是NestJS',
});
3.formatMessages:返回消息对象数组(BaseMessage[])
const res = await chatPromptTemplate.formatMessages({
role: '编程',
question: '什么是NestJS',
});
插入消息列表:MessagesPlaceholder
当你不确定消息提示模板使用什么角色,或者希望在格式化过程中 插入消息列表 时,该怎么办? 这就需要使用 MessagesPlaceholder,负责在特定位置添加消息列表。
// 创建聊天模板
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实现
// 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,说明:乘法运算