Skip to content

Commit

Permalink
OpenAI GPT-4 + FAISS DB + Paste Docs (#3492)
Browse files Browse the repository at this point in the history
* chore: checkpoint ai nextjs api route and faiss db

* chore: refine api endpoint

* chore: remove unused dep
  • Loading branch information
TheSisb authored Sep 22, 2023
1 parent 6bc4a8a commit 0d1ccef
Show file tree
Hide file tree
Showing 5 changed files with 658 additions and 10 deletions.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions packages/paste-website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"globby-esm": "npm:globby@^13.1.3",
"highcharts": "^9.3.3",
"highcharts-react-official": "^3.1.0",
"langchain": "^0.0.151",
"lodash": "4.17.21",
"lottie-web": "^5.7.4",
"markdown-to-jsx": "^7.3.2",
Expand Down
80 changes: 80 additions & 0 deletions packages/paste-website/src/pages/api/ai.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* API endpoint for querying our doc site with ChatGPT4
*
* Requires two environment variables:
* - OPENAI_API_KEY: Your OpenAI API key
* - OPENAI_API_SECRET: Custom secret to block unauthorized requests
*
* Please set these in your .env file and on your deployment boxes configuration.
*/
import {fileURLToPath} from 'url';
import path from 'path';

import {loadQAStuffChain} from 'langchain/chains';
import {OpenAIEmbeddings} from 'langchain/embeddings/openai';
import {ChatOpenAI} from 'langchain/chat_models/openai';
import {FaissStore} from 'langchain/vectorstores/faiss';
import type {NextApiRequest, NextApiResponse} from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse): Promise<void> {
const {question, secret} = req.body;
// Exit early if the required params aren't provided
if (!question || secret !== process.env.OPENAI_API_SECRET) {
res.status(200).send({answer: 'Please provide a question'});
return;
}

/*
* Get the FAISS DB
*/
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const directory = path.join(__dirname, '../../../indexes/faiss_index');
const loadedVectorStore = await FaissStore.loadFromPython(directory, new OpenAIEmbeddings());

/*
* Create the OpenAI model
*/
const model = new ChatOpenAI({
modelName: 'gpt-4',
temperature: 0,
});

/*
* Create the QA stuff chain from our GPT-4 model
*/
const stuffChain = loadQAStuffChain(model);

try {
/*
* We cannot provide GPT-4 with our entire doc site. For this reason we use the FAISS DB.
* This DB is a compressed vector db that allows us to search for similar "documents"
* based on a provided question string. We take the top 4 results and provide them to
* GPT-4 for further processing.
*/
const inputDocuments = await loadedVectorStore.similaritySearch(question, 4);

/*
* Ask GPT-4 the question and provide the input documents
*/
const answer = await stuffChain.call({
// eslint-disable-next-line camelcase
input_documents: inputDocuments,
question,
});

res.status(200).send({answer});
} catch (error) {
res.status(500).send({error});
}
}

export const config = {
api: {
bodyParser: {
sizeLimit: '10kb',
},
},
// Specifies the maximum allowed duration for this function to execute (in seconds)
maxDuration: 15,
};
Loading

0 comments on commit 0d1ccef

Please sign in to comment.