Azure AI Search hybrid search runs a keyword query and a vector query in one request and merges the two ranked lists with Reciprocal Rank Fusion (RRF). Semantic ranker then reranks the top 50 merged results using a language model, which is the combination Microsoft's documentation recommends for relevance in retrieval-augmented generation (RAG). You need an index with text and vector fields, a semantic configuration, and a query that sets search, vectorQueries and queryType.
Who this is for and what you will have
This guide is for developers who already have an Azure AI Search index with a vector field, or are about to create one, and want better results than keyword-only or vector-only search. At the end you will have a semantic configuration on your index, a working hybrid query with semantic reranking, an understanding of the scores in the response, and the billing plan set correctly.
Why combine keyword, vector and semantic ranking
Each method has a weakness the others cover:
- Keyword (BM25) search is precise for exact matches such as product codes, specialized jargon, dates and people's names.
- Vector search finds content that is conceptually similar even when no words match.
- Semantic ranker reorders the best candidates by meaning, but only the candidates it is given.
Microsoft's documentation states that benchmark testing on real-world and benchmark datasets indicates hybrid retrieval with semantic ranker offers significant benefits in search relevance. Treat that as a reason to try it, then confirm with your own test queries.
Prerequisites
- An Azure AI Search service in a region that provides semantic ranker. Check regional support in the documentation.
- An index with at least one
searchabletext field and one vector field. If you have not built one, see Azure AI Search integrated vectorization from Blob Storage for an end-to-end pipeline. - For semantic ranker, text content that is informational or descriptive. The documentation says it works best on prose such as knowledge bases and documentation.
- The embedding for each query, created with the same model and dimensions as the indexed vectors. See Choosing an embedding model: dimensions, cost and chunk size.
- Permission to create objects on the service. Microsoft recommends role-based access, with API keys as a fallback. To change billing you need Owner or Contributor on the search service.
How a hybrid query works
A hybrid query is a single request with both a search string and one or more entries in vectorQueries. The engine runs the full-text query (ranked with BM25) and the vector queries (HNSW or exhaustive KNN) in parallel, then merges the ranked lists with RRF and returns one result set.
How RRF scores results
RRF gives each document a reciprocal rank score in every list it appears in, calculated as 1/(rank + k), where rank is its position and k is a constant; the documentation notes the algorithm performs best with a small value such as 60. It then sums the scores per document and sorts. Documents that rank well in several lists rise to the top.
This k in RRF is a different setting from the k in a vector query, which controls how many nearest neighbors are returned. The documentation calls this out explicitly because they are easy to confuse.
RRF applies whenever more than one query executes. A full-text query plus one vector query targeting one field is two executions, and a full-text query plus one vector query targeting two fields is three.
What the scores mean
| Search method | Score property | Range |
|---|---|---|
| Full-text | @search.score (BM25) | No upper limit |
| Vector | @search.score | 0.333 to 1.00 for cosine; 0 to 1 for Euclidean and dot product |
| Hybrid | @search.score (RRF) | Bounded by the number of fused queries, each contributing at most about 1/k |
| Semantic ranking | @search.rerankerScore | 0.00 to 4.00 |
Because RRF scores are small numbers (the documentation's example response shows values around 0.03), do not compare them with BM25 scores or set thresholds as if they were percentages.
Step 1: Add a semantic configuration
A semantic configuration tells the ranker which fields to read. You can add or update it at any time without rebuilding the index, can create up to 100 per index, and can mark one as default.
Fields must be searchable and retrievable and be strings (Edm.String, Collection(Edm.String) or string subfields of a complex type). The properties are:
| Property | Guidance |
|---|---|
| Title field | One short string, ideally under 25 words, such as a document title or product name. Leave blank if none fits. |
| Content fields | Longer natural-language text such as the document body. List them in priority order. |
| Keyword fields | Tags or categories, listed in priority order. |
In the Azure portal
- Open your search service in the Azure portal.
- Under Indexes, select the index.
- Select Semantic configurations, then Add semantic configuration.
- Enter a name and choose the title, content and keyword fields in priority order.
- Select Save, then Save again on the index page.
With REST
Add a semantic section to the index definition in a Create or Update Index request:
"semantic": {
"defaultConfiguration": "my-semantic-config-default",
"configurations": [
{
"name": "my-semantic-config-default",
"prioritizedFields": {
"titleField": { "fieldName": "HotelName" },
"prioritizedContentFields": [
{ "fieldName": "Description" }
],
"prioritizedKeywordsFields": [
{ "fieldName": "Tags" }
]
}
}
]
}Replace the field names with your own. For a RAG index built from chunks, the title field is usually the document title, the content field is the chunk text and keywords can be a category or tags field.
Why field order matters
Semantic ranker processes at most 2,000 tokens per document (about 10 characters per token) when building the summary it scores, and the documentation lists these per-field limits: 128 tokens for the title, 128 tokens for keywords, and the remaining tokens for content. Anything longer is trimmed, so put your most informative field first. This is also another reason to chunk long documents rather than index them whole.
Step 2: Choose the billing plan
Semantic ranker is a premium feature billed by usage. Every search service starts on the free plan, which gives a monthly request allowance at no charge and is available on all pricing tiers. When that allowance is used up, semantic requests return a billing error. The standard plan is pay-as-you-go after the free allowance and requires the Basic tier or higher. The plan applies to the whole service, not a single index.
To switch in the portal:
- Open the search service and check on Overview that the tier is Basic or higher.
- Select Settings > Premium features.
- Under Semantic ranker, select Select plan on the Standard card.
To go back to free, select the Free card in the same place.
You can also set it with the Search Management REST API by patching the service. Microsoft recommends PATCH rather than PUT on an existing service, because PUT replaces unspecified properties with defaults and can cause an unexpected scaling or configuration change.
PATCH https://management.azure.com/subscriptions/{{subscription-id}}/resourcegroups/{{resource-group}}/providers/Microsoft.Search/searchServices/{{search-service-name}}?api-version=2026-03-01-preview
Content-Type: application/json
Authorization: Bearer {{management-access-token}}
{
"properties": {
"semanticSearch": "standard"
}
}For current prices, use the Azure AI Search pricing page; this guide does not quote them. A charge applies only when a request has queryType=semantic and a non-empty search string. A query with search=* is not charged even if the type is semantic.
Step 3: Run a hybrid query with semantic ranking
This is the documentation's representative query, trimmed to one vector field. The vector array is a placeholder for the embedding of the user's question.
POST https://{{searchServiceName}}.search.windows.net/indexes/{{indexName}}/docs/search?api-version=2026-04-01
content-type: application/json
api-key: {{query-key}}
{
"count": true,
"search": "historic hotel walk to restaurants and shopping",
"select": "HotelId, HotelName, Category, Description",
"vectorQueries": [
{
"kind": "vector",
"vector": [ <array of embeddings> ],
"k": 50,
"fields": "DescriptionVector"
}
],
"top": 10,
"queryType": "semantic",
"semanticConfiguration": "my-semantic-config-default"
}What each part does:
searchis the full-text query.vectorQueriescan hold several vector queries targeting several fields.ksets how many nearest neighbors the vector query returns. The documentation adviseskof 50 when you use semantic ranker, to maximize its inputs.selectshould list human-readable fields, which matters if you pass the results to an LLM.topis how many results come back after fusion and reranking.queryType: "semantic"turns on semantic ranker. If you do not want semantic ranking, remove the semantic parts and you have plain hybrid search. IfsemanticConfigurationis omitted, the default configuration is used.- Do not add
orderby. Explicit sort orders override relevance ranking, and the semantic ranking documentation says anorderbyclause on a semantically ranked query results in an HTTP 400 error. - Do not use an empty search string or
search=*with semantic ranking. There is nothing to measure relevance against, so no semantic ranking is applied.
Filters, facets and scoring profiles still work in a hybrid query. You can apply a filter before or after the vector search with vectorFilterMode; preFilter is the default. The hybrid search overview suggests that with semantic ranker you probably want post-filtering, but says to test which suits your queries. The hybrid query guide warns that a post-filter can leave the ranker with fewer than 50 documents, so check that your filters are not too selective.
For multilingual content, vector queries can match across languages without analyzers or translation, as long as the embedding space is multilingual.
Reading the response
Each result carries @search.score, the RRF value, and @search.rerankerScore, the semantic score from 0 to 4. In the documentation's scale, 4.0 means highly relevant and answering the question completely, 3.0 relevant but incomplete, 2.0 partially relevant, 1.0 related but answering a small part, and 0.0 irrelevant. Results are listed in descending reranker order.
If you want to understand why a result ranked where it did, add "debug": "vector", "semantic" or "all" to the request to get subscores.
What semantic ranker cannot do
The documentation is direct about the limits:
- It reranks the existing result set, only the top 50 results from BM25 or RRF. It does not rerun the query over the whole index.
- It uses text only. Even in a hybrid query, the reranking step reads the text fields in your semantic configuration.
- Captions and answers are extracted verbatim from your content. No generative model writes them, so if no passage answers the question, none is returned.
The practical effect is that retrieval quality before reranking still matters. If the right chunk is not in the first-stage top 50, semantic ranker cannot recover it. That is why chunking and embedding choices, covered in the embedding guide linked above, still decide a lot.
Verifying the setup
- Run the same query three ways: keyword only, vector only, and hybrid with semantic ranking.
- Compare the top 5 for questions you know the answers to, including at least one exact-term query such as a product code and one paraphrased question.
- Confirm that
@search.rerankerScoreis present in the hybrid results. If it is missing, semantic ranking did not run. - Check your usage against the free allowance in the portal before launching to users.
Troubleshooting
Semantic queries start failing with a billing error
The free monthly allowance is used up. Switch to the standard plan under Settings > Premium features on a service at Basic tier or higher, or wait for the allowance to reset.
No reranker score in results
Check that the request has "queryType": "semantic", a valid semanticConfiguration name (or a default configuration defined on the index) and a non-empty search string. Also confirm that your service is in a region that supports semantic ranker.
A field cannot be added to the semantic configuration
Only searchable and retrievable string fields are eligible. A vector field or a non-retrievable field is rejected.
Relevant documents are missing even with semantic ranking
The reranker only sees the first-stage top 50. Raise k to 50 on vector queries, check that your chunks are the right size, and test whether keyword or vector search alone finds the document.
Results ignore your sort order or seem unordered
If you added orderby, it overrides relevance ranking, and on a semantic query it returns an HTTP 400 error. Remove it for hybrid and semantic queries.
Reranker thresholds behave inconsistently
Scores can vary slightly with infrastructure conditions and model updates. Use coarse thresholds rather than fine-grained cut-offs.
Checklist
- The index has searchable text fields and a vector field that matches the query embedding model and dimensions.
- A semantic configuration lists title, content and keyword fields in priority order.
- The semantic ranker billing plan is set deliberately, standard on Basic tier or higher if you expect to exceed the free allowance.
- Queries use
search,vectorQuerieswithkset to 50, andqueryTypeset tosemantic. - No
orderbyin relevance-ranked queries. - You compared keyword-only, vector-only and hybrid results on your own questions.
References
- Hybrid search overview: https://learn.microsoft.com/en-us/azure/search/hybrid-search-overview
- Hybrid search scoring (RRF): https://learn.microsoft.com/en-us/azure/search/hybrid-search-ranking
- Semantic ranking overview: https://learn.microsoft.com/en-us/azure/search/semantic-search-overview
- Configure semantic ranker: https://learn.microsoft.com/en-us/azure/search/semantic-how-to-configure
- Enable or disable semantic ranker billing: https://learn.microsoft.com/en-us/azure/search/semantic-how-to-enable-disable
- Azure AI Search pricing: https://azure.microsoft.com/pricing/details/search
Comments
Questions and tips are welcome. Comments are checked by the EpiFive team before they appear; please do not share passwords, phone numbers or other private details.