UNPKG

langchain

Version:
178 lines (174 loc) 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatVectorDBQAChain = void 0; const prompts_1 = require("@langchain/core/prompts"); const base_js_1 = require("./base.cjs"); const llm_chain_js_1 = require("./llm_chain.cjs"); const load_js_1 = require("./question_answering/load.cjs"); const question_generator_template = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question. Chat History: {chat_history} Follow Up Input: {question} Standalone question:`; const qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. {context} Question: {question} Helpful Answer:`; /** @deprecated use `ConversationalRetrievalQAChain` instead. */ class ChatVectorDBQAChain extends base_js_1.BaseChain { get inputKeys() { return [this.inputKey, this.chatHistoryKey]; } get outputKeys() { return [this.outputKey]; } constructor(fields) { super(fields); Object.defineProperty(this, "k", { enumerable: true, configurable: true, writable: true, value: 4 }); Object.defineProperty(this, "inputKey", { enumerable: true, configurable: true, writable: true, value: "question" }); Object.defineProperty(this, "chatHistoryKey", { enumerable: true, configurable: true, writable: true, value: "chat_history" }); Object.defineProperty(this, "outputKey", { enumerable: true, configurable: true, writable: true, value: "result" }); Object.defineProperty(this, "vectorstore", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "combineDocumentsChain", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "questionGeneratorChain", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "returnSourceDocuments", { enumerable: true, configurable: true, writable: true, value: false }); this.vectorstore = fields.vectorstore; this.combineDocumentsChain = fields.combineDocumentsChain; this.questionGeneratorChain = fields.questionGeneratorChain; this.inputKey = fields.inputKey ?? this.inputKey; this.outputKey = fields.outputKey ?? this.outputKey; this.k = fields.k ?? this.k; this.returnSourceDocuments = fields.returnSourceDocuments ?? this.returnSourceDocuments; } /** @ignore */ async _call(values, runManager) { if (!(this.inputKey in values)) { throw new Error(`Question key ${this.inputKey} not found.`); } if (!(this.chatHistoryKey in values)) { throw new Error(`chat history key ${this.inputKey} not found.`); } const question = values[this.inputKey]; const chatHistory = values[this.chatHistoryKey]; let newQuestion = question; if (chatHistory.length > 0) { const result = await this.questionGeneratorChain.call({ question, chat_history: chatHistory, }, runManager?.getChild("question_generator")); const keys = Object.keys(result); console.log("_call", values, keys); if (keys.length === 1) { newQuestion = result[keys[0]]; } else { throw new Error("Return from llm chain has multiple values, only single values supported."); } } const docs = await this.vectorstore.similaritySearch(newQuestion, this.k, undefined, runManager?.getChild("vectorstore")); const inputs = { question: newQuestion, input_documents: docs, chat_history: chatHistory, }; const result = await this.combineDocumentsChain.call(inputs, runManager?.getChild("combine_documents")); if (this.returnSourceDocuments) { return { ...result, sourceDocuments: docs, }; } return result; } _chainType() { return "chat-vector-db"; } static async deserialize(data, values) { if (!("vectorstore" in values)) { throw new Error(`Need to pass in a vectorstore to deserialize VectorDBQAChain`); } const { vectorstore } = values; return new ChatVectorDBQAChain({ combineDocumentsChain: await base_js_1.BaseChain.deserialize(data.combine_documents_chain), questionGeneratorChain: await llm_chain_js_1.LLMChain.deserialize(data.question_generator), k: data.k, vectorstore, }); } serialize() { return { _type: this._chainType(), combine_documents_chain: this.combineDocumentsChain.serialize(), question_generator: this.questionGeneratorChain.serialize(), k: this.k, }; } /** * Creates an instance of ChatVectorDBQAChain using a BaseLanguageModel * and other options. * @param llm Instance of BaseLanguageModel used to generate a new question. * @param vectorstore Instance of VectorStore used for vector operations. * @param options (Optional) Additional options for creating the ChatVectorDBQAChain instance. * @returns New instance of ChatVectorDBQAChain. */ static fromLLM(llm, vectorstore, options = {}) { const { questionGeneratorTemplate, qaTemplate, verbose, ...rest } = options; const question_generator_prompt = prompts_1.PromptTemplate.fromTemplate(questionGeneratorTemplate || question_generator_template); const qa_prompt = prompts_1.PromptTemplate.fromTemplate(qaTemplate || qa_template); const qaChain = (0, load_js_1.loadQAStuffChain)(llm, { prompt: qa_prompt, verbose }); const questionGeneratorChain = new llm_chain_js_1.LLMChain({ prompt: question_generator_prompt, llm, verbose, }); const instance = new this({ vectorstore, combineDocumentsChain: qaChain, questionGeneratorChain, ...rest, }); return instance; } } exports.ChatVectorDBQAChain = ChatVectorDBQAChain;