天天看点

LangChain手册(JS/TS版)13链:索引相关链

Index Related Chains

与处理存储在索引中的非结构化数据相关的链。

️Document QA ️文档质量保证

LangChain provides an assortment of chains specifically tailored for dealing with unstructured text data: StuffDocumentsChain, MapReduceDocumentsChain, and RefineDocumentsChain. These chains form the basic building blocks for developing more complex chains that interact with such data. They are designed to take both documents and a question as input, then utilize the language model to formulate a response based on the provided documents.

LangChain提供了专门用于处理非结构化文本数据的各种链:StuffDocumentsChain,MapReduceDocumentsChain和RefineDocumentsChain。这些链构成了开发与此类数据交互的更复杂的链的基本构建块。它们旨在将文档和问题作为输入,然后利用语言模型根据提供的文档制定响应。

Document QA

LangChain provides an assortment of chains specifically tailored for dealing with unstructured text data: StuffDocumentsChain, MapReduceDocumentsChain, and RefineDocumentsChain. These chains form the basic building blocks for developing more complex chains that interact with such data. They are designed to take both documents and a question as input, then utilize the language model to formulate a response based on the provided documents.

LangChain 提供了专门用于处理非结构化文本数据的链: StuffDocumentsChain 、 MapReduceDocumentsChain 和 RefineDocumentsChain 。这些链构成了开发与此类数据交互的更复杂的链的基本构建块。它们旨在将文档和问题作为输入,然后利用语言模型根据提供的文档制定响应。

  • StuffDocumentsChain: This chain is the most straightforward among the three. It simply injects all input documents into the prompt as context and returns the answer to the question. It is suitable for QA tasks over a small number of documents.

    StuffDocumentsChain :这条链是三者中最直接的。它只是将所有输入文档作为上下文注入到提示中,并返回问题的答案。它适用于少量文档的 QA 任务。

  • MapReduceDocumentsChain: This chain incorporates a preprocessing step to select relevant sections from each document until the total number of tokens is less than the maximum number of tokens allowed by the model. It then uses the transformed documents as context to answer the question. It is suitable for QA tasks over larger documents and can run the preprocessing step in parallel, reducing the running time.

    MapReduceDocumentsChain :此链包含一个预处理步骤,用于从每个文档中选择相关部分,直到令牌总数小于模型允许的最大令牌数。然后,它使用转换后的文档作为上下文来回答问题。它适用于较大文档的 QA 任务,可以并行运行预处理步骤,减少运行时间。

  • RefineDocumentsChain: This chain iterates over the input documents one by one, updating an intermediate answer with each iteration. It uses the previous version of the answer and the next document as context. It is suitable for QA tasks over a large number of documents.

    RefineDocumentsChain :此链逐个迭代输入文档,每次迭代更新中间答案。它使用答案的先前版本和下一个文档作为上下文。它适用于大量文档的 QA 任务。

Usage,StuffDocumentsChainandMapReduceDocumentsChain用法,StuffDocumentsChain和MapReduceDocumentsChain

import { OpenAI } from "langchain/llms/openai";
import { loadQAStuffChain, loadQAMapReduceChain } from "langchain/chains";
import { Document } from "langchain/document";

export const run = async () => {
  // This first example uses the `StuffDocumentsChain`.
  const llmA = new OpenAI({});
  const chainA = loadQAStuffChain(llmA);
  const docs = [
    new Document({ pageContent: "Harrison went to Harvard." }),
    new Document({ pageContent: "Ankush went to Princeton." }),
  ];
  const resA = await chainA.call({
    input_documents: docs,
    question: "Where did Harrison go to college?",
  });
  console.log({ resA });
  // { resA: { text: ' Harrison went to Harvard.' } }

  // This second example uses the `MapReduceChain`.
  // Optionally limit the number of concurrent requests to the language model.
  const llmB = new OpenAI({ maxConcurrency: 10 });
  const chainB = loadQAMapReduceChain(llmB);
  const resB = await chainB.call({
    input_documents: docs,
    question: "Where did Harrison go to college?",
  });
  console.log({ resB });
  // { resB: { text: ' Harrison went to Harvard.' } }
};
           

