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
相关推荐
AAA小肥杨4 分钟前
2025人工智能AI新突破:PINN内嵌物理神经网络火了
人工智能·深度学习·神经网络·ai·大模型部署
堕落年代8 分钟前
Vue主流的状态保存框架对比
前端·javascript·vue.js
没资格抱怨9 分钟前
el-pagination的使用说明
javascript·vue.js·elementui
冴羽19 分钟前
Svelte 最新中文文档教程(22)—— Svelte 5 迁移指南
前端·javascript·svelte
青红光硫化黑28 分钟前
React基础之useEffect
javascript·react.js·ecmascript
bin915335 分钟前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14基础固定表头示例
前端·javascript·vue.js·ecmascript·deepseek
梓羽玩Python40 分钟前
太牛了!OWL:Manus 最强开源复现,开源框架GAIA基准测试中排第一!
人工智能·python
二川bro43 分钟前
TensorFlow.js 全面解析:在浏览器中构建机器学习应用
javascript·机器学习·tensorflow
颜酱43 分钟前
后台系统从零搭建(三)—— 具体页面之部门管理(抽离通用的增删改查逻辑)
前端·javascript·react.js
qq_3325394543 分钟前
JavaScript性能优化实战指南
前端·javascript·性能优化