Embedding Providers Overview
Relevant source files
The following files were used as context for generating this wiki page:The embedding system is a core component of MauQNotes, responsible for converting textual notes into numerical vector representations. This process, known as embedding, is fundamental to enabling semantic search capabilities. The system is designed to be flexible, supporting multiple embedding providers like Ollama and OpenAI. These generated vectors are then ingested into a Qdrant vector database for efficient similarity searching.
The primary goal is to transform unstructured text into a format that a machine can understand and compare based on semantic meaning rather than just keywords. This allows users to query their notes using natural language and find the most relevant results even if the exact words don't match.
Architecture and Data Flow
The system's architecture involves the main application logic, the search service, the embedding providers, and the Qdrant vector database. The search service orchestrates the process of either ingesting new notes or querying existing ones. In both cases, it relies on an embedding provider to generate a vector for the given text.
This diagram illustrates the high-level data flow for ingesting and querying notes.
Configuration
The embedding system is configured via environment variables, typically loaded from a .env file. These variables determine which provider to use, the specific model, and the necessary API credentials or URLs.
| Variable | Description | Default Value | Source File |
|---|---|---|---|
EMBEDDING_MODEL | Specifies the embedding model to use. | nomic-embed-text | internal/search/service.go:12 |
OLLAMA_URL | The base URL for the Ollama API service. | http://localhost:11434 | internal/embeddings/ollama.go:27 |
OPENAI_API_KEY | The API key for accessing the OpenAI API. | (none) | internal/embeddings/openai.go:23 |
QDRANT_URL | The base URL for the Qdrant vector database. | (none) | internal/qdrant/client.go:73 |
QDRANT_API_KEY | The API key for the Qdrant service. | (none) | internal/qdrant/client.go:74 |
QDRANT_COLLECTION | The name of the collection in Qdrant to use. | (none) | internal/qdrant/client.go:75 |
Sources: internal/search/service.go:11-14, internal/embeddings/ollama.go:26-32, internal/embeddings/openai.go:22-26, internal/qdrant/client.go:72-76
Supported Providers
The application supports generating embeddings via local Ollama instances or the remote OpenAI API.
Ollama
The FromOllama function handles the generation of embeddings using a running Ollama instance. It is the default provider used in the search service.
Sources: internal/search/service.go:45, internal/search/service.go:64
Process Flow
The function constructs an HTTP POST request to the /api/embeddings endpoint of the configured Ollama URL. The request body contains the model name and the text to be embedded. The resulting vector is converted from []float64 to []float32 to match the type required by the Qdrant client.
This sequence diagram shows the interaction for the FromOllama function.
Sources: internal/embeddings/ollama.go:23-72
Request/Response Structures
The communication with the Ollama API uses the following JSON structures.
Request (ollamaRequest)
type ollamaRequest struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
}
Sources: internal/embeddings/ollama.go:16-19
Response (ollamaResponse)
type ollamaResponse struct {
Embedding []float64 `json:"embedding"`
Error string `json:"error,omitempty"`
}
Sources: internal/embeddings/ollama.go:21-24
OpenAI
The FromOpenAI function provides an alternative for generating embeddings using the OpenAI API. It requires an OPENAI_API_KEY to be set.
Sources: internal/embeddings/openai.go
Process Flow
This function sends an HTTP POST request to https://api.openai.com/v1/embeddings. It includes the API key in the Authorization header. The response contains the embedding vector, which is then converted to []float32.
This sequence diagram shows the interaction for the FromOpenAI function.
Sources: internal/embeddings/openai.go:21-65
Request/Response Structures
Request (openAIRequest)
type openAIRequest struct {
Model string `json:"model"`
Input []string `json:"input"`
}
Sources: internal/embeddings/openai.go:13-16
Response (openAIResponse)
type openAIResponse struct {
Data []struct {
Embedding []float64 `json:"embedding"`
} `json:"data"`
Error *struct {
Message string `json:"message"`
} `json:"error,omitempty"`
}
Sources: internal/embeddings/openai.go:18-26
Model and Dimension Handling
The vector dimension is a critical parameter for creating a collection in Qdrant. The search.Init() function determines the correct dimension based on the EMBEDDING_MODEL environment variable. If the model is not recognized, it defaults to a dimension of 768.
| Model Name | Vector Dimension | Source |
|---|---|---|
nomic-embed-text | 768 | internal/search/service.go:23, setup-ollama.md:21 |
all-minilm | 384 | internal/search/service.go:25, setup-ollama.md:22 |
mxbai-embed-large | 512 | internal/search/service.go:27 |
| default | 768 | internal/search/service.go:29 |
Note: setup-ollama.md lists mxbai-embed-large as having 1024 dimensions, while search/service.go implements it as 512. The code's implementation (512) takes precedence in the application's logic.
Sources: internal/search/service.go:18-31, setup-ollama.md:21-23
This logic is encapsulated in a switch statement within the Init function:
// internal/search/service.go:21-30
var dim int
switch model {
case "nomic-embed-text":
dim = 768
case "all-minilm":
dim = 384
case "mxbai-embed-large":
dim = 512
default:
dim = 768 // Default
}
Sources: internal/search/service.go:21-30
Integration with Search Service
The embedding providers are consumed by the search service, which is the central point for ingestion and querying operations.
Ingestion Flow (IngestNotes)
When search.IngestNotes is called, it iterates through a list of text notes. For each note, it calls embeddings.FromOllama to get a vector. It then creates a qdrant.Point object containing the vector and payload (the original text) and upserts it into the Qdrant collection.
Query Flow (Query)
When search.Query is called, it first generates an embedding for the query string q using embeddings.FromOllama. This query vector is then passed to the Qdrant client's Search method to find the topK most similar vectors in the database. The service also performs a naive re-ranking by slightly boosting the score of results that contain the query keyword.
Sources: internal/search/service.go:61-82