[LangChain] 04. 提示词模板

在使用 LangChain 构建大模型应用时,提示词(Prompt)设计是第一步。但直接写死字符串容易出错、复用性差,也不利于维护。这时候就该用上 LangChain 提供的 Prompt Template —— 一个专为语言模型设计的提示词模板工具。

快速上手

无变量,纯字符串模板

import { PromptTemplate } from "@langchain/core/prompts";

// 创建一个最简单的提示模板
const prompt = new PromptTemplate({
  inputVariables: [], // 变量列表
  template: "Hello, AI!", // 模板
});

// 使用 format 方法格式化模板(此处无变量)
const result = await prompt.format();

console.log(result); // Hello, AI!

有变量,嵌入到字符串模板

import { PromptTemplate } from "@langchain/core/prompts";

// 创建一个包含变量的提示模板
const prompt = new PromptTemplate({
  inputVariables: ["user"], // 在这个数组里面,声明有哪些变量
  template: "Hi, {user}!", // 使用了 {} 作为变量名的容器
});

// 使用 format 方法替换变量
// 需要提供变量的值
const output = await prompt.format({
  user: "Alex",
});

console.log(output); // Hi, Alex!

嵌入多个变量:

import { PromptTemplate } from "@langchain/core/prompts";

// 定义一个多变量模板
const prompt = new PromptTemplate({
  inputVariables: ["period", "user"], // 会用到2个变量
  template: "Good {period}, {user}!",
});

// 提供对应的变量值进行格式化
const result = await prompt.format({
  period: "evening",
  user: "Lynn",
});

console.log(result); // Good evening, Lynn!

如果你想在最终结果中保留 {} 字符,比如输出 {debug}{info},可以使用 {{}} 进行转义:

import { PromptTemplate } from "@langchain/core/prompts";

// 创建一个包含变量的提示模板
const prompt = new PromptTemplate({
  inputVariables: ["info"],
  template: "{{debug}}: 当前调试的信息为{info}",
});

// 使用 format 方法替换变量
// 需要提供变量的值
const output = await prompt.format({
  info: "日志已经上传至数据库",
});

console.log(output);

这样就不会被当作变量解析,而是原样输出 {debug}

静态方法

PromptTemplate.fromTemplate() 用来快速创建模板:

import { PromptTemplate } from "@langchain/core/prompts";

const pt = PromptTemplate.fromTemplate(
  "你是一位精通{subject}的专家,请用{language}来回答用户的问题"
);
console.log(pt.inputVariables); // [ 'subject', 'language' ]

const result = await pt.format({
  subject: "生物学",
  language: "中文",
});
console.log(result); // 你是一位精通生物学的专家,请用中文来回答用户的问题

通过这种方式,我们无需手动声明 inputVariables,LangChain 会自动从模板字符串中识别 {} 包裹的变量,是构建快速模板的理想选择。

prompt.inputVariables // ["subject", "language"]

部分填充

我们有时并不会一次性拿到所有的变量数据。这时就可以先传入一部分变量生成一个“部分填充”的模板,后续再继续补全 —— 这与函数式编程中的柯里化(Currying)思路非常相似。

import { PromptTemplate } from "@langchain/core/prompts";

const pt = PromptTemplate.fromTemplate(
  "你是一位精通{subject}的专家,请用{language}来回答用户的问题:{info}"
);
const pt2 = await pt.partial({
  subject: "生物学",
});
const pt3 = await pt2.partial({
  language: "中文",
});
const result = await pt3.format({
  info: "大象的鼻子为什么那么长",
});
console.log(result);

动态生成变量值

在某些场景下,我们希望在模板格式化时动态生成变量值,比如当前时间、随机数或用户上下文。

此时可以在 partial 方法中传入一个函数,而不是固定的值。

之后在调用 .format() 时,函数会自动执行,生成实际变量内容。

import { PromptTemplate } from "@langchain/core/prompts";

// 定义一个函数,获取当前的日期
const getToday = () => new Date().toLocaleDateString();

const pt = PromptTemplate.fromTemplate("今天是{date},今天的活动是:{event}");

const pt2 = await pt.partial({
  date: getToday,
});

const result = await pt2.format({
  event: "出去郊游",
});
console.log(result);

另外一个示例:

import { PromptTemplate } from "@langchain/core/prompts";

// 获取当前日期
const getDate = () => new Date().toLocaleDateString();

function createGreeting(period) {
  const date = getDate(); // 获取了当前的日期
  if (period === "早上") return `${date},早上好`;
  if (period === "下午") return `${date},下午好`;
  if (period === "晚上") return `${date},晚上好`;
  return `${date},你好`;
}

// 定义提示模板
const prompt = new PromptTemplate({
  template: "{greeting}!欢迎回来。",
  inputVariables: ["greeting"],
});

// 设置当前时间段
const timePeriod = "下午";

// 传入函数,而不是字符串
const partialPrompt = await prompt.partial({
  greeting: createGreeting(timePeriod),
});

const result = await partialPrompt.format();

console.log(result); // 8/6/2025,下午好!欢迎回来。

构建少样本提示词

🤔什么是少样本提示词?

少样本学习(few-shot learning),也称之为少样本提示,这是一种范式,在这种范式中,模型通过提示词获得你希望模型执行的任务示例。

示例:

例子:
评论:这个产品真不错,用得很顺手! → 情感:正面
评论:完全失望,质量太差了。 → 情感:负面
评论:快递到了。 → 情感:中性

评论:外观还行,性能一般般。 → 情感:
例子:
句子:马云是阿里巴巴的创始人。  
实体:[马云: 人名], [阿里巴巴: 组织]

句子:乔布斯出生在旧金山。  
实体:[乔布斯: 人名], [旧金山: 地点]

句子:李雷明天去北京出差。  
实体:

PromptTemplate.fromExamples() 已经不推荐使用,在 @langchain/core@0.3.x 版本中已经逐步转向使用 FewShotPromptTemplate

import { PromptTemplate, FewShotPromptTemplate } from "@langchain/core/prompts";

const examples = [
  { input: "apple", output: "苹果" },
  { input: "banana", output: "香蕉" },
  { input: "orange", output: "橙子" },
];

// 每个示例的模板
const examplePt = PromptTemplate.fromTemplate(
  "输入: {input} --- 输出: {output}"
);

const pt = new FewShotPromptTemplate({
  examples, // 示例的数组
  examplePrompt: examplePt, // 示例的模板
  suffix: "输入: {fruit} --- 输出: ",
  inputVariables: ["fruit"],
});

const result = await pt.format({
  fruit: "grape",
});
console.log(result);

课堂练习

生成情感反馈的 few-shot 提示词

参考答案

import { PromptTemplate, FewShotPromptTemplate } from "@langchain/core/prompts";

const examples = [
  { comment: "这个产品真不错,用得很顺手!", sentiment: "正面" },
  { comment: "完全失望,质量太差了。", sentiment: "负面" },
  { comment: "快递到了。", sentiment: "中性" },
];

// 每个示例的模板
const examplePt = PromptTemplate.fromTemplate(
  "评论:{comment} → 情感:{sentiment}"
);

const pt = new FewShotPromptTemplate({
  examples, // 示例的数组
  examplePrompt: examplePt, // 示例的模板
  suffix: "评论:{comment} → 情感: ",
  inputVariables: ["comment"],
});

const result = await pt.format({
  comment: "外观还行,性能一般般",
});
console.log(result);

-EOF-

posted @ 2025-10-18 17:55  Zhentiw  阅读(3)  评论(0)    收藏  举报