Stage embeddings: ship Path A (text) now, prepare Path C (text+visual) additively
Decision (Q15 resolved): start with text-only via TEI + bge-m3 in Phase 3.1, prepare data shapes so Phase 3.2 (visual collection via infinity + jina-clip-v2) is a pure additive operation — no rename, no schema migration, no n8n rewiring. Concretely: - Qdrant collection renamed nexa_knowledge → nexa_knowledge_text (1024-dim for bge-m3) with modality-aware payload (modality, source_type, media_uri, graph_iri, content_hash, context). Visual placeholder schema committed alongside (qdrant_schema_visual.json, 768-dim, jina-clip-v2). - Image attachments captured in 3.1 are recorded in GraphDB as nexa:Note with nexa:modality "image" + nexa:pendingVisualIndex true; the 3.2 backfill workflow picks them up and embeds. No data lost between phases — the queue is the GraphDB itself. - RDF schema (docs/08) gains nexa:modality, nexa:mediaUri, nexa:vectorCollection, nexa:pendingVisualIndex from day one. - docs/02 roadmap split: 3.1 = text RAG (Path A), 3.2 = visual collection (Path C), 3.4 = Ontotext GraphDB. - docs/09 grows a "Phase add-on: visual collection (Phase 3.2)" section with the TEI→infinity swap, second collection create, LiteLLM second model registration, and the SPARQL-driven backfill query. - New open questions: Q16 (queue ergonomics + does SAIA already proxy an embed model?), Q17 (reuse Immich's CLIP for photo-library queries?). - docs/03 + CLAUDE.md updated so future runs use the new collection names and don't re-decide the staging.
This commit is contained in:
@@ -45,14 +45,22 @@ nexa:mentions a rdf:Property ; rdfs:domain nexa:Note ; rdfs:range n
|
||||
nexa:scheduledFor a rdf:Property ; rdfs:domain nexa:Task ; rdfs:range xsd:dateTime .
|
||||
|
||||
# Datatype properties
|
||||
nexa:status a rdf:Property ; rdfs:range xsd:string . # "needs-action" | "in-progress" | "done"
|
||||
nexa:context a rdf:Property ; rdfs:range xsd:string . # "work" | "personal"
|
||||
nexa:urgency a rdf:Property ; rdfs:range xsd:integer . # 1–5
|
||||
nexa:vectorId a rdf:Property ; rdfs:range xsd:string . # Qdrant point ID — bridges the two pillars
|
||||
nexa:contentHash a rdf:Property ; rdfs:range xsd:string . # for de-dup
|
||||
nexa:status a rdf:Property ; rdfs:range xsd:string . # "needs-action" | "in-progress" | "done"
|
||||
nexa:context a rdf:Property ; rdfs:range xsd:string . # "work" | "personal"
|
||||
nexa:urgency a rdf:Property ; rdfs:range xsd:integer . # 1–5
|
||||
nexa:contentHash a rdf:Property ; rdfs:range xsd:string . # for de-dup
|
||||
|
||||
# Cross-pillar / multimodality
|
||||
nexa:modality a rdf:Property ; rdfs:range xsd:string . # "text" | "image"
|
||||
nexa:mediaUri a rdf:Property ; rdfs:range xsd:anyURI . # memos://… , nextcloud://… , obsidian://…
|
||||
nexa:vectorCollection a rdf:Property ; rdfs:range xsd:string . # "nexa_knowledge_text" | "nexa_knowledge_visual"
|
||||
nexa:vectorId a rdf:Property ; rdfs:range xsd:string . # Qdrant point ID
|
||||
nexa:pendingVisualIndex a rdf:Property ; rdfs:range xsd:boolean . # set true on image notes until Phase 3.2 backfills them
|
||||
```
|
||||
|
||||
The `nexa:vectorId` property is the **bridge** between graph and vector store. Every node that has semantic content carries the Qdrant point ID, so a SPARQL hit can trigger a vector lookup and vice versa.
|
||||
`nexa:vectorId` + `nexa:vectorCollection` together are the **bridge** between graph and vector store. A SPARQL hit can trigger a vector lookup, and a Qdrant payload's `graph_iri` field walks back the other way.
|
||||
|
||||
`nexa:modality`, `nexa:mediaUri` and `nexa:pendingVisualIndex` exist from Phase 3.1 even though only the text path is wired up. Image attachments captured in 3.1 are recorded as `nexa:Note` with `modality "image"` and `pendingVisualIndex true`, then picked up by the Phase-3.2 backfill workflow — no data loss across phases.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user