API Reference:

  • OpenAI from langchain/llms/openai OpenAI从 langchain/llms/openai
  • loadQAStuffChain from langchain/chains

    loadQAStuffChainfrom langchain/chains

  • loadQAMapReduceChain from langchain/chains

    loadQAMapReduceChainfrom langchain/chains

  • Document from langchain/document 文档从 langchain/document

Usage,RefineDocumentsChain​ 用法,RefineDocumentsChain

import { loadQARefineChain } from "langchain/chains";
import { OpenAI } from "langchain/llms/openai";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";

export async function run() {
  // Create the models and chain
  const embeddings = new OpenAIEmbeddings();
  const model = new OpenAI({ temperature: 0 });
  const chain = loadQARefineChain(model);

  // Load the documents and create the vector store
  const loader = new TextLoader("./state_of_the_union.txt");
  const docs = await loader.loadAndSplit();
  const store = await MemoryVectorStore.fromDocuments(docs, embeddings);

  // Select the relevant documents
  const question = "What did the president say about Justice Breyer";
  const relevantDocs = await store.similaritySearch(question);

  // Call the chain
  const res = await chain.call({
    input_documents: relevantDocs,
    question,
  });

  console.log(res);
  /*
  {
    output_text: '\n' +
      '\n' +
      "The president said that Justice Stephen Breyer has dedicated his life to serve this country and thanked him for his service. He also mentioned that Judge Ketanji Brown Jackson will continue Justice Breyer's legacy of excellence, and that the constitutional right affirmed in Roe v. Wade—standing precedent for half a century—is under attack as never before. He emphasized the importance of protecting access to health care, preserving a woman's right to choose, and advancing maternal health care in America. He also expressed his support for the LGBTQ+ community, and his commitment to protecting their rights, including offering a Unity Agenda for the Nation to beat the opioid epidemic, increase funding for prevention, treatment, harm reduction, and recovery, and strengthen the Violence Against Women Act."
  }
  */
}
           

API Reference:

  • loadQARefineChain from langchain/chains

    loadQARefineChainfrom langchain/chains

  • OpenAI from langchain/llms/openai OpenAI从 langchain/llms/openai
  • TextLoader from langchain/document_loaders/fs/text 文本加载器从 langchain/document_loaders/fs/text
  • MemoryVectorStore from langchain/vectorstores/memory

    MemoryVectorStorefrom langchain/vectorstores/memory

  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

️Retrieval QA ️检索质量保证

The RetrievalQAChain is a chain that combines a Retriever and a QA chain (described above). It is used to retrieve documents from a Retriever and then use a QA chain to answer a question based on the retrieved documents.

检索QAChain是一个结合了检索器和QA链的链(如上所述)。它用于从检索器检索文档,然后使用 QA 链根据检索到的文档回答问题。

Retrieval QA

The RetrievalQAChain is a chain that combines a Retriever and a QA chain (described above). It is used to retrieve documents from a Retriever and then use a QA chain to answer a question based on the retrieved documents.

RetrievalQAChain 是结合了 Retriever 和 QA 链的链(如上所述)。它用于从 Retriever 中检索文档,然后使用 QA 链根据检索到的文档回答问题。

Usage​ 用法

In the below example, we are using a VectorStore as the Retriever. By default, the StuffDocumentsChain is used as the QA chain.

在下面的示例中,我们使用 VectorStore 作为 Retriever 。默认情况下, StuffDocumentsChain 用作 QA 链。

