# Semantic Search + Preference Learning Investigation Date: 2026-06-28 ## Goal Add semantic recipe search ("etwas Leichtes für heiße Tage") and preference learning ("wenn warm dann kein Eintopf") to the meal-planning pipeline. ## Embedding Model Requirements - **Dimensions:** 1024 (user requirement) - **Language:** Multilingual / German-capable - **Hosting:** Preferred on norris (same provider as LLM models) ## Norris Embedding Endpoint Investigation Tested all 20 models listed at `https://ai.noris.de/v1/models` against the `/v1/embeddings` endpoint: ### Models tested via `/v1/embeddings` | Model | Result | |-------|--------| | vllm/bge-reranker-v2-m3 | 404 — provider API error | | vllm/glm-5-2-nvfp4 | 404 — provider API error | | vllm/gemma-4-31b-it | 404 — provider API error | | vllm/qwen3.6-27b-nvfp4 | 404 — provider API error | ### Additional embedding models tested by name | Model | Result | |-------|--------| | vllm/bge-m3 | "no keys found that support model: bge-m3" | | vllm/multilingual-e5-large | "no keys found that support model" | | vllm/e5-mistral-7b-instruct | "no keys found that support model" | | vllm/gte-large | "no keys found that support model" | | vllm/NV-Embed-v2 | "no keys found that support model" | | vllm/snowflake-arctic-embed-l-v2.0 | "no keys found that support model" | ### Conclusion Norris recognizes embedding model names (gateway returns "no keys found" not "model not found"), meaning the Bifrost gateway knows about them but no API key has them activated. The `/v1/embeddings` endpoint returns 404 for all currently-available models (LLM models don't serve embeddings). **Action needed:** User must request norris to activate an embedding model (bge-m3 recommended — 1024 dims, multilingual, strong German performance). ## Local vLLM Check Checked for local vLLM instances that might serve embeddings: - `10.0.30.97:8000` (ComfyUI CT) — No route to host (SSH and HTTP both unreachable) - `10.0.30.102:8000` (OpenWebUI CT) — No response - `10.0.30.99:8000` (Docker host) — No response - `localhost:8000/8001` — No response No local vLLM embedding server found. ComfyUI CT (10.0.30.97) has GPU but was unreachable during investigation. ## Proposed Architecture (pending embedding model availability) ### Database Schema Additions ```sql -- Add embedding column to recipes table ALTER TABLE recipes ADD COLUMN embedding JSON NULL COMMENT '1024-dim vector as JSON array'; -- Decision logging CREATE TABLE meal_decisions ( id INT AUTO_INCREMENT PRIMARY KEY, decided_at DATETIME DEFAULT CURRENT_TIMESTAMP, recipe_id VARCHAR(255) NOT NULL, decision ENUM('accepted', 'rejected') NOT NULL, context JSON COMMENT 'temperature, season, weekday, recent_meals', INDEX idx_recipe (recipe_id), INDEX idx_decided (decided_at) ); -- Learned preference rules CREATE TABLE preference_rules ( id INT AUTO_INCREMENT PRIMARY KEY, rule_pattern VARCHAR(255) NOT NULL COMMENT 'e.g. temp>20=>avoid:eintopf', weight FLOAT DEFAULT 1.0 COMMENT 'confidence, grows with confirmations', confirmed_count INT DEFAULT 0, rejected_count INT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uniq_pattern (rule_pattern) ); ``` ### Pipeline Flow ``` Meal Planner selects recipes: 1. SQL filter (rating > 4.0, not used this week) 2. Preference rules apply (boost/penalize by context) 3. Semantic search for "mood" query (light, hearty, asian...) 4. Top-K presented as proposal User feedback ("nein, kein Eintopf bei dem Wetter"): → INSERT INTO meal_decisions (rejected, temp=28°C, category=eintopf) → Rule mining detects pattern → INSERT/UPDATE preference_rules → Next run: Eintopf auto-downweighted when warm ``` ### Embedding Generation Strategy - Batch-generate embeddings for existing 28k+ recipes (one-time) - Incrementally embed new recipes as v7 scraper inserts them - Store as JSON array in `embedding` column (simple, no pgvector/Qdrant dependency) - Cosine similarity computed in Python at query time (28k × 1024 floats ≈ 115MB RAM, <1s) - At 100k recipes: ~400MB RAM for full similarity matrix — still feasible in-process ### Alternative: MariaDB VECTOR Type MariaDB 11.6+ supports native `VECTOR` type with `VEC_DISTANCE` functions. If the Galera cluster upgrades, switch from JSON-stored arrays to native vectors for indexed similarity search. Current MariaDB version on the cluster should be checked before relying on this.