-
Howdy folks, sorry in advance for the novel, I am working on a project and I have gotten through a lot of the hard parts already. I have hit a point where the JS docs seem to be lacking. I am trying to make what seems to be a relatively simple chain, but I am running into some confusion around how SequentialChain works, in relation to Retrieval, Prompts, Vector DBs, etc.
If there is an alternative way to accomplish this goal, I would love to hear it, otherwise, here is the error I am stuck with at the moment, and the current implementation I have. I'm facing issues when calling the
And here's a snippet of the code that's causing the error: const config = loadConfig();
const prompt =
'You are a helpful assistant that answers questions about the table top role playing game Pathfinder 1e. ...';
export const createQAChain = async (
model: ChatOpenAI,
retriever: BaseRetriever,
): Promise<{
chain: RetrievalQAChain;
memory: EntityMemory;
}> => {
log('Creating QA chain...');
const chatPrompt = ChatPromptTemplate.fromPromptMessages([
SystemMessagePromptTemplate.fromTemplate(prompt),
new MessagesPlaceholder('entities'),
new MessagesPlaceholder('history'),
HumanMessagePromptTemplate.fromTemplate('{question}'),
]);
const memory = new EntityMemory({
llm: new OpenAI({
modelName: 'text-ada-001',
openAIApiKey: config.openAPIKey,
temperature: 0,
}),
inputKey: 'input',
outputKey: 'input',
});
log('Memory created', memory.chatHistory.getMessages());
const PromptChain = new LLMChain({
prompt: chatPrompt,
outputKey: 'text',
llm: model,
memory: memory,
});
const seqChain = new SequentialChain({
chains: [PromptChain],
inputVariables: [
'question',
'llm_chain',
'entities',
'history',
'input',
'input_documents',
'memory', // Adding memory here
'vectorStore', // Adding vectorStore here
],
outputVariables: ['question', 'input', 'memory', 'vectorStore'], // Including memory and vectorStore in the output
});
const RetrievalChain = new RetrievalQAChain({
retriever: retriever,
inputKey: 'question',
combineDocumentsChain: seqChain,
returnSourceDocuments: true,
});
log('QA chain created');
return { chain: RetrievalChain, memory };
};
export const askQuestion = async (
chain: ConversationChain,
question: string,
vectorStore: Document<Record<string, any>>[],
memory: ConversationSummaryMemory,
// You might need to replace any[] with the correct type for chat_history.
): Promise<ChainValues> => {
log(`Asking question: ${question}`);
log(
`Chat history: `,
await memory.loadMemoryVariables({ input: 'Who is Pine?' }),
);
const response = await chain.call({
question,
input: question,
memory, // Including memory in the chain call
vectorStore, // Including vectorStore in the chain call
});
log(`Received response: ${JSON.stringify(response, null, 2)}`);
memory.chatHistory.addAIChatMessage(response.res);
return response;
}; I've tried several approaches but none have resolved the problem. Can anyone suggest a different way to achieve my goals or recommend changes to my existing code? Any guidance would be greatly appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
So, I am not going to call this a solution, but it works for sure. Moving away from automatically combining things, I am calling them all individually with pretty good success. I will keep looking into a better solution, but hopefully the SequentialAction docs get expanded. For those searching for the same thing, here is the code I used to manually call all the different bits of functionality. export const askQuestion = async (
qaChain: RetrievalQAChain,
promptChain: LLMChain,
memory: EntityMemory,
question: string,
retriever: BaseRetriever,
// You might need to replace any[] with the correct type for chat_history.
): Promise<ChainValues> => {
// call each chain individually.
await memory.chatHistory.addUserMessage(question);
const qaPrompt = ChatPromptTemplate.fromPromptMessages([
SystemMessagePromptTemplate.fromTemplate(prompt),
HumanMessagePromptTemplate.fromTemplate('{question}'),
]);
const promptQuestion = await qaPrompt.format({
question,
});
const retRes = await qaChain.call({
query: promptQuestion,
});
const finalPrompt = ChatPromptTemplate.fromPromptMessages([
SystemMessagePromptTemplate.fromTemplate(prompt),
SystemMessagePromptTemplate.fromTemplate('DB Source: {QA_source}'),
SystemMessagePromptTemplate.fromTemplate('DB Text: {QA_text}'),
SystemMessagePromptTemplate.fromTemplate('Chat History: {History}'),
SystemMessagePromptTemplate.fromTemplate('Entities: {entities}'),
HumanMessagePromptTemplate.fromTemplate('{question}'),
]);
const finalQuestion = await finalPrompt.format({
question,
QA_source: retRes.sourceDocuments,
QA_text: retRes.text,
History: await memory.chatHistory.getMessages(),
entities: await memory.entityCache,
});
log('chat history: ', JSON.stringify(JSON.parse(finalQuestion), null, 2));
const promptRes = await promptChain.call({
question: finalQuestion,
});
await memory.chatHistory.addAIChatMessage(promptRes.text);
return promptRes;
}; |
Beta Was this translation helpful? Give feedback.
So, I am not going to call this a solution, but it works for sure. Moving away from automatically combining things, I am calling them all individually with pretty good success. I will keep looking into a better solution, but hopefully the SequentialAction docs get expanded.
For those searching for the same thing, here is the code I used to manually call all the different bits of functionality.