import { OpenAI } from "langchain/llms/openai";
import { RetrievalQAChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import * as fs from "fs";

export const run = async () => {
  // Initialize the LLM to use to answer the question.
  const model = new OpenAI({});
  const text = fs.readFileSync("state_of_the_union.txt", "utf8");
  const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
  const docs = await textSplitter.createDocuments([text]);

  // Create a vector store from the documents.
  const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());

  // Create a chain that uses the OpenAI LLM and HNSWLib vector store.
  const chain = RetrievalQAChain.fromLLM(model, vectorStore.asRetriever());
  const res = await chain.call({
    query: "What did the president say about Justice Breyer?",
  });
  console.log({ res });
  /*
  {
    res: {
      text: 'The president said that Justice Breyer was an Army veteran, Constitutional scholar,
      and retiring Justice of the United States Supreme Court and thanked him for his service.'
    }
  }
  */
};           

API Reference:

  • OpenAI from langchain/llms/openai OpenAI从 langchain/llms/openai
  • RetrievalQAChain from langchain/chains

    检索 QAChainfrom langchain/chains

  • HNSWLib from langchain/vectorstores/hnswlib HNSWLibfrom langchain/vectorstores/hnswlib
  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

  • RecursiveCharacterTextSplitter from langchain/text_splitter

    递归字符文本从 langchain/text_splitter 拆分器

Usage, with a customQAchain​用法,使用自定义QA链

In the below example, we are using a VectorStore as the Retriever and a RefineDocumentsChain as the QA chain.

在下面的示例中,我们使用 VectorStore 作为 Retriever ,使用 RefineDocumentsChain 作为 QA 链。

import { OpenAI } from "langchain/llms/openai";
import { RetrievalQAChain, loadQARefineChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import * as fs from "fs";

// Initialize the LLM to use to answer the question.
const model = new OpenAI({});
const text = fs.readFileSync("state_of_the_union.txt", "utf8");
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
const docs = await textSplitter.createDocuments([text]);

// Create a vector store from the documents.
const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());

// Create a chain that uses a Refine chain and HNSWLib vector store.
const chain = new RetrievalQAChain({
  combineDocumentsChain: loadQARefineChain(model),
  retriever: vectorStore.asRetriever(),
});
const res = await chain.call({
  query: "What did the president say about Justice Breyer?",
});
console.log({ res });
/*
{
  res: {
    output_text: '\n' +
      '\n' +
      "The president said that Justice Breyer has dedicated his life to serve his country, and thanked him for his service. He also said that Judge Ketanji Brown Jackson will continue Justice Breyer's legacy of excellence, emphasizing the importance of protecting the rights of citizens, especially women, LGBTQ+ Americans, and access to healthcare. He also expressed his commitment to supporting the younger transgender Americans in America and ensuring they are able to reach their full potential, offering a Unity Agenda for the Nation to beat the opioid epidemic and increase funding for prevention, treatment, harm reduction, and recovery."
  }
}
*/
           

API Reference:

  • OpenAI from langchain/llms/openai OpenAI从 langchain/llms/openai
  • RetrievalQAChain from langchain/chains

    检索 QAChainfrom langchain/chains

  • loadQARefineChain from langchain/chains

    loadQARefineChainfrom langchain/chains

  • HNSWLib from langchain/vectorstores/hnswlib HNSWLibfrom langchain/vectorstores/hnswlib
  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

  • RecursiveCharacterTextSplitter from langchain/text_splitter

    递归字符文本从 langchain/text_splitter 拆分器

️Conversational Retrieval QA ️会话检索 QA

The ConversationalRetrievalQA chain builds on RetrievalQAChain to provide a chat history component.

ConversationalRetrievalQA链建立在RetrievalQAChain之上,以提供聊天历史组件。

Conversational Retrieval QA 会话检索 QA

The ConversationalRetrievalQA chain builds on RetrievalQAChain to provide a chat history component.

ConversationalRetrievalQA 链建立在 RetrievalQAChain 之上,以提供聊天记录组件。

It first combines the chat history (either explicitly passed in or retrieved from the provided memory) and the question into a standalone question, then looks up relevant documents from the retriever, and finally passes those documents and the question to a question answering chain to return a response.

它首先将聊天历史记录(显式传入或从提供的内存中检索)和问题合并到一个独立的问题中,然后从检索器查找相关文档,最后将这些文档和问题传递给问答链以返回响应。

