Skip to content

Instantly share code, notes, and snippets.

@agovc
Created November 11, 2023 00:56
Show Gist options
  • Save agovc/bab7b31e934541af601354ddd6a035ff to your computer and use it in GitHub Desktop.
Save agovc/bab7b31e934541af601354ddd6a035ff to your computer and use it in GitHub Desktop.
import { ChatOpenAI } from "langchain/chat_models/openai"
import { PromptTemplate } from "langchain/prompts"
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'
import { OpenAIEmbeddings } from 'langchain/embeddings/openai'
import { createClient } from '@supabase/supabase-js'
import { StringOutputParser } from 'langchain/schema/output_parser'
import { RunnablePassthrough, RunnableSequence } from "langchain/schema/runnable"
const openAIApiKey = process.env.OPENAI_API_KEY
const supabaseApiKey = process.env.SUPABASE_API_KEY
const supabaseURL = process.env.SUPABASE_URL
function createDatebase() {
const text = await readFile('aliceInWonderland.txt', 'utf-8');
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 500,
separators: ['\n\n', '\n', ' ', ''], // default setting
chunkOverlap: 50
})
const output = await splitter.createDocuments([text])
const client = createClient(supabaseURL, supabaseApiKey)
await SupabaseVectorStore.fromDocuments(
output,
new OpenAIEmbeddings({ openAIApiKey }),
{
client,
tableName: 'documents'
}
)
}
const embeddings = new OpenAIEmbeddings({ openAIApiKey })
const client = createClient(supabaseURL, supabaseApiKey)
const vectorStore = new SupabaseVectorStore(embeddings, {
client,
tableName: 'documents',
queryName: 'match_documents'
})
const retriever = vectorStore.asRetriever()
const llm = new ChatOpenAI({ openAIApiKey })
const standaloneQuestionTemplate = `Given a question, convert it to a standalone 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 Alice in Wonderland 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." 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)
function combineDocuments(docs){
return docs.map((doc)=>doc.pageContent).join('\n\n')
}
const standaloneQuestionChain = RunnableSequence.from([
standaloneQuestionPrompt,
llm,
new StringOutputParser()
])
const retrieverChain = RunnableSequence.from([
prevResult => prevResult.standalone_question,
retriever,
combineDocuments
])
const answerChain = RunnableSequence.from([
answerPrompt,
llm,
new StringOutputParser()
])
const chain = RunnableSequence.from([
{
standalone_question: standaloneQuestionChain,
input_variables: new RunnablePassthrough()
},
{
context: retrieverChain,
question: ({ input_variables }) => input_variables.question
},
answerChain
])
const result = await chain.invoke({
question: question
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment