OBLETHdocs

Knowledge

Ground a model's answers on documents you upload, by retrieving the most relevant passages from your collections into each request.

5 min readUpdated for v2.4.0Edit on GitHub

You needA registered embedding model and some .txt, .md or .csv files
Turn it onKnowledge › Retrieval settings, then attach a collection to a model
It costsNothing billed; query embeddings are free to the tenant

You upload files into collections. The gateway splits each document into chunks and embeds them with the collection's embedding model. For a model that has the Knowledge boon and at least one attached collection, it embeds the user's question, finds the best-scoring chunks, and places them ahead of the conversation. Retrieval runs from an in-process index inside the gateway; the request path never queries Postgres.

Turn it on

  1. 1

    Create a collection

    Open Knowledge and choose New collection. Give it a name, an optional description and the Embedding model. Names are unique. Register an embedding model on the Models page first if you have none.

  2. 2

    Upload documents

    On the collection's page (/knowledge/<name>), upload files under Documents. Each moves from Queued to Indexing to Indexed, or to Failed with the error shown; failures are listed first.

  3. 3

    Attach it to a model

    Under Used by, pick a chat model and choose Attach. Attaching grants that model the Knowledge boon. You can also switch Knowledge on under a model's Boons and pick its collections there.

  4. 4

    Turn retrieval on

    On the Knowledge page, choose Turn retrieval on, or open the Retrieval settings tab and switch Retrieval on. Pick a profile and save.

  5. 5

    Try a search

    On the collection's page, type a question under Try a search. It shows the chunks that match, their scores, and which would be handed to the model under the current settings.

A request where it helps

curl http://localhost/v1/chat/completions \
  -H "Authorization: Bearer $OBLETH_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-5-3",
    "messages": [{"role": "user", "content": "How many credits can a student transfer in?"}]
  }'

When passages were added, the response carries x-obleth-boons: knowledge.

What the model sees

The passages arrive in a <knowledge> block with a short instruction to use them only when they are relevant. It is appended to the system message, or becomes one; for a model flagged as not supporting system messages, it is put at the start of the latest user message.

The query is the last Question from user messages, newest first, cut to 2,000 characters. It is captured before compression and the block is added after compression and after the tenant's input guardrails, so the query is the user's own words and the passages reach the model unchanged. A follow-up turn in the tool loop carries the same block.

Retrieval settings

These live on Knowledge › Retrieval settings and apply to every model. A profile sets the first four:

ProfileChunks per questionMinimum scoreToken budgetQuestion from
Standard (default)50.3515002 turns
Precise30.58001 turn
Broad100.2540004 turns
Settings labelFieldDefault
Retrievalenabledfalse
Chunks per questiontop_k5
Minimum scoremin_score0.35, cosine similarity from 0 to 1
Token budgetmax_context_tokens1500
Question fromquery_turns2
Embedding timeoutembed_timeout_ms1500 ms
Query cachequery_cache_ttl_s600 s
Largest uploadmax_upload_bytes10 MiB per file, at most 50 MiB
Chunks per collectionmax_chunks_per_collection100000
Index batchindex_batch_size32 chunks per embedding call
Index timeoutindex_timeout_ms30000 ms
Stale afterindex_stale_after_secs1800 s
Keep chunk text in tracesdebug_snapshotfalse

Through the Management API, send only what you want to change; an omitted field, a 0, or a min_score outside 0 to 1 keeps the stored value:

curl -X PUT http://localhost:9180/api/v1/settings/knowledge \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "top_k": 5, "min_score": 0.35, "max_context_tokens": 1500 }'

Each collection also has Chunk size (chunk_tokens, default 400) and Overlap (chunk_overlap_tokens, default 50, less than the chunk size) under its Settings. Existing chunks keep the old sizes until you Reindex.

How retrieval picks passages

The query is embedded once per distinct embedding model among the attached collections, within Embedding timeout, and cached in Redis for Query cache. Chunks from every attached collection are scored by cosine similarity, those below Minimum score are dropped even when they are the best match, and the best Chunks per question are kept. They are added in score order while they fit the Token budget and still leave the prompt, the block and 512 tokens for the answer inside the model's context window.

Indexing

A background indexer takes queued documents one at a time, chunks and embeds them in batches of Index batch, and commits the chunks and the Indexed status together. A document stuck in Indexing longer than Stale after (after a crash or redeploy) is picked up again. Reindexing one document never touches another's chunks, and the old chunks keep serving until the new ones commit. Uploading identical content again updates the existing document.

Changing a collection's embedding model marks it as needing a reindex rather than mixing vectors from two embedders; retrieval keeps using the old vectors until you Reindex it.

The gateway refreshes its index every 15 seconds, loading only collections attached to at least one model. If Postgres is unreachable during a refresh, the last good index keeps serving.

When it applies and fail-open

Retrieval runs on a chat request when Retrieval is on, the model has knowledge in its boons list and at least one attached collection, and the key is not an internal probe key. It leaves the request as it arrived when there is no user text, the model has no context window set, the embedding model is missing, errors or times out, the collections are empty or not yet indexed, or nothing scores high enough or fits.

obleth_knowledge_retrievals_total{outcome} counts attempts by hit, miss, no_query, error and no_window. With tracing on, a boon:knowledge span records the chunk ids and scores, and their text only with Keep chunk text in traces.

Management API and backups
MethodPathPurpose
POST, GET/api/v1/knowledge/collectionsCreate (name, description, embedding_model) or list collections
GET, PUT, DELETE/api/v1/knowledge/collections/{id}Read, update or delete a collection
GET, POST/api/v1/knowledge/collections/{id}/documentsList documents, or upload one (title, filename, content_base64)
POST/api/v1/knowledge/collections/{id}/reindexReindex every document
POST/api/v1/knowledge/collections/{id}/searchTry a search (query, top_k)
DELETE/api/v1/knowledge/documents/{id}Delete a document
POST/api/v1/knowledge/documents/{id}/reindexReindex one document
GET, PUT/api/v1/models/{id}/knowledgeRead or set a model's collection_ids
GET, PUT/api/v1/settings/knowledgeRead or update retrieval settings

Setting a model's collections through the API does not add knowledge to its boons list; do that with PUT /api/v1/models/{id}.

Configuration backups include the retrieval settings but not collections, documents, chunks or attachments. Re-create collections and re-upload documents on a restored gateway.