Extraction
When Krafa runs a taste extraction, what it reads, what it deliberately skips, and the limits that keep a profile from bloating.
Extraction is the step between "there's a screenshot on the board" and "your agent knows you prefer tabular figures." It runs automatically; there is no button.
When it runs
Adding a node to the canvas triggers one extraction pass for that node. You'll see the node shimmer while it's in flight, and a single toast at the top of the screen that morphs from Extracting design taste… to Extracted rather than stacking up one notification per paste.
Deleting nodes runs the reverse: memories sourced from the deleted nodes are pruned, with the toast reading Updating taste… then Updated.
What gets read
| Content | Extracted? |
|---|---|
| Images | Yes, analyzed visually, once the upload resolves |
| Colors and palettes | Yes |
| Links, YouTube, Figma | Yes, URL plus the resolved page metadata |
| X posts | Yes, when the post has text |
| Code | Yes |
| Markdown | Yes |
| Plain notes | Only at 100 characters or more |
| Video, audio, tables | No |
| Folders and stacks | No, the nodes inside them were already read |
The exclusions aren't arbitrary. A table of numbers and a screen recording carry almost no transferable design signal relative to the noise they'd add, and a three-word sticky note is a reminder to yourself, not a design statement.
An image still uploading has a temporary local URL and is skipped rather than analyzed half-formed. Once the upload lands, the real reference is what gets read.
What the model does
Each pass is a single claude-sonnet-4-5 call that receives the new reference and every memory the board already holds. One call, both jobs: propose new principles, and flag anything the new reference contradicts.
Running them together is what makes contradiction detection possible at all. A pass that only saw the incoming reference could tell you the palette is pastel; only a pass that also sees the existing memories can tell you that's a reversal of what you said last week. Those flagged contradictions become conflicts rather than silent writes.
The limits
| Limit | Value |
|---|---|
| New memories per pass | 3 |
| Conflicts per pass | 3 |
| Statement length | 400 characters |
| Evidence entries per memory | 8 |
| Evidence entry length | 160 characters |
Capping at three memories per reference is a quality decision, not a cost one. A model asked to extract everything it can from a screenshot will pad, inventing principles from incidental details until the profile is mostly noise. Three forces it to pick the load-bearing observations.
Krafa also drops any proposed memory whose statement duplicates one already on the board, so pasting five screenshots from the same product doesn't produce five phrasings of the same idea.
Without an API key
Extraction depends on an Anthropic API key. On self-hosted instances without ANTHROPIC_API_KEY set, it quietly no-ops: pastes still work, nodes still render, boards still save, and the taste panel stays empty. Nothing errors and nothing blocks.
The hosted app at app.krafa.ai always has it configured.
Extraction isn't the last word
Everything on this page describes a first draft. The model is proposing, not deciding: you edit statements, delete memories, and resolve conflicts, and those choices stick. See Curating.