> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anotherwrapper.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Vector Database & RAG

> How document chat works with PostgreSQL, pgvector, embeddings, and citations

<Info>
  This isn't a fake "upload a PDF" button. It's a real document-chat pipeline. Users upload documents, the app indexes them, and they get answers with citations. Here's how it all works.
</Info>

## What Is RAG?

**RAG** stands for **Retrieval-Augmented Generation**. In plain English:

1. Your app stores source material (like PDFs)
2. When a user asks a question, the app finds the most relevant pieces
3. Those pieces get passed into the model as context
4. The model answers using that context

This is how the chat app answers questions about **your documents** -- not just what the model already knew.

<Tabs>
  <Tab title="How It Works">
    ## The Pipeline, Step by Step

    <Steps>
      <Step title="Upload">
        The user uploads a PDF in chat. The file is stored and tracked in the database.
      </Step>

      <Step title="Text extraction">
        The repo extracts readable text from the PDF so the AI system has something to work with.
      </Step>

      <Step title="Chunking">
        The text is split into smaller sections. Models and vector search work much better on focused chunks than one giant blob.
      </Step>

      <Step title="Embedding">
        Each chunk is turned into a vector embedding using OpenAI's embedding model. Think of it as converting meaning into numbers.
      </Step>

      <Step title="Storage">
        Those embeddings are stored in PostgreSQL in the `embeddings` table, alongside document metadata.
      </Step>

      <Step title="Retrieval">
        When the user asks a question, the question is embedded too. The app runs similarity search to find the closest matching chunks.
      </Step>

      <Step title="Prompt injection">
        The best chunks are assembled into prompt-ready context and passed into the chat generation flow.
      </Step>

      <Step title="Citations">
        The answer includes source metadata so the UI can show citations back to the user. No more "trust me, bro."
      </Step>
    </Steps>

    ## The Vector Database

    The vector database is what makes semantic search possible. Instead of just storing raw text, the app stores:

    * The original chunk of text
    * Metadata (document ID, page number, etc.)
    * A vector embedding for that chunk

    That embedding is a numeric representation of *meaning*. It lets the app find chunks that are conceptually similar to a question, even when the wording is completely different.

    This is all implemented with **PostgreSQL** + **pgvector** + **OpenAI embeddings**.

    <Note>
      `pgvector` is a Postgres extension enabled at the database level. Your host must support `CREATE EXTENSION vector` for this to work.
    </Note>
  </Tab>

  <Tab title="Setup">
    ## What You Need

    <CardGroup cols={3}>
      <Card title="Auth + PostgreSQL" icon="database" href="/services/better-auth-postgresql">
        For auth, hosted Postgres, and the documented setup path.
      </Card>

      <Card title="Storage" icon="hard-drive" href="/services/storage">
        For uploaded documents and file-backed workflows.
      </Card>

      <Card title="OpenAI" icon="microchip" href="/providers/openai">
        For embeddings in the RAG pipeline.
      </Card>
    </CardGroup>

    <Warning>
      Even if your users mostly chat with Claude, Gemini, Grok, or DeepSeek, the document pipeline uses **OpenAI embeddings** for indexing and retrieval. Treat [OpenAI](/providers/openai) as required for this feature.
    </Warning>

    ## Key Tables

    | Table                 | Purpose                                |
    | --------------------- | -------------------------------------- |
    | `pdf_documents`       | Uploaded documents and indexing status |
    | `embeddings`          | Chunk vectors and metadata             |
    | `chat_document_links` | Links documents to chat sessions       |

    Documents aren't floating around as random files. They're part of a real, queryable data model.

    ## Key Files

    | File                                          | Purpose                 |
    | --------------------------------------------- | ----------------------- |
    | `lib/rag/pdf-extract.ts`                      | PDF text extraction     |
    | `lib/rag/chunking.ts`                         | Chunk creation          |
    | `lib/rag/embedding-ingest.ts`                 | Embedding + persistence |
    | `lib/rag/retrieve.ts`                         | Semantic retrieval      |
    | `lib/rag/citations.ts`                        | Citation formatting     |
    | `app/(apps)/chat/api/chat/chat-generation.ts` | Injecting RAG into chat |
  </Tab>
</Tabs>

## What You Can Build With This

This setup is perfect for:

* PDF question answering
* Internal knowledge assistants
* Customer support bots grounded in your docs
* Contract or policy lookup
* Document-aware research workflows

It turns the chat app from "just another assistant" into something that works with user-provided knowledge.

## Common Mistakes

<AccordionGroup>
  <Accordion title="Uploading PDFs but never indexing them">
    The upload and indexing are separate steps. Make sure the indexing pipeline completes before expecting RAG answers.
  </Accordion>

  <Accordion title="Expecting RAG to work without storage">
    You need object storage configured so the app can store the uploaded files. See the [Storage guide](/services/storage).
  </Accordion>

  <Accordion title="Forgetting that embeddings need OpenAI">
    The embedding pipeline uses OpenAI regardless of which chat model the user picks. Set your `OPENAI_API_KEY`.
  </Accordion>

  <Accordion title="Assuming any Postgres host supports pgvector">
    Not every provider has `pgvector` enabled. Supabase supports it out of the box. Check your host's docs if you're using something else.
  </Accordion>

  <Accordion title="Expecting perfect answers every time">
    RAG improves grounded answers, but it doesn't replace good prompts, reasonable chunking, or careful product design. It gives the model better context -- it doesn't magically make every answer perfect.
  </Accordion>
</AccordionGroup>