To create one, you will need a retriever. In the below example, we will create one from a vector store, which can be created from embeddings.

要创建一个,您将需要一个检索器。在下面的示例中,我们将从向量存储创建一个,该向量存储可以从嵌入中创建。

import { OpenAI } from "langchain/llms/openai";
import { ConversationalRetrievalQAChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { BufferMemory } from "langchain/memory";
import * as fs from "fs";

export const run = async () => {
  /* Initialize the LLM to use to answer the question */
  const model = new OpenAI({});
  /* Load in the file we want to do question answering over */
  const text = fs.readFileSync("state_of_the_union.txt", "utf8");
  /* Split the text into chunks */
  const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
  const docs = await textSplitter.createDocuments([text]);
  /* Create the vectorstore */
  const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());
  /* Create the chain */
  const chain = ConversationalRetrievalQAChain.fromLLM(
    model,
    vectorStore.asRetriever(),
    {
      memory: new BufferMemory({
        memoryKey: "chat_history", // Must be set to "chat_history"
      }),
    }
  );
  /* Ask it a question */
  const question = "What did the president say about Justice Breyer?";
  const res = await chain.call({ question });
  console.log(res);
  /* Ask it a follow up question */
  const followUpRes = await chain.call({
    question: "Was that nice?",
  });
  console.log(followUpRes);
};
           

API Reference:

  • OpenAI from langchain/llms/openai OpenAI从 langchain/llms/openai
  • ConversationalRetrievalQAChain from langchain/chains

    会话检索QAChainfrom langchain/chains

  • HNSWLib from langchain/vectorstores/hnswlib HNSWLibfrom langchain/vectorstores/hnswlib
  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

  • RecursiveCharacterTextSplitter from langchain/text_splitter

    递归字符文本从 langchain/text_splitter 拆分器

  • BufferMemory from langchain/memory 缓冲区内存从 langchain/memory

In the above code snippet, the fromLLM method of the ConversationalRetrievalQAChain class has the following signature:

在上面的代码片段中, ConversationalRetrievalQAChain 类的 fromLLM 方法具有以下签名:

static fromLLM(
  llm: BaseLanguageModel,
  retriever: BaseRetriever,
  options?: {
    questionGeneratorChainOptions?: {
      llm?: BaseLanguageModel;
      template?: string;
    };
    qaChainOptions?: QAChainParams;
    returnSourceDocuments?: boolean;
  }
): ConversationalRetrievalQAChain
           

Here's an explanation of each of the attributes of the options object:

下面是选项对象的每个属性的说明:

  • questionGeneratorChainOptions: An object that allows you to pass a custom template and LLM to the underlying question generation chain.

    questionGeneratorChainOptions :允许您将自定义模板和 LLM 传递到基础问题生成链的对象。If the template is provided, the ConversationalRetrievalQAChain will use this template to generate a question from the conversation context instead of using the question provided in the question parameter. This can be useful if the original question does not contain enough information to retrieve a suitable answer.

    如果提供了模板,则 ConversationalRetrievalQAChain 将使用此模板从对话上下文生成问题,而不是使用 question 参数中提供的问题。如果原始问题不包含足够的信息来检索合适的答案,这会很有用。Passing in a separate LLM here allows you to use a cheaper/faster model to create the condensed question while using a more powerful model for the final response, and can reduce unnecessary latency.

    在此处传递单独的LLM允许您使用更便宜/更快的模型来创建压缩问题,同时使用更强大的模型进行最终响应,并且可以减少不必要的延迟。

  • qaChainOptions: Options that allow you to customize the specific QA chain used in the final step. The default is the StuffDocumentsChain, but you can customize which chain is used by passing in a type parameter. Passing specific options here is completely optional, but can be useful if you want to customize the way the response is presented to the end user, or if you have too many documents for the default StuffDocumentsChain. You can see documentation about the usable fields here.

    qaChainOptions :允许您自定义最后一步中使用的特定 QA 链的选项。默认值为 StuffDocumentsChain ,但您可以通过传入 type 参数来自定义使用哪个链。在此处传递特定选项是完全可选的,但如果要自定义向最终用户显示响应的方式,或者对于默认 StuffDocumentsChain 的文档过多,则可能很有用。您可以在此处查看有关可用字段的文档。

  • returnSourceDocuments: A boolean value that indicates whether the ConversationalRetrievalQAChain should return the source documents that were used to retrieve the answer. If set to true, the documents will be included in the result returned by the call() method. This can be useful if you want to allow the user to see the sources used to generate the answer. If not set, the default value will be false.

    returnSourceDocuments :一个布尔值,指示 ConversationalRetrievalQAChain 是否应返回用于检索答案的源文档。如果设置为 true,则文档将包含在 call() 方法返回的结果中。如果要允许用户查看用于生成答案的源,这可能很有用。如果未设置,默认值将为 false。If you are using this option and passing in a memory instance, set inputKey and outputKey on the memory instance to the same values as the chain input and final conversational chain output. These default to "question" and "text" respectively, and specify the values that the memory should store.

    如果使用此选项并传入内存实例,请将内存实例上的 inputKey 和 outputKey 设置为与链输入和最终会话链输出相同的值。它们分别默认为 "question" 和 "text" ,并指定内存应存储的值。

