RAG Retrieval Strategies for ASP.NET Core Developers
Selecting the smallest set of current, permitted and authoritative evidence for a grounded answer
The ingestion pipeline creates searchable knowledge. Chunking gives that knowledge useful boundaries. Then a user asks a question and the application must decide what evidence deserves to enter the model's limited context.
That decision is retrieval.
Retrieval is not merely “search the vector database and return five results.” A dependable pipeline may establish scope, apply permissions, resolve conversational references, decompose a multi-part question, combine keyword and vector search, merge candidates, remove duplicates, rerank by relevance and authority, reject weak evidence, expand useful parents and construct controlled citations.
The principle for this guide is:
Good RAG does not give the model every piece of possibly related information. It retrieves the smallest set of current, permitted, authoritative evidence needed to answer the user's actual question.The examples use BuildEstate Pro, my public enterprise property-development case study. The retrieval design is a teaching extension, not a claim that this production feature already exists in the repository.
1. Retrieval finds; generation synthesises
Suppose the user asks:
Can delivery lorries enter project 152 through the western road?The retrieval system should locate evidence such as:
Highway Access — Construction vehicles must not enter from the western road. All deliveries must use the eastern service entrance.The generative model can explain that evidence in natural language. It should not be asked to search millions of raw records inside its prompt.
The responsibilities are different:
Retrieval layer Generative model
--------------- ----------------
Enforces tenant and permission scope Explains supplied evidence
Finds exact and semantic matches Synthesises across selected sources
Prefers current authoritative sources Follows response and citation contract
Rejects weak or duplicate evidence Admits when evidence is insufficient
When an answer is wrong, this separation helps identify whether the correct evidence was missing or the model misused evidence that was present.
2. Retrieval is a controlled pipeline
A useful baseline is:
question → query embedding → vector search → top five chunks
A production-minded flow is closer to:
Authenticate and establish business scope
↓
Interpret the question and conversation
↓
Route, rewrite or decompose where justified
↓
Run exact, keyword, vector and structured retrieval
↓
Merge and deduplicate a broad candidate set
↓
Rerank for relevance, authority and freshness
↓
Apply calibrated thresholds and diversity rules
↓
Expand parents or neighbouring evidence if needed
↓
Assemble a small cited evidence package
Every stage should have a reason. Query rewriting, multiple searches and reranking add latency and new failure modes. They should earn their place through evaluation.
3. Define a retrieval request before talking to search
Do not pass an unstructured user string throughout the application. Build a trusted contract that separates user language from server-established scope.
public sealed record RetrievalRequest(
string OriginalQuestion,
Guid TenantId,
Guid? ProjectId,
string UserId,
IReadOnlyCollection<string> PermittedGroupIds,
DateTimeOffset AsOfUtc,
IReadOnlyList<ConversationTurn> RelevantConversation,
int MaximumEvidenceTokens);
TenantId, ProjectId and permissions come from authenticated identity and business authorisation—not from a model-generated rewrite.
The request also establishes a context budget. Retrieval is not successful merely because it finds relevant content; it must select evidence that fits the downstream answer safely and economically.
4. Keyword search remains essential
Keyword or lexical search is strong for exact planning references, customer names, error codes, clause numbers, product codes, addresses, dates and technical phrases.
If the query contains PLN-2026-00452, the exact identifier should carry strong weight. Vector similarity can find text about planning applications while missing or diluting that precise record.
Modern full-text search performs language analysis, word breaking, stemming, phrase handling, synonyms, field weighting and relevance ranking. BM25 is a common ranking algorithm. Its mathematics matters less here than its role: it rewards useful lexical matches while considering term rarity, frequency and document length.
Do not describe keyword search as primitive. Enterprise questions frequently combine natural language with exact identifiers, and exactness is often the fastest path to the authoritative record.
5. Vector search retrieves related meaning
Vector search compares the embedding of the question with stored chunk embeddings.
Question:
Are lorries allowed to use the west entrance?Document:
Construction vehicles must not enter from the western road.The wording differs, but the meanings are related. Vector search is valuable for paraphrases, synonyms and conceptually related language.
It is not a truth detector. A nearby vector may be thematically similar but belong to the wrong project, an obsolete policy or an unauthorised tenant. Similarity answers one question:
Which vectors are close to this query vector?Metadata, business rules and reranking must answer the rest.
The embeddings and semantic search guide develops vector similarity, HNSW, Top-K and hybrid search in greater depth.
6. Hybrid search is a strong enterprise default
Hybrid search runs lexical and vector retrieval for the same request, then combines the rankings.
Consider:
What drainage restrictions apply to application PLN-2026-00452?Keyword search strongly matches the application number. Vector search finds semantically related passages about drainage conditions, flood controls, surface water and approval requirements.
Azure AI Search can merge keyword and vector rankings using Reciprocal Rank Fusion (RRF). RRF uses positions in the ranked lists rather than pretending raw BM25 and vector scores are directly comparable.
Keyword ranking ──┐
├─ RRF merge ─► candidate ranking
Vector ranking ──┘
Hybrid search is not automatically perfect. Field configuration, language analysers, vector quality, candidate counts and filters still matter. But it is often a better starting point than choosing keyword or vector search exclusively.
7. Filter before content is allowed to compete
Search asks which chunks are relevant. Filtering asks which chunks are eligible.
Useful deterministic filters include:
- tenant and project;
- permitted user, role or security group;
- current document generation;
- approved rather than draft status;
- effective and expiry dates;
- language, region and document type;
- deleted, withdrawn or superseded flags.
Find passages related to delivery access
WHERE TenantId = A
AND ProjectId = 152
AND IsCurrent = true
AND ApprovalStatus = Approved
AND user belongs to an allowed group
These constraints are not prompt suggestions. ASP.NET Core derives them from trusted application state and sends them as search filters.
public sealed record RetrievalScope(
Guid TenantId,
Guid? ProjectId,
IReadOnlyCollection<string> GroupIds,
bool CurrentVersionsOnly = true,
bool ApprovedOnly = true);
An unauthorised chunk must not reach the model and then rely on an instruction saying “do not reveal this.” The security boundary has already failed if prohibited data enters model context.
8. Pre-filtering and post-filtering affect recall
In vector retrieval, filter timing matters.
Pre-filtering
Restrict candidates first, then find the nearest vectors inside the eligible set.
If the index contains one million chunks but only 500 belong to project 152, the similarity search considers the correct project scope.
Post-filtering
Find globally nearest vectors first, then discard ineligible results.
If nine of the nearest ten belong to other projects, the application may receive one result even though useful project-152 chunks existed slightly lower in the global ranking.
Azure AI Search supports vector filter modes. The right configuration depends on index topology and performance, but security and tenant boundaries must always fail closed. Test filtered recall using realistic low-selectivity and high-selectivity scopes.
9. Resolve conversational questions carefully
Users ask follow-ups such as:
What did they decide about it?The search engine lacks the conversation's referents. A rewrite might become:
What decision did Hounslow Council make about the drainage strategy for project 152?Useful rewriting can:
- resolve pronouns and omitted entities;
- correct spelling;
- expand domain abbreviations;
- remove conversational filler;
- preserve exact identifiers;
- convert a request into concise search language.
public sealed record SearchIntent(
string OriginalQuestion,
string SearchQuery,
IReadOnlyCollection<string> ExactTerms,
IReadOnlyCollection<string> ResolvedEntities,
IReadOnlyCollection<string> Assumptions);
Record original question, rewritten query and resolved entities in a protected trace. This makes retrieval failures explainable without exposing unrelated conversation content.
10. Query expansion should be domain-aware
For “lorry access,” related terms might include construction vehicle, delivery route, service entrance, traffic access and highway condition.
Expansion can improve recall when documents use different vocabulary. Uncontrolled expansion creates noise: “access” might become road access, user access, disabled access and system access.
Prefer approved domain synonym maps for stable terminology. Model-generated expansion can assist ambiguous cases, but validate and bound it.
Keep exact terms separate from expanded concepts. The planning reference PLN-2026-00452 should not be paraphrased.
11. Decompose genuine multi-part questions
Question:
Why was planning delayed, what conditions remain outstanding, and what should the project manager do next?This contains at least three information needs:
- evidence explaining the delay;
- authoritative current state of outstanding conditions;
- permitted next actions or process guidance.
public sealed record RetrievalSubquery(
string Id,
string Question,
RetrievalSourceKind PreferredSource,
int CandidateLimit,
int FinalEvidenceLimit);
Use decomposition for comparisons, research questions and requests spanning structured state plus documents. Do not split a simple factual question into five costly searches merely because the system can.
The response should show which evidence supports each part, not blend all sources into an untraceable narrative.
12. Route exact current facts to SQL or APIs
Not every answer belongs in vector search.
Question:
What is the current project status, and why is it delayed?The current status may be an exact SQL Server field. Planning correspondence may explain why.
Use:
- SQL or an authorised API for current structured facts;
- document retrieval for explanations and unstructured evidence.
public sealed record EvidenceItem(
string EvidenceId,
string SourceType,
string Content,
string Authority,
DateTimeOffset ObservedAtUtc,
Citation Citation);
Label the sources. The model should know that Project.Status = OnHold came from the current application record, while the explanation came from a dated planning letter.
This is a key enterprise pattern: use the best retrieval method for each fact rather than forcing every business question through vectors.
13. Retrieve broadly, but do not prompt broadly
The first stage often optimises recall: did the relevant evidence enter the candidate set?
If the correct chunk ranks twelfth and candidate Top-K is five, no later stage can rescue it. An advanced pipeline may collect 20–50 candidates from keyword and vector retrieval.
Those candidates are not all sent to the model. They are merged, deduplicated and reranked. Perhaps the best four or five enter the final evidence package.
Distinguish:
- Candidate Top-K: broad enough to protect recall.
- Final Top-N: small enough to protect context quality.
14. Merge rankings without comparing incompatible scores
Keyword scores, vector similarities and semantic reranker scores represent different calculations. A vector score of 0.82 is not inherently stronger than a BM25 score of 7.4.
Use a defined fusion method such as RRF, or normalise and calibrate only with evidence. Preserve retrieval-channel information for diagnostics.
public sealed record RetrievalCandidate(
string ChunkId,
string DocumentId,
string Content,
int? KeywordRank,
int? VectorRank,
double? VectorSimilarity,
double? RerankerScore,
SourceAuthority Authority,
DateTimeOffset EffectiveFromUtc);
Rank positions explain how the candidate entered the set. Final selection can then consider semantic relevance, current status and authority separately.
15. Reranking spends more effort on fewer candidates
Initial search must be fast across a large collection. A reranker examines the smaller candidate set more carefully against the complete question.
Hybrid retrieval: 40 candidates
↓
Deduplication: 27 distinct candidates
↓
Semantic reranker: reordered by question relevance
↓
Business rules: current and authoritative sources preferred
↓
Final evidence: 5 chunks
Azure AI Search semantic ranker is a second-stage reranker over text or hybrid results. Other options include cross-encoders, specialised reranking services and carefully constrained model-based ranking.
Reranking adds latency and cost. Measure whether it improves expected-passage ranking, especially for complex natural-language questions. Exact identifier lookup may not need it.
16. Relevance and authority are different
Two chunks can be equally similar while differing greatly in business value:
- current approved policy versus withdrawn draft;
- signed decision versus informal email;
- primary document versus copied summary;
- tenant record versus generic guidance;
- 2026 procedure versus superseded 2023 procedure.
public enum SourceAuthority
{
Informal,
Supporting,
Authoritative
}
public sealed record BusinessRankingSignals(
SourceAuthority Authority,
bool IsCurrent,
bool IsApproved,
DateTimeOffset? EffectiveFromUtc,
DateTimeOffset? EffectiveToUtc,
int SourcePriority);
Do not let a highly similar obsolete document silently outrank the current approved source. Equally, do not use freshness as a universal truth: a historical question may deliberately require the older version.
Question intent determines which business signals matter.
17. Thresholds let the system abstain
Top-ranked does not mean relevant. Search will normally return its best available matches even when all are weak.
A calibrated threshold can reject insufficient evidence. If nothing passes, the application should say that it could not find enough support in the permitted current sources.
This is safer than compelling the model to answer from vaguely related passages.
Avoid copying a threshold from another project. Scores vary by model, index, query type and ranking stage. Vector similarity and semantic reranker scores are not interchangeable.
Calibrate thresholds from labelled questions:
Known answerable questions → retain enough true evidence
Known unanswerable questions → reject plausible-looking noise
Often the decision uses several signals: reranker score, exact-term coverage, authority, freshness and evidence completeness.
18. Deduplicate repeated and overlapping evidence
The same paragraph may appear in an original PDF, meeting pack, copied email, revised report and summary. Overlapping chunks can also repeat the same passage.
Sending five near-identical chunks:
- wastes context;
- creates false apparent corroboration;
- crowds out complementary evidence;
- can cause repetitive answers.
Do not deduplicate genuinely independent sources merely because they state the same fact. Independent corroboration can matter. The distinction requires source identity, not only text similarity.
19. Diversity depends on the question
For a narrow question—“Which entrance must deliveries use?”—one complete authoritative section may be enough.
For “What are the major planning risks?” useful coverage may include drainage, highway, environmental and legal evidence.
A diversity policy balances relevance with coverage. Techniques such as maximal marginal relevance can penalise candidates that are too similar to already selected results.
The goal is not variety for its own sake. It is coverage of the question's distinct information needs without repetitive evidence.
Decomposed subqueries offer a transparent form of diversity: select evidence for each part, then combine under one shared context budget.
20. Parent and neighbour expansion restores context
Small child chunks are precise search targets. They may still need surrounding context.
If a child says:
Deliveries are restricted to 9 a.m.–4 p.m.Its parent section may clarify that the restriction applies only during construction.
After matching the child, retrieval can load:
- the parent section;
- one previous or next chunk;
- explicitly referenced clauses;
- a small document summary.
The RAG chunking strategies guide explains the parent-child design in detail.
21. Construct citations in application code
Every evidence item should keep document title, version, page, section, source link, effective date, chunk ID and parent document ID.
Give the model controlled evidence identifiers:
[S1] Planning Officer Report v4, Highway Access, page 18
Construction vehicles must not enter from the western road...
[S2] Project Register, observed 20 August 2026
Project 152 status: On Hold
The response contract can permit citations only from the supplied IDs. Application code maps [S1] to a real, permission-checked link.
public sealed record Citation(
string SourceId,
string Title,
string? Section,
int? Page,
int Version,
Uri? AuthorisedSourceUri);
Do not ask the model to invent URLs. A citation shows which source was used; it does not prove the model interpreted it correctly. Answer evaluation must still check entailment and completeness.
22. Build a bounded evidence package
The final selection should be explicit:
public sealed record EvidencePackage(
string Question,
IReadOnlyList<EvidenceItem> Items,
int TotalTokens,
bool IsSufficient,
IReadOnlyList<string> MissingEvidence,
RetrievalTraceSummary Trace);
Budget by usefulness, not merely rank. One large parent may consume the space of four precise sources. Reserve space for source labels and response instructions.
Order evidence consistently—for example by subquestion and authority—rather than relying on accidental search order. Keep user content and retrieved documents clearly delimited because documents may contain prompt-injection instructions.
If the package is insufficient, tell the generation layer to abstain or ask a focused clarification. Do not hide uncertainty behind fluent prose.
23. Distinguish retrieval failure from generation failure
An incorrect answer can arise in two places.
Retrieval failure
The correct evidence was not provided because the source was absent, chunking broke it, filtering was wrong, the query was poor, candidate K was too small or reranking demoted it.
Generation failure
The correct evidence was present, but the model ignored it, combined incompatible passages, misread a condition, invented detail or produced invalid citations.
These need different remedies. Prompt changes cannot retrieve a missing document. A new embedding model cannot force a generator to follow a clear evidence contract.
Trace the candidate set, final evidence IDs, scores, filters, rewrite, pipeline version and generated citation IDs. Protect that trace as business data.
24. Evaluate retrieval separately
Build a labelled dataset before judging answer fluency.
public sealed record RetrievalTestCase(
string Question,
RetrievalScope Scope,
IReadOnlyCollection<string> ExpectedDocumentIds,
IReadOnlyCollection<string> ExpectedSections,
IReadOnlyCollection<string> ForbiddenDocumentIds,
bool IsAnswerable);
Measure:
- Recall at K: did the candidate set include relevant evidence?
- Precision at N: how much final evidence was useful?
- Mean reciprocal rank or NDCG: did strong evidence appear early?
- filtered recall: did restrictions accidentally remove eligible evidence?
- authority accuracy: did current approved sources beat obsolete copies?
- abstention quality: were unsupported questions rejected?
- security: did forbidden documents remain absent at every stage?
- latency and cost: what did rewriting, extra queries and reranking add?
25. Observe retrieval in production
Useful telemetry includes:
- search type and number of subqueries;
- candidate counts per channel;
- filter selectivity;
- zero-result and below-threshold rates;
- reranker latency;
- duplicates removed;
- parents expanded;
- evidence tokens sent;
- citation usage;
- user feedback and follow-up reformulations.
Monitor changes by pipeline version. A new synonym map, embedding model, chunking strategy or threshold can improve one query class while damaging another.
26. BuildEstate Pro end-to-end example
The user asks:
Why can we not begin construction, and what approvals are outstanding for project 152?The application already knows the authenticated tenant, permitted security groups, project 152 and current date.
- The intent layer separates “why construction is blocked” from “which approvals remain outstanding.”
- SQL Server supplies current project status and live approval records.
- Hybrid search retrieves documentary explanations from planning material.
- Filters allow only the correct tenant, project, current generations and permitted groups.
- Keyword search protects exact project and condition identifiers.
- Vector search finds paraphrased concepts such as commencement restrictions.
- The merged candidate set is deduplicated.
- Semantic reranking promotes the strongest passages.
- Business ranking favours signed current decisions over copied or superseded documents.
- A threshold rejects weak material.
- Parent expansion adds the scope of relevant conditions.
- The final evidence package contains current SQL facts plus four cited document passages.
If the user lacks access to the environmental report, that report never enters the candidate set or model context. The answer states only what the permitted evidence supports.
That is retrieval as an application capability—not merely a nearest-neighbour query.
27. Common retrieval mistakes
Using vector search for every question
Exact current facts, calculations and identifiers may belong in SQL, APIs or keyword lookup.
Filtering after sensitive content reaches the model
Prompt instructions are not an authorisation boundary.
Sending every candidate to generation
High recall at retrieval time should not become noisy, expensive prompt context.
Comparing raw scores from different rankers
BM25, vector similarity and semantic reranker scores are not one common scale.
Preferring similarity over authority
An obsolete draft can be close in meaning and still be the wrong evidence.
Forcing an answer when evidence is weak
The system must be able to abstain.
Treating citations as proof of correctness
A cited answer can still misinterpret its source.
Tuning against impressive demonstrations
Use representative questions, difficult negatives and permission cases.
28. A practical implementation sequence
- Define trusted retrieval scope and permission filters.
- Create realistic labelled questions and expected evidence.
- Establish keyword, vector and hybrid baselines.
- Route exact current structured facts to SQL or APIs.
- Tune candidate K and final N separately.
- Add deduplication and explicit authority/current-version rules.
- Introduce semantic reranking only after measuring the baseline.
- Calibrate thresholds with answerable and unanswerable questions.
- Add query rewriting and decomposition for proven failure classes.
- Build controlled citation and evidence-package contracts.
- Trace retrieval separately from generation.
- Monitor real failures and extend the evaluation dataset.
Final mental model
Retrieval is evidence selection under constraints:
User's actual question
+
Authenticated business scope
↓
Exact + lexical + semantic + structured retrieval
↓
Eligible current authoritative candidates
↓
Merge, deduplicate, rerank and threshold
↓
Controlled context expansion
↓
Small permission-safe evidence package with citations
↓
Grounded generation or honest abstention
Keyword search protects exactness. Vector search connects related meaning. Hybrid search combines their strengths. Filters enforce eligibility. Reranking spends more effort on a manageable candidate set. Business signals distinguish relevance from authority. Thresholds let the application decline unsupported answers.
The aim is not to find everything remotely related. It is to supply enough trustworthy evidence—and no more than necessary—for the user's specific task.
Continue through the AI Engineering learning journey, revisit RAG chunking strategies, or review the complete ingestion pipeline.
If this guide helped you, or you would like to discuss ASP.NET Core, Azure, SQL Server, Microsoft Foundry or RAG engineering, contact me at dotnetdeveloper20xx@hotmail.com.
