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
相关推荐
todoitbo5 分钟前
本地图库语义搜索实战:接上蓝耘元生代,让“傍晚的海边“能搜到图
人工智能·ai·api·工具实战
羊羊小栈10 分钟前
基于「YOLO目标检测 + 多模态AI分析」的水稻病害智能检测分析预警系统(LangChain框架)
人工智能·yolo·目标检测·毕业设计·创业创新·大作业
IT_陈寒12 分钟前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
lisw0515 分钟前
提升社会科学领域的计算可重复性
人工智能·数字时代
HyperAI超神经19 分钟前
HyperAI 入选 36氪「East Forward 2026 出海全球化拓新企业」
人工智能·深度学习·全球化企业
9呀22 分钟前
VS Code Codex 多窗口使用与补丁记录
人工智能
七仔啊25 分钟前
安防通行人脸抓拍识别
人工智能
天若有情67328 分钟前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具
guoran_shini1 小时前
SVD矩阵分解
人工智能
烟锁池塘柳01 小时前
【Agent】如何从大模型构建真正的 Agent?以 Claude Code 为例,理解能构建智能体的真正的 Harness 工程
人工智能·agent