Built-in Memory​ 内置内存

Here's a customization example using a faster LLM to generate questions and a slower, more comprehensive LLM for the final answer. It uses a built-in memory object and returns the referenced source documents:

这是一个自定义示例,使用更快的LLM生成问题,使用更慢,更全面的LLM生成最终答案。它使用内置内存对象并返回引用的源文档:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { ConversationalRetrievalQAChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { BufferMemory } from "langchain/memory";

import * as fs from "fs";

export const run = async () => {
  const text = fs.readFileSync("state_of_the_union.txt", "utf8");
  const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
  const docs = await textSplitter.createDocuments([text]);
  const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());
  const fasterModel = new ChatOpenAI({
    modelName: "gpt-3.5-turbo",
  });
  const slowerModel = new ChatOpenAI({
    modelName: "gpt-4",
  });
  const chain = ConversationalRetrievalQAChain.fromLLM(
    slowerModel,
    vectorStore.asRetriever(),
    {
      returnSourceDocuments: true,
      memory: new BufferMemory({
        memoryKey: "chat_history",
        inputKey: "question", // The key for the input to the chain
        outputKey: "text", // The key for the final conversational output of the chain
        returnMessages: true, // If using with a chat model
      }),
      questionGeneratorChainOptions: {
        llm: fasterModel,
      },
    }
  );
  /* Ask it a question */
  const question = "What did the president say about Justice Breyer?";
  const res = await chain.call({ question });
  console.log(res);

  const followUpRes = await chain.call({ question: "Was that nice?" });
  console.log(followUpRes);
};
           

API Reference:

  • ChatOpenAI from langchain/chat_models/openai 聊天打开AI从 langchain/chat_models/openai
  • ConversationalRetrievalQAChain from langchain/chains

    会话检索QAChainfrom langchain/chains

  • HNSWLib from langchain/vectorstores/hnswlib HNSWLibfrom langchain/vectorstores/hnswlib
  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

  • RecursiveCharacterTextSplitter from langchain/text_splitter

    递归字符文本从 langchain/text_splitter 拆分器

  • BufferMemory from langchain/memory 缓冲区内存从 langchain/memory

Streaming​ 流

You can also use the above concept of using two different LLMs to stream only the final response from the chain, and not output from the intermediate standalone question generation step. Here's an example:

您还可以使用上述概念,即使用两个不同的 LLM 仅流式传输来自链的最终响应,而不是来自中间独立问题生成步骤的输出。下面是一个示例:

