diff --git a/crates/modules/verbo/SDD.md b/crates/modules/verbo/SDD.md new file mode 100644 index 0000000..06d2497 --- /dev/null +++ b/crates/modules/verbo/SDD.md @@ -0,0 +1,43 @@ +# modules/verbo/ — Provider de embeddings model-agnostic (era dime) + +**Propósito.** Capa de embeddings estructuralmente agnóstica al modelo: +la elección de backend es config por instancia. Los vectores quedan +atados a su `ModelId` — comparar vectores de modelos distintos es un +error explícito, no un sinsentido silencioso. Un daemon permite cargar +un modelo una vez y compartirlo entre procesos. + +## Crates + +| crate | tipo | rol | +| -------------- | ---- | ------------------------------------------------------------ | +| `verbo-core` | lib | Contrato: `ModelId`, `EmbeddingVector` (cosine), `EmbedError`, trait `Provider` | +| `verbo-mock` | lib | Backend determinista sin modelo (FNV-1a + LCG) — para tests | +| `verbo-daemon` | lib | `Daemon` (sirve un `Provider` por socket Unix) + `DaemonClient` (lo consume como `Provider`) | + +## Dependencias + +- `mock`, `daemon` ← `verbo-core`. +- `daemon` ← `tokio` + `postcard` (frames con prefijo de largo). +- `verbo-core` es `#![forbid(unsafe_code)]`, sólo `serde` + `async-trait`. + +## Compartir entre procesos + +`verbo-daemon` resuelve la duplicación de modelos en RAM: un `Daemon` +carga el modelo una vez; N procesos lo consumen vía `DaemonClient`, que +implementa `Provider` y por tanto es indistinguible de un backend local. +Multi-instancia = un daemon por modelo, cada uno en su socket. + +## Estado + +Contrato + mock + daemon implementados y verdes (~25 tests). + +**Pendiente** — backends de modelos reales (requieren infra/API keys): + +| backend pendiente | tipo | nota | +| ----------------- | ------ | --------------------------------------------- | +| `verbo-cohere` | remoto | API Cohere — recomendado para uso remoto | +| `verbo-bge` | local | `bge-code-large` vía ONNX — recomendado local | +| `verbo-fastembed` | local | modelos ligeros (MiniLM 384d) | + +Cada uno implementa `Provider` y puede servirse vía `verbo-daemon` sin +cambios — el daemon es agnóstico del backend.