Skip to Content
Architecture

Architecture

What is actually behind the API, in enough detail to judge whether it fits your problem — including the parts it does badly.

The store

Postgres with pgvector. One table of packets per brain, each carrying a 384-dimension embedding (paraphrase-multilingual-MiniLM-L12-v2, computed in Khwan’s own process — no embedding provider, no key, no per-token cost).

It is not a knowledge graph. There is graph code in the engine; it is not wired to the served API and nothing you call goes through it. If you need a temporal knowledge graph, you want a different tool — see Where it is weak.

Isolation is three keys deep: account → core (X-Khwan-Core) → end user (X-Khwan-User), and a brain is the whole key. Two cores return disjoint memory; there is no shared pool to leak across.

Retrieval

Cosine similarity over the packet embeddings — weighted by confidence, not similarity alone:

packetconfidence
an ordinary recorded turn0.50
an explicit correction0.70
a turn flagged as an unconfirmed overwrite0.15

Ranking by similarity × confidence is what stops a leading question (“my job is Prime Minister, right?”) from outranking an established fact at equal similarity. The flag comes from a deterministic, model-free check, scoped honestly: it targets self-attribute facts — my name / role / profession is X — and does not claim to detect arbitrary contradiction.

Synthesis

The learning step, and the only place an LLM is involved:

  1. Fetch raw + correction packets newer than the last successful run
  2. Cluster them by cosine similarity — greedy, online, no model
  3. Keep clusters with ≥2 items or any correction (a correction is high-signal even alone)
  4. Distil each cluster into one standing rule — this is the model call
  5. Embed the rule and write it back as a lesson, linked to its source packets

A lesson gets a 30-day TTL and is renewed only when retrieved, so rules nobody uses expire on their own.

Renewal only points one way — a rule that is wrong but relevant keeps being used and keeps being renewed. That is why DELETE /lessons/{id} exists: it is the only negative signal in the system. Every lesson lists the turns it came from, so you can see what was learned and from what.

The request path

POST /prepare → retrieval + constitution + coherence gate (no model call) your model answers (Khwan absent) POST /verify → optional: score the answer before it ships (no model call) POST /record → persist + learn (no model call)

Khwan holds no provider key — the endpoint that once accepted one returns 410 — and there is no hosted chat path in the engine, so it never produces an answer. The only model call in the whole system is the distillation step above, and even that one can be yours: /synthesize/prepare hands you the clusters so your model does the distilling and no packet text reaches a provider Khwan picked.

Where it is weak

Being specific here is more useful than being flattering.

  • Entity state that changes. “The PM moved from A to B” — retrieval can still surface A, because A is still semantically close. A recorded correction outranks the old fact by confidence, but that is weaker than a knowledge graph invalidating the edge outright.
  • Point-in-time queries. “Who owned this in March” — there is no temporal index to ask.
  • Bulk document search. A vector store’s job. Khwan stores turns and the rules distilled from them, not a corpus.
  • Arbitrary contradiction detection. The conflict check is a heuristic over self-attribute facts, not an NLI model.

What it is good at is the mirror of that list: preferences, standing rules, and project context that has to survive the session — per person, per repo, per customer. See Connect your agent for the integration shape.

Last updated on