😁 作者简介:前端开发爱好者,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏:JavaScript小贴士
👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气
🔥前言:
这里是关于LangChain框架中的提示词模板使用的技巧,希望可以帮助到大家,欢迎大家的补充和纠正
一、使用LangChain的提示词模板:技巧与总结
1、格式化示例集
我们可以使用使用FewShotPromptTemplate来格式化示例集
const examples = [
{
question: "Who lived longer, Muhammad Ali or Alan Turing?",
answer: `
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
`,
},
{
question: "When was the founder of craigslist born?",
answer: `
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
`,
},
{
question: "Who was the maternal grandfather of George Washington?",
answer: `
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
`,
},
{
question:
"Are both the directors of Jaws and Casino Royale from the same country?",
answer: `
Are follow up questions needed here: Yes.
Follow up: Who is the director of Jaws?
Intermediate Answer: The director of Jaws is Steven Spielberg.
Follow up: Where is Steven Spielberg from?
Intermediate Answer: The United States.
Follow up: Who is the director of Casino Royale?
Intermediate Answer: The director of Casino Royale is Martin Campbell.
Follow up: Where is Martin Campbell from?
Intermediate Answer: New Zealand.
So the final answer is: No
`,
},
];
const examplePrompt = PromptTemplate.fromTemplate(
"Question:{question} \n {answer}"
)
const prompt = new FewShotPromptTemplate({
examples,
examplePrompt,
suffix: "Question:{input}",
inputVariables: ["input"]
})
const formatted = await prompt.format({
input: "Who was the father of Mary Ball Washington?"
})
console.log(formatted)
最后输出的示例中,会将examples中的示例加入到提示词模板的前面,组合成为完整的示例
//提示词模板输出结果
Question:Who lived longer, Muhammad Ali or Alan Turing?
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
Question:When was the founder of craigslist born?
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
Question:Who was the maternal grandfather of George Washington?
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
Question:Are both the directors of Jaws and Casino Royale from the same country?
Are follow up questions needed here: Yes.
Follow up: Who is the director of Jaws?
Intermediate Answer: The director of Jaws is Steven Spielberg.
Follow up: Where is Steven Spielberg from?
Intermediate Answer: The United States.
Follow up: Who is the director of Casino Royale?
Intermediate Answer: The director of Casino Royale is Martin Campbell.
Follow up: Where is Martin Campbell from?
Intermediate Answer: New Zealand.
So the final answer is: No
Question:Who was the father of Mary Ball Washington?
2、示例选择器来组合提示词模板
我们可以使用 SemanticSimilarityExampleSelector类来使用嵌入模型来计算输入样本和少数样本之间的相似性,并使用向量存储来执行最近邻搜索
let AzureOpenAIEmbedding = await getAzureEmbeddings()
const exampleSelecttor = await SemanticSimilarityExampleSelector.fromExamples(
examples,
AzureOpenAIEmbedding,
MemoryVectorStore,
{
k: 1
}
)
const question = "Who was the father of Mary Ball Washington?"
const selectedExamples = await exampleSelecttor.selectExamples({ question })
console.log("🚀 ~ mainScript2 ~ selectedExamples:", selectedExamples)、
/**
🚀 ~ mainScript2 ~ selectedExamples: [
{
question: 'Who was the maternal grandfather of George Washington?',
answer: '\n' +
' Are follow up questions needed here: Yes.\n' +
' Follow up: Who was the mother of George Washington?\n' +
' Intermediate answer: The mother of George Washington was Mary Ball Washington.\n' +
' Follow up: Who was the father of Mary Ball Washington?\n' +
' Intermediate answer: The father of Mary Ball Washington was Joseph Ball.\n' +
' So the final answer is: Joseph Ball\n' +
' '
}
]
**/
当调用exampleSelecttor中的selectExamples方法的时候,它会根据输入的question来使用向量搜索从示例集中找出与输入的问题最相似的示例集
3、在聊天模型中使用合适的少数示例
在提示词结构中有一个重要的概念是示例,给大模型的输入中提供示例会让输出结果更加精准,而示例选择器可以实现一个效果:根据用户的输入选择合适的示例
在langchian中是可以实现这个功能的,使用SemanticSimilarityExampleSelector示例选择器,根据用户的输入使用向量数据库匹配更加合适的例子
实现步骤:
- 先准备一些示例数据-最好是数组形式的
- 然后再实例化向量大模型
- 创建好向量数据库
- 使用模型选择器
完整的代码如下:
//1、先准备一个例子,这个例子是数组对象类型的,对象需要拥有input哥output
const examples = [
{ input: "2+2", output: "4" },
{ input: "2+3", output: "5" },
{ input: "2+4", output: "6" },
{ input: "What did the cow say to the moon?", output: "nothing at all" },
{
input: "Write me a poem about the moon",
output:
"One for the moon, and one for me, who are we to talk about the moon?",
},
];
//2、从例子中格式化数据,准备好插入到向量数据库中
const toVectorize=examples.map(
(examples)=>`${examples.input}${examples.output}`
)
//3、实例化向量数据库的查询
const vectorStore=await MemoryVectorStore.fromTexts(
toVectorize,
examples,
await getAzureEmbeddings()
)
//4、创建一个选择器
const exampleSelect=new SemanticSimilarityExampleSelector({
vectorStore,
k:1
})
//5、使用
const result=await exampleSelect.selectExamples({input:"hourse"})
// console.log("🚀 ~ mainScript4 ~ result:", result)
//6、和动态模版添加方法组合
const messsageTemplate=ChatPromptTemplate.fromMessages([
["user","{input}"],
["ai","{output}"]
])
const fewPrompt=new FewShotChatMessagePromptTemplate({
examplePrompt:messsageTemplate,
// examples:result,
exampleSelector:exampleSelect,
inputVariables:['input']
})
// //原文档有bug,这里是修复的,不可以直接传入fewShotPrompt,而是需要实例化一下,封装成为消息类型
const finalPrompt=ChatPromptTemplate.fromMessages([
["system","You are a wondrous wizard of math."],
ChatPromptTemplate.fromMessages((await fewPrompt.invoke({})).toChatMessages()),
["user","{input}"],
])
//7、模型结合使用
const azureModel=await getAzureModel()
const chain = finalPrompt.pipe(azureModel);
console.log(await chain.invoke({ input: "What's 3+3?" }))
4、如何部分格式化提示词模板
想要对提示模板进行部分分配的一个常见用例是,如果您在其他变量之前访问提示中的某些变量。例如,假设您有一个需要两个变量(foo
和 baz
)的提示模板。如果你在链的早期获得 foo
值,但后来获得 baz
值,那么在链中完全传递这两个变量可能会很不方便。相反,你可以用 foo
值对 prompt 模板进行部分化处理,然后传递部分 prompt 模板并使用它
// 第一种使用,在partial方法中进行实例化
const prompt = new PromptTemplate({
template: "{foo}{bar}",
inputVariables: ["foo", "bar"]
})
const partialPrompt = await prompt.partial({
foo: "foo"
})
const fromattedPrompt = await partialPrompt.format({
bar: "baz"
})
console.log(fromattedPrompt)
// 第二种使用,在模板初始化中进行实例化
const prompt = new PromptTemplate({
template: "{foo}{bar}",
inputVariables: ["bar"],
partialVariables: {
foo: "foo"
}
})
const formattedPrompt = await prompt.format({
bar: "baz",
})
// console.log("🚀 ~ mainScript2 ~ formattedPrompt:", formattedPrompt)