LangChain: 提示词


在这里插入图片描述

1、提示词模板

所谓提示词Prompt,指对模型的输入。语言模型接受一个文本作为输入,这个文本通常就指的是模板。LangChain提供了一些类和函数,用于构建提示词模板和使用提示词模板:

  • 提示词模板:参数化模型输入
  • 示例选择器:动态选择要包含在提示词中的示例

1.1 什么是提示词模板

从形式上来讲,提示词模板是一个字符串。它可以接受一系列参数,生成不同的模板。一个提示词模板里包含以下内容:

  • 对于语言模型的介绍
  • 一组简洁的示例,帮助语言模型生成一个更好的响应
  • 对语言模型的提问

下面是一个简单的示例:

// 首先导入提示词模板类PromptTemplate
import { PromptTemplate } from "langchain/prompts";

// 传入一个模板,语言模型会自动从模板中推断出输入变量
const prompt = PromptTemplate.fromTemplate(
  `You are a naming consultant for new companies.
What is a good name for a company that makes {product}?`
);

// product是该模板的参数
const formattedPrompt = await prompt.format({
  product: "colorful socks",
});

// 格式化模板后,会得到如下的结果。可以看到,输入的变量被自动添加到了提示词模板变量的位置
/*
  You are a naming consultant for new companies.
  What is a good name for a company that makes colorful socks?
*/

1.2 创建一个提示词模板

可以使用上述示例中的PromptTemplate类,创建一个硬编码的提示词模板。提示词模板可以接受任意数量的输入变量,并且可以被格式化来生成模板。下面列举几种生成提示词模板的方法:

首先引入PromptTemplate类:

import { PromptTemplate } from "langchain/prompts";
  • 生成无参数的提示词模板
const noInputPrompt = new PromptTemplate({
  inputVariables: [], // 没有参数,inputVariables为空
  template: "Tell me a joke.",
});
const formattedNoInputPrompt = await noInputPrompt.format();

console.log(formattedNoInputPrompt);
// "Tell me a joke."
  • 包含一个参数的提示词模板
const oneInputPrompt = new PromptTemplate({
  inputVariables: ["adjective"], // 一个参数:adjective
  template: "Tell me a {adjective} joke."
})
const formattedOneInputPrompt = await oneInputPrompt.format({
  adjective: "funny",
});

console.log(formattedOneInputPrompt);
// "Tell me a funny joke."
  • 生成包含多个参数的提示词模板
const multipleInputPrompt = new PromptTemplate({
  inputVariables: ["adjective", "content"], // 多个参数
  template: "Tell me a {adjective} joke about {content}.",
});
// .format参数进行格式化,并传入参数
const formattedMultipleInputPrompt = await multipleInputPrompt.format({
  adjective: "funny",
  content: "chickens",
});

console.log(formattedMultipleInputPrompt);
// "Tell me a funny joke about chickens."
  • 使用fromTemplate生成提示词模板。如果你不想手动设定inputVariables,则可以使用fromTemplate来生成提示词模板。
// 编写模板
const template = "Tell me a {adjective} joke about {content}.";

const promptTemplate = PromptTemplate.fromTemplate(template);
console.log(promptTemplate.inputVariables); // 获取模板参数
// ['adjective', 'content']

// 格式化模板
const formattedPromptTemplate = await promptTemplate.format({
  adjective: "funny",
  content: "chickens",
});
console.log(formattedPromptTemplate); // 最终生成的模板
// "Tell me a funny joke about chickens."

1.3 对话提示词模板

对话模型接受的输入是一个聊天消息列表,这个消息列表通常被称为对话模型的提示词。聊天消息与原始字符串的区别是:每条消息都与一个角色相关联。例如,在OpenAI的聊天模型中,聊天消息的角色可以是AI,humansystem等,LangChain也针对这些角色分别提供了不同的提示词生成类,如AIMessagePromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate等。如下为LangChain所提供的提示词模板:

