In an October 15, 2026 announcement on the Microsoft Agent Framework blog by Senior Software Engineer Eduard van Valkenburg, Microsoft detailed native vector store support for Python in Microsoft Agent Framework. While the foundational primitives—typed record definitions, stores and collections, batch storage and retrieval, embedding generation, and vector search—will look immediately familiar to Semantic Kernel veterans, the update is far more than a copy-paste job. Microsoft has streamlined model registration and batch APIs, reworked filtering and embedding options, and introduced two major architectural additions: VectorCollectionContextProvider and VectorStoreHistoryProvider.
Before you rush to Rip-and-Replace your production pipelines, however, a quick reality check is in order. Microsoft explicitly notes that these native Python vector-store APIs remain experimental, and the accompanying database integration packages are currently distributed in alpha or beta states. Still, for Python developers building agentic workflows on Windows, Linux, or Azure, the update offers a clear look at how Microsoft intends to solve two of agentic AI's biggest headaches: turning structured vector search into safe, callable tools, and keeping long-running conversation histories from blowing up your context window.
Familiar Foundations: Your Data Model Comes First
One of the smartest design choices carried over from Semantic Kernel is that the framework starts with the data model your application already owns, rather than forcing you to inherit from a database vendor's proprietary SDK class.
In the Microsoft Agent Framework for Python, the core contracts live directly in agent-framework-core and, as Microsoft Learn documentation highlights, do not require heavy mandatory dependencies like Pydantic, NumPy, pandas, or Semantic Kernel itself to function. Instead, you annotate your fields with VectorStoreField to designate the record's key, data, and vector properties, and apply the @vectorstoremodel decorator to derive the collection definition.
Here is how a clean, self-contained workflow looks using a standard Python dataclass, an in-memory collection, and OpenAI's text-embedding-3-small model:
from dataclasses import dataclass
from typing import Annotated
from agent_framework import (
Filter,
InMemoryCollection,
VectorStoreField,
vectorstoremodel,
)
from agent_framework.openai import OpenAIEmbeddingClient
@vectorstoremodel(collection_name="documents")
@dataclass
class Document:
id: Annotated[str, VectorStoreField("key")]
category: Annotated[str, VectorStoreField("data", is_indexed=True)]
text: Annotated[str, VectorStoreField("data")]
embedding: Annotated[
list[float] | str | None,
VectorStoreField(
"vector",
dimensions=1536,
distance_function="cosine_similarity",
),
] = None
async def index_and_search() -> None:
documents: InMemoryCollection[str, Document] = InMemoryCollection(
Document,
embedding_generator=OpenAIEmbeddingClient(model="text-embedding-3-small"),
)
await documents.ensure_collection_exists()
await documents.upsert([
Document(
id="release-checklist",
category="operations",
text="Verify rollback, monitoring, and owner sign-off.",
embedding="Verify rollback, monitoring, and owner sign-off.",
)
])
results = await documents.search(
"What should I check before a release?",
filter=Filter("category", "eq", "operations"),
top=3,
)
async for result in results:
print(result["record"].text, result["score"])
To run that snippet, you set OPENAI_API_KEY in your environment. Notice a neat ergonomic touch in the upsert call: although embedding can hold a list[float], passing a string tells the configured OpenAIEmbeddingClient to generate the 1,536-dimension vector automatically during both ingestion and search.
What if your team isn't standardized on dataclasses? The same model layer supports:
- Pydantic models (when you want runtime validation and are willing to pay the small round-trip cost)
msgspecstructs and plain Python classes- Dictionaries, configured directly via
VectorStoreCollectionDefinition - Externally owned types from third-party packages, which can be wired up via
register_vectorstoremodel()with an explicit definition and custom encoder/decoder codecs.
Furthermore, array-like vector values serialize cleanly through tolist() without forcing a NumPy dependency onto lightweight microservice deployments.
Flexible Embeddings and Dimension Validation
In real-world enterprise architectures, document ingestion and runtime user queries rarely share the exact same parameters. Agent Framework separates these concerns cleanly. Applications can pass precomputed vectors (setting generate_vectors=False on upsert), generate every vector field on a record, or selectively generate only specific fields using GenerateVectors.
Even better, you can pass embeddings_options (or embeddings_options_by_field when different vector fields need separate configurations) during upsert(), while using entirely different embeddings_options for search() or tool creation. Because the vector dimensions (dimensions=1536 in the example above) stay attached to the model definition, Agent Framework validates both generated and caller-supplied vectors—and rejects conflicting dimension settings—before a malformed payload ever hits your backing database.
- Section Summary: Agent Framework keeps Semantic Kernel's model-first philosophy in
agent-framework-core, supporting dataclasses, Pydantic,msgspec, dictionaries, and external types while validating vector dimensions and separating ingestion embedding options from query embedding options.
From Passive Databases to Active Agent Tools
Having a clean CRUD and vector search API is great for standard application code, but agents need tools they can reason over and invoke autonomously. Why write custom wrapper functions for every collection when the framework already knows your schema?
Dynamic Search Schemas with create_vector_search_tool and Param
Just like in Semantic Kernel, you can wrap any searchable collection into a first-class agent function tool using create_vector_search_tool. You control the tool's name, description, result mapping (result_mapper), filter rules, and approval behavior.
The standout improvement here is how filters work. Instead of parsing or executing arbitrary Python source strings—which is always a fragile proposition across diverse database backends—Agent Framework uses portable, data-only structures: Filter, FilterGroup, and Param.
When you drop a Param inside a Filter or FilterGroup, the helper automatically exposes that parameter as a typed argument in the tool's JSON schema so the LLM can supply it at runtime:
from typing import Literal
from agent_framework import Filter, Param, create_vector_search_tool
category = Param(
"category",
Literal["engineering", "operations", "product"],
required=False,
description="Only return documents from this category.",
)
search_documents = create_vector_search_tool(
collection,
name="search_documents",
description="Search the document collection.",
filter=Filter("category", "eq", category),
result_mapper=lambda result: result["record"].text,
)
Look at what happens under the hood:
- The generated tool always takes a natural-language query string.
- Because
categoryuses Python'sLiteral["engineering", "operations", "product"], the tool schema exposes those exact strings as an enum, preventing the model from hallucinating nonexistent category names. - Because
required=Falseis set, if the agent decides a broad search is better and omitscategory, the filter is cleanly omitted from the query. - For richer queries—say, filtering hotels by both a category enum and a
floatmin_ratingconstrained between0and5—you can nest multipleParamobjects inside aFilterGroup("and", (...)).
The Headline Upgrade: Context Providers for Collections and History
The biggest leap forward in this release is the introduction of context providers, which elevate vector stores from simple search utilities into managed, lifecycle-aware components of an agent's execution loop.
1. VectorCollectionContextProvider: Full Collection Management with Safety Rails
Sometimes an agent needs more than a single read-only search tool. What if you are building a project-notes assistant or an operational runbook manager that needs to read, search, create, and prune records?
VectorCollectionContextProvider attaches a caller-owned collection directly to an agent, automatically provisioning upsert, get, delete, and search tools alongside instructions teaching the agent how to use them.
Crucially, Microsoft built sensible human-in-the-loop defaults into these generated tools. According to Microsoft Learn's vector store documentation, generated upsert and delete tools require approval by default, whereas read-only get and search operations do not. Developers can customize this behavior—for instance, passing approval_mode={"upsert": "never_require"} for an unattended note-taking bot while leaving delete locked behind an approval prompt, or exposing a strictly read-only knowledge base.
A Critical Security Caveat for Architects: VectorCollectionContextProvider accepts a scope_filter to logically partition records for generated tools. However, Microsoft Learn explicitly warns that scope_filter is not an authorization boundary or an atomic backend guarantee. If you pass custom search tools via additional_search_tools on a shared collection, they retain their own filters—meaning you must apply equivalent filters to each custom tool and enforce real tenant/user authorization at the application and credential level.
2. VectorStoreHistoryProvider: Taming Context Window Bloat
Every developer who has put a multi-turn conversational agent into production knows the pain of growing chat transcripts. As a conversation stretches over dozens of turns, sending every prior message on every model invocation drives up token costs, increases latency, and eventually degrades reasoning quality.
VectorStoreHistoryProvider solves this by splitting persistence from active working context:
- Full Transcript Persistence: It automatically saves the full conversation into a provider-owned vector collection, using
application_id,tenant_id,agent_id, source, and session identifiers to prevent accidental overlap across sessions. - Compacted Working Context: By pairing the provider with a compaction strategy—such as
SlidingWindowStrategy(keep_last_groups=2, preserve_system=True)—only a compact projection of recent turns is loaded into the model's active context window on each turn. - On-Demand Memory Recall: When you set
include_search_tool=True, the agent is handed a search tool wired to the complete scoped transcript. If a user asks about an architectural constraint or preference mentioned 40 turns ago that has already aged out of the sliding window, the agent can query its own conversation history to retrieve the exact detail on demand.
Just as with collection scoping, Microsoft notes that while application, tenant, and agent identifiers prevent accidental data collisions, your application remains responsible for access control and properly scoped database credentials or namespaces.
- Section Summary:
create_vector_search_toolandParamturn portable data filters into strongly typed JSON schema arguments for agents. Meanwhile,VectorCollectionContextProvideradds CRUD and search tools (with default approvals on writes/deletes), andVectorStoreHistoryProviderkeeps active prompt tokens bounded via compaction while letting agents semantically search older conversation turns.
Under the Hood: Python Integrations and Real-World Limitations
A unified API is a wonderful abstraction, right up until you assume every database underneath behaves identically. While the same @vectorstoremodel and collection methods work across backends, Microsoft's documentation makes it very clear that native Agent Framework connectors and Semantic Kernel connectors are separate families and are not interchangeable.
Furthermore, if you inspect the Microsoft Learn documentation for Agent Framework's native Python vector store packages, you will find important maturity differences, search mode limitations, and Python version constraints that every engineering team should check before committing to a backend:
| Integration Backend | Package Name & Lifecycle Stage | Supported Search Modes | Notable Version & Feature Constraints |
|---|---|---|---|
| In-Memory | agent-framework-core (Released package; experimental vector APIs) | Dense vector with portable filters | Process-local linear scan; data does not survive restarts. Built for local dev and unit tests, not production. |
| Azure AI Search | agent-framework-azure-ai-search (Beta; experimental vector APIs) | Dense vector and keyword-hybrid | Supports one top-level dense vector field per query. Certain thresholds, hybrid recall controls, and strict post-filtering require preview SDK/API with allow_preview=True. |
| Azure Cosmos DB for NoSQL | agent-framework-azure-cosmos (Beta; experimental vector APIs) | Dense vector with portable filters | Keys must be strings stored as id (partition key /id). No keyword or hybrid search; Euclidean search lacks score thresholds. |
| Redis | agent-framework-redis (Beta; experimental vector APIs) | Dense vector over HASH or JSON records | Requires Python 3.10–3.14 (RedisVL lacks Python 3.15 support) and Redis 8.0.3+ with Search (plus RedisJSON for JSON records). No Redis Cluster, keyword, or hybrid search. |
PostgreSQL (pgvector) | agent-framework-postgres (Alpha) | Exact dense vector, HNSW, and IVFFlat | Requires PostgreSQL 13+ and pgvector 0.8.0+. No keyword/hybrid search. Uses binary Psycopg on Python 3.10–3.14, but falls back to pure-Python Psycopg on Python 3.15+ (requiring a host libpq install). |
| SQL Server / Azure SQL | agent-framework-sql-server (Alpha) | Exact dense vector with portable filters | Supports Python 3.10–3.15. Requires SQL Server 2025 or a vector-enabled Azure SQL database. No approximate indexes, keyword/hybrid search, or schema migration. |
| DuckDB | agent-framework-duckdb (Alpha) | Exact dense vector with portable filters | Supports Python 3.10–3.14 and DuckDB 1.4.1–1.5.x (no Python 3.15 wheels). Defaults to a persistent local agent-framework.duckdb file (single writer process). No approximate indexes or hybrid search. |
| MongoDB | agent-framework-mongodb (Alpha) | Approximate or exact dense vector with portable filters | Requires PyMongo 4.13.2+ and MongoDB Vector Search. Rejects models declaring is_full_text_indexed; newly written records become searchable asynchronously. |
| Qdrant | agent-framework-qdrant (Alpha) | Dense vector with server-side portable filters | Server mode requires Qdrant 1.16.2+. Keys must be unsigned 64-bit ints or UUIDs. Filters are not available in local SDK mode. |
| Oracle AI Database 26ai | agent-framework-oracle (Alpha) | Dense vector with portable filters | Requires Oracle AI Database 26ai (COMPATIBLE >= 23.4.0) and python-oracledb 2.2.x or 3.x. No index management, hybrid search, or nested filters. |
| Azure DocumentDB | agent-framework-azure-documentdb (Alpha) | Dense vector with portable metadata filters | String or integer keys only; no generated ObjectIds, nested filter paths, or hybrid/full-text search. |
Three Takeaways from the Compatibility Matrix
- Keyword-Hybrid Search is Currently Rare: Although the core
BaseVectorSearchcontract defines keyword-hybrid search, Azure AI Search is currently the only native Python connector in the table that supports keyword-hybrid queries. If your RAG pipeline depends heavily on hybrid lexical + semantic scoring, keep that limitation front and center. - Watch Your Python 3.15 Environments: If your workstation or container images are already testing bleeding-edge Python 3.15 builds, note that
agent-framework-duckdbandagent-framework-redistop out at Python 3.14 due to upstream wheel and library dependencies (DuckDBandRedisVL), whileagent-framework-postgresrequires a systemlibpqlibrary on Python 3.15+. - What About Chroma, Pinecone, Faiss, or Weaviate? If your favorite store isn't on the native list yet, you aren't locked out. Microsoft notes that applications can continue to use Semantic Kernel's Python vector stores directly—which currently cover Chroma, Faiss, Pinecone, Weaviate, and Azure Cosmos DB for MongoDB vCore—by installing
semantic-kerneland using its separate vector store contracts. (And for polyglot shops wondering about Go: Microsoft Learn notes that vector store integration is not yet available in Agent Framework for Go.)
How to Test It Yourself
Because all of the external database connectors are currently in alpha or beta, you will need the --pre flag with pip when installing them alongside the core framework:
pip install agent-framework-azure-ai-search --pre
pip install agent-framework-postgres --pre
pip install agent-framework-sql-server --pre
If you just want to kick the tires on a local Windows dev box without spinning up Docker containers or cloud resources, start with InMemoryCollection or InMemoryStore from agent-framework-core and an embedding client, then explore Microsoft's runnable vector-store samples for models, search, and bounded vector-store-backed conversation history in the Microsoft Agent Framework GitHub repository.
Microsoft's engineering team is actively soliciting developer feedback on the new context-provider workflows, VectorStoreHistoryProvider compaction and recall, and which database integrations should be prioritized next. Are you planning to migrate your Semantic Kernel Python agents over to the native Agent Framework vector stores, or are you waiting for the experimental API label to come off first? Drop your thoughts—and your favorite vector database stack—in the WindowsForum.com developer discussions!
References
- Vector stores in Agent Framework for Python: familiar foundations, streamlined for agents Microsoft Agent Framework Blog · 2026-10-15T12:10:05+00:00
- agent-framework/docs/features/vector-stores-and-embeddings/README.md at main · microsoft/agent-framework github.com
- Vector store integrations - Microsoft Agent Framework | Microsoft Learn learn.microsoft.com