langchain 快速入门,使用聊天模型 (js版)

本文介绍了如何使用LangChain库与OpenAI的聊天模型进行交互,包括安装设置、发送单条或多条消息、使用模板和提示进行翻译,以及如何构建和使用工具和代理来扩展模型的功能。此外,还提到了状态管理和流式API的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速入门,使用聊天模型

聊天模型是语言模型的一种变体。
虽然聊天模型在内部使用语言模型,但它们公开的接口略有不同。
它们不是公开“文本输入,文本输出”的 API,而是公开一个接口,其中“聊天消息”是输入和输出。

聊天模型 API 相当新,因此我们仍在确定正确的抽象。

安装和设置

要开始使用聊天模型,请按照安装说明安装 LangChain。

入门指南

本节介绍如何开始使用聊天模型。该接口基于消息而不是原始文本。

import { ChatOpenAI } from "langchain/chat_models/openai";
import { HumanChatMessage, SystemChatMessage } from "langchain/schema";

const chat = new ChatOpenAI({ temperature: 0 });

在这里,我们使用存储在环境变量OPENAI_API_KEYAZURE_OPENAI_API_KEY中的 API 密钥创建聊天模型。在本节中,我们将调用此聊天模型。

注意,如果您正在使用 Azure OpenAI,请确保还设置了环境变量 AZURE_OPENAI_API_INSTANCE_NAMEAZURE_OPENAI_API_DEPLOYMENT_NAMEAZURE_OPENAI_API_VERSION

聊天模型:输入消息,输出消息

您可以通过向聊天模型传递一个或多个消息来获取聊天完成。响应也将是一条消息。目前在 LangChain 中支持的消息类型有 AIChatMessageHumanChatMessageSystemChatMessage 和通用的 ChatMessage – ChatMessage 接受一个任意的角色参数,这里我们不会使用。大多数情况下,您只需要处理 HumanChatMessageAIChatMessageSystemChatMessage

const response = await chat.call([
  new HumanChatMessage(
    "Translate this sentence from English to French. I love programming."
  ),
]);

console.log(response);
AIChatMessage { text: "J'aime programmer." }
多条消息

OpenAI 的基于聊天的模型(目前为 gpt-3.5-turbogpt-4,在 Azure OpenAI 的情况下为 gpt-4-32k)支持多条消息作为输入。有关更多信息,请参见此处。以下是向聊天模型发送系统和用户消息的示例:

注意,如果您正在使用 Azure OpenAI,请确保将部署名称更改为您选择的模型的部署名称。

const responseB = await chat.call([
  new SystemChatMessage(
    "You are a helpful assistant that translates English to French."
  ),
  new HumanChatMessage("Translate: I love programming."),
]);

console.log(responseB);
AIChatMessage { text: "J'aime programmer." }
多个完成

您可以更进一步,使用 generate 为多组消息生成完成。这将返回一个带有额外消息参数的 LLMResult。

const responseC = await chat.generate([
  [
    new SystemChatMessage(
      "You are a helpful assistant that translates English to French."
    ),
    new HumanChatMessage(
      "Translate this sentence from English to French. I love programming."
    ),
  ],
  [
    new SystemChatMessage(
      "You are a helpful assistant that translates English to French."
    ),
    new HumanChatMessage(
      "Translate this sentence from English to French. I love artificial intelligence."
    ),
  ],
]);

console.log(responseC);
{
  generations: [
    [
      {
        text: "J'aime programmer.",
        message: AIChatMessage { text: "J'aime programmer." },
      }
    ],
    [
      {
        text: "J'aime l'intelligence artificielle.",
        message: AIChatMessage { text: "J'aime l'intelligence artificielle." }
      }
    ]
  ]
}

聊天提示模板:管理聊天模型的提示

您可以使用 MessagePromptTemplate 使用模板。您可以从一个或多个 MessagePromptTemplates 构建一个 ChatPromptTemplate。您可以使用 ChatPromptTemplateformatPromptValue – 这将返回一个 PromptValue,您可以将其转换为字符串或 Message 对象,具体取决于您是否想将格式化值用作 llm 或聊天模型的输入。

继续上一个示例:

import {
  SystemMessagePromptTemplate,
  HumanMessagePromptTemplate,
  ChatPromptTemplate,
} from "langchain/prompts";

首先,我们创建一个可重用的模板:

const translationPrompt = ChatPromptTemplate.fromPromptMessages([
  SystemMessagePromptTemplate.fromTemplate(
    "You are a helpful assistant that translates {input_language} to {output_language}."
  ),
  HumanMessagePromptTemplate.fromTemplate("{text}"),
]);

然后,我们可以使用该模板生成响应:

const responseA = await chat.generatePrompt([
  await translationPrompt.formatPromptValue({
    input_language: "English",
    output_language: "French",
    text: "I love programming.",
  }),
]);

console.log(responseA);
{
  generations: [
    [
      {
        text: "J'aime programmer.",
        message: AIChatMessage { text: "J'aime programmer." }
      }
    ]
  ]
}

