# Knowledge

## Give an agent knowledge

A **knowledge base** holds **documents**: markdown, plain text or the text of a
PDF, which your agent answers from, such as prices, policies, opening hours and
product details.
Link up to 3 bases to an agent with `knowledge_base_ids` when you create or
update it. The change raises the agent's version, so every call records what it
knew.

In the console, [Knowledge](/console/knowledge) holds the bases and their
documents, and the agent editor's **What does it know?** picks them, or makes
the agent its own base in one click.

## Small or large

At the start of every call we measure the text of the agent's linked bases
(their ready documents) and decide once:

- **Small, 12,000 characters or less:** the whole text goes into the agent's
  prompt. It reads all of it on every call and searches nothing. The agent's
  own prompt and tools plus this text must stay within 32,000 characters; past
  that it searches instead.
- **Larger:** the agent gets a `search_knowledge` tool. For each question it
  searches and reads the best passages: up to 4 per search and 2,400
  characters in all, at most 12 searches per call. A search has 0.9 seconds.
- **One-model (realtime) agents** can only read knowledge in their prompt. Past
  12,000 characters such an agent answers without its knowledge; the agent
  editor says so before you save.

Each base's `ready_chars` is exactly what it serves now, the number this
measures (`total_chars` is what was uploaded; the two differ while a document is
read). Reading one agent (get, create or update) returns `knowledge_mode`:
`inline` (in the prompt), `search` or `none` (nothing linked, nothing ready,
or a realtime agent's knowledge too long). A list leaves it `null`.

## Keyword or meaning search

Every base has **keyword search**. It works with no setup and costs nothing.

Add **meaning search** by choosing one of the project's verified Google or
OpenAI provider accounts as the base's `embedding_account_id`. It also finds
passages that say the same thing in other words ("cost" for "price"). Each
document is turned into vectors once on that account, and each question asked
on a call is turned into one there too, so that provider bills you for both.
**Dvaarik charges nothing for knowledge.** `embedding_account_id: null` turns
meaning search off. When the meaning search cannot answer in time, the question
is answered by keyword, never left waiting.

## Make a base, add a document, ask it

```bash
# 1. Make a base (keyword search; add "embedding_account_id" for meaning search)
curl -sS -X POST https://api.developers.dvaarik.com/v2/knowledge-bases \
  -H "X-Api-Key: $DVAARIK_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Prices and policies"}'

# 2. Add a document: the file itself as the body, its name in ?name= (201, "queued")
curl -sS -X POST "https://api.developers.dvaarik.com/v2/knowledge-bases/$BASE_ID/documents?name=Prices" \
  -H "X-Api-Key: $DVAARIK_API_KEY" -H "Content-Type: text/markdown" \
  --data-binary @prices.md

# 3. Ask every few seconds until each document is ready or failed
curl -sS https://api.developers.dvaarik.com/v2/knowledge-bases/$BASE_ID/documents \
  -H "X-Api-Key: $DVAARIK_API_KEY"

# 4. Try a question: exactly the passages an agent's search gets, with mode and time
curl -sS -X POST https://api.developers.dvaarik.com/v2/knowledge-bases/$BASE_ID/search \
  -H "X-Api-Key: $DVAARIK_API_KEY" -H "Content-Type: application/json" \
  -d '{"query": "What time do you open on Saturday?"}'

# 5. Give it to an agent (up to 3 bases; [] removes them)
curl -sS -X PATCH https://api.developers.dvaarik.com/v2/agents/$AGENT_ID \
  -H "X-Api-Key: $DVAARIK_API_KEY" -H "Content-Type: application/json" \
  -d '{"knowledge_base_ids": ["'"$BASE_ID"'"]}'
```

A document can also be sent as JSON (`kind` is `markdown` or `text`):
`{"name": "Returns", "kind": "markdown", "content": "# Returns\nWithin 30 days..."}`.
In markdown, each `#` heading starts a section, and search names the section
of every passage it returns. Reading and searching take `voice:read`; saving,
deleting and re-indexing take `voice:write`. The console
door is the same under `/console/v2/projects/{project_id}/knowledge-bases`
with your account session.

## PDF documents

Send a PDF the same way, with `Content-Type: application/pdf` (or upload it on
the Knowledge page):

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/v2/knowledge-bases/$BASE_ID/documents?name=Menu" \
  -H "X-Api-Key: $DVAARIK_API_KEY" -H "Content-Type: application/pdf" \
  --data-binary @menu.pdf
```

- **Text-layer PDFs only.** We read the text the PDF carries. A scanned PDF
  (pictures of pages) has none and is refused with a sentence saying so, as is
  one that needs a password. Upload its text instead.
- **At most 10 MB**, and at most 500,000 characters of text. A larger file is
  refused (413, naming the limit).
- **The original file is not kept.** Its text is read while the request waits
  and saved as the document (`kind` `pdf`); the PDF itself is stored nowhere.
- If another PDF is being read on that server, the upload is refused with 503
  and `Retry-After`: send it again after that many seconds.

## While a document is read

A new document is `queued`, then `indexing`, then `ready` or `failed`; a failed
one carries `error`, one sentence saying why. Replacing a document
(`PUT .../documents/{document_id}`, JSON or the raw text) is safe on a live
agent: the previous version keeps answering until the new one is ready, and
`indexed_version` says which version agents read now.

If the meaning-search provider fails (a refused key, rate limits that do not
pass), the document is still found by keyword and reads `failed` with the
provider's sentence. `POST /v2/knowledge-bases/{base_id}/reindex` (the
console's **Retry indexing**) queues every document that is not fully indexed
again; vectors already made are reused, not bought twice. Saving the same
`embedding_account_id` again does the same. Choosing another account, or
turning meaning search off, reads every document again.

## Documents are evidence, not instructions

Text in a document reaches the model as quoted evidence, never as
instructions. The agent is told to ignore anything in a document that asks it
to change its rules, tools, identity or behaviour, and to answer only what the
documents support; the markers that fence knowledge in the prompt are removed
from documents before they are stored. A document can still state wrong
facts, so upload only text you trust.

## Limits

| What | Limit |
| --- | --- |
| Knowledge bases | 10 per project |
| Documents | 50 per base |
| One document | 500,000 characters (a raw text upload at most 2 MB, a PDF at most 10 MB); at most 400 passages, and no single line over 3,800 characters |
| All documents | 5,000,000 characters per project |
| Bases one agent reads | 3 |
| Whole in the prompt | 12,000 characters or less, within the 32,000-character prompt |
| Kinds | markdown (`text/markdown`) or plain text (`text/plain`), UTF-8, or a PDF with a text layer (`application/pdf`; only its text is kept) |
| A question | 2 to 500 characters |
| Search on a call | 4 passages and 2,400 characters per search, 12 searches per call |

Documents are kept until you delete them or their base; see
[Your data](/docs/your-data).

---

Source: https://developers.dvaarik.com/docs/knowledge · every page as one file: https://developers.dvaarik.com/docs.md
