I. Project Overview

1.1 What this app does

ResearchAI is a multi-chat research assistant. You type a question, and it answers using Gemini, using your uploaded notes when relevant and calling tools such as the current time or a calculator when needed. Uploaded .txt and .md files are split, embedded, and stored so later questions can retrieve the matching passages before the model replies.

1.1.1 Architecture

Browser
  → chat page, /chat/, /upload/
  → views.py
       ├─ upload: save file → ingest_document()
       │     load → split → embed → Chroma
       └─ chat: load history → generate_response()
             → LangGraph
                  START → retrieve → model
                  model → tools → model   (only if the model requested a tool)
                  model → END              (when there is no tool call)

1.1.2 Project layout

.env.example                  # environment variable template; copy to .env
.gitignore                    # ignores .env, the database, uploads, and Chroma data
manage.py                     # Django command entry point
Procfile                      # production start command for Railway
requirements.txt              # pinned Python dependencies

config/                       # Django project package
├── settings.py               # settings, API keys, Chroma path, upload limit
├── urls.py                   # mounts the chat app at /
├── wsgi.py                   # production WSGI entry used by gunicorn
├── asgi.py                   # ASGI entry; not used by the current server
├── templates/chat.html       # chat page markup
└── static/
    ├── css/chat.css          # page styles
    └── js/
        ├── chat.js           # page behavior, including drag and drop
        ├── api.js            # /chat/ and /upload/ requests
        ├── state.js          # chat list saved in the browser
        └── markdown.js       # render assistant markdown

chat/                         # the application
├── views.py                  # page, chat API, and upload API
├── urls.py                   # /, /chat/, and /upload/ routes
├── models.py                 # Conversation and Message tables
├── admin.py                  # registers models in the Django admin
├── apps.py                   # Django app config
├── file_upload.py            # checks and saves an uploaded file
├── migrations/               # database schema changes
├── langchain_backend/        # live answer and ingestion path
│   ├── services.py           # LangGraph and generate_response()
│   ├── nodes.py              # retrieve, model, and tool nodes
│   ├── tools.py              # current time and calculator
│   ├── rag.py                # search existing Chroma data
│   └── ingestion.py          # load, split, embed, and store a file
└── manual_backend/           # earlier handwritten version, not used by the page
    ├── services.py           # handwritten agent loop and generate_response()
    ├── tools.py              # current time and calculator declarations
    ├── document_loader.py    # read and split a .txt or .md file
    ├── embeddings.py         # turn text into Gemini vectors
    ├── vector_store.py       # save chunk vectors in Chroma
    ├── retrieval.py          # search Chroma and filter by distance
    └── ingestion.py          # load, split, embed, and store a file

doc/example/                  # sample notes for trying retrieval
├── sample_research_notes.txt # plain-text sample
└── sample_research_notes.md  # Markdown sample

## 1.2 Workflow

<aside>
💡

Basic app → LLM → Conversation feature→ Tools → RAG → LangChain → LangGraph → Deployment

</aside>

Example: We are making a little teaching robot helper.

1. **Basic app:** You build a little box where you can type and see an answer.
2. **LLM API:** You connect the box to the “robot brain.”
3. **Conversation features:** Now the robot remembers what you said a moment ago.
4. **Tool calling:** Now the robot gets hands. It can use tools, like a calculator, a database, or another API
5. **RAG:** Now you give the robot a bookshelf. It can look inside your PDFs or documents before answering.
6. **LangChain:** LangChain is like a box of Lego pieces that helps you connect the robot brain, tools, documents, and prompts more easily.
7. **LangGraph:** Now you can give the robot a real map: `start → search → check → maybe search again → answer`. It helps with more complicated workflows.