模型 + 提示 = LLMChain

这种要求完成格式化提示的模式非常常见,因此我们引入了下一个拼图:LLMChain

const chain = new LLMChain({
  prompt: translationPrompt,
  llm: chat,
});

然后,您可以调用该链:

const responseB = await chain.call({
  input_language: "English",
  output_language: "French",
  text: "I love programming.",
});

console.log(responseB);
{ text: "J'aime programmer." }

代理:根据用户输入动态运行链

最后,我们介绍工具和代理,它们通过其他功能(例如搜索或计算器)扩展模型。

工具是一个函数,它接受一个字符串(例如搜索查询)并返回一个字符串(例如搜索结果)。它们还有一个名称和描述,这些名称和描述由聊天模型用于识别应调用哪个工具。

class Tool {
  name: string;
  description: string;
  call(arg: string): Promise<string>;
}

代理是一个无状态的包装器,它包装了代理提示链(例如 MRKL),并负责将工具格式化到提示中,以及解析从聊天模型获取的响应。

interface AgentStep {
  action: AgentAction;
  observation: string;
}

interface AgentAction {
  tool: string; // Tool.name
  toolInput: string; // Tool.call argument
}

interface AgentFinish {
  returnValues: object;
}

class Agent {
  plan(steps: AgentStep[], inputs: object): Promise<AgentAction | AgentFinish>;
}

为了使代理更加强大,我们需要使它们迭代,即多次调用模型,直到它们到达最终答案。这就是 AgentExecutor 的工作。

class AgentExecutor {
  // a simplified implementation
  run(inputs: object) {
    const steps = [];
    while (true) {
      const step = await this.agent.plan(steps, inputs);
      if (step instanceof AgentFinish) {
        return step.returnValues;
      }
      steps.push(step);
    }
  }
}

最后,我们可以使用 AgentExecutor 来运行代理:

// Define the list of tools the agent can use
const tools = [
  new SerpAPI(process.env.SERPAPI_API_KEY, {
    location: "Austin,Texas,United States",
    hl: "en",
    gl: "us",
  }),
];
// Create the agent from the chat model and the tools
const agent = ChatAgent.fromLLMAndTools(new ChatOpenAI(), tools);
// Create an executor, which calls to the agent until an answer is found
const executor = AgentExecutor.fromAgentAndTools({ agent, tools });

const responseG = await executor.run(
  "How many people live in canada as of 2023?"
);

console.log(responseG);
38,626,704.

内存:将状态添加到链和代理

您还可以使用链来存储状态。这对于例如聊天机器人非常有用,您希望跟踪对话历史记录。MessagesPlaceholder 是一个特殊的提示模板,将在每次调用中用传递的消息替换。

const chatPrompt = ChatPromptTemplate.fromPromptMessages([
  SystemMessagePromptTemplate.fromTemplate(
    "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know."
  ),
  new MessagesPlaceholder("history"),
  HumanMessagePromptTemplate.fromTemplate("{input}"),
]);

const chain = new ConversationChain({
  memory: new BufferMemory({ returnMessages: true, memoryKey: "history" }),
  prompt: chatPrompt,
  llm: chat,
});

链将在内部累积发送到模型的消息和接收到的消息。然后它将在下一次调用时将消息注入提示中。因此,您可以多次调用链,它会记住以前的消息:

const responseH = await chain.call({
  input: "hi from London, how are you doing today",
});

console.log(responseH);
{
  response: "Hello! As an AI language model, I don't have feelings, but I'm functioning properly and ready to assist you with any questions or tasks you may have. How can I help you today?"
}
const responseI = await chain.call({
  input: "Do you know where I am?",
});

console.log(responseI);
{
  response: "Yes, you mentioned that you are from London. However, as an AI language model, I don't have access to your current location unless you provide me with that information."
}

流式

您还可以使用流式 API,以便在生成单词时将其流式传回。这对于例如聊天机器人非常有用,您希望在生成时向用户显示正在生成的内容。注意:在启用流式传输时,OpenAI 在撰写本文时不支持 tokenUsage 报告。

import { ChatOpenAI } from "langchain/chat_models/openai";
import { HumanChatMessage } from "langchain/schema";

const chat = new ChatOpenAI({
  streaming: true,
  callbacks: [
    {
      handleLLMNewToken(token: string) {
        process.stdout.write(token);
      },
    },
  ],
});

await chat.call([
  new HumanChatMessage("Write me a song about sparkling water."),
]);
/*
Verse 1:
Bubbles rise, crisp and clear
Refreshing taste that brings us cheer
Sparkling water, so light and pure
Quenches our thirst, it's always secure

Chorus:
Sparkling water, oh how we love
Its fizzy bubbles and grace above
It's the perfect drink, anytime, anyplace
Refreshing as it gives us a taste

Verse 2:
From morning brunch to evening feast
It's the perfect drink for a treat
A sip of it brings a smile so bright
Our thirst is quenched in just one sip so light
...
*/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值