import {
  ChatPromptTemplate,
  PromptTemplate,
  SystemMessagePromptTemplate,
  AIMessagePromptTemplate,
  HumanMessagePromptTemplate,
} from "langchain/prompts";

在调用聊天模型时,可以使用这些类来替换PromptTemplate生成提示词。有时候,为了使用方便,也可以将消息提示模板声明成为一个数组,如:

// 定义两个消息模板:系统模板和人工模板
const systemTemplate = "You are a helpful assistant that translates {input_language} to {output_language}.";
const humanTemplate = "{text}";

// 形成一个聊天模板
const chatPrompt = ChatPromptTemplate.fromMessages([
  ["system", systemTemplate],
  ["human", humanTemplate],
]);

// 格式化消息
const formattedChatPrompt = await chatPrompt.formatMessages({
  input_language: "English",
  output_language: "French",
  text: "I love programming.",
});

console.log(formattedChatPrompt);
// 结果
/*
  [
    SystemMessage {
      content: 'You are a helpful assistant that translates English to French.'
    },
    HumanMessage {
      content: 'I love programming.'
    }
  ]
*/

1.4 部分提示词模板举例

  • 字符串形式
  • 函数形式

1.5 提示词模板组合使用

这里我们介绍如何将多个模板组合使用。这对于对部分模板重复使用具有重要作用,其中,PipelinePrompt可以将多个模板进行组合。PipelinePrompt包括两个主要的组成部分:

  • Final prompt:最后返回的提示
  • Pipeline prompts:一个由提示词名称和提示词模板组成的元组,每一个提示词都将会被格式化,并且会作为具有相同名称的变量传递到未来的提示模板。

首先,从langchain/prompts中引入PromptTemplatePipelinePromptTemplate

import { PromptTemplate, PipelinePromptTemplate } from "langchain/prompts";

下面,通过PromptTemplate.fromTemplate方法,开始定义多个提示词模板。这里我们定义了四个模板,分别为:

  • fullPrompt:是用于最终会返回的模板,包括三个变量{introduction},{example},{start},当finalPrompt使用这个模板时,pipelinePrompts就应该输入包括这三个变量的模板。
  • introductionPrompt:包含一个变量person
  • examplePrompt:包含两个变量example_q,example_a
  • startPrompt:包含一个变量input
// 全部模板
const fullPrompt = PromptTemplate.fromTemplate(`{introduction}

{example}

{start}`);

const introductionPrompt = PromptTemplate.fromTemplate(
  `You are impersonating {person}.`
);

const examplePrompt =
  PromptTemplate.fromTemplate(`Here's an example of an interaction:
Q: {example_q}
A: {example_a}`);

const startPrompt = PromptTemplate.fromTemplate(`Now, do this for real!
Q: {input}
A:`);

最后,通过PipelinePromptTemplate创建一个组合模板,并使用.format方法,获得一个格式化的模板:

const composedPrompt = new PipelinePromptTemplate({
  pipelinePrompts: [
    {
      name: "introduction",
      prompt: introductionPrompt,
    },
    {
      name: "example",
      prompt: examplePrompt,
    },
    {
      name: "start",
      prompt: startPrompt,
    },
  ],
  finalPrompt: fullPrompt,
});

const formattedPrompt = await composedPrompt.format({
  person: "Elon Musk",
  example_q: `What's your favorite car?`,
  example_a: "Telsa",
  input: `What's your favorite social media site?`,
});

打印formattedPrompt,可得到如下的结果:

console.log(formattedPrompt);

/*
  You are impersonating Elon Musk.

  Here's an example of an interaction:
  Q: What's your favorite car?
  A: Telsa

  Now, do this for real!
  Q: What's your favorite social media site?
  A:
*/

可以看到,这是一个将三个模板组合得到的模板。将这个模板通过如下方式传入到大语言模型,即可进行问到:

const model = new OpenAI({
    openAIApiKey: OPENAI_API_KEY,
    temperature: 0
})

let result = await model.call(formattedPrompt)

2、示例选择器

