赞
踩
所谓提示词Prompt
,指对模型的输入。语言模型接受一个文本作为输入,这个文本通常就指的是模板。LangChain
提供了一些类和函数,用于构建提示词模板和使用提示词模板:
从形式上来讲,提示词模板是一个字符串。它可以接受一系列参数,生成不同的模板。一个提示词模板里包含以下内容:
下面是一个简单的示例:
// 首先导入提示词模板类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? */
可以使用上述示例中的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."
对话模型接受的输入是一个聊天消息列表,这个消息列表通常被称为对话模型的提示词。聊天消息与原始字符串的区别是:每条消息都与一个角色相关联。例如,在OpenAI
的聊天模型中,聊天消息的角色可以是AI
,human
或system
等,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.' } ] */
这里我们介绍如何将多个模板组合使用。这对于对部分模板重复使用具有重要作用,其中,PipelinePrompt
可以将多个模板进行组合。PipelinePrompt
包括两个主要的组成部分:
首先,从langchain/prompts
中引入PromptTemplate
和PipelinePromptTemplate
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)
假如你有一堆选择器,想要自动选择一种包含在提示中,就可以使用示例选择器。示例选择器的接口定义是:
class BaseExampleSelector {
addExample(example: Example): Promise<void | string>;
selectExamples(input_variables: Example): Promise<Example[]>;
}
这里暴露了两个方法:
addExample
:保存一个示例,以供下一次选择selectExamples
:它接受输入变量,返回示例方法的列表这些示例如何保存和选择,取决于上述方法的具体实现。
此示例选择器是根据长度选择要使用的示例。当您担心构建的提示会超过上下文窗口的长度时,这非常有用。对于较长的输入,它将选择较少的示例来包含,而对于较短的输入,它将选择更多的示例。
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:
*/
该对象根据与输入的相似性来选择示例。它通过查找与输入具有最大余弦相似度的嵌入示例来实现这一点。
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: */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。