Knowledge + behavior — using RAG and adapters together¶
The two services answer two different questions:
- Knowledge (RAG) changes what the model can talk about — it answers from your documents, with citations. No weights change.
- An adapter (LoRA) changes how the model behaves — its tone, its output structure, a narrow skill. It does not reliably add facts.
The strongest production pattern uses both on one endpoint: retrieval supplies the facts, the adapter makes the answer come out in your voice and your format. This page explains when to use which.
Adapta does not train adapters
In-product training was removed on 2026-10-10. You bring a GGUF or PEFT LoRA; import converts it, probe-loads it and scores it against the base on your eval set. Only a passed adapter can back an endpoint. See Bring your own adapter.
Knowledge inputs: PDF, DOCX, Markdown, TXT, HTML and images (PNG, JPG, TIFF). Scanned pages are OCR'd (Docling + RapidOCR) only where there is no text layer; low-confidence OCR flags the file for review.
When to use which — real-life cases¶
| Your situation | Use | Why |
|---|---|---|
| "Answer questions about our 400-page product manuals" | Knowledge | The facts live in documents; they change when the docs change — re-index, done. |
| "Our internal wiki updates weekly and answers must cite the source" | Knowledge | RAG citations point at the exact passage; updates are instant. |
| "Support replies must always follow our 5-part template and sound like us" | Adapter | A format/voice is a behavior — it lives in weights, not in any document. |
| "Classify incoming tickets into our 12 internal categories" | Adapter | A narrow skill with your private taxonomy; small local models learn it well from examples. |
| "Always answer in strict JSON our backend parses" | JSON mode first, adapter if the content is still wrong | response_format constrains every endpoint's output to valid JSON (or your JSON Schema) at decode time — no adapter needed for the shape. Import an adapter only if the field values themselves need your conventions. |
| "A support assistant that answers from our manuals, in our voice and template" | Both | Facts from retrieval (cited), form from the adapter. |
What an adapter is not for
Don't use an adapter to teach the model facts ("memorize our price list"). Facts belong in documents the model retrieves — they stay current and come back cited. An adapter that tries to memorize facts is brittle and goes stale on the first product change. Rule of thumb: facts → Knowledge, form → Adapter.
How the combination works¶
A project of type finetune can also index documents (console: the
Documents step of the finetune flow; API: the same
POST /v1/projects/{id}/files used by RAG projects). At serve time the
endpoint composes whatever the project has:
- documents indexed → relevant passages are retrieved and injected, and the
response carries
citations; - an imported adapter that passed the eval gate → it is applied on top of the base model.
A finetune project with indexed documents gets both in the same call.
(A pure-RAG project and a documents-free finetune project behave exactly as
before.) Bonus: those same indexed documents are what
POST …/datasets/synthesize reads when you bootstrap an eval set from documents — mode: "rag_eval"
(questions + the file that answers them, to measure retrieval) or mode: "behavior" with a task (an adapter
eval set), generated by the project's base model or an optional OpenAI-compatible teacher.
Follow-up questions
In a conversation, a follow-up like "who has to approve that?" is first rewritten by the model into a standalone
question ("Who has to approve the vacation days that can be carried over?") and retrieval runs on both. On our
12-question bilingual follow-up set it lifts recall@5 from 0.50 to 0.75 (English 0.67 → 0.83, Spanish 0.33 → 0.67)
with no question getting worse, for about 0.5 s (p95 0.7 s) and ~100 prompt tokens per follow-up turn on CPU with
qwen2.5-1.5b-instruct. A first question skips it. Send "adapta": {"condense": false} to turn it off.
Contextual retrieval (off by default)
PATCH /v1/projects/{id} with {"contextual_retrieval": true} makes indexing add a short "where this chunk sits
in the document" sentence to each chunk before it is embedded (citations still show the original text). It costs
one model generation per chunk at upload time and only applies to files indexed after you turn it on. On our
short-document benchmark it did not improve recall (0.978 → 0.956); try it on long manuals or contracts and
keep it only if your own measurements improve.
How retrieval works — hybrid vector + full-text
Retrieval is hybrid by default. Two searches run independently: a dense
vector search (sentence-transformers embeddings) and a Postgres full-text
search over every chunk of the project — so a chunk the vector search
never surfaced can still be found by an exact word. Very common words are
ignored and rarer words weigh more. The two rankings are merged via
Reciprocal Rank Fusion (RRF). Finally a cross-encoder reranker re-scores the shortlist
before the top-k are injected, and the score in each citation comes from
that last stage.
The result is more accurate than pure vector search on keyword-heavy queries (product codes, names, exact phrases) and more robust than pure keyword search on paraphrase-style questions. No configuration is needed — this is always on.
To tune it, set these on the app container (retrieval runs there, not
in the worker):
| Variable | Default | Effect |
|---|---|---|
ADAPTA_RAG_TOP_K |
5 |
Chunks injected into the prompt |
ADAPTA_RAG_HYBRID_FETCH_MULTIPLIER |
4 |
Vector candidates = top_k × N |
ADAPTA_RAG_SPARSE_FETCH_MULTIPLIER |
4 |
Full-text candidates = top_k × N |
ADAPTA_RAG_SPARSE_MAX_DF |
0.5 |
A query word found in more than this share of the project's chunks is ignored by the full-text search |
ADAPTA_RAG_RERANKER_MODEL |
"" (off) |
Opt-in cross-encoder reranker, e.g. cross-encoder/ms-marco-MiniLM-L-6-v2 — English-only, so enable it only for English-only documents |
ADAPTA_RAG_TIMEOUT_SECONDS |
10 |
Whole retrieval path; exceeding it returns a typed 504 |
Realistic expectations¶
- Knowledge is live: add or remove a manual and re-index — the very next answer reflects it. No retraining.
- Behavior is a swap: changing the template means a new adapter (trained elsewhere), imported and gated again.
- The adapter only ever changes how answers read. If an answer's facts are wrong, fix the documents or their chunking — not the eval set.
- Start with the default
qwen2.5-1.5b-instructbase (Apache-2.0); move up toqwen2.5-7b-instructif quality demands it (GET /v1/modelslists the catalog names). - Requests with images (vision base models) are non-streaming, up to 4 images per request, and skip document retrieval. See Consuming the API.