scrimba
Learn Langchain
Super Challenge: Wire up the memory
Go Pro!Bootcamp

Bootcamp

Study group

Collaborate with peers in your dedicated #study-group channel.

Code reviews

Submit projects for review using the /review command in your #code-reviews channel

Super Challenge: Wire up the memory
AboutCommentsNotes
Super Challenge: Wire up the memory
Expand for more info
index.js
run
preview
console
import { ChatOpenAI } from 'langchain/chat_models/openai'
import { PromptTemplate } from 'langchain/prompts'
import { StringOutputParser } from 'langchain/schema/output_parser'
import { retriever } from '/utils/retriever'
import { combineDocuments } from '/utils/combineDocuments'
import { RunnablePassthrough, RunnableSequence } from "langchain/schema/runnable"
import { formatConvHistory } from '/utils/formatConvHistory'

document.addEventListener('submit', (e) => {
e.preventDefault()
progressConversation()
})

/**
* Super Challenge:
*
* 1. Pass convHistory into the chain as conv_history at
* the point where we invoke it. Remember to make use
* of our formatConvHistory function!
* 2. Update the standaloneQuestionTemplate to make use
* of convHistory.
* 3. Make sure the answerChain has access to convHistory
* and edit answerTemplate to make use of it.
* 4. Test by giving the chatbot some information and
* checking in the next question to see if it remembers it.
*
* */

const openAIApiKey = process.env.OPENAI_API_KEY
const llm = new ChatOpenAI({ openAIApiKey })

const standaloneQuestionTemplate = 'Given a question, convert it to a standalone question. question: {question} standalone question:'
const standaloneQuestionPrompt = PromptTemplate.fromTemplate(standaloneQuestionTemplate)

const answerTemplate = `You are a helpful and enthusiastic support bot who can answer a given question about Scrimba based on the context provided. Try to find the answer in the context. If you really don't know the answer, say "I'm sorry, I don't know the answer to that." And direct the questioner to email help@scrimba.com. Don't try to make up an answer. Always speak as if you were chatting to a friend.
context: {context}
question: {question}
answer: `
const answerPrompt = PromptTemplate.fromTemplate(answerTemplate)

const standaloneQuestionChain = standaloneQuestionPrompt
.pipe(llm)
.pipe(new StringOutputParser())

const retrieverChain = RunnableSequence.from([
prevResult => prevResult.standalone_question,
retriever,
combineDocuments
])
const answerChain = answerPrompt
.pipe(llm)
.pipe(new StringOutputParser())

const chain = RunnableSequence.from([
{
standalone_question: standaloneQuestionChain,
original_input: new RunnablePassthrough()
},
{
context: retrieverChain,
question: ({ original_input }) => original_input.question
},
answerChain
])

const convHistory = []

async function progressConversation() {
const userInput = document.getElementById('user-input')
const chatbotConversation = document.getElementById('chatbot-conversation-container')
const question = userInput.value
userInput.value = ''

// add human message
const newHumanSpeechBubble = document.createElement('div')
newHumanSpeechBubble.classList.add('speech', 'speech-human')
chatbotConversation.appendChild(newHumanSpeechBubble)
newHumanSpeechBubble.textContent = question
chatbotConversation.scrollTop = chatbotConversation.scrollHeight
const response = await chain.invoke({
question: question
})
convHistory.push(question)
convHistory.push(response)

// add AI message
const newAiSpeechBubble = document.createElement('div')
newAiSpeechBubble.classList.add('speech', 'speech-ai')
chatbotConversation.appendChild(newAiSpeechBubble)
newAiSpeechBubble.textContent = response
chatbotConversation.scrollTop = chatbotConversation.scrollHeight
}
Console
/index.html
-6:21