Knowledge bases
A folder of documents pushed, attached to an agent, and searched before every turn.
A knowledge base is a folder of Markdown documents kept by the gateway. Attach it to an agent, and the platform searches it before every turn and hands the model the chunks that answer the caller.
What is a knowledge base?#
A base has a name and holds Markdown files. Sandbox and production each have their own bases, so a base you
push from your laptop is the one your own pinecall start answers from, never the one your phone number
answers from.
bases: which bases it reads, and how.
The searchRun by the platform before each turn, or by the model when it decides to.
Your manager adds and edits documents in the console, on the agent's Knowledge ▸ Docs screen, one file at a time. Your repository holds none of them.
Create one#
Write the documents#
Put Markdown under docs/<agent>/ in your project, one file per subject, with headings. This folder is kept
out of git.
Push them#
pinecall docs push
The base takes the agent's name unless --base names another. Add --prod to push production's base.
Attach the base to the agent#
pinecall docs attach clinica-norte --k 4
From the next call on, every turn searches it.
Hold it to a golden#
Write test/<agent>/goldens/docs.json and run pinecall docs eval.
Testing knowledge & memory shows how.
A push replaces the base whole. If someone added a document in the console after your first push, pushing again takes it out. Push once to start a base, then keep it in the console.
What a push does#
- Each file is cut at its headings (
#to###). A section longer than 350 tokens is cut again at a paragraph or a sentence. A fenced code block is never cut. - Each chunk carries its heading path, for example
prices.md › Prices › Check-up, in the text both indexes read. - Front matter (a
title:/source:block at the top of a file) is dropped. - Every chunk is indexed twice: by its embedding and by its words. A search asks both and fuses the two rankings.
- A file that did not change since the last push is not embedded again.
A push cannot tell a menu from a paragraph. A scraped page full of navigation and footers competes for the chunks a turn gets and answers nothing, so read what goes into the folder.
An org's chunks count against its knowledge_chunks quota. Limits & provider keys
says where to see it.
Attach it to an agent#
attach writes the agent's bases setting as a new version, in sandbox unless you add --prod.
| flag | what it sets | default |
|---|---|---|
--k <n> |
how many chunks a turn is handed | 8 |
--mode retrieved |
the platform searches before every turn | yes |
--mode tool |
the model calls search when it decides to |
|
--min-score <x> |
drops chunks scored below x, on a 0 to 1 scale where the best chunk of each search is 1 |
none |
--team |
writes the team's settings instead of yours |
--min-scorecuts the tail of an answer. It can never say "nothing here answers this", because the best chunk of any search scores 1. Whether to search at all is decided before the search, on the caller's words.
An agent may read several bases. A turn then searches all of them in one pass, with one ranking over
everything, so a base with nothing to say about the question takes none of the turn's chunks. The turn's
k is the largest of the attachments; each --min-score applies to its own base.
When a turn searches#
With --mode retrieved, the search starts while the caller is still speaking, once they have said four
words. A turn with no letter in it (a phone number being read out) is never searched. A spoken turn waits
at most 250 ms for the answer and a written one 3 s; a search that is late is dropped, the turn goes on
without it, and the log says search_skipped.
Search from a tool#
A tool can search the attached bases itself:
/** Looks up what the patient asks in the clinic's documents and returns the paragraphs that answer it. */
@tool()
async lookUp(question: string): Promise<Found[]> {
return await this.knowledge.search(question, { k: 3 });
}
Each result is { path, heading, text }. A class that uses this.knowledge is refused at registration when
no base is attached to it, with the command that fixes it:
clinica-norte searches its bases, and none is attached to it in sandbox: pinecall docs attach <base> --agent clinica-norte
The other verbs#
pinecall docs list # the bases, their chunks, when each was pushed
pinecall docs attached # which agents read which base
pinecall docs detach clinica-norte # the agent stops reading it
pinecall docs drop clinica-norte # the base is deleted