1. 直接使用openAI
1.1 计算1+1
js
import { Configuration, OpenAIApi } from "openai";
// 1. 直接使用OpenAI API
const configuration = new Configuration({
apiKey: process.env.VUE_APP_OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
const response = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{
"role": "user",
"content": "What is 1+1?"
},],
temperature: 0,
});
// "1+1 equals 2."
console.log(response.data.choices[0].message["content"]);
1.2 用美式英语表达海盗邮件
这里海盗的英文表达可以理解为英文的方言,其与美式英语的关系,就如四川话与普通话的关系。
假设我们是电商公司员工,我们的顾客是一名海盗,他在我们的网站上买了一个榨汁机用来做奶昔,在制作奶昔的过程中,奶昔的盖子飞了出去,弄得厨房墙上到处都是。于是海盗给我们的客服中心写来以下邮件:customer_email
js
const customer_email = "Arrr, I be fuming that me blender lid \
flew off and splattered me kitchen walls \
with smoothie! And to make matters worse,\
the warranty don't cover the cost of \
cleaning up me kitchen. I need yer help \
right now, matey! \
"
客服人员对于海盗的措辞表达觉得有点难以理解。 现在我们想要实现两个小目标:
- 让模型用美式英语的表达方式将海盗的邮件进行翻译,客服人员可以更好理解。
- 让模型在翻译是用平和尊重的语气进行表达,客服人员的心情也会更好。
根据这两个小目标,定义一下文本表达风格:style
js
// 美式英语 + 平静、尊敬的语调
const customer_style = "American English \
in a calm and respectful tone \
"
下一步需要做的是将customer_email
和style
结合起来构造我们的提示:prompt
js
// 要求模型根据给出的语调进行转化
prompt = ```
Translate the text
that is delimited by triple backticks
into a style that is ${style}.
text: """${customer_email}"""
```
print(prompt)
prompt
构造好了,我们可以调用get_completion
得到我们想要的结果 - 用平和尊重的语气,美式英语表达的海盗语言邮件
TypeScript
response = get_completion(prompt)
// "Oh, I'm really frustrated because the lid of my blender fell off and splattered the milkshake all over the kitchen wall! To make matters worse, the warranty doesn't cover the cost of cleaning the kitchen. I could really use your help right now, buddy!"
2. Langchain提示模板
2.1导入ChatOpenAI
从langchain/chat_models/openai
导入OpenAI
的对话模型ChatOpenAI
。 除去OpenAI以外,langchain
还集成了其他对话模型,更多细节可以查看Langchain官方文档
javascript
import { ChatOpenAI } from "langchain/chat_models/openai";
import { PromptTemplate } from "langchain/prompts";
import { HumanChatMessage } from "langchain/schema";
const chat = new ChatOpenAI({
modelName: "gpt-3.5-turbo",
openAIApiKey: process.env.VUE_APP_OPENAI_API_KEY,
temperature: 0,
});
2.2使用LangChain提示模版
js
const customer_email = "Arrr, I be fuming that me blender lid \
flew off and splattered me kitchen walls \
with smoothie! And to make matters worse,\
the warranty don't cover the cost of \
cleaning up me kitchen. I need yer help \
right now, matey!"
const customer_style = "American English \
in a calm and respectful tone"
// 构造提示模版字符串
const template_string = "Translate the text \
that is delimited by triple backticks \
into a style that is {style}. \
text: ```{text}```"
// 构造LangChain提示模版
const prompt = PromptTemplate.fromTemplate(template_string);
const response = await prompt.format({
style: customer_style,
text: customer_email
});
// "Translate the text that is delimited by triple backticks into a style that is American English in a calm and respectful tone. text: ```Arrr, I be fuming that me blender lid flew off and splattered me kitchen walls with smoothie! And to make matters worse, the warranty don't cover the cost of cleaning up me kitchen. I need yer help right now, matey!```"
console.log(response);
2.3 调用chat模型转换客户消息风格
js
// 调用chat模型转换客户消息风格
const customerResponse = await chat.call([
new HumanChatMessage(response),
]);
// "I'm really frustrated that my blender lid flew off and made a mess on my kitchen walls with smoothie! And to make things even worse, the warranty doesn't cover the cost of cleaning up my kitchen. I would greatly appreciate your assistance at this moment, my friend."
console.log(customerResponse.content);
2.4 使用模版得到回复消息提示
接下来,我们更进一步,将客服人员回复的消息,转换为海盗的语言风格,并确保消息比较有礼貌。
js
const service_reply = "Hey there customer, \
the warranty does not cover \
cleaning expenses for your kitchen \
because it's your fault that \
you misused your blender \
by forgetting to put the lid on before \
starting the blender. \
Tough luck! See ya! \
"
const service_style_pirate = "\
a polite tone \
that speaks in English Pirate \
"
const serviceMessage = await promptTemplate.format({ style: service_style_pirate, text: service_reply });
// 调用chat模型转换客户消息风格
const serviceResponse = await chat.call([
new HumanChatMessage(serviceMessage),
]);
// "Ahoy there, matey! Thee bein' informed that the warranty be not coverin' the expenses fer cleanin' yer galley, as 'tis yer own fault fer misusin' yer blender. Ye be forgettin' to put the lid on afore startin' the blender, arrr! 'Tis a tough break, me heartie! Fare thee well!"
console.log(serviceResponse.content);
2.5 为什么需要提示模版
在应用于比较复杂的场景时,提示可能会非常长并且包含涉及许多细节。使用提示模版,可以让我们更为方便地重复使用设计好的提示。
3. 输出解析器
对于给定的评价customer_review
, 我们希望提取信息,并按以下格式输出:
js
{
"gift": False,
"delivery_days": 5,
"price_value": "pretty affordable!"
}
3.1 构造langchain提示模版
js
const chat = new ChatOpenAI({
modelName: "gpt-3.5-turbo",
openAIApiKey: process.env.VUE_APP_OPENAI_API_KEY,
temperature: 0,
});
const customer_review = "\
This leaf blower is pretty amazing. It has four settings:\
candle blower, gentle breeze, windy city, and tornado. \
It arrived in two days, just in time for my wife's \
anniversary present. \
I think my wife liked it so much she was speechless. \
So far I've been the only one using it, and I've been \
using it every other morning to clear the leaves on our lawn. \
It's slightly more expensive than the other leaf blowers \
out there, but I think it's worth it for the extra features. \
"
// 构造提示模版字符串
const review_template = ```
For the following text, extract the following information:
gift: Was the item purchased as a gift for someone else?
Answer True if yes, False if not or unknown.
delivery_days: How many days did it take for the product
to arrive? If this information is not found, output -1.
price_value: Extract any sentences about the value or price,
and output them as a comma separated Python list.
Format the output as JSON with the following keys:
gift
delivery_days
price_value
text: {text}
{format_instructions}
```
const promptTemplate = PromptTemplate.fromTemplate(review_template); const messages = await promptTemplate.format({ text: customer_review });
const response = await chat.call([ new HumanChatMessage(messages), ]);
// "{\n "gift": false,\n "delivery_days": 2,\n "price_value": ["It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features."]\n}" // `response.content`类型为字符串(`str`),而并非对象(`object`), 直接使用`get`方法会报错。因此,我们需要输出解释器。 console.log(response.content);
📝 分析与总结
response.content
类型为字符串(str
),而并非对象(object
), 直接使用get
方法会报错。因此,我们需要输出解释器。
3.2 LangChain输出解析器
TypeScript
// 创建一个ChatOpenAI实例
const chat = new ChatOpenAI({
modelName: "gpt-3.5-turbo",
openAIApiKey: process.env.VUE_APP_OPENAI_API_KEY,
temperature: 0,
});
// 客户评论的文本
const customer_review = "\
This leaf blower is pretty amazing. It has four settings:\
candle blower, gentle breeze, windy city, and tornado. \
It arrived in two days, just in time for my wife's \
anniversary present. \
I think my wife liked it so much she was speechless. \
So far I've been the only one using it, and I've been \
using it every other morning to clear the leaves on our lawn. \
It's slightly more expensive than the other leaf blowers \
out there, but I think it's worth it for the extra features. \
"
// 构造提取信息的提示模版字符串,这里增加了{format_instructions}
const review_template = "\
For the following text, extract the following information: \
gift: Was the item purchased as a gift for someone else? \
Answer True if yes, False if not or unknown. \
delivery_days: How many days did it take for the product \
to arrive? If this information is not found, output -1. \
price_value: Extract any sentences about the value or price, \
and output them as a comma separated Python list. \
Format the output as JSON with the following keys: \
gift \
delivery_days \
price_value \
text: {text} \
{format_instructions} \
"
// 创建一个StructuredOutputParser实例,用于解析提取信息的输出结果
const parser = StructuredOutputParser.fromNamesAndDescriptions({
gift: "Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown.",
delivery_days: "How many days did it take for the product to arrive? If this information is not found, output -1.",
price_value: "Extract any sentences about the value or price, and output them as a comma separated Python list."
});
// 获取格式化指令,用于在模板中替换format_instructions占位符
const formatInstructions = parser.getFormatInstructions();
// 创建一个PromptTemplate实例,用于格式化模板并传递相应的变量
const prompt = new PromptTemplate({
template: review_template,
inputVariables: ["text"],
partialVariables: { format_instructions: formatInstructions },
});
// 使用PromptTemplate的format方法,将客户评论的文本进行格式化,替换模板中的变量
const messages = await prompt.format({
text: customer_review,
});
console.log(messages);
// 使用chat.call方法执行一个聊天对话,并传入经过格式化的客户评论
const response = await chat.call([
new HumanChatMessage(messages),
]);
// 使用StructuredOutputParser的parse方法,解析聊天模型的响应结果,提取特定的信息
const output_dict = await parser.parse(response.content)
console.log(output_dict);
此时messages
的输出如下
js
For the following text, extract the following information: gift: Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown. delivery_days: How many days did it take for the product to arrive? If this information is not found, output -1. price_value: Extract any sentences about the value or price, and output them as a comma separated Python list. Format the output as JSON with the following keys: gift delivery_days price_value text: This leaf blower is pretty amazing. It has four settings: candle blower, gentle breeze, windy city, and tornado. It arrived in two days, just in time for my wife's anniversary present. I think my wife liked it so much she was speechless. So far I've been the only one using it, and I've been using it every other morning to clear the leaves on our lawn. It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features. You must format your output as a JSON value that adheres to a given "JSON Schema" instance.
"JSON Schema" is a declarative language that allows you to annotate and validate JSON documents.
For example, the example "JSON Schema" instance {{"properties": {{"foo": {{"description": "a list of test words", "type": "array", "items": {{"type": "string"}}}}}}, "required": ["foo"]}}}}
would match an object with one required property, "foo". The "type" property specifies "foo" must be an "array", and the "description" property semantically describes it as "a list of test words". The items within "foo" must be strings.
Thus, the object {{"foo": ["bar", "baz"]}} is a well-formatted instance of this example "JSON Schema". The object {{"properties": {{"foo": ["bar", "baz"]}}}} is not well-formatted.
Your output will be parsed and type-checked according to the provided schema instance, so make sure all fields in your output match the schema exactly and there are no trailing commas!
Here is the JSON Schema instance your output must adhere to. Include the enclosing markdown codeblock:
```json
{"type":"object","properties":{"gift":{"type":"string","description":"Was the item purchased as a gift for someone else? Answer True if yes, False if not or unknown."},"delivery_days":{"type":"string","description":"How many days did it take for the product to arrive? If this information is not found, output -1."},"price_value":{"type":"string","description":"Extract any sentences about the value or price, and output them as a comma separated Python list."}},"required":["gift","delivery_days","price_value"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
```
调用chat模型提取信息,并使用输出解析器解析输出
js
// 使用chat.call方法执行一个聊天对话,并传入经过格式化的客户评论
const response = await chat.call([
new HumanChatMessage(messages),
]);
// 使用StructuredOutputParser的parse方法,解析聊天模型的响应结果,提取特定的信息
const output_dict = await parser.parse(response.content)
console.log(output_dict);
输出结果如下
js
{
"gift": "False",
"delivery_days": "2",
"price_value": "It's slightly more expensive than the other leaf blowers out there, but I think it's worth it for the extra features."
}
📝 分析与总结
output_dict
类型为json
, 可直接使用get
方法。这样的输出更方便下游任务的处理。
js
typeof output_dict // object