Skip to content
lorenzocozza91Public

About

Java desktop AI client for experimenting with Spring AI, PDF RAG, Ollama embeddings, vector search, DeepSeek Flash, and future agent tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

22 Commits

Folders and files

Repository files navigation

Mate AI

Mate AI is a Java desktop client for experimenting with Spring AI and agent-like workflows.

The application imports text-based PDF documents, creates chunks, generates embeddings with Ollama, persists the documents and vectors in a local SQLite database, searches the document context with cosine similarity, and uses DeepSeek Flash to answer questions based on the relevant document content.

Features

  • Native Java Swing chat interface
  • PDF import with Apache PDFBox
  • Replaceable document importer and chunker interfaces
  • 600-token target chunks with 80-token overlap in the simple chunker
  • Ollama embeddings for document chunks and user questions
  • Persistent SQLite storage for documents, chunks, metadata, and embeddings
  • SHA-256 hash check to skip already imported documents before extraction and chunking
  • Cosine similarity search over stored vectors
  • DeepSeek Flash for document-based answers
  • Background processing so PDF import and AI calls do not block the UI
  • Conversation-aware answers with local follow-up-question rewriting
  • Non-blocking toast notifications showing the imported document name, page count, and chunk count

Architecture

Document import

Selected document
   ↓
DocumentImportService
   ↓
Calculate file hash
   ↓
Already stored?
   ├─ Yes: load stored chunks and vectors
   └─ No: continue importing
           ↓
       PdfImportService
           ↓
       IDocumentChunker
           ↓
       Ollama EmbeddingModel
           ↓
       SQLite database

Question answering

User question
   ↓
Ollama creates a question embedding
   ↓
VectorDocumentStore loads stored chunk vectors
   ↓
Cosine similarity search
   ↓
Relevant document chunks
   ↓
DeepSeek Flash via Spring AI
   ↓
Answer in the desktop chat

DeepSeek is responsible for generating the answer. Ollama is used to create embeddings for document chunks and questions. SQLite stores the extracted chunks, metadata, and serialized embedding vectors.

Persistence

The application uses SQLite through Spring JDBC. The database is created automatically from src/main/resources/schema.sql and is stored as:

mate-ai.db

The database contains two main tables:

  • documents stores the source name, file hash, import time, and document metadata;
  • document_chunks stores the chunk text, chunk metadata, embedding model, and serialized vector.

When the same file is imported again, DocumentImportService calculates its SHA-256 hash before PDF extraction and chunk creation. If the same source name and hash already exist, the stored chunks are reused.

The current application supports one active imported document. Importing a different document replaces the currently stored document.

Requirements

  • Java 25
  • Maven (or the included Maven Wrapper)
  • Ollama running on a reachable machine
  • An Ollama model that supports embeddings
  • A DeepSeek API key

The default embedding model is qwen3-embedding:4b. The local rewrite model is llama3.2:3b. The default Ollama URL is http://localhost:11434.

Configuration

Set the DeepSeek API key:

$env:DEEPSEEK_API_KEY="your-api-key"

If Ollama runs on another machine, set its URL as well:

$env:OLLAMA_BASE_URL="http://ollama-host:11434"

The application uses these Spring AI properties:

spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.chat.model=deepseek-v4-flash
spring.ai.ollama.base-url=${OLLAMA_BASE_URL:http://localhost:11434}
spring.ai.ollama.embedding.model=qwen3-embedding:4b
mate-ai.conversation.memory.max-messages=10
mate-ai.conversation.rewrite.model=llama3.2:3b
spring.datasource.url=jdbc:sqlite:mate-ai.db

Run

$env:DEEPSEEK_API_KEY="your-api-key"
$env:OLLAMA_BASE_URL="http://localhost:11434"
$env:JAVA_HOME="C:\Path\To\jdk-25"
.\mvnw.cmd spring-boot:run

Import a PDF with the + button. The import runs in the background, and a toast notification displays the document name and import result. After the embeddings have been created, ask questions in the chat. Pull the local rewrite model before using follow-up questions:

ollama pull llama3.2:3b

Test

$env:JAVA_HOME="C:\Path\To\jdk-25"
.\mvnw.cmd test

Current limitations

  • Only text-based PDFs are supported.
  • Scanned PDFs require OCR and are not supported yet.
  • The simple chunker uses whitespace-separated units as a token approximation.
  • The tokenizer-based chunker and semantic chunking are not yet active in the import flow.
  • Persistent conversation history is kept only while the application is running; it is cleared when a PDF is imported.
  • SQLite stores vectors as serialized JSON and similarity search currently runs in Java; there is no database-side vector index yet.
  • The current version supports one active imported document at a time.
  • Complex PDF layouts such as tables, columns, headers, and footers may not be extracted correctly.

Planned features

  • Support for additional document types, including images, source code, and speech-to-text transcripts
  • Semantic and structure-aware chunking
  • Local AI-driven semantic chunking: let a local language model identify coherent chunk boundaries and return the original text with metadata
  • Better table and complex PDF layout extraction
  • Database-side vector indexing for faster similarity search
  • Tool calling with Spring AI and Spring Boot
  • Improved answer formatting and presentation
  • OCR for scanned PDFs
  • Persistent conversation history
  • Web search
  • Agent planning and workflow orchestration

Future idea: local AI-driven chunking

The project could use a local language model to analyze an imported document and decide where meaningful chunk boundaries occur. Instead of splitting only by a fixed token count, the model would recognize sections, topics, and related content and return coherent chunks.

The proposed process is:

Document text
   ↓
Local AI identifies semantic boundaries
   ↓
Validate chunks and preserve original text
   ↓
Create embeddings with Ollama
   ↓
Persist chunks, metadata, and vectors in SQLite

The AI-generated chunks should be created only once and stored together with the document hash. When the same document is imported again, the hash can be checked before extraction and chunk creation, so the existing chunks and vectors can be reused.

The application should remain responsible for validating the AI response. It should enforce minimum and maximum chunk sizes, detect missing or duplicated text, preserve page information, and fall back to a deterministic chunker if the AI response is invalid. This combines the semantic understanding of a local AI model with predictable application behavior.

About

Java desktop AI client for experimenting with Spring AI, PDF RAG, Ollama embeddings, vector search, DeepSeek Flash, and future agent tools.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages