Langchain模型、提示和输出解释器

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_emailstyle结合起来构造我们的提示: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
相关推荐
IT古董28 分钟前
【漫话机器学习系列】017.大O算法(Big-O Notation)
人工智能·机器学习
凯哥是个大帅比28 分钟前
人工智能ACA(五)--深度学习基础
人工智能·深度学习
joan_8533 分钟前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
m0_748232921 小时前
DALL-M:基于大语言模型的上下文感知临床数据增强方法 ,补充
人工智能·语言模型·自然语言处理
szxinmai主板定制专家1 小时前
【国产NI替代】基于FPGA的32通道(24bits)高精度终端采集核心板卡
大数据·人工智能·fpga开发
还是大剑师兰特1 小时前
什么是尾调用,使用尾调用有什么好处?
javascript·大剑师·尾调用
海棠AI实验室1 小时前
AI的进阶之路:从机器学习到深度学习的演变(三)
人工智能·深度学习·机器学习
机器懒得学习1 小时前
基于YOLOv5的智能水域监测系统:从目标检测到自动报告生成
人工智能·yolo·目标检测
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
QQ同步助手1 小时前
如何正确使用人工智能:开启智慧学习与创新之旅
人工智能·学习·百度