Tutorial: your first corpus¶
Fifteen minutes, from nothing to a corpus you can search by meaning. Every command and every output below was run; only the corpus paths are shown at their default location rather than the throwaway one used to produce them.
You will need kennis installed. Nothing else - this tutorial uses no PDFs and no API keys.
1. Set kennis up¶
The wizard asks only what depends on you, and every question offers what is
already in effect, so pressing return throughout is a valid run. Accept the
defaults: fastembed for embedding, which runs locally and needs no key.
Every setting is then written to the file, including those you left at their
default.
To skip it entirely and take every default:
2. Create the corpus¶
That directory is now a git repository. Everything from here commits.
3. Write three notes¶
kennis remember writes a note and files it in the notes collection.
kennis remember "Reciprocal rank fusion scores a chunk by 1/(60+rank) summed \
over the legs that ranked it, so agreement between two methods that fail \
differently is what wins." --title "Why fusion uses ranks"
Remembered Why fusion uses ranks, not indexed in 1ms
+ /home/you/.local/share/kennis/corpus/notes/Why fusion uses ranks.md
hint: run `kennis corpus index` to make it searchable
Two things to notice.
The note is a real file with the name you gave it, in a directory you can open in any editor. kennis stores markdown, not a database.
And it says not indexed. Writing a document and making it searchable are
separate steps, and kennis tells you which one has happened. Once an index
exists, remember updates it in the same command; the first note has no
index to update yet.
Add two more:
kennis remember "A cosine similarity has an absolute meaning only for the \
model that produced it. Cuts measured for one embedding model say nothing \
about another." --title "Relevance bands are per-model"
kennis remember "The corpus is ordinary markdown in ordinary directories. A \
directory holding content.md is a document with assets; any other directory \
is a group." --title "Corpus layout"
4. Index them¶
The first time you run this, kennis downloads the embedding model - about
65 MB - and prints a line saying so before it starts. It is cached in
~/.cache/kennis/models, so this happens once and survives a reboot.
5. Search¶
Here is the point of the whole exercise. Ask a question that shares almost no words with any note:
warning: not searched, no index yet: literature, docs
hint: run `kennis corpus index`
Found 4 passages, relevance by cosine similarity
[1] [notes] Why fusion uses ranks
relevance: medium id=30ed1x2rt8 chunk=0
Reciprocal rank fusion scores a chunk by 1/(60+rank) summed over the
legs that ranked it, so agreement between two methods that fail
differently is what wins.
[2] [notes] Relevance bands are per-model
relevance: low id=gs0wo39jle chunk=0
A cosine similarity has an absolute meaning only for the model that
produced it. Cuts measured for one embedding model say nothing about
another.
The query and the winning note share one word, "scores", and it is not even used in the same sense. A keyword search would not have found it. The dense leg matched on meaning.
Your identifiers will differ from these - they are minted per document.
Three things in that output are worth reading properly.
The warning. Two collections have no index because they have no documents. kennis says which, rather than quietly searching less than you asked it to.
relevance by cosine similarity. This names the scale the levels are on.
Here it is absolute: medium means the same thing for every query, because
the cuts were measured for this specific model. That is why the top hit is
medium and not very high - it is a decent match, and kennis says so
rather than flattering the best result it happened to find.
id= and chunk=. The coordinates for reading.
6. Read¶
Read [notes] Why fusion uses ranks (30ed1x2rt8) .../notes/Why fusion uses ranks.md
Reciprocal rank fusion scores a chunk by 1/(60+rank) summed over the legs
that ranked it, so agreement between two methods that fail differently is
what wins.
The Read ... provenance line goes to standard error, the document goes
to standard output. So this gives you the markdown and nothing else:
For a long document, read just the passage a hit pointed at:
7. See the difference a model makes¶
Run the same kind of search with the dense leg switched off:
Found 1 in notes
Notes keywords as a fraction of the best match here
[1] Why fusion uses ranks
keywords: very high id=30ed1x2rt8 chunk=0
kennis://open/30ed1x2rt8/0
hint: run `kennis read 30ed1x2rt8 --chunks 0:2` to read one in context
Only one measure is reported now. With the meaning leg switched off there
is no absolute scale, so the keywords level is a fraction of this query's own
best match in the collection - and the top hit is very high by
construction. The line above the group says so, rather than presenting a
relative number as though it were absolute.
8. Look at what you built¶
Literature
Docs
Notes
dxk40v39l3 Corpus layout.md
gs0wo39jle Relevance bands are per-model.md
30ed1x2rt8 Why fusion uses ranks.md
Every step committed. Nothing you have done is unrecoverable.
Where to go next¶
- Add documents - papers, PDFs, whole documentation sites
- How retrieval works - what the relevance levels actually mean
- Commands - every option