Skip to content

Rag engine - #18

Open
IsaacBurns7 wants to merge 10 commits into
mainfrom
rag
Open

Rag engine#18
IsaacBurns7 wants to merge 10 commits into
mainfrom
rag

Conversation

@IsaacBurns7

Copy link
Copy Markdown
Contributor

OVERARCHING GOAL:

Support scholarship matching based upon user documents, attributes, and scholarship documents and attributes.

To this end, the following must be created:

  1. Test suite for the below
  2. Vector store and accompanying scripts
  3. Embedding Service
  4. Retrieval Engine and accompanying scripts
  5. Context Builder and accompanying scripts
  6. LLM Client
  7. Response processor to verify model fits deterministic parameters
  8. Query classifier to route user queries (may be separated from current rag engine)
  9. Rag engine (to bundle together)

IsaacBurns7 and others added 8 commits October 9, 2025 21:51
- Updated electron package-lock.json
- Removed frontend build output files (out/main/index.js, out/preload/index.js)
- Removed frontend/src/features/health/HealthDashboard.tsx
- Added backend/services/llm_manager/TODO.md
- Added PostgreSQL 16 Alpine Dockerfile with pgvector, pg_trgm, and pg_stat_statements
- Created comprehensive init.sql with extension initialization and configuration
- Consolidated schema into fiapply.sql with all tables, indexes, and views
- Updated docker-compose.yml with PostgreSQL and pgAdmin services
- Created database utility script (db_utils.sh) for common operations
- Added comprehensive database documentation (README.md)
- Updated main README to reflect PostgreSQL usage
- Updated Makefile to launch pgAdmin instead of SQLite Web
- Updated architecture and tech stack documentation
- Removed SQLite references from documentation

Database features:
- pgvector for 384-dimensional embeddings and semantic search
- pg_trgm for fuzzy text search with trigram similarity
- pg_stat_statements for query performance monitoring
- HNSW indexes for fast approximate nearest neighbor search
- GIN indexes for efficient trigram-based text search
- Materialized views for statistics
- Auto-updating triggers for updated_at timestamps
- Replace SQLite database paths with PostgreSQL connection parameters
- Update DATABASE_URL to use postgresql:// connection string format
- Update RAG Engine database settings to use PostgreSQL environment variables
- Switch to PostgreSQL 17-alpine3.22 (from 16)
- Update pgvector to v0.8.0 for compatibility
- Skip LLVM bitcode generation (with_llvm=no) to avoid clang-19 dependency
- All extensions (vector, pg_stat_statements, pg_trgm) working correctly
- Successfully tested with full schema initialization
- Migrated all custom components from Archive/frontend to frontend/
- Installed and configured ShadCN UI with Tailwind CSS v3
- Migrated UI components: button, card, badge, separator, hover-card
- Migrated pages: Dashboard, HealthDashboard, Landing
- Added Redux Toolkit store with healthSlice
- Configured React Router for navigation
- Updated TypeScript paths and build configuration
- Created Dockerfile for Electron frontend
- Updated docker-compose.yml to reflect new frontend structure
- Consolidated electron directory into frontend root
- Removed old /electron directory in favor of /frontend as the Electron app
…being used solely for reference. Created test file, basic document upload. will add more sophisticated upload later, probably using minilm for now. we should probably use resume as initial doc score (run on up to 10000), then use cv / essays / career goals with colbert(heay) for doc score 2 (run on up to 100)
@IsaacBurns7 IsaacBurns7 linked an issue Oct 11, 2025 that may be closed by this pull request
@IsaacBurns7 IsaacBurns7 self-assigned this Oct 11, 2025

@FOOincognita FOOincognita left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RAG Engine is missing a core library, LangChain, which it should be built on; this will greatly lower development time & increase functionality. It must also receive & handle requests from AI Orchestrator, as well as send requests to LLM Manager for all LLM Interactions.

Comment thread backend/services/rag_engine/core/rag.py Outdated
Comment on lines +2 to +8
import datetime
from typing import List, Dict, Any, Optional, Tuple
from dataclasses import dataclass
from enum import Enum
import psycopg2

import ollama

@FOOincognita FOOincognita Oct 12, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed you don't import gRPC nor LangChain anywhere; RAGEngine is meant to be built using LangChain, & also must invoke gRPC to make calls to LLM Manager. It must also receive requests from ai orchestrator.

LangChain will provide every possible operation & performance enhancement we'd need for RAG Engine. The challenge with this service is to use LangChain to handle requests from ai orchestrator & apply the correct LangChain functions to the request to generate a valuable response, as well as optimizing that process using LangChain's optimizations + supportive caching libraries.

No other service aside from LLM Manager should ever call OpenRouter or Ollama; RAG Engine must make all requests to LLMs by calling LLM Manager.

I'll add that arrow to the architecture diagram.

------------

CREATE EXTENSION vector;
CREATE EXTENSION IF NOT EXISTS vector;

@FOOincognita FOOincognita Oct 12, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove; pg_vector is already initialized in init.sql along with the other plugins

Comment thread db/models/users.sql
------------

CREATE EXTENSION vector;
CREATE EXTENSION IF NOT EXISTS vector;

@FOOincognita FOOincognita Oct 12, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove; pg_vector is already initialized in init.sql along with the other plugins

