How can I return the chunks that are being used in the query? #24244
-
Checked other resources
Commit to Help
Example Codeimport { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";
import { formatDocumentsAsString } from "langchain/util/document";
import { PromptTemplate } from "@langchain/core/prompts";
import {
RunnableSequence,
RunnablePassthrough,
} from "@langchain/core/runnables";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { PineconeStore } from "@langchain/pinecone";
import { Pinecone } from '@pinecone-database/pinecone';
export default async function langchain() {
const model = new ChatOpenAI({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
modelName: "gpt-3.5-turbo",
temperature: 0,
streaming: true,
});
async function getVectorStore() {
try {
const client = new Pinecone({
apiKey: process.env.NEXT_PUBLIC_PINECONE_API_KEY || 'mal'
});
const embeddings = new OpenAIEmbeddings({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
batchSize: 1536,
model: "text-embedding-ada-002",
});
const index = client.Index(process.env.NEXT_PUBLIC_PINECONE_INDEX_NAME || 'mal');
const vectorStore = await PineconeStore.fromExistingIndex(embeddings, {
pineconeIndex: index,
namespace: process.env.NEXT_PUBLIC_PINECONE_ENVIRONMENT,
textKey: 'text',
});
return vectorStore;
} catch (error) {
console.log('error ', error);
throw new Error('Something went wrong while getting vector store!');
}
}
const formatChatHistory = (chatHistory: [string, string][]) => {
const formattedDialogueTurns = chatHistory.map(
(dialogueTurn) => `Human: ${dialogueTurn[0]}\nAssistant: ${dialogueTurn[1]}`
);
return formattedDialogueTurns.join("\n");
};
const condenseQuestionTemplate = `Given the following conversation and a follow-up question, rephrase the follow-up question to be a standalone question, in its original language.
Chat History:
{chat_history}
Follow Up Input: {question}
Standalone question:`;
const CONDENSE_QUESTION_PROMPT = PromptTemplate.fromTemplate(
condenseQuestionTemplate
);
const answerTemplate = `Answer the question based only on the following context:
{context}
Question: {question}
`;
const ANSWER_PROMPT = PromptTemplate.fromTemplate(answerTemplate);
type ConversationalRetrievalQAChainInput = {
question: string;
chat_history: [string, string][];
};
const standaloneQuestionChain = RunnableSequence.from([
{
question: (input: ConversationalRetrievalQAChainInput) => input.question,
chat_history: (input: ConversationalRetrievalQAChainInput) =>
formatChatHistory(input.chat_history),
},
CONDENSE_QUESTION_PROMPT,
model,
new StringOutputParser(),
]);
const vectorStore = await getVectorStore();
const retriever = vectorStore.asRetriever( );
const answerChain = RunnableSequence.from([
{
context: retriever.pipe(formatDocumentsAsString),
question: new RunnablePassthrough(),
},
ANSWER_PROMPT,
model,
]);
const conversationalRetrievalQAChain =
standaloneQuestionChain.pipe(answerChain );
const result = await conversationalRetrievalQAChain.invoke({
question: "Que es la SS?",
chat_history: [],
});
console.log('Answer: ', result);
return result;
} DescriptionI am making a simple RAG application using OpenAI, Pinecone as database and LangChain, it works and I get the expected response, but I can't find the way to return the chunks that were found as most similar, regularly in python in the retriver a parameter is specified as "return_source_documents=True" but I can't find the option in node. System InfoI am using the versions:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Hello, @DiegoCastr00! I'm here to assist you with any bugs, questions, or contributions you might have. Let's work together to solve the issue at hand. To return the chunks that are being used in the query in your RAG application using OpenAI, Pinecone, and LangChain in Node.js, you can modify your code to include the retrieval of the chunks. Here is an example of how you can achieve this: import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";
import { formatDocumentsAsString } from "langchain/util/document";
import { PromptTemplate } from "@langchain/core/prompts";
import {
RunnableSequence,
RunnablePassthrough,
RunnableParallel,
} from "@langchain/core/runnables";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { PineconeStore } from "@langchain/pinecone";
import { Pinecone } from '@pinecone-database/pinecone';
export default async function langchain() {
const model = new ChatOpenAI({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
modelName: "gpt-3.5-turbo",
temperature: 0,
streaming: true,
});
async function getVectorStore() {
try {
const client = new Pinecone({
apiKey: process.env.NEXT_PUBLIC_PINECONE_API_KEY || 'mal'
});
const embeddings = new OpenAIEmbeddings({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
batchSize: 1536,
model: "text-embedding-ada-002",
});
const index = client.Index(process.env.NEXT_PUBLIC_PINECONE_INDEX_NAME || 'mal');
const vectorStore = await PineconeStore.fromExistingIndex(embeddings, {
pineconeIndex: index,
namespace: process.env.NEXT_PUBLIC_PINECONE_ENVIRONMENT,
textKey: 'text',
});
return vectorStore;
} catch (error) {
console.log('error ', error);
throw new Error('Something went wrong while getting vector store!');
}
}
const formatChatHistory = (chatHistory) => {
const formattedDialogueTurns = chatHistory.map(
(dialogueTurn) => `Human: ${dialogueTurn[0]}\nAssistant: ${dialogueTurn[1]}`
);
return formattedDialogueTurns.join("\n");
};
const condenseQuestionTemplate = `Given the following conversation and a follow-up question, rephrase the follow-up question to be a standalone question, in its original language.
Chat History:
{chat_history}
Follow Up Input: {question}
Standalone question:`;
const CONDENSE_QUESTION_PROMPT = PromptTemplate.fromTemplate(
condenseQuestionTemplate
);
const answerTemplate = `Answer the question based only on the following context:
{context}
Question: {question}
`;
const ANSWER_PROMPT = PromptTemplate.fromTemplate(answerTemplate);
const standaloneQuestionChain = RunnableSequence.from([
{
question: (input) => input.question,
chat_history: (input) => formatChatHistory(input.chat_history),
},
CONDENSE_QUESTION_PROMPT,
model,
new StringOutputParser(),
]);
const vectorStore = await getVectorStore();
const retriever = vectorStore.asRetriever();
const answerChain = RunnableSequence.from([
{
context: retriever.pipe(formatDocumentsAsString),
question: new RunnablePassthrough(),
},
ANSWER_PROMPT,
model,
]);
const conversationalRetrievalQAChain = RunnableParallel.from({
context: retriever,
question: new RunnablePassthrough(),
}).assign({
answer: answerChain,
context: (input) => input.context,
});
const result = await conversationalRetrievalQAChain.invoke({
question: "Que es la SS?",
chat_history: [],
});
console.log('Answer: ', result.answer);
console.log('Chunks: ', result.context);
return result;
} In this code, the |
Beta Was this translation helpful? Give feedback.
-
This is the solution to the problem, we do it by modifying this function:
Complete code:
|
Beta Was this translation helpful? Give feedback.
This is the solution to the problem, we do it by modifying this function:
Complete code: