Was macht victor?

Vektor liegt im Bett. Der Pfeil ist mit VEKTOR beschriftet. Das ist das Logo und der Witz. Die Arbeit ist kein Witz.
Victor ist der Einbettungs-Skill. Er sieht eine Zeichenkette als Punkt und misst dann die Nachbarn. Er sieht dieselbe Zeichenkette auch ohne Vektor, sodass du Geometrie von Überlappung unterscheiden kannst. Pferdeschwanz: ein Raum, ein Modell, Cosinus, kein extra Speicher. Neckbart: Die Zahlen sind kein Verständnis. Sie sind eine Richtung, trainiert auf Kookkurrenz. Die Welt, wie sie ist.
Sieh die Welt, wie sie ist
Ein Embedding ist eine Liste von Gleitkommazahlen. Nähe auf der Sphäre bedeutet Ähnlichkeit in diesem Modell, nicht Wahrheit, nicht Synonyme, nicht Zustimmung. Gemischte Modelle sind gemischte Welten. Gemischte Dimensionen sind ein Absturz. Unnormalisierte L2 und Cosinus sind unterschiedliche Fragen.
Nicht einbetten:
- IDs, Pfade, Hashes, exakte Namen, die du exakt abgleichen musst
- Ja / Nein / Erledigt
- Zwei Zeilen, die du bereits als Zwillinge gebaut hast (argubot YES/NO-Paare)
- Geheimnisse
Hole kein Modell auf eine Seite, die kein Netzwerk aufrufen darf. Die Buchstaben-Seite von Argubot hat kein fetch. Ihr embedVec in argubot.js zeichnet SVG-Vektoren. Das ist ein Bild eines Vektors, kein Embedding. Verwechsle sie nicht.
Der Markt, wie er tatsächlich ist
Bibliotheken, die Vektoren erzeugen:
| Job | Repo | Was es ist |
|---|---|---|
| Python embed / rerank | huggingface/sentence-transformers | Der Standard. SBERT, sparse, ColBERT. Prüfe MTEB, bevor du einen Namen wählst. |
| JS / Browser embed | huggingface/transformers.js | ONNX-In-Prozess. Standard Englisch: Xenova/all-MiniLM-L6-v2 (384-d). Paket @huggingface/transformers. |
| Gleiche Gewichte, Python | sentence-transformers/all-MiniLM-L6-v2 | 384-d, klein. Gut, bis es nicht mehr reicht. |
Bibliotheken, die in bereits vorhandenen Vektoren suchen:
| Job | Repo | Was es ist |
|---|---|---|
| Exakt / GPU NN | facebookresearch/faiss | In-Prozess. IndexFlatIP nach L2-Normalisierung ist Cosinus. Keine Datenbank. |
| Kleines HNSW | unum-cloud/usearch | Header-ähnlich, viele Sprachen. Immer noch kein Verständnis. |
| Gefilterter Speicher | qdrant/qdrant | Ein Server. Verwende ihn, wenn du Filter und Persistenz benötigst. |
| Lokaler Spielzeugspeicher | chroma-core/chroma | Einfach. Nicht erforderlich. |
Bezahlte APIs gibt es (OpenAI, Cohere, Nomic). Sie sind ein Modell hinter einer Mauer. Gleiche Regeln: ein Raum, niemals mischen, niemals den Score als Wahrheit behandeln.
Pferdeschwanz-Reihenfolge: Brute-Force Cosinus im Speicher. Dann FAISS/USearch. Dann ein Speicher. Überspringe den Speicher, wenn ein Array ausreicht.
Nicht-Vektor zuerst
Führe immer eine Nicht-Vektor-Baseline aus. Wenn die Überlappung bereits eine Rangfolge liefert, hast du kein Modell gebraucht.
function tokens(s) {
return String(s).toLowerCase().match(/[a-z0-9]+/g) || [];
}
function overlap(a, b) {
const A = new Set(tokens(a));
const B = new Set(tokens(b));
let hit = 0;
for (const t of A) if (B.has(t)) hit += 1;
return hit / Math.max(1, A.size, B.size);
}
Exakte Zeichenketten-Gleichheit bleibt exakt. Cosinus eine ID nicht.
Billiger Vektor (kein Modell)
Gehashte n-Gramme erzeugen eine vektorförmige Zahl. Es ist immer noch Beutel-von-Teilen, keine Bedeutung. Verwende es, um Cosinus zu sehen und zu wissen, dass es nicht MiniLM ist.
Führe die lokale Sonde aus (keine Installation):
node .cursor/skills/victor/victor.mjs "cars is a fix" "cars makes more problems"
Es gibt Überlappung und gehashten Cosinus nebeneinander aus. Zwillinge teilen Wörter, also steigen beide Werte. Ein echtes Modell könnte sie trotzdem nahe beieinander platzieren, weil sie ein Thema teilen. Das ist die Welt, wie sie ist: JA und NEIN über Autos sind Nachbarn. Sie sind nicht dieselbe Behauptung.
Echter Vektor (Modell)
Python, mit sentence-transformers wie ausgeliefert:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
vecs = model.encode(["cars is a fix", "cars makes more problems"], normalize_embeddings=True)
# Cosinus ist das Skalarprodukt zweier Einheitsvektoren
JS / Browser, mit transformers.js. Benötigt einen Download. Nicht für argubots Buchstaben-Seite.
import { pipeline } from "@huggingface/transformers";
const extractor = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2");
const out = await extractor(["cars is a fix", "cars makes more problems"], {
pooling: "mean",
normalize: true,
});
Immer pooling: "mean" und normalize: true, sonst misst du das Falsche. Verwende eine einzige Pipeline. Erstelle sie nicht pro Aufruf.
Cosinus von Einheitsvektoren:
function dot(a, b) {
let s = 0;
for (let i = 0; i < a.length; i += 1) s += a[i] * b[i];
return s;
}
Wenn du nicht normalisiert hast, nenne es nicht Cosinus.
Wie Victor eine Aufgabe erledigt
- Benenne die Zeichenketten. Wenn sie exakt übereinstimmen müssen, höre auf. Verwende die Zeichenkette.
- Führe Überlappung aus (und
victor.mjs, wenn du einen billigen Vektor möchtest). - Wenn du immer noch Bedeutung-Nachbarn brauchst, wähle ein Modell aus. Bette ein. Cosinus. Zeige den Score.
- Füge FAISS/Qdrant/Chroma erst hinzu, wenn ein Array von Floats zu groß oder zu langsam ist.
- Sage, was der Score ist: ein Nachbar in diesem Raum. Kein Urteil.
Victor bestimmt keinen Gewinner. Nah ist nah. Das ist alles, was er weiß.
