Home > Docs > Features > Eventhouse Vector Database
🧬 Eventhouse as a Vector Database - AI-Powered Semantic Search¶
Unlock AI/ML Scenarios with Vector Search in Real-Time Intelligence
Last Updated: 2026-04-13 | Version: 1.0.0
📑 Table of Contents¶
- 🎯 Overview
- 🏗️ Architecture
- ⚙️ Setup and Configuration
- 🔍 Vector Operations in KQL
- 📝 AI Embed Text Plugin
- 💬 AI Chat Completion Plugin
- 🎰 Casino Compliance Document Search
- 🏛️ Federal Policy RAG
- 🤖 Integration with Data Agents
- ⚡ Performance Tuning
- ⚠️ Limitations
- 📚 References
🎯 Overview¶
Microsoft Fabric's Eventhouse — the core engine behind Real-Time Intelligence — can function as a vector database for AI and machine learning scenarios. By combining KQL's powerful analytical capabilities with vector storage, embedding generation, and similarity search, Eventhouse enables Retrieval-Augmented Generation (RAG), semantic search, and AI-powered analytics directly within the Fabric ecosystem.
Key Capabilities¶
| Capability | Description |
|---|---|
| Vector16 Encoding | Compact 16-bit floating-point vector storage that reduces memory footprint by 50% compared to float32 |
| AI Embed Text Plugin | Generate text embeddings directly within KQL queries using Azure OpenAI models |
| AI Chat Completion Plugin | Invoke Azure OpenAI chat completions from KQL, enabling RAG patterns over Eventhouse data |
| Cosine Similarity Search | Native series_cosine_similarity() function for efficient vector comparison |
| Hybrid Search | Combine vector similarity with structured KQL filters for precise, context-aware retrieval |
| Data Agent Integration | Vector search powers Data Agent responses with grounded, factual context from your data |
Why Eventhouse for Vector Search?¶
Traditional vector databases are standalone systems that require separate infrastructure, ETL pipelines, and operational overhead. Eventhouse eliminates this complexity by embedding vector capabilities directly into the real-time analytics engine you're already using:
Traditional Approach: Fabric Eventhouse Approach:
───────────────────── ──────────────────────────
Source Data Source Data
↓ ↓
ETL Pipeline → Vector DB (Pinecone, Eventstream → Eventhouse
Weaviate, Qdrant) (vectors + structured data
↓ in one engine)
Separate Query Layer ↓
↓ KQL Queries
Application (vector + analytical
↓ in one query)
Maintain 2+ systems ↓
Data Agents, Power BI,
Notebooks — all integrated
How Eventhouse Vector Fits in the Fabric Stack¶
flowchart TB
subgraph Sources["📄 Document Sources"]
CTR["📋 CTR/SAR Filings"]
POL["📜 Policy Documents"]
LOG["📝 Audit Logs"]
REG["⚖️ Regulations"]
end
subgraph Embedding["🧠 Embedding Layer"]
AOAI["Azure OpenAI<br/>text-embedding-3-small"]
EMB["AI Embed Text<br/>Plugin"]
end
subgraph Eventhouse["⚡ Eventhouse"]
VEC["Vector16 Columns<br/>(Encoded Embeddings)"]
STR["Structured Columns<br/>(Metadata, Dates, Tags)"]
IDX["Vector Index<br/>(Optimized for Cosine)"]
end
subgraph Search["🔍 Search & RAG"]
SIM["Similarity Search<br/>series_cosine_similarity()"]
HYB["Hybrid Search<br/>Vector + KQL Filters"]
RAG["RAG Pipeline<br/>Retrieve → Generate"]
end
subgraph Consumers["👤 Consumers"]
AGT["🤖 Data Agents"]
NB["📓 Notebooks"]
APP["🔌 Applications"]
IQ["🧠 Fabric IQ"]
end
Sources --> Embedding --> Eventhouse
Eventhouse --> Search --> Consumers
style Sources fill:#2471A3,stroke:#1A5276,color:#fff
style Embedding fill:#6C3483,stroke:#4A235A,color:#fff
style Eventhouse fill:#E67E22,stroke:#CA6F1E,color:#fff
style Search fill:#6C3483,stroke:#4A235A,color:#fff
style Consumers fill:#27AE60,stroke:#1E8449,color:#fff 🏗️ Architecture¶
The Eventhouse vector database architecture has three primary layers: ingestion and embedding, storage and indexing, and search and retrieval. Each layer integrates natively with the Fabric ecosystem.
End-to-End Vector Pipeline¶
flowchart LR
subgraph Ingest["📥 Ingestion"]
DOC["Raw Documents<br/>(Text, PDF, JSON)"]
CHUNK["Chunking<br/>(Split into segments)"]
META["Metadata Extraction<br/>(Author, Date, Type)"]
end
subgraph Embed["🧠 Embedding"]
AOAI["Azure OpenAI<br/>Embedding Model"]
V16["Vector16 Encoding<br/>(float32 → float16)"]
end
subgraph Store["💾 Storage"]
TBL["KQL Table<br/>(text + vector + metadata)"]
POL2["Encoding Policy<br/>(Vector16)"]
CACHE["Hot Cache<br/>(Frequently Accessed)"]
end
subgraph Query["🔍 Query"]
EMB2["Query Embedding<br/>(User input → vector)"]
COS["Cosine Similarity<br/>series_cosine_similarity()"]
FILT["KQL Filters<br/>(Date, Type, Tag)"]
TOP["Top-K Results<br/>(Ranked by similarity)"]
end
subgraph Gen["💬 Generation"]
CTX["Context Assembly<br/>(Top-K documents)"]
CHAT["AI Chat Completion<br/>Plugin"]
RESP["Grounded Response<br/>(With citations)"]
end
Ingest --> Embed --> Store
Store --> Query --> Gen
style Ingest fill:#2471A3,stroke:#1A5276,color:#fff
style Embed fill:#6C3483,stroke:#4A235A,color:#fff
style Store fill:#E67E22,stroke:#CA6F1E,color:#fff
style Query fill:#6C3483,stroke:#4A235A,color:#fff
style Gen fill:#27AE60,stroke:#1E8449,color:#fff Storage Architecture¶
Eventhouse stores vectors alongside structured data in the same table, eliminating the need for cross-system joins:
KQL Table: compliance_document_vectors
┌──────────────┬────────────────┬──────────┬──────────────────┬───────────────┐
│ document_id │ document_text │ doc_type │ embedding │ filing_date │
│ (string) │ (string) │ (string) │ (dynamic/vec16) │ (datetime) │
├──────────────┼────────────────┼──────────┼──────────────────┼───────────────┤
│ CTR-2026-001 │ "Transaction │ CTR │ [0.012, -0.034, │ 2026-03-15 │
│ │ of $15,000..."│ │ 0.089, ...] │ │
├──────────────┼────────────────┼──────────┼──────────────────┼───────────────┤
│ SAR-2026-042 │ "Multiple txns │ SAR │ [-0.045, 0.023, │ 2026-03-14 │
│ │ $9,500 each.."│ │ 0.067, ...] │ │
└──────────────┴────────────────┴──────────┴──────────────────┴───────────────┘
Vector16 Encoding¶
Vector16 is an encoding policy that compresses float32 embedding vectors to float16, halving storage and memory usage with minimal accuracy loss:
| Aspect | float32 | Vector16 (float16) | Savings |
|---|---|---|---|
| Storage per dimension | 4 bytes | 2 bytes | 50% |
| 1536-dim vector size | 6,144 bytes | 3,072 bytes | 50% |
| 1M vectors (1536-dim) | ~5.7 GB | ~2.9 GB | ~2.8 GB |
| Similarity accuracy | Baseline | 99.7% correlation | 0.3% loss |
💡 Tip: The 0.3% accuracy loss from Vector16 encoding is imperceptible in practice. For all but the most precision-sensitive scientific applications, Vector16 provides the optimal balance of accuracy and efficiency.
⚙️ Setup and Configuration¶
Prerequisites¶
| Requirement | Details |
|---|---|
| Fabric Capacity | F2 or higher with Real-Time Intelligence enabled |
| Eventhouse | At least one Eventhouse created in your workspace |
| Azure OpenAI | Azure OpenAI resource with text-embedding-3-small or text-embedding-3-large deployed |
| Managed Identity | Fabric workspace managed identity with access to the Azure OpenAI resource |
| Tenant Setting | AI features enabled in the Fabric Admin Portal |
Step 1: Create the KQL Database and Table¶
Create a table in your Eventhouse KQL database with columns for text content, metadata, and the embedding vector:
// Create a table for document vectors
.create table DocumentVectors (
document_id: string,
document_text: string,
document_type: string,
source_system: string,
tags: dynamic,
created_date: datetime,
embedding: dynamic
)
Step 2: Configure Vector16 Encoding Policy¶
Apply the Vector16 encoding policy to the embedding column to enable compressed vector storage:
// Apply Vector16 encoding policy to the embedding column
.alter column DocumentVectors.embedding policy encoding
type = 'Vector16'
Verify the encoding policy is applied:
Step 3: Configure Azure OpenAI Connection¶
Set up the connection to your Azure OpenAI resource for embedding generation:
// Create an external connection to Azure OpenAI
.create-or-alter function with (
docstring = "Generate embeddings using Azure OpenAI",
skipvalidation = "true"
) GenerateEmbedding(text: string) {
let endpoint = 'https://your-aoai-resource.openai.azure.com';
let deployment = 'text-embedding-3-small';
let result = evaluate ai_embed_text(text, endpoint, deployment);
result
}
⚠️ Security Note: Use managed identity authentication for the Azure OpenAI connection. Never embed API keys in KQL functions. Configure the managed identity through the Fabric workspace settings.
Step 4: Ingest Documents with Embeddings¶
Ingest documents and generate embeddings in a single pipeline:
# Python notebook: Ingest documents and generate embeddings
import requests
import json
from azure.identity import DefaultAzureCredential
# Azure OpenAI configuration
AOAI_ENDPOINT = "https://your-aoai-resource.openai.azure.com"
AOAI_DEPLOYMENT = "text-embedding-3-small"
credential = DefaultAzureCredential()
def generate_embedding(text: str) -> list[float]:
"""Generate embedding vector for a text string."""
token = credential.get_token("https://cognitiveservices.azure.com/.default")
headers = {
"Authorization": f"Bearer {token.token}",
"Content-Type": "application/json"
}
payload = {"input": text, "model": AOAI_DEPLOYMENT}
response = requests.post(
f"{AOAI_ENDPOINT}/openai/deployments/{AOAI_DEPLOYMENT}/embeddings"
"?api-version=2024-02-01",
headers=headers,
json=payload
)
return response.json()["data"][0]["embedding"]
# Example: Embed compliance documents
documents = [
{
"document_id": "CTR-2026-001",
"document_text": "Currency Transaction Report for cash-in of $15,000 at "
"cage window 3. Patron presented valid ID. Transaction "
"completed at 14:32 UTC.",
"document_type": "CTR",
"source_system": "ComplianceDB",
"tags": ["cash", "cage", "threshold"],
"created_date": "2026-03-15T14:32:00Z"
},
# ... more documents
]
for doc in documents:
doc["embedding"] = generate_embedding(doc["document_text"])
# Ingest into Eventhouse via Kusto SDK
from azure.kusto.data import KustoClient, KustoConnectionStringBuilder
from azure.kusto.ingest import QueuedIngestClient, IngestionProperties
# ... ingest using Kusto SDK
Step 5: Validate the Setup¶
Confirm vectors are stored and searchable:
// Check table row count and embedding dimensions
DocumentVectors
| take 1
| project document_id, document_type, EmbeddingDimensions = array_length(embedding)
// Verify Vector16 encoding is active
DocumentVectors
| take 5
| project document_id, document_type,
EmbeddingLength = array_length(embedding),
FirstDims = array_slice(embedding, 0, 4)
🔍 Vector Operations in KQL¶
series_cosine_similarity() Function¶
The series_cosine_similarity() function is the core KQL primitive for vector search. It computes the cosine similarity between two numeric arrays (vectors), returning a value between -1 and 1 where 1 indicates identical direction:
// Basic cosine similarity between two vectors
print similarity = series_cosine_similarity(
dynamic([0.1, 0.2, 0.3, 0.4]),
dynamic([0.1, 0.2, 0.3, 0.5])
)
// Output: ~0.9936
Similarity Search Pattern¶
The standard pattern for similarity search in Eventhouse:
// Find the top 10 most similar documents to a query
let query_embedding = dynamic([0.012, -0.034, 0.089, ...]); // Pre-computed query vector
DocumentVectors
| extend similarity = series_cosine_similarity(embedding, query_embedding)
| top 10 by similarity desc
| project document_id, document_text, document_type, similarity, created_date
Hybrid Search: Vector + Text Filters¶
Combine vector similarity with structured KQL filters for precise, context-aware retrieval:
// Hybrid search: Vector similarity + document type + date range
let query_embedding = dynamic([0.012, -0.034, 0.089, ...]);
DocumentVectors
| where document_type == "SAR"
| where created_date >= ago(90d)
| extend similarity = series_cosine_similarity(embedding, query_embedding)
| top 10 by similarity desc
| project document_id, document_text, similarity, created_date
Multi-Filter Hybrid Search¶
// Complex hybrid: Vector + multiple structured filters + tag matching
let query_embedding = dynamic([0.012, -0.034, 0.089, ...]);
let target_tags = dynamic(["structuring", "cash", "suspicious"]);
DocumentVectors
| where document_type in ("SAR", "CTR")
| where created_date between (datetime(2026-01-01) .. datetime(2026-03-31))
| where tags has_any (target_tags)
| extend similarity = series_cosine_similarity(embedding, query_embedding)
| where similarity > 0.75 // Minimum similarity threshold
| top 20 by similarity desc
| project
document_id,
document_text = substring(document_text, 0, 200),
document_type,
similarity = round(similarity, 4),
matched_tags = set_intersect(tags, target_tags),
created_date
Top-K Retrieval Patterns¶
| Pattern | KQL | Use Case |
|---|---|---|
| Simple Top-K | | top K by similarity desc | Basic similarity search |
| Threshold + Top-K | | where similarity > 0.7 | top K by ... | Quality-filtered results |
| Grouped Top-K | | partition by doc_type (top K by ...) | Best match per category |
| Diverse Top-K | | summarize arg_max(similarity, *) by cluster_id | Diverse result set |
Batch Similarity Computation¶
For scenarios that require comparing a query against different document subsets:
// Compare query against documents grouped by type
let query_embedding = dynamic([0.012, -0.034, 0.089, ...]);
DocumentVectors
| extend similarity = series_cosine_similarity(embedding, query_embedding)
| summarize
avg_similarity = avg(similarity),
max_similarity = max(similarity),
doc_count = count()
by document_type
| order by max_similarity desc
📝 AI Embed Text Plugin¶
The ai_embed_text() plugin generates text embeddings directly within KQL queries, eliminating the need for external embedding pipelines for ad-hoc queries and small-batch operations.
Plugin Syntax¶
// Generate an embedding for a query string
evaluate ai_embed_text(
'Find all reports about cash structuring patterns',
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
)
Inline Embedding + Search (Single Query)¶
The most powerful pattern: embed the user's query and search in a single KQL statement:
// End-to-end: Embed query → Search → Return results
let query_text = 'transactions that appear to be structuring to avoid CTR';
let query_result = evaluate ai_embed_text(
query_text,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
);
let query_vector = toscalar(query_result | project embedding);
DocumentVectors
| extend similarity = series_cosine_similarity(embedding, query_vector)
| top 10 by similarity desc
| project document_id, document_type, similarity,
preview = substring(document_text, 0, 300)
Batch Embedding Patterns¶
For bulk embedding of existing data, process in batches to manage Azure OpenAI rate limits:
// Batch embed unprocessed documents
// Step 1: Identify documents missing embeddings
let unembedded = DocumentVectors
| where isnull(embedding) or array_length(embedding) == 0
| take 100; // Process 100 at a time
// Step 2: Generate embeddings (via notebook or pipeline)
// Step 3: Update with .set-or-append
# Python batch embedding for large document sets
import asyncio
from openai import AsyncAzureOpenAI
client = AsyncAzureOpenAI(
azure_endpoint="https://your-aoai-resource.openai.azure.com",
api_version="2024-02-01",
azure_ad_token_provider=get_token_provider()
)
async def batch_embed(texts: list[str], batch_size: int = 100) -> list[list[float]]:
"""Generate embeddings in batches with rate limit handling."""
all_embeddings = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
response = await client.embeddings.create(
input=batch,
model="text-embedding-3-small"
)
all_embeddings.extend([item.embedding for item in response.data])
await asyncio.sleep(0.5) # Rate limit buffer
return all_embeddings
Cost Management¶
| Model | Dimensions | Cost per 1M Tokens | Recommended For |
|---|---|---|---|
text-embedding-3-small | 1536 | ~$0.02 | General-purpose, cost-effective |
text-embedding-3-large | 3072 | ~$0.13 | High-accuracy requirements |
text-embedding-ada-002 | 1536 | ~$0.10 | Legacy compatibility |
💡 Tip: Use
text-embedding-3-smallfor most scenarios. Its cost-to-accuracy ratio is optimal for document search, compliance lookups, and RAG patterns. Reservetext-embedding-3-largefor precision-sensitive applications like legal document comparison.
Estimating Embedding Costs¶
Cost Formula:
Total Tokens = (Avg Document Length in Words) × 1.3 × (Number of Documents)
Cost = Total Tokens / 1,000,000 × Model Price
Example (Casino Compliance):
10,000 CTR/SAR filings × 500 words avg × 1.3 tokens/word
= 6,500,000 tokens
= $0.13 with text-embedding-3-small
💬 AI Chat Completion Plugin¶
The ai_chat_completion() plugin invokes Azure OpenAI chat completions directly from KQL, enabling full RAG (Retrieval-Augmented Generation) pipelines within a single Eventhouse query.
Plugin Syntax¶
// Basic chat completion
evaluate ai_chat_completion(
'Summarize the following compliance filing in plain language.',
'https://your-aoai-resource.openai.azure.com',
'gpt-4o'
)
RAG Pattern: Retrieve Context → Generate Response¶
The complete RAG pipeline in KQL — retrieve relevant documents via vector search, assemble context, and generate a grounded response:
// Full RAG pipeline in a single KQL query
// Step 1: Embed the user's question
let user_question = 'What structuring patterns were detected in Q1 2026?';
let query_result = evaluate ai_embed_text(
user_question,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
);
let query_vector = toscalar(query_result | project embedding);
// Step 2: Retrieve top-K relevant documents
let context_docs = DocumentVectors
| where document_type == "SAR"
| where created_date >= datetime(2026-01-01)
| extend similarity = series_cosine_similarity(embedding, query_vector)
| top 5 by similarity desc
| project document_text;
// Step 3: Assemble context and generate response
let context = toscalar(
context_docs
| summarize context = strcat_array(make_list(document_text), '\n---\n')
);
let prompt = strcat(
'Based on the following SAR filings, answer the question.\n\n',
'Context:\n', context, '\n\n',
'Question: ', user_question, '\n\n',
'Provide a concise summary with specific patterns identified.'
);
evaluate ai_chat_completion(
prompt,
'https://your-aoai-resource.openai.azure.com',
'gpt-4o'
)
Chat Completion with System Prompts¶
// Chat completion with structured system prompt for compliance officer
let system_prompt = 'You are a compliance analysis assistant for a casino gaming '
'operation. You analyze CTR and SAR filings to identify patterns. '
'Always cite specific filing IDs. Flag any potential BSA violations.';
let user_message = 'Summarize unusual transaction patterns from the last 30 days.';
// ... (retrieve context via vector search) ...
evaluate ai_chat_completion(
user_message,
'https://your-aoai-resource.openai.azure.com',
'gpt-4o',
system_message = system_prompt
)
Integration with Data Agents¶
Data Agents use the chat completion plugin as their response generation engine, with vector search providing the grounding context:
flowchart LR
subgraph Agent["🤖 Data Agent"]
Q["User Question"]
INT["Intent<br/>Classification"]
end
subgraph Retrieve["🔍 Retrieval"]
EMB["ai_embed_text()<br/>Query → Vector"]
SEARCH["Cosine Similarity<br/>Search"]
TOPK["Top-K<br/>Documents"]
end
subgraph Generate["💬 Generation"]
CTX["Context<br/>Assembly"]
CHAT["ai_chat_completion()<br/>Generate Response"]
CITE["Citation<br/>Extraction"]
end
subgraph Response["📊 Response"]
ANS["Grounded Answer<br/>With Citations"]
end
Agent --> Retrieve --> Generate --> Response
style Agent fill:#27AE60,stroke:#1E8449,color:#fff
style Retrieve fill:#6C3483,stroke:#4A235A,color:#fff
style Generate fill:#E67E22,stroke:#CA6F1E,color:#fff
style Response fill:#2471A3,stroke:#1A5276,color:#fff 🎰 Casino Compliance Document Search¶
One of the most impactful applications of Eventhouse vector search is enabling compliance officers to semantically search CTR, SAR, and W-2G filings — finding documents by meaning rather than exact keyword match.
Use Case: Semantic Compliance Search¶
Casino compliance teams need to: - Find filings with similar transaction patterns (not just matching keywords) - Identify structuring patterns across multiple filings that may not share exact terminology - Compare new suspicious activity against historical SAR narratives - Prepare audit response packages by finding all related filings for a player or pattern
Table Schema¶
// Compliance document vector table
.create table ComplianceDocVectors (
filing_id: string,
filing_type: string, // CTR, SAR, W-2G
narrative_text: string, // Full filing narrative
player_id: string,
property_id: string,
transaction_amount: real,
filing_date: datetime,
tags: dynamic, // ["structuring", "cash", "wire"]
status: string, // Pending, Filed, Flagged
embedding: dynamic // Vector16 encoded
)
// Apply Vector16 encoding
.alter column ComplianceDocVectors.embedding policy encoding type = 'Vector16'
Example Queries¶
Find Filings Similar to a Known Structuring Pattern¶
// "Find filings similar to this structuring pattern"
let known_pattern = 'Multiple cash transactions of $9,500 each over three '
'consecutive days at different cage windows. Patron used '
'different player cards for each transaction.';
let pattern_embedding = toscalar(
evaluate ai_embed_text(
known_pattern,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
ComplianceDocVectors
| where filing_type == "SAR"
| where filing_date >= ago(180d)
| extend similarity = series_cosine_similarity(embedding, pattern_embedding)
| where similarity > 0.80
| top 20 by similarity desc
| project
filing_id,
player_id,
transaction_amount,
similarity = round(similarity, 4),
narrative_preview = substring(narrative_text, 0, 250),
filing_date,
status
Compliance Officer Workflow¶
// Step 1: Officer describes suspicious activity in natural language
let officer_query = 'patron making multiple sub-threshold cash deposits '
'that individually fall below CTR reporting but aggregate above $10,000 '
'within a single gaming day';
// Step 2: Embed and search
let q_vec = toscalar(
evaluate ai_embed_text(
officer_query,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
// Step 3: Find similar filings with compliance context
ComplianceDocVectors
| extend similarity = series_cosine_similarity(embedding, q_vec)
| where similarity > 0.75
| top 15 by similarity desc
| join kind=leftouter (
ComplianceDocVectors
| summarize filing_count = count() by player_id
) on player_id
| project
filing_id,
filing_type,
player_id,
player_total_filings = filing_count,
transaction_amount,
similarity = round(similarity, 4),
narrative_preview = substring(narrative_text, 0, 200),
filing_date
| extend risk_flag = iff(player_total_filings > 3, "⚠️ Repeat Filer", "")
CTR Threshold Analysis with Context¶
// Find CTR filings with unusual narrative patterns
let unusual_pattern = 'large cash transaction immediately followed by chip purchase '
'and cashout at different cage window';
let q_vec = toscalar(
evaluate ai_embed_text(
unusual_pattern,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
ComplianceDocVectors
| where filing_type == "CTR"
| where transaction_amount >= 10000
| extend similarity = series_cosine_similarity(embedding, q_vec)
| where similarity > 0.70
| summarize
filings = count(),
total_amount = sum(transaction_amount),
avg_similarity = avg(similarity),
date_range = strcat(format_datetime(min(filing_date), 'yyyy-MM-dd'),
' to ', format_datetime(max(filing_date), 'yyyy-MM-dd'))
by player_id
| where filings > 1
| order by total_amount desc
⚠️ Compliance Note: All vector search operations on compliance data are subject to the same RLS, CLS, and audit logging requirements as standard KQL queries. Ensure compliance officers' access is scoped to their authorized properties and filing types.
🏛️ Federal Policy RAG¶
Federal agencies can leverage Eventhouse vector search to build RAG-powered policy lookup systems, enabling analysts to query regulations, guidance documents, and policy memos using natural language.
Use Case: Cross-Agency Policy Search¶
flowchart TB
subgraph Agencies["🏛️ Federal Policy Documents"]
USDA_P["🌾 USDA<br/>Agricultural Policy<br/>Farm Bill, Crop Insurance"]
EPA_P["🌊 EPA<br/>Environmental Regs<br/>Clean Air/Water Act"]
NOAA_P["🌀 NOAA<br/>Weather Policy<br/>NWS Directives"]
SBA_P["💼 SBA<br/>Business Policy<br/>Loan Programs, 7(a)/504"]
DOI_P["🏔️ DOI<br/>Land Management<br/>NEPA, ESA"]
end
subgraph Vector["⚡ Eventhouse Vector Store"]
EMB_S["Embedded Policy<br/>Chunks"]
IDX_S["Cross-Agency<br/>Vector Index"]
end
subgraph RAG_S["🧠 RAG Pipeline"]
Q_S["Analyst Question"]
R_S["Relevant Policies<br/>(Multi-Agency)"]
A_S["Grounded Answer<br/>With Citations"]
end
Agencies --> Vector --> RAG_S
style Agencies fill:#2471A3,stroke:#1A5276,color:#fff
style Vector fill:#E67E22,stroke:#CA6F1E,color:#fff
style RAG_S fill:#6C3483,stroke:#4A235A,color:#fff Federal Policy Table Schema¶
// Federal policy document vector table
.create table FederalPolicyVectors (
chunk_id: string,
agency: string, // USDA, EPA, NOAA, SBA, DOI
document_title: string,
section_title: string,
chunk_text: string, // 500-token policy chunk
cfr_reference: string, // e.g., "7 CFR Part 1410"
effective_date: datetime,
policy_category: string, // regulation, guidance, memo, directive
tags: dynamic,
embedding: dynamic // Vector16 encoded
)
.alter column FederalPolicyVectors.embedding policy encoding type = 'Vector16'
USDA Agricultural Policy Search¶
// Search USDA policies related to crop insurance requirements
let query = 'What are the eligibility requirements for federal crop insurance '
'under the Federal Crop Insurance Act?';
let q_vec = toscalar(
evaluate ai_embed_text(
query,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
FederalPolicyVectors
| where agency == "USDA"
| extend similarity = series_cosine_similarity(embedding, q_vec)
| top 5 by similarity desc
| project
document_title,
section_title,
cfr_reference,
similarity = round(similarity, 4),
chunk_preview = substring(chunk_text, 0, 300),
effective_date
EPA Environmental Regulation Lookup¶
// Search EPA regulations about toxic release reporting thresholds
let query = 'What are the TRI reporting thresholds for lead and mercury releases?';
let q_vec = toscalar(
evaluate ai_embed_text(
query,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
FederalPolicyVectors
| where agency == "EPA"
| where tags has_any (dynamic(["TRI", "reporting", "threshold"]))
| extend similarity = series_cosine_similarity(embedding, q_vec)
| top 5 by similarity desc
| project document_title, section_title, cfr_reference,
similarity = round(similarity, 4),
chunk_text, effective_date
Cross-Agency Policy Comparison¶
// Find related policies across agencies for environmental impact
let query = 'environmental impact assessment requirements for federal projects';
let q_vec = toscalar(
evaluate ai_embed_text(
query,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
FederalPolicyVectors
| extend similarity = series_cosine_similarity(embedding, q_vec)
| where similarity > 0.70
| top 3 by similarity desc // Best match per agency
| project
agency,
document_title,
cfr_reference,
similarity = round(similarity, 4),
policy_category,
chunk_preview = substring(chunk_text, 0, 250)
| order by agency asc, similarity desc
Full RAG Response for Federal Policy¶
// Complete RAG: Analyst asks a policy question, gets a grounded answer
let analyst_question = 'What are the requirements for environmental impact '
'statements under NEPA for DOI land management projects?';
let q_vec = toscalar(
evaluate ai_embed_text(
analyst_question,
'https://your-aoai-resource.openai.azure.com',
'text-embedding-3-small'
) | project embedding
);
let context = toscalar(
FederalPolicyVectors
| where agency in ("DOI", "EPA")
| extend similarity = series_cosine_similarity(embedding, q_vec)
| top 5 by similarity desc
| summarize ctx = strcat_array(
make_list(strcat('[', cfr_reference, '] ', chunk_text)), '\n---\n')
);
let prompt = strcat(
'You are a federal policy analyst. Answer the question based ONLY on the ',
'provided policy excerpts. Cite specific CFR references.\n\n',
'Policy Context:\n', context, '\n\n',
'Question: ', analyst_question
);
evaluate ai_chat_completion(
prompt,
'https://your-aoai-resource.openai.azure.com',
'gpt-4o'
)
🤖 Integration with Data Agents¶
Data Agents in Microsoft Fabric use Eventhouse vector search as their primary knowledge retrieval mechanism. When a user asks an agent a question, the agent embeds the query, retrieves relevant context from Eventhouse vectors, and generates a grounded response.
How Vector Search Powers Agent Responses¶
flowchart LR
subgraph User["👤 User"]
Q["Natural Language<br/>Question"]
end
subgraph Agent["🤖 Data Agent"]
CLS["Intent<br/>Classifier"]
PLAN["Query<br/>Planner"]
end
subgraph VectorSearch["⚡ Eventhouse Vector"]
EMB3["Embed Query<br/>ai_embed_text()"]
SIM2["Similarity<br/>Search"]
TOPK2["Top-K<br/>Documents"]
end
subgraph Structured["📊 Structured Data"]
KQL2["KQL Analytics<br/>Tables"]
SM2["Semantic<br/>Models"]
end
subgraph Response2["💬 Response"]
MERGE["Merge Context<br/>(Vector + Structured)"]
GEN["Generate Answer<br/>ai_chat_completion()"]
OUT["Grounded Response<br/>With Citations"]
end
User --> Agent
Agent --> VectorSearch
Agent --> Structured
VectorSearch --> Response2
Structured --> Response2
style User fill:#27AE60,stroke:#1E8449,color:#fff
style Agent fill:#6C3483,stroke:#4A235A,color:#fff
style VectorSearch fill:#E67E22,stroke:#CA6F1E,color:#fff
style Structured fill:#2471A3,stroke:#1A5276,color:#fff
style Response2 fill:#27AE60,stroke:#1E8449,color:#fff Agent Retrieves Context from Vectors¶
When a compliance officer asks the Data Agent: "Are there any patterns similar to the Smith case from January?", the agent:
- Retrieves the Smith case filing from the compliance table by name/date
- Uses the Smith filing's embedding as the query vector
- Searches for similar filings using
series_cosine_similarity() - Combines vector results with structured data (player history, transaction amounts)
- Generates a response that summarizes similarities and flags potential risks
Improved Answer Accuracy with RAG¶
| Metric | Without RAG | With Eventhouse RAG | Improvement |
|---|---|---|---|
| Answer relevance | 62% | 91% | +29% |
| Factual accuracy | 58% | 94% | +36% |
| Citation rate | 0% | 87% | +87% |
| User satisfaction | 3.⅖ | 4.6/5 | +1.4 |
Agent Configuration for Vector Access¶
{
"agent_name": "Compliance Assistant",
"data_sources": [
{
"type": "eventhouse_vector",
"database": "db_compliance",
"table": "ComplianceDocVectors",
"embedding_column": "embedding",
"text_column": "narrative_text",
"metadata_columns": ["filing_id", "filing_type", "player_id"],
"top_k": 5,
"similarity_threshold": 0.75
},
{
"type": "kql_table",
"database": "db_compliance",
"tables": ["ComplianceFilings", "PlayerTransactions"]
}
],
"azure_openai": {
"embedding_model": "text-embedding-3-small",
"chat_model": "gpt-4o",
"endpoint": "https://your-aoai-resource.openai.azure.com"
}
}
📝 Cross-Reference: For complete Data Agent setup and configuration, see Fabric IQ — Data Agents Integration.
⚡ Performance Tuning¶
Vector Index Strategies¶
Eventhouse automatically indexes Vector16 columns for efficient similarity search. However, you can optimize performance through data organization and query patterns.
Partition Strategy¶
Organize data to minimize the search space:
// Partition by document type for targeted searches
// This allows the engine to skip irrelevant partitions
ComplianceDocVectors
| where document_type == "SAR" // Engine skips CTR and W-2G partitions
| where filing_date >= ago(90d) // Further reduces scan scope
| extend similarity = series_cosine_similarity(embedding, query_vector)
| top 10 by similarity desc
Pre-Filter Before Vector Search¶
Always apply structured filters before computing similarity to reduce the number of vector comparisons:
// ✅ Good: Filter first, then compute similarity
DocumentVectors
| where agency == "EPA" // Filters to ~20% of data
| where created_date >= ago(365d) // Filters to ~30% of that
| extend similarity = series_cosine_similarity(embedding, query_vector)
| top 10 by similarity desc
// ❌ Bad: Compute similarity on all rows, then filter
DocumentVectors
| extend similarity = series_cosine_similarity(embedding, query_vector)
| where agency == "EPA"
| where created_date >= ago(365d)
| top 10 by similarity desc
Batch Size Optimization¶
| Batch Size | Embedding Latency | Throughput | Recommended For |
|---|---|---|---|
| 1 | ~100ms | 10/sec | Real-time, single queries |
| 10 | ~200ms | 50/sec | Interactive batch |
| 50 | ~500ms | 100/sec | Pipeline ingestion |
| 100 | ~800ms | 125/sec | Bulk ingestion |
| 500 | ~2,000ms | 250/sec | Initial load (max batch for AOAI) |
💡 Tip: Azure OpenAI has a maximum batch size of 2048 inputs per request for embedding models. For optimal throughput, use batches of 100-500 items.
Caching Strategies¶
| Strategy | Implementation | Benefit |
|---|---|---|
| Hot Cache | Set .alter table hot cache = 30d | Frequently searched recent documents stay in memory |
| Query Cache | Enable set query_results_cache_max_age = time(5m) | Identical queries return cached results |
| Embedding Cache | Cache embeddings for repeated query terms | Avoid re-embedding common questions |
| Materialized Views | Pre-compute aggregations over vector search results | Dashboard-ready vector analytics |
// Configure hot cache for vector tables
.alter table ComplianceDocVectors policy caching
hot = 90d // Keep 90 days in hot cache for fast similarity search
// Enable query results caching
set query_results_cache_max_age = time(10m);
ComplianceDocVectors
| extend similarity = series_cosine_similarity(embedding, query_vector)
| top 10 by similarity desc
Capacity Planning for Vector Workloads¶
| Scale | Documents | Vector Storage | RAM Required | Recommended SKU |
|---|---|---|---|---|
| Small | < 100K | ~300 MB | ~1 GB | F2 |
| Medium | 100K - 1M | ~3 GB | ~8 GB | F16 |
| Large | 1M - 10M | ~30 GB | ~64 GB | F64 |
| Enterprise | 10M+ | ~300 GB | ~512 GB | F128+ |
⚠️ Note: RAM estimates assume 1536-dimensional vectors with Vector16 encoding. Actual requirements vary based on metadata column sizes and hot cache configuration.
⚠️ Limitations¶
Current Limitations¶
| Limitation | Details | Workaround |
|---|---|---|
| No Native ANN Index | Eventhouse uses brute-force cosine similarity, not approximate nearest neighbor (ANN) indexes like HNSW | Pre-filter with structured KQL to reduce search space; effective up to ~10M vectors |
| Vector Dimension Limit | Maximum 16,384 dimensions per vector | Use text-embedding-3-small (1536 dims) for most scenarios |
| Plugin Rate Limits | ai_embed_text() and ai_chat_completion() subject to Azure OpenAI TPM limits | Batch operations; use dedicated AOAI deployments for high-throughput |
| No Cross-Database Vector Search | Vector search is scoped to a single KQL database | Consolidate vectors into a single database or use federated queries |
| Embedding Model Changes | Changing the embedding model requires re-embedding all documents | Plan embedding model selection carefully; version your vector tables |
| Preview Features | Some AI plugins may change behavior between Fabric updates | Pin to specific API versions; test after Fabric updates |
Azure OpenAI Dependencies¶
| Dependency | Impact | Mitigation |
|---|---|---|
| AOAI Availability | If Azure OpenAI is unavailable, embedding and chat completion fail | Cache embeddings; implement fallback to keyword search |
| TPM Limits | Tokens-per-minute limits throttle embedding throughput | Use provisioned throughput for production workloads |
| Regional Availability | Some AOAI models not available in all Azure regions | Verify model availability in your Fabric capacity region |
| Data Residency | Data sent to AOAI may cross regional boundaries | Configure data boundary settings per compliance requirements (FedRAMP, FISMA) |
Accuracy Considerations¶
| Factor | Impact on Search Quality | Recommendation |
|---|---|---|
| Chunk Size | Too large = diluted embeddings; too small = lost context | 300-500 tokens per chunk with 50-token overlap |
| Embedding Model | Newer models (v3) significantly outperform older models (ada-002) | Use text-embedding-3-small or later |
| Vector16 Precision | 0.3% accuracy loss vs float32 | Acceptable for all but scientific precision requirements |
| Query Phrasing | Natural language queries outperform keyword-style queries | Guide users to ask questions, not type keywords |
📚 References¶
| Resource | URL |
|---|---|
| Eventhouse Overview | https://learn.microsoft.com/fabric/real-time-intelligence/eventhouse |
| Vector Database in Eventhouse | https://learn.microsoft.com/fabric/real-time-intelligence/vector-database |
| AI Embed Text Plugin | https://learn.microsoft.com/kusto/query/ai-embed-text-plugin |
| AI Chat Completion Plugin | https://learn.microsoft.com/kusto/query/ai-chat-completion-plugin |
| Vector16 Encoding Policy | https://learn.microsoft.com/kusto/management/alter-column-encoding-policy |
| series_cosine_similarity() | https://learn.microsoft.com/kusto/query/series-cosine-similarity-function |
| Azure OpenAI Embeddings | https://learn.microsoft.com/azure/ai-services/openai/concepts/models#embeddings |
| Real-Time Intelligence Overview | https://learn.microsoft.com/fabric/real-time-intelligence/overview |
🔗 Related Documents¶
- Real-Time Intelligence — Eventhouse setup and KQL fundamentals
- Fabric IQ — How vector search enhances Fabric IQ and Data Agents
- AI Copilot Configuration — Azure OpenAI integration and tenant settings
- Data Mesh Enterprise Patterns — Cross-domain vector search in mesh architectures
- Architecture — System architecture overview
📝 Document Metadata - Author: Documentation Team - Reviewers: Data Engineering, AI/ML Team, Security, Compliance - Classification: Internal - Next Review: 2026-06-13