AI Engineer World's Fair 2024
RAG at scale: production-ready GenAI apps with Azure AI Search
Read the talk
RAG at scale: building the retrieval system behind the answer
Production RAG needs more than vector similarity: hybrid retrieval, careful candidate budgets, stronger ranking, compact indexes, and ingestion that keeps pace with changing data.
From a talk by Pablo Castro
Before you start: Basic familiarity with language models, embeddings, and Python will help; the article introduces the retrieval and ranking concepts as they appear.
Give the model access to facts it never learned
How do you get a language model to work with your application data, company documents, or information about your users—facts it never saw during training? Pablo Castro, from Microsoft’s Azure AI team, starts by separating three approaches that address different needs.
| Approach | Useful when you need to… |
|---|---|
| Prompt engineering | Supply instructions and context directly, taking advantage of longer context windows. |
| Fine-tuning | Teach recurring patterns or domain-specific jargon. |
| Retrieval-augmented generation | Answer using an external collection of facts. |
Prompt engineering can go a long way. When the problem is access to a changing body of knowledge, however, RAG separates the model’s reasoning capabilities from the system that stores that knowledge.
The basic workflow is straightforward:
- An orchestrator receives a task, such as the next question in a chat.
- It searches a knowledge base for candidate pieces of evidence.
- It sends instructions, the question, and those candidates to the language model.
- The model produces an answer grounded in the retrieved material.
Real applications usually need multiple attempts, tuning, and more elaborate orchestration. But this division of responsibility remains: retrieval determines which evidence the model gets to reason over.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
A successful prototype creates several scaling problems
Castro describes 2023 as a year of prototypes and 2024 as the move into production. A convincing demo establishes that an interaction is useful; production adds simultaneous users who want more data and faster answers. Success creates pressure to put the organization’s entire collection into the system. Data volume grows, updates arrive more frequently, and query traffic increases.
The initial workflow—take a question, search, call the model—also tends to expand. A single user request may require several retrieval calls and several model calls, multiplying the work performed by both systems. Meanwhile, adding more organizational knowledge brings different file types and data sources. Scaling therefore means handling volume, change rate, query load, workflow complexity, and data diversity together.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Treat vector search as part of a retrieval platform
Azure AI Search is designed to cover the broader retrieval problem rather than require applications to assemble every search component themselves. Vector search sits alongside Microsoft’s other retrieval capabilities, Azure data integration, and platform security and compliance features. The goal is to make these pieces work together as one service.
Vectors are useful because they capture soft conceptual similarity: a query can find related content without sharing its exact wording. Production applications also need control over how those matches are found and constrained.
- Approximate and exhaustive search: Fast approximate nearest-neighbor search serves retrieval workloads; exhaustive search provides precise results for baselines and recall evaluation.
- Filters and projections: Metadata conditions restrict eligible documents, while projections select the fields returned to the application.
- Multiple vectors: A document can carry vectors for different content sections or data types, potentially using different embeddings. A query can also contain multiple vectors.
These capabilities let an application combine database-style selection with similarity search.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Build a small index, then add text and filters
The notebook demonstration starts with an already provisioned search service. Castro connects using a default Azure credential and creates an index containing categorical metadata, text, and a vector field. The vectors have just three dimensions so the example is easy to inspect; practical embeddings commonly have hundreds or thousands. He selects HNSW, a graph-based approximate nearest-neighbor algorithm, as the indexing strategy.
This Python example expresses the same index structure, using current SDK profile-style configuration rather than reproducing the historical notebook cell:
python
import os
from azure.identity import DefaultAzureCredential
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
HnswAlgorithmConfiguration,
SearchField,
SearchFieldDataType,
SearchIndex,
SearchableField,
SimpleField,
VectorSearch,
VectorSearchProfile,
)
endpoint = os.environ["AZURE_SEARCH_ENDPOINT"]
credential = DefaultAzureCredential()
index_name = "toy-retrieval"
index = SearchIndex(
name=index_name,
fields=[
SimpleField(name="id", type=SearchFieldDataType.String, key=True),
SimpleField(
name="category",
type=SearchFieldDataType.String,
filterable=True,
),
SearchableField(name="text", type=SearchFieldDataType.String),
SearchField(
name="vector",
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
searchable=True,
vector_search_dimensions=3,
vector_search_profile_name="toy-profile",
),
],
vector_search=VectorSearch(
algorithms=[HnswAlgorithmConfiguration(name="toy-hnsw")],
profiles=[VectorSearchProfile(
name="toy-profile",
algorithm_configuration_name="toy-hnsw",
)],
),
)
SearchIndexClient(endpoint, credential).create_index(index)
The categorical field must be filterable to support the metadata restriction added later. The vector field’s dimensions and search profile establish how its values will be indexed.
Once the index exists, Castro obtains a document client and explicitly pushes records containing vectors, text, and categories. Managed ingestion is another option, but direct uploads make the mechanics visible. He first searches with a vector and requests its two nearest candidates. Next, he adds the text hello: the system now retrieves through both the text and vector paths, then fuses and ranks their results. Finally, he restricts the query to category A, excluding records in category B.
Continuing the Python example, these teaching records make the same progression explicit:
python
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizedQuery
client = SearchClient(endpoint, index_name, credential)
client.upload_documents([
{"id": "1", "category": "A", "text": "hello world",
"vector": [1.0, 0.0, 0.0]},
{"id": "2", "category": "A", "text": "nearby concept",
"vector": [0.9, 0.1, 0.0]},
{"id": "3", "category": "B", "text": "hello again",
"vector": [0.0, 1.0, 0.0]},
])
query = VectorizedQuery(
vector=[1.0, 0.0, 0.0],
fields="vector",
k_nearest_neighbors=2,
)
vector_results = list(client.search(vector_queries=[query]))
hybrid_results = list(client.search(
search_text="hello",
vector_queries=[query],
))
filtered_results = list(client.search(
search_text="hello",
vector_queries=[query],
filter="category eq 'A'",
select=["id", "category", "text"],
))
Filters can also combine conditions with AND, OR, and ranges. Castro says filtering remains fast with hundreds of millions of documents, though he provides no latency measurements or workload configuration for that claim.
An audience member notices a detail in the live demonstration: why did a query with k = 2 return three results? Because k controls the vector branch’s candidate budget, not the size of the entire hybrid response. Two candidates came from vector retrieval; keyword retrieval contributed additional candidates; fusion selected three results.
Candidate count and returned-result count are separate controls. An application can ask vector retrieval for a larger pool, combine that pool with keyword matches, and still return only the top N results. In the Python call, k_nearest_neighbors controls the vector candidate count; adding top=2 to client.search(...) limits the final response instead.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Retrieve broadly, then rank a small candidate set
An answer can only use evidence the retrieval system actually finds. That makes retrieval quality a central production concern. Azure AI Search addresses it with two stages: a recall-oriented first stage gathers candidates using vectors and keywords, then a stronger second-stage model reranks them.
Consider Castro’s illustrative corpus of a hundred million vectors. A fast retriever can reduce that corpus to a small candidate set. Once the set is small, running a more sophisticated ranking model becomes affordable. The expensive model does not need to evaluate every document in the index.
The comparison progresses through four configurations:
| Configuration | Retrieval and ranking |
|---|---|
| Keywords | BM25 text scoring |
| Vectors | OpenAI Ada embeddings |
| Hybrid | Fused keyword and vector results |
| Hybrid plus reranking | Fusion followed by a stronger ranking model |
Castro reports better retrieval results across the displayed evaluations when reranking is enabled. The related Microsoft hybrid retrieval evaluation measures ranking quality, not generated-answer accuracy: it uses NDCG@3 for customer datasets and NDCG@10 for academic datasets. The useful distinction is between finding plausible candidates and ordering those candidates well enough to supply the right evidence to the model.
Semantic reranking is not another cosine-similarity calculation. A bi-encoder encodes the document and query independently. That enables fast comparisons between their vectors, but the model never examines the query and document together. A cross-encoder takes both as input and predicts how well the document corresponds to the query.
| Model pattern | What it evaluates | Suitable scope |
|---|---|---|
| Bi-encoder | Separately computed representations | Large-scale candidate retrieval |
| Cross-encoder | Query and document together | Reranking a small candidate set |
The cross-encoder performs inference at query time for the candidate pairs. Applying it to an entire large corpus would be impractical for an interactive application, which is why the fast first stage matters.
Castro puts Azure’s reranker latency at roughly 100 milliseconds, depending on the cross-encoder, as the service’s chosen speed–quality trade-off. He describes that overhead as largely hidden by the longer LLM call in the overall response time; he does not supply a percentile, concurrency level, or benchmark setup.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Scope the search and preserve the original text
Before investing in more sophisticated ranking, use any known metadata that can narrow the relevant dataset. Discrete metadata gives the system a direct way to exclude irrelevant material. Apply the ranking machinery to that scoped set. The category filter in the notebook is a small example of this broader quality technique.
The next audience question concerns the keyword side of hybrid search. What input does it need? Castro returns to the notebook: the request can supply text and a vector, or it can supply text that the service also vectorizes. A vector alone does not recover the original keywords. Preserving the text gives the system an input for lexical retrieval as well as one from which it can obtain an embedding.
The audience member’s deeper question is how a chatbot should derive useful search terms dynamically from an arbitrary user prompt or conversation. That is a separate orchestration problem from accepting text and vector inputs. Castro mentions extracting a candidate search from the user’s input before calling the answer-generating LLM, but the exchange ends with the details deferred. No keyword-extraction algorithm or conversation-rewriting procedure is demonstrated.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Larger collections change the capacity requirement
The next constraint is how much content fits in an index. As applications moved from tiny experimental collections to organizational datasets, Azure increased its service limits. Castro reports a historical increase of 10–12 times the vector density for most services on the same SKUs, without changing prices. Microsoft’s May 2024 announcement corroborates an increase of up to 12 times at no additional cost; the change was not uniform across every deployment.
Castro says the new limits enable multi-billion-vector applications through service provisioning and data upload. He contrasts this with the previous year, when a billion-vector dataset was primarily a benchmark curiosity. The talk does not specify vector dimensions, tier, partition layout, or performance conditions for that scale.
OpenAI provides his customer example. Castro identifies Azure AI Search as the backing system for vector stores used with ChatGPT files and the Assistants API, and connects Azure’s capacity increase to larger limits exposed by OpenAI. The concrete historical change in OpenAI’s April 2024 announcement was a 500-fold increase in files per assistant, from 20 to 10,000—not a speedup or a general increase in every ChatGPT limit.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Trade vector precision for capacity and speed
Higher service limits are one way to fit more data. Another is quantization: represent each vector component with a narrower type. Moving from full floating-point values to int8 reduces storage at the cost of some precision. Single-bit encoding goes further, reducing each component to one bit.
Castro reports that Microsoft’s single-bit evaluations retained performance in the low-to-mid 90% range for some models, without naming the metric or models. He also cites a Cohere evaluation retaining almost 95% of the original precision with bit encoding, and says reranking can recover the remaining precision. Cohere’s int8 and binary embeddings work is the related approach; the talk does not establish the dataset or rescoring conditions behind that cited percentage.
Float32-to-one-bit encoding reduces the raw vector representation by a factor of 32. That arithmetic concerns the vector components, not the complete index, which also has indexing structures and may retain original vectors. Binary comparisons can use Hamming distance instead of computing cosine similarity over wider values, reducing the work involved in comparing representations. Castro presents support for these narrower vector types as available in AI Search at the time of the talk.
You can quantize vectors yourself or enable managed quantization. In the managed path Castro describes, the service keeps the original full-precision vectors alongside the compressed representation. Retrieval then proceeds in two steps:
- Search the compressed vectors and oversample candidates—retrieve more than the final answer needs.
- Rescore those candidates using their original full-precision vectors, then select the final results.
This full-precision vector rescoring is different from the earlier semantic cross-encoder: it revisits vector similarity rather than jointly reading query and document text.
That produces a practical set of choices:
| Choice | Benefit | Cost |
|---|---|---|
| Compressed retrieval | Smaller vector representation | Some quality loss |
| Compressed retrieval plus rescoring | Capacity with quality recovery | Additional query work and retained originals |
| Uncompressed retrieval | Original vector precision | Larger vector representation |
The controls let an application prioritize capacity, latency, and quality according to its workload. Oversampling helps only when relevant candidates survive into the pool that will be rescored.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Keep the index following the source data
The final scaling problem is getting new and changing data into the index. Every source has its own connection mechanism and way to enumerate changes. Azure AI Search’s ingestion system incorporates integrated vectorization so applications do not have to rebuild that pipeline for each source. Castro names Blob Storage, OneLake, and Cosmos DB as examples, with source access and security handled through the configured integration.
Change tracking makes the pipeline incremental: it processes changed data rather than reprocessing the entire collection for every update. After source access, the pipeline proceeds through file extraction, chunking, vectorization, and indexing. PDFs, Office documents, images, and nested formats become inputs to the same sequence.
The intended operating model is to configure the pipeline once and keep the index following the source as it changes. In practice, this applies to supported sources with configured indexers and skills; scheduled runs collect changes and retry work, rather than providing instantaneous synchronization of arbitrary Azure data. This shifts application effort toward retrieval queries and RAG orchestration instead of repeated ingestion plumbing.
Castro closes by inviting developers to try AI Search, pointing to a starting page and a free search instance available through an Azure subscription. That is a way to explore indexing and retrieval; it is not a promise that every embedding, enrichment, or generation component in a complete RAG application is free.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
Further reading
A 2023 evaluation of keyword, Ada-002 vector, hybrid and semantic reranking configurations, with datasets and measurement methodology.
The historical announcement increasing file-search capacity from 20 to 10,000 files per assistant.
Cohere's March 2024 introduction of native int8 and binary embedding representations.
Updates since the talk
Current guidance for combining text and vector queries with reciprocal rank fusion.
Current configuration guidance for scalar and binary quantization, oversampling and rescoring.
How indexers, chunking skills, embedding models and query vectorizers form a managed ingestion pipeline.
Read the complete timestamped transcript
- 0:00
[upbeat music] All right, let's get started. Hi, everyone. Thanks for coming.
- 0:16
Uh, I'm Pablo. I work in the Azure AI team at Microsoft. Um, and in this session, we'll talk about, uh, RAG at scale. Uh, and in particular, I'll focus on the retrieval portion of, of the RAG pattern.
- 0:29
The plan for, for this session is, uh, we'll do a quick recap, just make sure that we all have the s- we're, uh, use the same terms for the same things.
- 0:36
Uh, and then I'll go through kind of different dimensions of scale, and I'll comment a little bit on how do we tackle this in the context of AI search, what we've learned from doing this, and what are we doing to make it easier, uh, to scale these applications.
- 0:52
So kind of as a... By u-by means of a quick recap, when it comes to bringing your own domain knowledge, uh, to work together with, with language models, you effectively you have three options.
- 1:03
Either you, you can do, um, uh, prompt engineering. And, you know, while it's easy to dismiss, you can go a long way with, uh, prompt engineering along, especially these days, you know, models have longer co-longer context and whatnot.
- 1:16
Um, if, if that's not enough, sometimes the challenge is more along the lines of I wanna teach, uh, particular patterns o-of, or, or I want the model to learn jargon of some, in some particular vertical domain and things like that.
- 1:28
And for that, fine-tuning is often a good option.
- 1:32
However, in many, many of these cases, what I want is to have the model work over a set of data that the model didn't see during training. This could be my application data, my company data, company about the information about my users or anything like that.
- 1:45
And for that, the, the, uh, prevailing pattern right now is to use retrieval-augmented generation. Effectively, uh, what that means is if what-- if you want the model to know facts, then what you do is you kind of separate the reasoning piece of the picture from the knowledge piece of the picture.
- 2:01
You lean on the language model for the reasoning capabilities, and you lean on the use an external knowledge base to model what you know about a particular domain, the data that you have.
- 2:10
And you-- And the way you glue them together is, like, in principle, mechanically very simple. Of course, then it gets complicated because, you know, life is never that easy.
- 2:18
But in principle, uh, you have some orchestration component that, uh, you know, takes the task, uh, at hand. Let's say you have a chat application, and then the user takes a turn and asks, asks the next, uh, question.
- 2:29
Um, uh, the orchestration component hits some knowledge base, uh, seeking for pieces of information that could be used to produce an answer, uh, to this question and then grabs a bunch of candidates, and then you go to the language model and then give it a bunch of instructions, your candidates, uh, and ask the model to produce, uh,
- 2:46
like an answer to the, to the user question. That's kind of the essence o-of the pattern. We all know that in practice, it usually takes multiple goes, and there is a lot of tuning in the middle and, and whatnot, but the fundamentals boil down to that.
- 2:58
Um, so, uh, just by, by way of context, like, how many of you are doing, are creating and working on RAG applications today?
- 3:06
Everyone. Okay. Excellent. Um, so with that backdrop, what I wanted to do is talk about what are the pressure points when it-when you scale these applications. One, one thing that has been fascinating to see is, you know, we had, we had the opportunity to be involved in this space, uh, from very early, like Azure OpenAI has been
- 3:25
there from, you know, the early days of scaled language models. And one thing we saw was all of, I'd say last year, twenty twenty-three, everybody built a prototype of something to kind of learn and figure out what could be done with this technology.
- 3:38
Um, and, uh, the interesting shift to this year, to twenty twenty-four, it's been these applications are going to production. And when you go to production, you go from, "Oh, this demo is really cool," to all these users are, are, you know, are using it at the same time, and they want more.
- 3:51
They want more data. They want, uh, more, uh, faster answers and, and whatnot. Um, so the result of that is that, you know, when before we could focus only on figuring out the interaction model and the applicability of this technology, now, you know, elements of scale also, also play a role.
- 4:08
Uh, and scale can-- takes multiple kind of, uh, flavors. Like you-- These thing-things tend to scale in volume because one of the things that happens is when your application works well, users come back or the leadership of the organization come back, comes back and says, "Let's put all the data there."
- 4:22
Uh, and then you have to deal with it. Um, uh, the, also the rate of change of the data kind of increases, uh, and the query load increases as well because, you know, more people are using the stuff.
- 4:32
Um, also workflows tend to get more complicated. At first you go like, "Oh, like how complicated it can be? I'll take the question, search the thing, and then send it to the model."
- 4:41
Well, it turns out that, that sometimes it works, but often it doesn't. So you end up doing these multi-step workflows that hit the retrieval system and the language model multiple times, um, and that taxes all the systems and they all have to scale.
- 4:54
Also in, in the kind of, in the spirit of now let's put all the data there, now you have to deal with more, uh, more data types, different kinds, different data sources and whatnot.
- 5:04
Um, so, um, let's cover each, each of these dimensions of scale, um, in detail. And what, what I'll do is I'll cover it in the context of Azure AI Search.
- 5:13
That-that's what I, what I work mostly, uh, and, uh, because it's, you know, the way we think about this in Azure is we want to produce a system that is, that encompasses entire retrieval problem.
- 5:23
Uh, it's of course it has this kind of vector database capabilities. The, uh, vector-based retrieval emerged as a very, uh, useful solution in many contexts. So, uh, we have full support for that.
- 5:35
But we also brought into it like, uh, years and years of Microsoft experience in, in retrieval systems in the more general sense. Um, and, uh, we integrate them together so you don't have to connect a bunch of parts, uh, to have a proper, uh, high-quality retrieval system.
- 5:49
It all comes integrated. And of course, you know, we integrate it into the rest of Azure, so it's easy to pull data in, to connect to the other data sources and whatnot.
- 5:57
Um, and, you know, Azure is, is a place that is used to build some of the largest applications out there. So all the kind of enterprise readiness comes pre-built in, you know, from security to compliance to all these things that you don't wanna deal with directly.
- 6:10
You wanna kinda build on a platform that is already taken care of.
- 6:14
So while there are multiple moving parts to retrieval systems, what we've seen the last, uh, I don't know, eighteen months or so since the emergence of, uh, kind of RAG, uh, patterns at scale is, uh, vector retrieval is an important part of the solution.
- 6:29
And, you know, you, you can see why. Like, the interesting part about vector retrieval is, like, it's incredibly effective at getting this kind of soft conceptual similarity, uh, and, uh, put it to work right away.
- 6:39
So in Azure AI Search, we built a system that has kind of complete, uh, a complete feature set when it comes to, uh, vector search, including, uh, a pr-fast approximate nearest neighbor search, uh, and a-as well as also exhaustive search.
- 6:52
Sometimes you want precise search either to create baselines, uh, to know how kind of your recall performance is looking and things like that. Um, also, often applications need to combine, uh, vector search with the rest of the queries.
- 7:04
You need to filter, uh, filter things. You need to, uh, slice and dice, like, you know, filter, select the columns you want to project and things like that. Like effectively treat it like a database that also does retrieval.
- 7:13
Um, and we also see multiple scenarios where the documents have multiple queries, maybe for different parts of the content or for different data types that use different embeddings. Um, and, uh, and sometimes the queries need multiple vectors.
- 7:25
So we try to make it, uh, as these, all these specific needs come up as you're building an application, you'll find answers to all of them directly in, in Azure Search.
- 7:33
Let me show you this in action. Um, so let me start with a very simple example. So what I'll do is, uh, I'll-- I'm just here, I have a sm-small, uh, Jupyter notebook, uh, and what I'll do is I'll connect to, um,
- 7:49
uh, I can set up a default credential point at my Azure Search service, and I'll create an index from scratch. So this is all, like, all it takes to, to create an index once you have a service provisioned.
- 7:59
So in this case, I create a few fields. I create a categorical field, like this serves as metadata that you want sometimes to attach, to be attached to, to this.
- 8:07
I create a text field. Sometimes you want to mix text and vectors. Um, and I'll talk a little bit more about this later. And I create a vector field.
- 8:15
In, in this case, this is a toy example, so dimension is three. Of course, that's not very useful. You know, in practic- in practice, this is gonna be in the hundreds or maybe thousands of dimensions.
- 8:24
I'll also say what strategy you want the system to use for vector search. In this case, I'm using HNSW, which is a well-known, um, uh, graph-based algorithm for,
- 8:34
um, for indexing vectors. So when I run this, and I hope, uh, the, like the network was a little wonky, so, oh, there. Perfect. Um, so now I have an index.
- 8:42
I'm gonna get a, kind of a client to it, and then I'm gonna index data. And you can see here, this is a very simple case. These are my vectors.
- 8:48
Um, this is my full text, and these are my cat-- these are my categorical data bits. So you can let us do all the ingestion for you, or you can push data into the index.
- 8:57
In this case, I'm pushing data explicitly into the index. And once you have data, uh, if you look at here, like we have some vectors and we have some categories.
- 9:05
So you can, first you can just search. And because it's, in this case, I'm indexing vectors, when you search, you search with a vector. Uh, so I can, I can search for that and say these are the two closest to the reference vector that I gave.
- 9:17
And I can do, uh, um, a few, a few things, uh, kind of incrementally. Like for example, if I wanna combine text and keyword search, I can also, uh, search text right here.
- 9:27
Uh, I'm gonna go hello. Uh, and now I'm searching for both, uh, the, the text and the vectors, and then we fuse the result and rank appropriately. Um, and, and often in applications, you also need to filter stuff.
- 9:39
You can see here I have A's and B's in categories. So I can, I can, like, write filters. Uh, for example, here I'll say category equals A.
- 9:49
Uh, and then, you know, I only get the A's. Uh, and, uh, this is a trivial example, but of course, you can do full filter expressions and ands and ors and, and, uh, uh, ranges and, and whatnot.
- 9:58
And the filters are fast. So, so even if you have, um, hundreds of millions of documents, these are not a problem.
- 10:05
So in, in that one, if you had, uh, k-nearest neighbors, k-nearest neighbors equals two, how come they had three results?
- 10:12
Oh, because, uh, great question. Because, so what I, what I was telling this, the, the system here is from the vectors retrieve two candidates. But then I was like, I also told it, "Go to the keyword side and retrieve a bunch of candidates from there and then fuse them."
- 10:26
Uh, so only two of them were from vectors, but the fuse, the fusion of the two, uh, selected three. I actually, like if I, um, I can make this a larger number, and that sometimes is useful, um, to get more candidates.
- 10:40
And then still I can say, uh, as a result of that, get the keyword ones too and then rank the top N. So basically separate how many candidates you want from how many you wanna return.
- 10:54
So, so as, those are the basics of a vector engine, but there are a few, uh, key elements to, to consider when you're actually building an application in production.
- 11:01
The probably the most se- the most salient one is quality. Like in the end, the, your application works well for your users when they ask a question and they get the answer they're looking for.
- 11:10
And that is highly, highly influenced by whether your retrieval system actually found the, uh, the bits of information that you wanted, uh, that, that you wanted to produce that answer.
- 11:19
Um, in, in AI search, the way we do this is we do, um, what kind of most, uh, kind of more sophisticated search engines do that where you use a two-stage retrieval system.
- 11:28
First stage is recall-oriented and uses vectors and keywords and kind of all these recall-oriented tricks to produce as many candidates as we can find. And then the second stage re-ranks those candidates using like a, um, a, like a larger model that you maybe, let's say you have a hundred million, uh, vectors in your database.
- 11:46
Uh, you, you wanna use something fast to go from a hundred million to a small set. But then once you have a small set, you can afford to lar- run a larger, more sophisticated language, um, sorry, um, ranking model, uh, to create better quality ranking.
- 11:59
So that's what we're doing in the L2 stage. Uh, so when you turn this on, you effectively get better results. And, uh, what you can see here, there is a link at the bottom, happy to share it later, uh, with more details on the numbers.
- 12:09
But you can see that, um, so from the left, this is what you get when you just do keyword search using BM25. It's a well-known scoring approach. Second one is only vectors using Ada, uh, OpenAI Ada vectors.
- 12:21
Third one is using fusion, combined vectors and keywords. And the fourth one is using fusion plus, uh, re-ranking, um, re-ranking step, where across the board we see better results just out of the box when, uh, when re-ranking is enabled.
- 12:34
Yes.
- 12:35
So the re-ranking is the semantic re-ranking. Is that Is that another cosine similarity style thing, or how does that actually work?
- 12:43
Oh, great, great question. The question is, is it a cosine similarity thing? No. So the, the thing, bind coders are useful when, uh... because you can do-- you can encode all your documents as vectors and then the query as a vector.
- 12:54
Um, and then you can evaluate them fast because you are only comparing similarity. But that means that at no point the model sees the, the vec-- the document and the query at the same time.
- 13:02
So the re-ranker is, uh, these type of rankers are often called cross-encoders. And, uh, these are transformer models that you feed them the document and the query, and you ask them to predict a label of the correspondence of the query to the document.
- 13:16
So they are much better positioned to produce a high quality result. Uh, but they are, they're, they're, they're... At, at inference time, or rather at query time, you're running an inference step.
- 13:26
So, um, you can do it only on a smaller set. You couldn't do it on the entire data set. It wouldn't be practical. Uh, at least not for interactive performance applications.
- 13:34
And speed?
- 13:36
Speed?
- 13:37
Yeah.
- 13:37
Uh, this is like a hundred milliseconds, give or take, for a model like this. Depends on the cross-encoder that you, that you use. Ours, our trade-off between, you know, make it fast enough but make it very high quality, we landed on a hundred milliseconds ballpark.
- 13:49
Um, uh, and we found that that works well in terms of interactive performance because the majority of the latency ends up hidden on the LLM call. Uh, uh, and you still get very high quality results.
- 14:01
Um, the other thing, I won't drill into this, but, uh, often, uh, one second. Often the other dimension of getting quality out of the system is to narrow the data set.
- 14:10
If you know discrete, um, metadata elements that can help you narrow the data set, that's the most effective way. Uh, then do all the ranking tricks on top of the resulting set.
- 14:19
But, uh, first, uh, scoping is a, is a very effective way to, uh, to get quality up. Yes, question.
- 14:25
So my question is, do you, uh, extract the keyword from the prompt, or like how do you set the keyword?
- 14:31
The, for the keyword part of keyword search?
- 14:33
Yeah.
- 14:33
Oh. So if you look at, um... Let me show you this example. So if you look at what I did here, is, uh, you give us keywords, you give us text-
- 14:42
Yeah
- 14:42
... and then you give us a vector as well. Or you just give us the text, and we'll turn it into a vector too. Uh, so we need the original text.
- 14:48
The vector alone is not enough because we can't go back to a keyword.
- 14:52
No. So, I mean, if you have a RAG application, let's say you have a chat bot.
- 14:55
Yeah.
- 14:55
How can you know how to find what kind of keywords could be relevant, let's say, to the prompt that the user is giving?
- 15:01
Oh. So, um, u-usually in a RAG app, w- the question is, what of the conversation so far do you wanna use for search? Is that, is that the question?
- 15:10
No, like I understand, but my question is, so if you wanna use... Because in your method you showed that the fused search-
- 15:16
Yeah
- 15:17
... plus
- 15:18
Yeah
- 15:18
... uh, prompt. So how, how do you... Like for vector search it's easy, right? You vectorize the prompt and then search.
- 15:25
Yeah.
- 15:26
But if you wanna like search and vector fuse-
- 15:28
Yeah
- 15:29
... is there a way you can extract like from the user's element to, uh, extract the potential keywords for you to search? Because you cannot pre fix those keywords for every potential chat or, or prompt that the user can have.
- 15:45
Yeah, I... Maybe we should talk after the talk because I'm not sure I understand the question. Like usually, like you, in the index you have the se- the text and the vectors.
- 15:53
Uh, and then from the user, you extract a candidate search for, for that. This is before you send it to the LLM. Uh, but maybe we should chat right after the talk on the details.
- 16:02
Um, so let me go back here. So the, the other dimension of scaling is, um, is, uh, just, just how many vectors and how much content you can fit in one of your indexes.
- 16:16
Uh, and, uh, for that, in, in AI search, like one thing we learned last year, uh, or in the beginning of this year, is that it went from everybody had tiny indexes to everybody put all their data in these systems.
- 16:26
Uh, so we re- we, uh, accommodated for that by significantly increasing the limits. Like for most of the ser- services, uh, you'll get anywhere ten, between ten and twelve times the vector density on, on the same SKUs, and we didn't change prices or anything, just so you can build larger applications on the same setup.
- 16:42
With these new limits, you can build multi-billion vector apps by just provisioning a service and uploading the data. And it's surprisingly straightforward. Like, you know, a year ago, the billion dataset vectors was the thing...
- 16:53
It was a curiosity used for, uh, for benchmarking. And now you can just create an index and upload them, which is very impressive to, to see. Um, I'm not gonna drain the slide.
- 17:01
I put it here for reference. Uh, these are kind of all the new limits that, uh, that we have, are significantly higher than the, than the ones we had before.
- 17:10
Um, one of the things that has been exciting for us to watch, uh, to watch grow is, uh, you know, among our customers, one of them is OpenAI themselves, uh, where they have a lot of RAG workloads, like when you have files in ChatGPT or when you use the Assistance API.
- 17:24
All of those, you can create these vector stores inside their system and, uh, all of those are backed by AI search. Uh, and when we increased these limits, um, one of the things they did is they increased the limits they give to their users by five hundred times.
- 17:37
Um, so, uh, it's been impressive to see how fast they grow, and it's been fun to kind of see, uh, kind of first, um, uh, from up close how a system can scale at, at like this big and, uh, and still be fast and responsive and whatnot.
- 17:52
Um, so finally, the, the other thing you can do is sometimes the limits, higher limits are enough. Sometimes you wanna push even more data into it. So the other thing we've been working on is quantization, where we, we...
- 18:04
you can use narrower types. Like instead of using full floats, you can use ints, uh, like int eights. Uh, and they just simply use less space at the trade-off for a little bit of quality.
- 18:14
Uh, and interestingly, you can even do single-bit quantization. And I confess that when people said, "Hey, like we're gonna do metrics for single bit," I felt people were wasting their time.
- 18:23
Uh, but it actually works. Uh, it works surprisingly well. Our evaluations show that they are still, for some models, in the mid, uh, low to mid ninety percents of the original performance.
- 18:34
And other companies have seen the same thing. Like for example, this is an evaluation from Cohere, but separate company. Um, and they also see like about almost ninety-five percent of the original precision is preserved.
- 18:44
When, uh, when using bit encoding. And you can get the precision, remaining precision back by re-ranking, uh, when you're done. So surprising that it works, but you go for float thirty-two to one bit.
- 18:54
That's thirty-two x the vector density. Um, and it's faster because you just do Hamming distance mu-much faster than computing on a small number of... a smaller number of bits instead of cosine similarity or something like that on a wider, wider set.
- 19:08
So because of this, we now support all these types in AI Search as well.
- 19:13
Um, uh, I'm gonna skip this slide in the interest of time. Um, so and, uh, you can do quantization yourself, or you can just enable it, and we will do quantization, uh, for you.
- 19:23
And, uh, if we do quantization for you, we will also store the original, uh, precision data there, which means we can do oversampling, where we query at the quantized kind of compressed, uh, version of the vectors, but we have the full precision stored, stashed as, on the side.
- 19:39
Uh, so later, we can re-rank at full precision. Uh, and, uh, so you can effectively choose between you want a highly compressed, uh, index that is, uh, a little lower quality, but, but, but larger, or it's a little slower but larger.
- 19:53
Uh, or you just don't compress it, and then you get the quality up. So effectively, you can choose any of the three, uh, and it's effectively up to you, uh, what you wanna prioritize.
- 20:01
But we give you control for all three dimensions.
- 20:05
And then the last thing I wanted to, uh, touch on is the, the other challenge is you have to keep adding data sources that you bring into these RAG systems.
- 20:14
Um, and, uh, each of them, you connect to them differently, you enumerate changes differently, um, and, uh, that's, that's just not where you wanna spend your time. Um, so we have this ingestion system that includes integrated vectorization as part of AI Search, where if the data is in Azure, whether it's in Blob Storage or OneLake or Cosmos
- 20:32
DB, we will connect, deal with all the security and all of that. We will automatically track changes, so it's not a one-shot thing. But as, as the data changes, we'll pick up only the changes and will only in process the changes, so the cost is also incremental.
- 20:45
You don't pay as you update the stuff for the entire set. Uh, and then we'll deal with all file formats, you know, PDFs, Office documents, images, un-unpack the nested formats and whatnot.
- 20:55
Do chunking, do vectorization, and land it on an index all in one go. And this is a, like, industrial strength pipeline that you set up once, and then it continuously runs, uh, af-after that.
- 21:04
As your data changes, your, it reflects the changes. So you can focus on the RAG stack, you know, the workflow, how you query the system, but you don't have to think about how the data makes it there.
- 21:13
If the data is anywhere in Azure, we'll index it and create, like, an index that follows the original data automatically.
- 21:21
All right. And, and with that, uh, I know I raced through this content in these twenty minutes. I'll be hanging out outside if anybody wants to chat or have questions.
- 21:29
Um, and I would encourage you to go try AI Search today. Here's a link to the starting point. Um, uh, and Azure subscriptions include a, include a free instance of AI Search, so you can even give it a shot in a minute without, uh, without having to pay for any of this stuff.
- 21:43
With that, thank you. [clapping] [upbeat music]