Communitygithub.com

Justichuu/victor

Vector embedder skill. Treats meaning as geometry, and says when geometry is the wrong tool. Non-vector baseline first.

Was ist victor?

victor is a Codex agent skill that vector embedder skill. Treats meaning as geometry, and says when geometry is the wrong tool. Non-vector baseline first.

Funktioniert mit~Claude CodeCodex CLICursor
npx skills add Justichuu/victor

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht victor?

Vector in bed. Arrow tagged VECTOR.

Vector is in bed. The arrow is tagged VECTOR. That is the logo and the joke. The work is not a joke.

Victor is the embedder skill. It sees a string as a point, then measures neighbors. It also sees the same string without a vector, so you can tell geometry from overlap. Ponytail: one space, one model, cosine, no extra store. Neckbeard: the numbers are not understanding. They are a direction trained on co-occurrence. The world as it is.

See the world as it is

An embedding is a list of floats. Near on the sphere means similar in that model, not true, not synonyms, not consent. Mixed models are mixed worlds. Mixed dimensions are a crash. Unnormalized L2 and cosine are different questions.

Do not embed:

  • IDs, paths, hashes, exact names you must match exactly
  • Yes / no / done
  • Two lines you already built as twins (argubot YES/NO pairs)
  • Secrets

Do not fetch a model onto a page that must not call the network. Argubot's letter page has no fetch. Its embedVec in argubot.js draws SVG vectors. That is a picture of a vector, not an embedding. Do not confuse them.

The market, as it actually is

Libraries that make vectors:

JobRepoWhat it is
Python embed / rerankhuggingface/sentence-transformersThe default. SBERT, sparse, ColBERT. Check MTEB before picking a name.
JS / browser embedhuggingface/transformers.jsONNX in-process. Default English: Xenova/all-MiniLM-L6-v2 (384-d). Package @huggingface/transformers.
Same weights, Pythonsentence-transformers/all-MiniLM-L6-v2384-d, small. Fine until it is not.

Libraries that search vectors you already have:

JobRepoWhat it is
Exact / GPU NNfacebookresearch/faissIn-process. IndexFlatIP after you L2-normalize is cosine. Not a database.
Small HNSWunum-cloud/usearchHeader-ish, many languages. Still not understanding.
Filtered storeqdrant/qdrantA server. Use when you need filters and persistence.
Local toy storechroma-core/chromaEasy. Not required.

Paid APIs exist (OpenAI, Cohere, Nomic). They are a model behind a wall. Same rules: one space, never mix, never treat the score as truth.

Ponytail order: brute cosine in memory. Then FAISS/USearch. Then a store. Skip the store if an array works.

Non-vector first

Always run a non-vector baseline. If overlap already ranks it, you did not need a model.

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);
}

Exact string equality stays exact. Do not cosine an id.

Cheap vector (no model)

Hashed n-grams make a vector-shaped number. It is still bag-of-pieces, not meaning. Use it to see cosine, and to know it is not MiniLM.

Run the local probe (no install):

node .cursor/skills/victor/victor.mjs "cars is a fix" "cars makes more problems"

It prints overlap and hashed-cosine side by side. Twins share words, so both scores go up. A real model may still put them near each other because they share a topic. That is the world as it is: YES and NO about cars are neighbors. They are not the same claim.

Real vector (model)

Python, from sentence-transformers as they ship it:

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)
# cosine is the dot product of two unit vectors

JS / browser, from transformers.js. Needs a download. Not for argubot's letter page.

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,
});

Always pooling: "mean" and normalize: true or you are measuring the wrong thing. Reuse one pipeline. Do not construct it per call.

Cosine of unit vectors:

function dot(a, b) {
  let s = 0;
  for (let i = 0; i < a.length; i += 1) s += a[i] * b[i];
  return s;
}

If you did not normalize, do not call it cosine.

How Victor works a task

  1. Name the strings. If they must match exactly, stop. Use the string.
  2. Run overlap (and victor.mjs if you want a cheap vector).
  3. If you still need neighbors-in-meaning, pick one model. Embed. Cosine. Show the score.
  4. Do not add FAISS/Qdrant/Chroma until an array of floats is too big or too slow.
  5. Say what the score is: a neighbor in that space. Not a verdict.

Victor does not pick a winner. Near is near. That is all it knows.

Verwandte Skills