Comment thread db/models/users.sql
updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS user_documents (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User documents should be placed in a separate model file, & user-document relationships should use a 1-to-many relationship to a general document table. This means users have a column which contains some int or string (hash) identifier corresponding to a document which is located in a separate table in a separate file.

Technically for now since this will be 100% local tho, a document can only ever belong to 1 user; the host user. However since we'll eventually add a cloud hosted option, setting it up to be distributed now will save us time down the line.

…nd matching of scholarships, along with tests

@FOOincognita FOOincognita left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left comments in new rag.py file, which shows significant improvement compared to previous versions.

Comment thread backend/services/rag_engine/core/rag.py Outdated
password = config["password"],
host = config["host"],
port = config["port"]
def embed_pdf(self, pdfFilePath):

@FOOincognita FOOincognita Oct 13, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment addresses the entire file:

This looks significantly better. Here are a few candidates for improvements:

  1. Lazy loading & batch processing - Don't load entire PDFs into memory, & add docs in batches.
  2. This implementation's missing error handling; there are multiple failure points without recovery methods.
  3. Implement token-aware chunking rather than character-based.
  4. Currently can't efficiently filter by user, document type, etc.
  5. This monolithic class does too many things; refactor for separation of concerns.
  6. Implement caching, maybe LRU policy.
  7. Leverage async for non-blocking operations.
  8. Leverage structured logger in /backend/shared/utils/logger.py

@FOOincognita FOOincognita Oct 13, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've included an example.py implementation which makes use of each of these improvements for reference (excluding the shared logger). Note that it's not meant to replace yours; it's just a handy reference.

…hing is async now :), will have to centralize from core/rag.py to server.py later once other smaller auxiliary services are made, after vectordbservice is finished, and then subsequently cut into several pieces

@FOOincognita FOOincognita left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good hoss. For those merge conflicts, many can be resolved by running a git pull origin main, which will update your .gitignore, which resolves the conflicts with **/generated directories + the swagger docs in docs/openapi.

#document embedding services
async def EmbedScholarshipBatch(self, request: rag_engine_pb2.EmbedScholarshipBatchRequest,
context: grpc.aio.ServicerContext) -> rag_engine_pb2.EmbedScholarshipBatchResponse:
print("Handler called!!")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change print() usage to logs.debug() unless you want output in cout rather than cerr; both will appear in terminal.

Comment thread proto/rag_engine.proto
Comment on lines +136 to +201
service VectorDBService {
// Initialize vector DB connection or collection
rpc Init(InitRequest) returns (InitResponse);

// Embed a batch of scholarships and store them
rpc EmbedScholarshipBatch(EmbedScholarshipBatchRequest) returns (EmbedScholarshipBatchResponse);
}

// =========================================
// VectorDBService - Define RPC method requests and response schemas
// =========================================

message InitRequest {
string connection_string = 1; // e.g. "postgresql://user:pass@localhost/db"
string collection_name = 2;
}

message InitResponse {
bool success = 1;
fi.common.v1.Error error = 2;
}

message EmbedScholarshipBatchRequest {
repeated Scholarship scholarships = 1; // Example dataclass converted below
}

message EmbedScholarshipBatchResponse {
int32 total_embedded = 1;
fi.common.v1.Error error = 2;
}

//may change
message Document {
string document_id = 1;
string content = 2;
google.protobuf.Struct metadata = 3;
}

message Scholarship {
// Unique scholarship identifier
int32 id = 1;

// Scholarship name
string name = 2;

// Scholarship description or summary
string description = 3;

// Minimum GPA required (e.g. 3.5)
double min_gpa = 4;

// Eligible majors (e.g. "Computer Science", "Engineering")
repeated string eligible_majors = 5;

// Citizenship requirement (optional, can be null)
string citizenship_required = 6;

// Location requirement or region (optional)
string location = 7;

// Award amount or range, kept as a string for flexibility
string award_amount = 8;

// Keywords for semantic search / classification
repeated string keywords = 9;
} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given these message types & service are meant to service database interactions rather than service-to-service communication, we should move it to its own proto file, maybe postgres.proto or something similar. Any other services which speak with the database will share this service to use when communicating with the DB.

Comment on lines +104 to +110
class DocumentType:
SCHOLARSHIP = "scholarship"
RESUME = "resume"
ESSAY = "essay"
TRANSCRIPT = "transcript"
FORM_CONTEXT = "form_context"
USER_PROFILE = "user_profile"

@FOOincognita FOOincognita Oct 16, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May benefit from inheriting from the base enum class:

class DocumentType(Enum):

iirc, you should be able to maintain the associated string values, tho they'd also map to an int, making case matching significantly safer/easier (if you plan on using the definitions for case matching later on)

import signal
import datetime
from backend.shared.utils import logs
from typing import List, Dict, Any, Optional, Tuple

@FOOincognita FOOincognita Oct 16, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While still valid, much of the Typing library is deprecated since Python 3.9+ excluding type Typing.Any. However, the use of the native type hint object is a valid native replacement for Typing.Any, tho contextually more ambiguous.

Conversions:

  • Typing.List $\rightarrow$ list
  • Typing.Dict $\rightarrow$ dict
  • Typing.Tuple $\rightarrow$ tuple
  • Typing.Optional $\rightarrow$ <type> | None
    • Example: Optional[str] $\rightarrow$ str | None

return rag_engine_pb2.InitResponse(error = e)

async def __getattr__(self, name):
print("gRPC called:", name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change print() usage to logs.debug() unless you want output in cout rather than cerr; both will appear in terminal.

@FOOincognita FOOincognita added the enhancement New feature or request label Oct 16, 2025
@FOOincognita FOOincognita added this to the Sprint 2 milestone Oct 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RAG engine scholarship, resume, essay storage

2 participants