Ingest a document and query it
Оваа содржина сè уште не е достапна на вашиот јазик.
End to end: a file on your disk becomes an answer with a citation
pointing back at it. Everything here is curl, and the whole path takes
about five minutes.
You need a key with the editor role — creating collections and uploading
documents are writes. Reading and running agents need only a valid key,
whatever its role.
export KOVAC_API_KEY="the-key-you-created"export KOVAC_BASE="https://your-platform-host"1. Create a collection
Section titled “1. Create a collection”export COLLECTION_ID=$(curl -s -X POST "$KOVAC_BASE/api/manage/collections" \ -H "Authorization: Bearer $KOVAC_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "handbook"}' | jq -r '.id')Defaults are fine to start with. If you already know your documents are
short and dense — reference tables, glossaries — a smaller chunk_size
retrieves more precisely; see Collections & knowledge
for the rest of the settings and why they are set once, at creation.
A 409 here means the name is taken in your tenant. Names are unique per
tenant, not global.
2. Upload a document
Section titled “2. Upload a document”curl -s -X POST "$KOVAC_BASE/api/manage/collections/$COLLECTION_ID/documents" \ -H "Authorization: Bearer $KOVAC_API_KEY" \ -F "file=@handbook.pdf" \ -F "source_uri=https://intranet.example.com/handbook.pdf"Set source_uri to wherever the document really lives. It is what
citations will name, so a real URL turns every citation into a link a
reader can follow. Skip it and you get upload://handbook.pdf, which
identifies the file but leads nowhere.
Accepted formats, by family:
| Family | Extensions |
|---|---|
| Documents | .pdf .docx .pptx .html .htm .md .txt .rtf .odt .odp .epub |
| Spreadsheets and delimited text | .csv .tsv .xlsx .xls .ods |
| Structured data | .json .yaml .yml .xml |
.eml .msg |
|
| Images (OCR) | .png .jpg .jpeg .tif .tiff .bmp .gif .webp .jp2 |
| Source files | .py .js .ts .tsx .java .go .rs .rb .php .c .cpp .cs .kt .swift .scala .sh .sql and others |
Anything else is rejected with 400 before any work starts. So is a file
whose content contradicts its extension — a ZIP renamed to .pdf, an
HTML error page saved as .docx. Text formats have no signature to check,
so they are never rejected on that ground.
The response is 202 with a document_id and status: "parsing". If it
comes back 200 with status: "done" instead, the collection already
holds a document with identical content — that is deduplication, not an
error.
3. Wait for it to finish
Section titled “3. Wait for it to finish”export DOCUMENT_ID="the-document-id-from-step-2"
curl -s "$KOVAC_BASE/api/manage/collections/$COLLECTION_ID/documents/$DOCUMENT_ID" \ -H "Authorization: Bearer $KOVAC_API_KEY" | jq '{status, error}'Poll until status is done. A scanned PDF that needs optical character
recognition can take a few minutes; a Markdown file is near-instant. A scan
in Cyrillic needs its language named at upload — see Scanned PDFs and
images in Collections.
If status is error, the error field says why. The two common causes
are a file that is not really the format its extension claims, and a PDF
that is entirely images with no recoverable text.
A document that has not reached done is not searchable. An agent
asked about it will correctly report finding nothing, which looks
identical to the document not existing. Check the status before concluding
retrieval is broken.
4. Point an agent at the collection
Section titled “4. Point an agent at the collection”An agent can only search collections named in its own configuration. Open
the agent on the Agents screen and add handbook to its knowledge
attachments — that is Attach knowledge to an
agent, which also covers what to do when you have
no suitable agent yet.
Then take its assistant_id:
curl -s "$KOVAC_BASE/api/manage/agents" \ -H "Authorization: Bearer $KOVAC_API_KEY" | jq '.[] | {name, assistant_id}'
export ASSISTANT_ID="the-assistant-id"5. Ask it something
Section titled “5. Ask it something”export THREAD_ID=$(curl -s -X POST "$KOVAC_BASE/api/agent/threads" \ -H "Authorization: Bearer $KOVAC_API_KEY" \ -H "Content-Type: application/json" \ -d '{}' | jq -r '.thread_id')
curl -N -X POST "$KOVAC_BASE/api/agent/threads/$THREAD_ID/runs/stream" \ -H "Authorization: Bearer $KOVAC_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"assistant_id\": \"$ASSISTANT_ID\", \"input\": {\"messages\": [{\"role\": \"user\", \"content\": \"What is the expense approval threshold?\"}]}, \"stream_mode\": [\"messages\", \"values\"] }"Ask something the document actually answers. A first test against a question the document does not cover proves nothing either way — an honest “I could not find that” is the correct response, and indistinguishable from a broken pipeline.
In the stream you should see a call to the search tool, its result — an
array of passages, each carrying a ref alongside its content,
source_uri, metadata and confidence — and then an answer citing
them inline by that ref, as [c9f3a12b]. An answer never contains a file
path or URL; see Verifiable citations.
When there are no citations
Section titled “When there are no citations”Work down this list in order; each step rules out one cause.
Did the run finish at all? Check the stream’s end event for
{"status": "success"}. A failed run still returns HTTP 200, so a
client that only checks the status code sees a success with no answer in
it. See Errors & limits.
Did the run search at all? Look for a search tool call in the
stream. No call means the agent did not think it needed one, or has no
search tool. Check that search is in the agent’s tools and that its
trust tier permits it — a stripped tool produces an
agent that says plainly it cannot search.
Did the search return nothing? An empty result array with a done
document usually means the collection is not attached to this agent.
The agent’s configured collections are a hard ceiling, so an agent with
the wrong attachments searches the wrong place and finds nothing.
Did it return passages but not cite them? That is a model behaviour problem, not a retrieval one. Check the agent’s system prompt for instructions that conflict with citing.
Is the document really indexed? Re-check its status. Also re-read
the passages the search did return: if they are from the right document
but the wrong part of it, the question and the document’s wording may be
too far apart, and a smaller chunk_size or a differently phrased
question is the lever.
The agent’s Traces tab shows the same run with the retrieved passages before and after re-scoring, which is the fastest way to tell “retrieved nothing” from “retrieved the wrong thing” — see Read traces and evals.
Next: Author a plugin.