假如你有一堆选择器,想要自动选择一种包含在提示中,就可以使用示例选择器。示例选择器的接口定义是:

class BaseExampleSelector {
  addExample(example: Example): Promise<void | string>;

  selectExamples(input_variables: Example): Promise<Example[]>;
}

这里暴露了两个方法:

  • addExample:保存一个示例,以供下一次选择
  • selectExamples:它接受输入变量,返回示例方法的列表

这些示例如何保存和选择,取决于上述方法的具体实现。

2.1 通过长度选择

此示例选择器是根据长度选择要使用的示例。当您担心构建的提示会超过上下文窗口的长度时,这非常有用。对于较长的输入,它将选择较少的示例来包含,而对于较短的输入,它将选择更多的示例。

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

创建一个提示词模板,它将会被用于格式化示例。

const examplePrompt = new PromptTemplate({
  inputVariables: ["input", "output"],
  template: "Input: {input}\nOutput: {output}",
});

创建一个基于长度的LengthBasedExampleSelector选择器,它将会被用于选择一个示例

const exampleSelector = await LengthBasedExampleSelector.fromExamples(
  [
    { input: "happy", output: "sad" },
    { input: "tall", output: "short" },
    { input: "energetic", output: "lethargic" },
    { input: "sunny", output: "gloomy" },
    { input: "windy", output: "calm" },
  ],
  {
    examplePrompt,
    maxLength: 25,
  }
);

创建一个FewShotPromptTemplate模板,它也会被用于示例选择

const dynamicPrompt = new FewShotPromptTemplate({
 // We provide an ExampleSelector instead of examples.
 exampleSelector,
 examplePrompt,
 prefix: "Give the antonym of every input",
 suffix: "Input: {adjective}\nOutput:",
 inputVariables: ["adjective"],
});

使用一个长度较小的输入,所以它会选择所有的示例。

console.log(await dynamicPrompt.format({ adjective: "big" }));
/*
 Give the antonym of every input

 Input: happy
 Output: sad

 Input: tall
 Output: short

 Input: energetic
 Output: lethargic

 Input: sunny
 Output: gloomy

 Input: windy
 Output: calm

 Input: big
 Output:
 */

这里使用一个长度较长的输入,它只会选择其中一个示例。

const longString =
  "big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else";
console.log(await dynamicPrompt.format({ adjective: longString }));
/*
 Give the antonym of every input

 Input: happy
 Output: sad

 Input: big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else
 Output:
 */

2.2 通过相似度选择

该对象根据与输入的相似性来选择示例。它通过查找与输入具有最大余弦相似度的嵌入示例来实现这一点。

import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import {
  SemanticSimilarityExampleSelector,
  PromptTemplate,
  FewShotPromptTemplate,
} from "langchain/prompts";
import { HNSWLib } from "langchain/vectorstores/hnswlib";

// 创建一个用于示例选择的提示词模板
const examplePrompt = new PromptTemplate({
  inputVariables: ["input", "output"],
  template: "Input: {input}\nOutput: {output}",
});

// 创建一个基于语法相似度SemanticSimilarityExampleSelector的选择器
const exampleSelector = await SemanticSimilarityExampleSelector.fromExamples(
  [
    { input: "happy", output: "sad" },
    { input: "tall", output: "short" },
    { input: "energetic", output: "lethargic" },
    { input: "sunny", output: "gloomy" },
    { input: "windy", output: "calm" },
  ],
  new OpenAIEmbeddings(),
  HNSWLib,
  { k: 1 }
);

// 创建一个FewShotPromptTemplate进行示例选择
const dynamicPrompt = new FewShotPromptTemplate({
  // We provide an ExampleSelector instead of examples.
  exampleSelector,
  examplePrompt,
  prefix: "Give the antonym of every input",
  suffix: "Input: {adjective}\nOutput:",
  inputVariables: ["adjective"],
});

