├── .env.example ├── .eslintrc.json ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierrc ├── README.md ├── README_ko.md ├── components ├── layout.tsx └── ui │ ├── LoadingDots.tsx │ ├── TextArea.tsx │ └── accordion.tsx ├── config └── chroma.ts ├── declarations └── pdf-parse.d.ts ├── docs └── .keep ├── faiss-store └── .keep ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.tsx ├── _document.tsx ├── api │ └── chat.ts └── index.tsx ├── postcss.config.cjs ├── public ├── bot-image.png ├── favicon.ico └── usericon.png ├── scripts └── ingest-data.ts ├── styles ├── Home.module.css ├── base.css ├── chrome-bug.css └── loading-dots.module.css ├── tailwind.config.cjs ├── tsconfig.json ├── types └── chat.ts ├── utils ├── cn.ts ├── customPDFLoader.ts └── makechain.ts └── visual-guide └── gpt-langchain-pdf.png /.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | OPENAI_CHAT_MODEL=gpt-3.5-turbo 3 | ANSWER_LANGUAGE=en-US 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | .env 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | #Notion_db 40 | /Notion_DB 41 | 42 | #docs and store 43 | /docs/ 44 | /faiss-store/ -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "singleQuote": true, 4 | "printWidth": 80, 5 | "tabWidth": 2 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Create a ChatGPT Chatbot for Your CSV, TXT, PDF Files 2 | 3 | [English](README.md) | [한국어](README_ko.md) 4 | 5 | Use the new GPT-4 api to build a chatGPT chatbot for multiple Large PDF, CSV, TET files. 6 | 7 | Tech stack used includes LangChain, Faiss, Typescript, Openai, and Next.js. LangChain is a framework that makes it easier to build scalable AI/LLM apps and chatbots. Faiss is a vectorstore for storing embeddings and your PDF in text to later retrieve similar docs. 8 | 9 | [Tutorial video](https://www.youtube.com/watch?v=ih9PBGVVOO4) 10 | 11 | [Join the discord if you have questions](https://discord.gg/E4Mc77qwjm) 12 | 13 | The visual guide of this repo and tutorial is in the `visual guide` folder. 14 | 15 | **If you run into errors, please review the troubleshooting section further down this page.** 16 | 17 | Prelude: Please make sure you have already downloaded node on your system and the version is 18 or greater. 18 | 19 | ## Development 20 | 21 | 1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) for your platform. 22 | 23 | 2. Clone the repo or download the ZIP 24 | 25 | ``` 26 | git clone [github https url] 27 | ``` 28 | 29 | 3. Install packages 30 | 31 | First run `npm install yarn -g` to install yarn globally (if you haven't already). 32 | 33 | Then run: 34 | 35 | ``` 36 | yarn install 37 | ``` 38 | 39 | After installation, you should now see a `node_modules` folder. 40 | 41 | 4. Set up your `.env` file 42 | 43 | - Copy `.env.example` into `.env` 44 | Your `.env` file should look like this: 45 | 46 | ``` 47 | OPENAI_API_KEY= 48 | OPENAI_CHAT_MODEL= 49 | ANSWER_LANGUAGE= 50 | ``` 51 | 52 | - Visit [openai](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key) to retrieve API keys and insert into your `.env` file. 53 | - If you want to use gpt-4, write gpt-4 in OPENAI_CHAT_MODEL. (default: gpt-3.5-turbo) 54 | - For ANSWER_LANGUAGE, enter the language you want ChatGPT to answer in. (default: English) 55 | 56 | 5. In `utils/makechain.ts` chain change the `QA_PROMPT` for your own usecase. Change `modelName` in `new OpenAI` to `gpt-4`, if you have access to `gpt-4` api. Please verify outside this repo that you have access to `gpt-4` api, otherwise the application will not work. 57 | 58 | ## Convert your PDF, CSV, TXT files to embeddings 59 | 60 | **This repo can load multiple PDF files** 61 | 62 | 1. Inside `docs` folder, add your pdf, csv, txt files or folders that contain files. 63 | 64 | 2. Run the script `npm run ingest` to 'ingest' and embed your docs. If you run into errors troubleshoot below. 65 | 66 | 3. Verify that the docstore.json and faiss.index files are successfully created in the `faiss-store` folder. 67 | 68 | ## Run the app 69 | 70 | Once you've verified that the embeddings and content have been successfully added to your faiss store, you can run the app `npm run dev` to launch the local dev environment, and then type a question in the chat interface. 71 | 72 | ## Troubleshooting 73 | 74 | In general, keep an eye out in the `issues` and `discussions` section of this repo for solutions. 75 | 76 | **General errors** 77 | 78 | - Make sure you're running the latest Node version. Run `node -v` 79 | - Try a different PDF or convert your PDF to text first. It's possible your PDF is corrupted, scanned, or requires OCR to convert to text. 80 | - `Console.log` the `env` variables and make sure they are exposed. 81 | - Make sure you're using the same versions of LangChain and Faiss as this repo. 82 | - Check that you've created an `.env` file that contains your valid (and working) API keys, environment and index name. 83 | - If you change `modelName` in `OpenAI`, make sure you have access to the api for the appropriate model. 84 | - Make sure you have enough OpenAI credits and a valid card on your billings account. 85 | - Check that you don't have multiple OPENAPI keys in your global environment. If you do, the local `env` file from the project will be overwritten by systems `env` variable. 86 | - Try to hard code your API keys into the `process.env` variables if there are still issues. 87 | 88 | ## Credit 89 | 90 | Frontend of this repo is inspired by [langchain-chat-nextjs](https://github.com/zahidkhawaja/langchain-chat-nextjs) 91 | -------------------------------------------------------------------------------- /README_ko.md: -------------------------------------------------------------------------------- 1 | # CSV, TXT, PDF 파일을 위한 ChatGPT 챗봇 만들기 2 | 3 | [English](README.md) | [한국어](README_ko.md) 4 | 5 | OpenAI API를 사용하여 PDF, CSV, TET 파일에 대한 ChatGPT 챗봇을 구축할 수 있습니다. 6 | 7 | 사용되는 기술 스택에는 LangChain, Faiss, Typescript, Openai 및 Next.js가 포함됩니다. LangChain은 확장 가능한 AI/LLM 앱과 챗봇을 쉽게 구축할 수 있는 프레임워크입니다. Faiss는 임베딩과 PDF를 텍스트에 저장하여 나중에 유사한 문서를 검색할 수 있는 벡터 저장소입니다. 8 | 9 | [튜토리얼 동영상](https://www.youtube.com/watch?v=ih9PBGVVOO4) 10 | 11 | [질문이 있는 경우 디스코드에 참여](https://discord.gg/E4Mc77qwjm) 12 | 13 | 이 리포지토리와 튜토리얼의 비주얼 가이드는 `visual guide` 폴더에 있습니다. 14 | 15 | **오류가 발생하면 이 페이지 아래쪽의 문제 해결 섹션을 참조하세요.** 16 | 17 | 준비사항: 시스템에 [Node.JS](https://nodejs.org/ko)가 이미 다운로드되어 있고 Node.JS 버전이 18 이상인지 확인하세요. 18 | 19 | ## 개발 20 | 21 | 1. 리포지토리를 복제하거나, 22 | 23 | ``` 24 | git clone https://github.com/anpigon/gpt4-pdf-chatbot-langchain-faiss.git 25 | ``` 26 | 27 | 2. 또는 ZIP 파일을 다운로드 합니다. 28 | 29 | 30 | 31 | 32 | 3. 패키지 설치 33 | 34 | 다음 명령을 실행합니다: 35 | 36 | ``` 37 | npm install 38 | ``` 39 | 40 | 설치가 완료되면 이제 `node_modules` 폴더가 표시됩니다. 41 | 42 | 4. `.env` 파일 설정 43 | 44 | - `.env.example`를 `.env`에 복사합니다. 45 | `.env` 파일은 다음과 같아야 합니다: 46 | 47 | ``` 48 | OPENAI_API_KEY= 49 | OPENAI_CHAT_MODEL= 50 | ANSWER_LANGUAGE= 51 | ``` 52 | 53 | - `OPENAI_API_KEY`: API 키를 [openai](https://platform.openai.com/account/api-keys)에서 발급받고, 이를 .env 파일에 입력합니다. 54 | - `OPENAI_CHAT_MODEL`: `gpt-4` 또는 `gpt-3.5-turbo`를 입력합니다. 55 | - `ANSWER_LANGUAGE`: ChatGPT가 응답할 언어를 입력합니다. 한국어로 응답을 받고 싶으면 **ko-KR**을 입력합니다. 56 | 57 | 5. `utils/makechain.ts` 파일에서 자신의 입맛에 맞게 `QA_PROMPT` 프롬프트를 변경할 수 있습니다. 58 | 59 | ## PDF, CSV, TXT 파일을 임베딩으로 변환하세요. 60 | 61 | **이 리포지토리는 여러 PDF, CSV, TXT 파일들을 로드할 수 있습니다**. 62 | 63 | 1. `docs` 폴더에 PDF, CSV, TXT 파일 또는 파일이 들어있는 폴더를 추가합니다. 64 | 65 | 2. `npm run ingest` 명령을 실행하여 문서를 'ingest'하고 문서를 임베드합니다. 오류가 발생하면 아래에서 문제를 해결하세요. 66 | 67 | 3. `faiss-store` 폴더에 docstore.json 및 faiss.index 파일이 성공적으로 생성되었는지 확인합니다. 68 | 69 | 4. ***주의***: `npm run ingest` 명령을 실행하면 기존 임베딩이 삭제되고 새로 생성됩니다. 70 | 71 | ## 앱 실행하기 72 | 73 | 임베딩과 콘텐츠가 faiss 스토어에 성공적으로 추가되었는지 확인한 후, `npm run dev` 명령을 실행하여 로컬 개발 환경을 시작합니다. 그런 다음, 채팅 인터페이스에 질문을 입력할 수 있습니다. 74 | 75 | ## 문제 해결 76 | 77 | 일반적으로 이 리포지토리의 `issues` 및 `discussions` 섹션에서 해결책을 찾아보세요. 78 | 79 | **General errors** 80 | 81 | - 최신 노드 버전을 실행하고 있는지 확인하세요. `node -v`를 실행하세요. 82 | - 다른 PDF를 시도하거나 먼저 PDF를 텍스트로 변환하세요. PDF가 손상되었거나 스캔되었거나 텍스트로 변환하기 위해 OCR이 필요할 수 있습니다. 83 | - `Console.log` 에서 `env` 변수를 확인하고 해당 변수가 노출되어 있는지 확인하세요. 84 | - 이 리포지토리와 동일한 버전의 LangChain 및 Faiss를 사용하고 있는지 확인하세요. 85 | - 유효한(그리고 작동하는) OpenAI API Key, 환경 및 인덱스 이름이 포함된 `.env` 파일을 생성했는지 확인합니다. 86 | - `modelName` 을 변경하는 경우, 해당 모델의 API에 대한 액세스 권한이 있는지 확인하세요. 87 | - 청구 계정에 충분한 OpenAI 크레딧과 유효한 카드가 있는지 확인하세요. 88 | - 글로벌 환경에 여러 개의 OPENAPI 키가 없는지 확인하세요. 여러 개가 있는 경우 프로젝트의 로컬 `env` 파일을 시스템 `env` 변수로 덮어쓰게 됩니다. 89 | - 여전히 문제가 있는 경우 API 키를 `process.env` 변수에 하드 코딩해 보세요. 90 | 91 | ##### (추가) faiss에서 libomp 관련 오류가 발생할 경우, 다음과 같은 방법을 시도해 볼 수 있습니다. 92 | "faiss-node"에서 "libomp" 관련 오류를 해결하려면 시스템에 "libomp" 라이브러리를 설치해 볼 수 있습니다. 이 라이브러리는 Faiss에 필요하며 우분투에서 다음 명령을 사용하여 설치할 수 있습니다: 93 | 94 | ```sh 95 | sudo apt-get install libomp-dev 96 | ``` 97 | 98 | macOS에서는 Homebrew를 사용하여 설치할 수 있습니다: 99 | ```sh 100 | brew install libomp 101 | ``` 102 | 103 | 윈도우에서는 다음 명령을 사용하여 설치할 수 있습니다: 104 | ```sh 105 | conda install libpython m2w64-toolchain -c msys2 106 | conda install faiss-cpu -c pytorch 107 | ``` 108 | 109 | 라이브러리를 설치한 후 코드를 다시 실행하여 오류가 지속되는지 확인합니다. 110 | 111 | 112 | ## 크레딧 113 | 이 리포지토리의 프론트엔드는 [langchain-chat-nextjs](https://github.com/zahidkhawaja/langchain-chat-nextjs)에서 영감을 얻었습니다. 114 | -------------------------------------------------------------------------------- /components/layout.tsx: -------------------------------------------------------------------------------- 1 | interface LayoutProps { 2 | children?: React.ReactNode; 3 | } 4 | 5 | export default function Layout({ children }: LayoutProps) { 6 | return ( 7 |
8 |
9 |
10 | 15 |
16 |
17 |
18 |
19 | {children} 20 |
21 |
22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /components/ui/LoadingDots.tsx: -------------------------------------------------------------------------------- 1 | import styles from '@/styles/loading-dots.module.css'; 2 | 3 | const LoadingDots = ({ 4 | color = '#000', 5 | style = 'small', 6 | }: { 7 | color: string; 8 | style: string; 9 | }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | export default LoadingDots; 20 | 21 | LoadingDots.defaultProps = { 22 | style: 'small', 23 | }; 24 | -------------------------------------------------------------------------------- /components/ui/TextArea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { cn } from '@/utils/cn'; 3 | 4 | export interface TextareaProps 5 | extends React.TextareaHTMLAttributes {} 6 | 7 | const Textarea = React.forwardRef( 8 | ({ className, ...props }, ref) => { 9 | return ( 10 |