Skip to content

morel-source/UserAssistant

Repository files navigation

UserAssistant - RAG API

A C# / ASP.NET Core Retrieval-Augmented Generation (RAG) API that allows users to upload documents and ask questions based on their content.

The system uses vector search with Qdrant and local LLM inference with Ollama to provide answers based on uploaded documents.


Stack

  • ASP.NET Core Web API
  • C#
  • Qdrant (Vector Database)
  • Ollama (Local LLM)
  • nomic-embed-text (Embedding Model)
  • FluentValidation
  • Docker / Docker Compose

Features

  • Document upload and processing
  • Text extraction from documents
  • Document chunking
  • Vector embeddings generation
  • Semantic similarity search
  • RAG-based question answering
  • Source tracking for generated answers
  • Request validation using FluentValidation
  • Logging and error handling
  • Retry policies for external services

API

All endpoints below require a JWT bearer token — see Authentication.

Upload Document

POST /api/documents

Uploads a document, processes its content, generates embeddings, and stores the vectors in Qdrant.


Ask Question

POST /api/chat

Searches for relevant document chunks using vector similarity search and generates an answer using the LLM.


Architecture

UserAssistant is a production-oriented Retrieval-Augmented Generation (RAG) system that combines document ingestion, vector search, LLM orchestration, and user memory.

The system is divided into two main flows:

  • Document Ingestion Pipeline - processes uploaded documents and stores knowledge in the vector database.
  • Chat Pipeline - retrieves relevant information, combines it with user memory, and generates an LLM response.

High-Level Architecture

                                  UserAssistant
                                        |
                    +-------------------+-------------------+
                    |                                       |
                    v                                       v
           Document Ingestion                         Chat Request
                Pipeline                                Pipeline

             Upload Document                          User Question
                    |                                       |
                    v                                       v
           Document Processing                      Query Processing
                    |                                       |
                    v                                       |
              Extract Text                                  |
                    |                                       |
                    v                                       |
            Split Into Chunks                               |
                    |                                       |
                    v                                       v
           Generate Embeddings                  Generate Query Embedding
                    |                                       |
                    +-------------------+-------------------+
                                        |
                                        v
                             Qdrant Vector Database
                             ======================

                                     Stores:
                                  - Embeddings
                                - Document chunks
                                   - Metadata

                                        |
                                        v
                                  Hybrid Search
                                        |
                    +-------------------+-------------------+
                    |                                       |
                    v                                       v
            Vector Similarity                       Keyword Matching
                    |                                       |
                    +-------------------+-------------------+
                                        |
                                        v
                                ReRanking Service
                                        |
                                        v
                            Retrieve Relevant Context
                                        |
                    +-------------------+-------------------+
                    |                                       |
                    v                                       v
             User Memory DB                        Retrieved Documents
                    |                                       |
                    +-------------------+-------------------+
                                        |
                                        v
                                 Prompt Builder
                                        |
                                        v
                                       LLM
                                        |
                    +-------------------+-------------------+
                    |                                       |
                    v                                       v
             Generate Answer                       Extract User Memory
                    |                                       |
                    v                                       v
             Return Response                     Save Important Memories
                                                            |
                                                            v
                                                  User Memory Database

Document Ingestion Flow

  1. User uploads a document.
  2. The document is processed and split into smaller chunks.
  3. Each chunk is converted into an embedding vector.
  4. Vectors and metadata are stored in Qdrant.

Stored information includes:

  • Document text
  • Source file
  • Chunk identifier
  • Vector representation

Chat Flow

When a user sends a question:

  1. The query is processed and optimized.
  2. The question is converted into an embedding vector.
  3. Hybrid search retrieves relevant documents from Qdrant:
    • Semantic vector similarity
    • Keyword matching
  4. Results are re-ranked to improve relevance.
  5. User memories are loaded from the memory database.
  6. A prompt is created containing:
    • User information
    • Retrieved context
    • User question
  7. The LLM generates:
    • Final answer
    • New user memories to store.
  8. The response is returned to the user.

Key Concepts

  • RAG (Retrieval-Augmented Generation) - combines information retrieval with LLM generation.
  • Embeddings - represent text as vectors for semantic search.
  • Vector Database - stores and retrieves relevant knowledge using similarity search.
  • Hybrid Search - combines semantic search with keyword-based matching.
  • LLM Orchestration - builds context-aware prompts and manages AI responses.
  • Memory System - stores long-term user information to improve future conversations.

Prerequisites

  • .NET 10 SDK
  • Docker (for Qdrant and Ollama)
  • dotnet-ef tool: dotnet tool install --global dotnet-ef

Running Locally

1. Start Infrastructure Services

Start Qdrant and Ollama using Docker Compose:

docker compose up -d

Verify Qdrant

Open:

http://localhost:6333/dashboard

Verify Ollama

Run:

curl http://localhost:11434/api/tags

Pull LLM Model

docker exec -it ollama ollama pull qwen2.5:1.5b

Pull Embedding Model

docker exec -it ollama ollama pull nomic-embed-text

2. Configure secrets

The JWT signing key must not be committed to appsettings.json. Set it locally via user secrets:

dotnet user-secrets init --project UserAssistant.Api
dotnet user-secrets set "Jwt:Key" "$(openssl rand -base64 32)" --project UserAssistant.Api

3. Apply database migrations and run the API

Migrations are applied automatically on startup, so you just need to run the API:

dotnet run --project UserAssistant.Api

This creates rag.db (SQLite) in the build output folder and applies all pending migrations, then starts the API. In Development, API docs are available at /scalar/v1.


Authentication

Most endpoints require a JWT bearer token. Register a user, log in, and pass the returned token as Authorization: Bearer <token> on subsequent requests.

Register

POST /api/auth/register
{
  "email": "user@example.com",
  "password": "P@ssw0rd123"
}

Login

POST /api/auth/login
{
  "email": "user@example.com",
  "password": "P@ssw0rd123"
}

Both endpoints return a JWT token valid for Jwt:ExpirationDays (default 7 days).


LLM Providers

The API switches providers based on environment:

  • Development — uses Ollama (local, no API key required) for both chat and embeddings.
  • Non-Development (e.g. Production) — uses OpenAI for both chat and embeddings. Requires OpenApiOptions:ApiKey and OpenAiEmbeddingOptions:ApiKey to be set via user secrets or environment variables — never commit a real API key to appsettings.json.

How RAG Works

  1. A user uploads a document.
  2. The document content is extracted and split into chunks.
  3. Each chunk is converted into a vector embedding.
  4. The vectors and metadata are stored in Qdrant.
  5. A user sends a question.
  6. The question is converted into an embedding vector.
  7. Qdrant searches for the most similar document chunks.
  8. The retrieved chunks are added as context to the prompt.
  9. The LLM generates an answer based on the retrieved information.

Roadmap / Known Limitations

This project is under active development. Known gaps, in priority order:

  • Automated test suite — unit tests for validators, AuthService, ChatService, and the retrieval pipeline are scoped and in progress, not yet merged.
  • CI pipeline — GitHub Actions workflow to run dotnet build + dotnet test on every push.
  • API containerization — Qdrant and Ollama run via Docker Compose; the API itself currently runs via dotnet run, not containerized.

About

Built a complete document intelligence pipeline including document ingestion, text processing, chunking strategies, embedding generation, vector storage with Qdrant, semantic retrieval, prompt orchestration, and LLM-powered question answering.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages