Kinthread

From a story to a thread.

Kinthread finds the people in your story, then traces the family facts that connect the two you choose. Two small models do the work, inside this browser tab.

  1. Find the people

    Ashley’s daughter, Lillian, asked her mom to read her a story. Nicholas’s sister Lillian asked him for some help.

    5.1M-parameter name model

    Reads the story and marks every word that is a person’s name. Places and companies are left out.

  2. Trace the path

    1. @0
    2. daughter
    3. @1
    4. <sep>
    5. @1
    6. brother
    7. @2
    8. <sep>

    13.0M-parameter transformer, 6 layers

    Writes the chain of family facts that leads from the first person to the second, one checked step at a time.

  3. Name the relation

    son

    Same transformer

    Reads its own chain and names the relationship, or says the story doesn’t establish one.

Reading the map

After you trace, the map works the answer out in front of you, one step at a time, the way you would on paper. Use the buttons under it to pause, step back, or jump to the answer.

  • Indigo marks the question: the two people you chose, and a dashed arrow with a “?” between them.
  • Gold arrows are facts from the story, numbered in the order the reasoning uses them. Each step quotes the sentence it came from.
  • Red is the answer: the red thread between the two people that replaces the question.
  • Shapes follow the pedigree charts used in biology: squares are male, circles female, and a diamond means the story never says.
  • Rows are generations: parents above, children below, people of the same generation side by side.
  • Arrows point from a person to their relative: Ashley → daughter → Lillian means Lillian is Ashley’s daughter.

Solve it like a student

Blood-relation questions are solved by combining two relations at a time. Each step on the map does exactly that, so you can check your own working against it. These combinations are worked out by the same rules the map uses:

Two relations at a time
If B is A’s…and C is B’s…then C is A’s…
fatherwifemother
motherbrotheruncle
fathersisteraunt
brothersonnephew
sisterdaughterniece
sonwifedaughter-in-law
daughterhusbandson-in-law
wifefatherfather-in-law
fatherfathergrandfather
sonsongrandson
daughterbrotherson
motherdaughtersister

Some combinations have more than one honest answer. A daughter’s uncle is usually your brother, but could be your brother-in-law; the map says “usually” and names the other possibility. When the steps the model wrote do not add up to its own answer, the map says so instead of hiding it.

Everything happens on your device

On your first visit the browser downloads the two models (61.4 MB) and keeps them. Each file is checked against a SHA-256 checksum before it is stored, and the decoded weights are checked again (CRC-32) every time they load. Later visits read the models from this device.

The models run in a background worker so the page never freezes. The arithmetic happens in a small engine written in C and compiled to WebAssembly, using SIMD instructions and several CPU threads when the browser allows. Your story is not sent to a server for inference.

Step 1: finding the people

The name model is a 5.12M-parameter GPT (4 layers) trained from scratch to decide, word by word, whether the word is a person’s name. A GPT only looks backwards, so it reads the text twice: while labelling the second copy, every word can see the whole sentence.

It learned from tens of thousands of stories with places, companies, months and holidays mixed in, so “Tokyo” or “Google” do not become people. It still makes mistakes; if it misses someone, use Missing someone? Add a name under the people.

Step 2: reading the story the way the model does

Before the relationship model sees the story, every name becomes an entity id: the first person is@0, the next @1, and so on. The model therefore learns relationships from the wording (“her son”, “his sister”), not from what particular names usually mean. The question comes first, then the story:

  1. <bos>
  2. <q>
  3. @0
  4. @2
  5. <s>
  6. @0
  7. 's
  8. daughter
  9. ,
  10. @1
  11. ,
  12. asked
  13. her
  14. mom
  15. …
  16. <c>

The relationship model is a 13.0M-parameter transformer with 6 layers, 6 attention heads and a 320-token context. Before answering, it writes the family facts along the path, a chain of thought: @0 daughter @1, then @1 brother @2, then the answer, son.

Step 3: searching for a path

The chain is found with a constrained beam search that keeps the 4 most likely partial paths. At each step the model may only pick a relation word and a person who appears in the story and is not already on the path, and the path must end at the person you asked about.

After every step the model also judges whether that fact is actually stated in the story. Paths built on facts it cannot verify lose weight. This step checker was trained on deliberately wrong chains, including convincing mistakes found by running the model’s own search.

Knowing when to say “I don’t know”

  • No link in the text. If the two people are never mentioned together, or through people who are, Kinthread answers that the story doesn’t establish a relationship without running the model.
  • No verified path. The model estimates how likely it is that the story gives no family link. At 0.50 or above, it says so instead of guessing.
  • Disagreement. Agreement is the share of its weighted reasoning paths that end in the top answer. Below 0.70, the answer is shown as a tentative best guess.

What the path is, and isn’t. The steps on the map are the chain the model wrote down before answering. They are an exact record of that chain, not a full account of every calculation inside the network.

Technical view

Decision rules

  • p(unknown) = max(pstart, 1 − plink). pstart: probability of the answer marker instead of the first person at the start of the chain. plink: probability-weighted share of steps the checker accepted (<sep> rather than <nofact>).
  • Answer = relation with the most weighted votes over finished paths; agreement = its vote share.
  • Search: beam 4, branching 3 per step, one person-id view (the 4-view, beam-8 reference setting scored the same on average at about six times the compute).

Engine

  • Six WebAssembly builds (relaxed SIMD, SIMD, scalar; each with and without threads). The page picks the fastest one this browser supports.
  • Matrix-multiply tiles and the thread count are tuned on this device when the model loads.
  • A shared key/value cache: every token on a path is computed once and reused by all paths that share it.
  • Weights are the original 32-bit floats, not quantized. Outputs match PyTorch to within 1.5×10-5.

Want the full story of how both models were built and trained? Read the build log. For what the models handle well and where they struggle, see limits & tips.