如何在 Next JS 应用程序中使用 langchain ConversationalRetrievalQA 链存储聊天记录?

问题描述 投票:0回答:2

我正在创建一个文本文档 QA 聊天机器人,我使用 Langchainjs 以及 OpenAI LLM 来创建嵌入和聊天,并使用 Pinecone 作为我的矢量存储。

见图:

成功上传嵌入并在松果上创建索引后。我正在使用 Next JS 应用程序与 OpenAI 和 Pinecone 进行通信。

我的应用程序当前的结构是这样的:

1:前端 -> 用户输入

question
并对 NEXT js 服务器 API 路由进行 POST 调用
/ask

2:服务器功能如下所示:

const vectorStore = await PineconeStore.fromExistingIndex(
        new OpenAIEmbeddings(),
        { pineconeIndex })

const model = new ChatOpenAI({ temperature: 0.5, modelName: 'gpt-3.5-turbo' })

const memory = new ConversationSummaryMemory({
    memoryKey: 'chat_history',
    llm: new ChatOpenAI({ modelName: 'gpt-3.5-turbo', temperature: 0 }),
})

const chain = ConversationalRetrievalQAChain.fromLLM(
    model,
    vectorStore.asRetriever(),
    {
        memory,
    }
)

const result = await chain.call({
    question,
})

return NextResponse.json({ data: result.text })

问题:聊天机器人永远无法访问任何历史记录,因为内存始终只存储最新消息。

console.log('memory:', await memory.loadMemoryVariables({}))

我也尝试过

BufferMemory
和同样的问题,内存缓冲区只有刚刚询问的消息,如果新查询进入缓冲区,则会被清除,并且新查询是内存中唯一的消息。

我可能不清楚如何正确存储历史记录,因此

const result = await chain.call({question,})
呼叫可以访问之前的信息

更新:我已成功使用 Upstash Redis 支持的聊天内存与 langchain,但是仍然好奇是否可以使用用户浏览器存储消息?

next.js chatbot openai-api langchain pinecone
2个回答
0
投票

我正在使用与您完全相同的堆栈(Next.js、Pinecone、Langchain ConversationalRetrievalQAChain),并且我与这个确切的问题斗争了一段时间。

最终我求助于下面的“hack”,它确实有效,基本上捕获了

messages
数组中的历史记录,我将其推入提示符的末尾。据我所知,这与 LangChain 的“内存”组件的工作原理并没有什么不同,所以我这样做并不觉得糟糕。

这是我的主处理函数的精简版本。记下以

queryText+='\nIf necessary ...

开头的行
export async function POST(req: Request) {
    const { messages } = await req.json();
    let queryText = messages[messages.length - 1].content;
    
    queryText+='\nIf necessary, utilize the below chat history as additional context:'+JSON.stringify(messages);
    
    const chain = ConversationalRetrievalQAChain.fromLLM(
            streamingModel,
            vectorStore.asRetriever(),
            {
                returnSourceDocuments: true,
                questionGeneratorChainOptions: {
                    llm: nonStreamingModel,
                },
            }

    const { stream, handlers } = LangChainStream();
    chain.call({ question: queryText }, [handlers]).catch(console.error)

    return new StreamingTextResponse(stream);
}

0
投票

我认为你应该使用

returnMessages:true
ConversationSummaryMemory
属性:

const memory = new ConversationSummaryMemory({
  memoryKey: 'chat_history',
  llm: new ChatOpenAI({ modelName: 'gpt-3.5-turbo', temperature: 0 }),
  returnMessages:true
})

这是来自

loadMemoryVariables

的代码
async loadMemoryVariables(_) {
        if (this.returnMessages) {
            const result = {
                [this.memoryKey]: [new this.summaryChatMessageClass(this.buffer)],
            };
            return result;
        }
        const result = { [this.memoryKey]: this.buffer };
        return result;
    }

如果设置

returnMessages:true
它将返回
this.summaryChatMessageClass(this.buffer)
对象,否则它只返回一个字符串。

© www.soinside.com 2019 - 2024. All rights reserved.