Skip to main content
Standard RAG is a fixed pipeline: embed the query, search the vector database, stuff the top-K results into a prompt, and call the LLM. This works for simple factual questions but fails in practice because:
  • Not all queries need retrieval. “What is 2 + 2?” should skip the vector database entirely.
  • Different queries need different retrieval strategies. A factual lookup needs high-precision single-pass search. An exploratory question needs broad multistage retrieval across multiple document types.
  • Retrieval confidence varies. If the top result scores 0.62, the LLM probably has enough context. If the best score is 0.04, the system should try a different strategy.
  • User feedback should improve future retrieval. When a user marks a response as unhelpful, the system should learn which documents were not relevant.
An Adaptive RAG system solves these problems by making the retrieval pipeline dynamic. Instead of one fixed strategy, the system classifies each query, selects the appropriate retrieval approach, evaluates result quality, and adapts based on feedback. This tutorial builds a complete adaptive RAG pipeline on Actian VectorAI DB. By the end, you will have:
  • A knowledge base collection with payload indexes for routing, feedback, and analytics.
  • A keyword-signal query classifier that maps queries to four retrieval strategies.
  • Three retrieval strategies (precise, broad multistage, and nested troubleshooting prefetch) plus an automatic fallback.
  • A confidence evaluator that decides whether results are good enough or a fallback is needed.
  • A user feedback loop that updates per-document usefulness scores over time.
  • A feedback-aware retrieval function that boosts historically helpful documents.
  • An analytics function that shows which documents are most retrieved and most useful.
  • A prompt-assembly step that packages context and confidence instructions for any LLM.

Environment setup


Step 1: Import dependencies and configure

Expected output


Step 2: Create the knowledge base collection

Each index serves a specific role: The combination of keyword, integer, float, and datetime indexes means the adaptive router can filter, sort, and range-query on any payload field without a full collection scan.

Expected output


Step 3: Ingest documents into the knowledge base

Expected output


Step 4: Build the query classifier

Expected output


Step 5: Strategy 1 — Precise retrieval for factual queries

Expected output

Note: score_threshold=0.4 is calibrated to all-MiniLM-L6-v2 on this corpus where top scores reach ~0.62. Calibrate thresholds by observing your actual score distribution — never use fixed values across different models or datasets.

Why these settings for factual queries

With these settings the search either returns a small number of highly confident matches or nothing at all — both are useful signals. An empty result set tells the router to invoke the fallback strategy rather than hallucinate an answer.

Step 6: Strategy 2 — Broad multistage retrieval for exploratory queries

Expected output

RRF scores are bounded by 1/(60 + rank) — they top out at ~0.033 for rank 1. This is expected and correct. Do not compare RRF scores to cosine scores from points.search.
The lower hnsw_ef=128 per stream is a deliberate trade-off: the four parallel streams compensate for any individual miss, so per-stream precision matters less than overall breadth.

Step 7: Strategy 3 — Troubleshooting retrieval

Expected output

The troubleshooting strategy uses three stages to progressively narrow candidates before the final rerank:
DBSF normalizes the scores from both inner streams before merging, giving a fair comparison between troubleshooting tips and changelog notes. The final rerank with the query vector ensures the most relevant results surface at the top.

Step 8: Build the confidence evaluator

RRF and cosine scores are on different scales. The evaluator detects which scale applies automatically:
  • points.search cosine scores: 0.0–1.0 → thresholds high=0.45, low=0.25
  • points.query RRF scores: 0.01–0.035 → thresholds high=0.025, low=0.015

Expected output


Note: query={"sample": Sample.Random} raises UnimplementedError 501 in VectorAI DB 1.0.0. Use an unfiltered points.search as the fallback widening pass.

Expected output

The fallback scores (0.069) are higher than the RRF scores (0.033) because they come from points.search (cosine scale). The confidence evaluator handles this automatically.
Sample.Random returns random points from the collection. In the fallback function above, it acts as a last-resort “did you mean?” response: if neither the original filtered search nor the unfiltered widening returns any results, the function returns these random documents so the user can see what is in the knowledge base and reformulate the query. Both fallback queries run inside a single client connection to avoid an extra round-trip.

Step 10: Build the adaptive router

Expected output

The “quantum flux capacitor” query returns strategy=broad, confidence=high because the RRF score of 0.0328 clears the RRF high threshold of 0.025. The fallback triggers only when scores fall below the threshold, not when a query is semantically out-of-domain. For domain detection, add a post-retrieval check on top_score or use a separate classifier.

Step 11: User feedback loop

Expected output

Each feedback event nudges a document’s score toward 1.0 (helpful) or toward 0.0 (unhelpful) using an exponential moving-average formula so that no single event dominates the history: After many feedback cycles, frequently helpful documents accumulate high scores while unhelpful ones sink. The feedback-aware retrieval function in the next step uses these scores to boost useful documents.

Step 12: Feedback-aware retrieval

Expected output

The function runs two prefetch streams in parallel and merges them with RRF, so documents that satisfy both criteria rank above those that satisfy only one:
A document that is both semantically relevant and historically useful gets a double boost. A document that is semantically relevant but has been marked unhelpful appears in only one stream and ranks lower.

Step 13: Analytics

Expected output


Step 14: Prepare the prompt for LLM integration

Expected output


Step 15: Collection cleanup


Adaptive strategies summary


APIs and features used in this tutorial


Next steps