import { ChatOpenAI } from "langchain/chat_models/openai";
import { ConversationalRetrievalQAChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { BufferMemory } from "langchain/memory";

import * as fs from "fs";

export const run = async () => {
  const text = fs.readFileSync("state_of_the_union.txt", "utf8");
  const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
  const docs = await textSplitter.createDocuments([text]);
  const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());
  let streamedResponse = "";
  const streamingModel = new ChatOpenAI({
    streaming: true,
    callbacks: [
      {
        handleLLMNewToken(token) {
          streamedResponse += token;
        },
      },
    ],
  });
  const nonStreamingModel = new ChatOpenAI({});
  const chain = ConversationalRetrievalQAChain.fromLLM(
    streamingModel,
    vectorStore.asRetriever(),
    {
      returnSourceDocuments: true,
      memory: new BufferMemory({
        memoryKey: "chat_history",
        inputKey: "question", // The key for the input to the chain
        outputKey: "text", // The key for the final conversational output of the chain
        returnMessages: true, // If using with a chat model
      }),
      questionGeneratorChainOptions: {
        llm: nonStreamingModel,
      },
    }
  );
  /* Ask it a question */
  const question = "What did the president say about Justice Breyer?";
  const res = await chain.call({ question });
  console.log({ streamedResponse });
  /*
    {
      streamedResponse: 'President Biden thanked Justice Breyer for his service, and honored him as an Army veteran, Constitutional scholar and retiring Justice of the United States Supreme Court.'
    }
  */
};
           

API Reference:

  • ChatOpenAI from langchain/chat_models/openai 聊天打开AI从 langchain/chat_models/openai
  • ConversationalRetrievalQAChain from langchain/chains

    会话检索QAChainfrom langchain/chains

  • HNSWLib from langchain/vectorstores/hnswlib HNSWLibfrom langchain/vectorstores/hnswlib
  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

  • RecursiveCharacterTextSplitter from langchain/text_splitter

    递归字符文本从 langchain/text_splitter 拆分器

  • BufferMemory from langchain/memory 缓冲区内存从 langchain/memory

Externally-Managed Memory​ 外部管理的内存

If you'd like to format the chat history in a specific way, you can also pass the chat history in explicitly by omitting the memory option and passing in a chat_history string directly into the chain.call method:

如果您想以特定方式格式化聊天记录,您还可以通过省略 memory 选项并将 chat_history 字符串直接传递到 chain.call 方法中来显式传入聊天记录:

import { OpenAI } from "langchain/llms/openai";
import { ConversationalRetrievalQAChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import * as fs from "fs";

export const run = async () => {
  /* Initialize the LLM to use to answer the question */
  const model = new OpenAI({});
  /* Load in the file we want to do question answering over */
  const text = fs.readFileSync("state_of_the_union.txt", "utf8");
  /* Split the text into chunks */
  const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
  const docs = await textSplitter.createDocuments([text]);
  /* Create the vectorstore */
  const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());
  /* Create the chain */
  const chain = ConversationalRetrievalQAChain.fromLLM(
    model,
    vectorStore.asRetriever()
  );
  /* Ask it a question */
  const question = "What did the president say about Justice Breyer?";
  const res = await chain.call({ question, chat_history: [] });
  console.log(res);
  /* Ask it a follow up question */
  const chatHistory = question + res.text;
  const followUpRes = await chain.call({
    question: "Was that nice?",
    chat_history: chatHistory,
  });
  console.log(followUpRes);
};
           

API Reference:

  • OpenAI from langchain/llms/openai OpenAI从 langchain/llms/openai
  • ConversationalRetrievalQAChain from langchain/chains

    会话检索QAChainfrom langchain/chains

  • HNSWLib from langchain/vectorstores/hnswlib HNSWLibfrom langchain/vectorstores/hnswlib
  • OpenAIEmbeddings from langchain/embeddings/openai

    OpenAIEmbeddingsfrom langchain/embeddings/openai

  • RecursiveCharacterTextSplitter from langchain/text_splitter

    递归字符文本从 langchain/text_splitter 拆分器

LangChain手册(JS/TS版)13链:索引相关链