// 使用天气相关的作为输入
console.log(await dynamicPrompt.format({ adjective: "rainy" }));
// 所以,输出也是天气相关
/*
 Give the antonym of every input

 Input: sunny
 Output: gloomy

 Input: rainy
 Output:
 */

// 使用一个测量相关的输入,所以会得到例如tall/short的示例
console.log(await dynamicPrompt.format({ adjective: "large" }));
/*
 Give the antonym of every input

 Input: tall
 Output: short

 Input: large
 Output:
 */
### LangChain Prompt Templates 的概述 LangChain 是一种用于构建语言模型应用程序的强大框架,其中 `Prompt Templates` 起到了核心作用。以下是关于 LangChain 中提示模板的相关介绍: #### 1. **String PromptTemplates** 这是最基础的一种提示模板形式,适用于简单的字符串操作场景。它允许开发者定义一个固定的字符串结构,并通过变量填充动态内容。 示例代码如下: ```python from langchain import PromptTemplate template = "What is a good name for a company that makes {product}?" prompt = PromptTemplate(input_variables=["product"], template=template) formatted_prompt = prompt.format(product="colorful socks") print(formatted_prompt) ``` 上述代码展示了如何利用 String PromptTemplates 创建并格式化提示语句[^1]。 --- #### 2. **ChatPromptTemplates** 这种类型的提示模板专为对话型应用设计,支持多轮交互以及复杂的消息处理逻辑。它可以组合多个消息组件(如人类提问、AI回复等),从而实现更自然流畅的对话体验。 下面是一个 ChatPromptTemplates 使用的例子: ```python from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, AIMessagePromptTemplate, ) system_template = "You are Qwen, an AI assistant who follows instructions extremely well." human_template = "{question}" ai_template = "The answer to your question is..." system_message_prompt = SystemMessagePromptTemplate.from_template(system_template) human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) ai_message_prompt = AIMessagePromptTemplate.from_template(ai_template) chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt, ai_message_prompt]) messages = chat_prompt.format_messages(question="How do I optimize my website?") for message in messages: print(message.content) ``` 此代码片段说明了如何配置系统角色、用户输入及 AI 输出的内容结构。 --- #### 3. **Few-Shot Learning with Examples** 为了进一步提升大语言模型的表现能力,“少样本学习”成为了一种常用策略。“Few-shot learning”的基本思路是在实际请求之前向模型展示若干示范案例,帮助其理解任务需求。 例如,当希望让模型生成特定风格的文章摘要时,可以通过以下方式设置 few-shot 提示模板: ```python from langchain.prompts.example_selector import LengthBasedExampleSelector from langchain.prompts.prompt import PromptTemplate from langchain.prompts.few_shot import FewShotPromptTemplate examples = [ {"input": "Apple", "output": "A fruit"}, {"input": "Carrot", "output": "A vegetable"} ] example_formatter_template = """Input: {input}\nOutput: {output}""" example_prompt = PromptTemplate( input_variables=["input", "output"], template=example_formatter_template ) dynamic_example_selector = LengthBasedExampleSelector(examples=examples, example_prompt=example_prompt, max_length=50) few_shot_prompt = FewShotPromptTemplate( example_selector=dynamic_example_selector, example_prompt=example_prompt, prefix="Classify the following items into categories.", suffix="\n\nInput: {new_input}\nOutput:", input_variables=["new_input"] ) final_prompt = few_shot_prompt.format(new_input="Banana") print(final_prompt) ``` 以上脚本演示了如何基于长度筛选合适的样例集合,并将其嵌入到最终提交给模型的任务描述之中[^3]。 --- #### 4. **自定义与扩展** 除了内置的标准功能外,LangChain 还提供了高度可定制化的接口,使得开发人员能够针对具体业务场景调整优化提示机制。比如引入外部数据源作为上下文补充材料;或者结合条件分支判断逻辑增强灵活性等等[^2]。 --- ### 总结 通过对 LangChain 提示模板的学习与实践,不仅可以简化日常工作中涉及的人工干预环节,而且有助于挖掘更大潜力释放出来的大规模预训练模型价值所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值