{"id":5922,"date":"2026-10-15T05:10:05","date_gmt":"2026-10-15T12:10:05","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/agent-framework\/?p=5922"},"modified":"2026-10-15T05:10:05","modified_gmt":"2026-10-15T12:10:05","slug":"vector-stores-in-python-agent-framework-familiar-foundations-streamlined-for-agents","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/vector-stores-in-python-agent-framework-familiar-foundations-streamlined-for-agents\/","title":{"rendered":"Vector stores in Agent Framework for Python: familiar foundations, streamlined for agents"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Vector stores have been part of the Python experience in Semantic Kernel for some time. With Microsoft Agent Framework, we have ported that work forward rather than starting over.<\/p>\n<p class=\"wp-block-paragraph\">This post focuses on Python. For the .NET equivalent, see <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/ai\/vector-stores\/how-to\/use-vector-stores\">Use vector stores in .NET AI apps<\/a>.<\/p>\n<p class=\"wp-block-paragraph\">The foundation remains familiar: typed record definitions, stores and collections, batch storage and retrieval, embedding generation, vector search, and a growing set of integrations. If you have used Semantic Kernel&#8217;s vector-store APIs, you will recognize the overall model.<\/p>\n<p class=\"wp-block-paragraph\">At the same time, this is more than a straight port. We streamlined model registration and the batch APIs, updated filters and embedding options, and made vector stores fit naturally into how agents receive and use context.<\/p>\n<p class=\"wp-block-paragraph\">The most important additions are the context providers. They expose your data to agents through tools, or use a vector store to keep conversation history searchable without continually expanding the model context.<\/p>\n<p class=\"wp-block-paragraph\">The vector-store APIs remain experimental, and the integration packages are alpha or beta. Use each implementation&#8217;s documentation for setup and its supported capabilities.<\/p>\n<h2 class=\"wp-block-heading\">Define the data your application already owns<\/h2>\n<p class=\"wp-block-paragraph\">Agent Framework starts with your data model rather than a database SDK model. Mark the key, data, and vector fields with <code>VectorStoreField<\/code>, and <code>@vectorstoremodel<\/code> derives the collection definition:<\/p>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from dataclasses import dataclass\r\nfrom typing import Annotated\r\n\r\nfrom agent_framework import (\r\n    Filter,\r\n    InMemoryCollection,\r\n    VectorStoreField,\r\n    vectorstoremodel,\r\n)\r\nfrom agent_framework.openai import OpenAIEmbeddingClient\r\n\r\n\r\n@vectorstoremodel(collection_name=\"documents\")\r\n@dataclass\r\nclass Document:\r\n    id: Annotated[str, VectorStoreField(\"key\")]\r\n    category: Annotated[str, VectorStoreField(\"data\", is_indexed=True)]\r\n    text: Annotated[str, VectorStoreField(\"data\")]\r\n    embedding: Annotated[\r\n        list[float] | str | None,\r\n        VectorStoreField(\r\n            \"vector\",\r\n            dimensions=1536,\r\n            distance_function=\"cosine_similarity\",\r\n        ),\r\n    ] = None\r\n\r\n\r\nasync def index_and_search() -&gt; None:\r\n    documents: InMemoryCollection[str, Document] = InMemoryCollection(\r\n        Document, embedding_generator=OpenAIEmbeddingClient(model=\"text-embedding-3-small\"),\r\n    )\r\n    await documents.ensure_collection_exists()\r\n\r\n    await documents.upsert([\r\n        Document(\r\n            id=\"release-checklist\",\r\n            category=\"operations\",\r\n            text=\"Verify rollback, monitoring, and owner sign-off.\",\r\n            embedding=\"Verify rollback, monitoring, and owner sign-off.\",\r\n        )\r\n    ])\r\n\r\n    results = await documents.search(\r\n        \"What should I check before a release?\",\r\n        filter=Filter(\"category\", \"eq\", \"operations\"),\r\n        top=3,\r\n    )\r\n\r\n    async for result in results:\r\n        print(result[\"record\"].text, result[\"score\"])\r\n<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Set <code>OPENAI_API_KEY<\/code> before running the code. The records are stored in-memory (so this will not survive a restart), while OpenAI generates embeddings during both upsert and search. You can swap out the InMemoryCollection with any of the other implementations without changing anything else, see the list below for the ones we currently support.<\/p>\n<p class=\"wp-block-paragraph\">Dataclasses are only one option. The same model layer supports Pydantic models, msgspec structs, plain classes, dictionaries, and externally owned types through custom codecs.<\/p>\n<h2 class=\"wp-block-heading\">Turn vector search into an agent tool<\/h2>\n<p class=\"wp-block-paragraph\">As in Semantic Kernel, you can expose search directly as a first-class agent tool. <code>create_vector_search_tool<\/code> wraps a searchable collection and lets you control its name, description, result shape, filters, and approval behavior.<\/p>\n<p class=\"wp-block-paragraph\"><code>Param<\/code> now makes custom search tools easier to build. Place a <code>Param<\/code> inside a <code>Filter<\/code> or <code>FilterGroup<\/code>, and the helper exposes it as a typed argument the model can supply. Given a collection configured to embed text queries, the tool definition stays small:<\/p>\n<pre class=\"prettyprint language-py\"><code class=\"language-py\">from typing import Literal\r\n\r\nfrom agent_framework import Filter, Param, create_vector_search_tool\r\n\r\ncategory = Param(\r\n    \"category\",\r\n    Literal[\"engineering\", \"operations\", \"product\"],\r\n    required=False,\r\n    description=\"Only return documents from this category.\",\r\n)\r\n\r\nsearch_documents = create_vector_search_tool(\r\n    collection,\r\n    name=\"search_documents\",\r\n    description=\"Search the document collection.\",\r\n    filter=Filter(\"category\", \"eq\", category),\r\n    result_mapper=lambda result: result[\"record\"].text,\r\n)\r\n<\/code><\/pre>\n<p class=\"wp-block-paragraph\">The resulting tool always accepts a natural-language query and optionally accepts <code>category<\/code>. The <code>Literal<\/code> values become an enum in the tool schema, giving the agent a clear set of valid choices. If the model omits the optional parameter, that filter is omitted. More complex tools can compose several parameters through <code>FilterGroup<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">The key addition: make collections available through context providers<\/h2>\n<p class=\"wp-block-paragraph\">When an agent needs more than one focused search tool, <code>VectorCollectionContextProvider<\/code> provides the higher-level experience.<\/p>\n<p class=\"wp-block-paragraph\"><code>VectorCollectionContextProvider<\/code> can add upsert, get, delete, and search tools to an agent, together with instructions for using them. You can expose a read-only knowledge collection, let an agent manage records with approvals, scope the available data, or replace the default search with specialized tools.<\/p>\n<p class=\"wp-block-paragraph\">Embedding setup stays specific to the operation: ingestion can use document embedding options while search uses query embedding options. Generated tools forward those settings to the same collection.<\/p>\n<h2 class=\"wp-block-heading\">A context provider for searchable conversation history<\/h2>\n<p class=\"wp-block-paragraph\">Conversation histories keep growing, increasing the context sent to the model on every turn. <code>VectorStoreHistoryProvider<\/code> persists the full conversation in a searchable vector collection while loading only a compacted working set into the model context.<\/p>\n<p class=\"wp-block-paragraph\">When <code>include_search_tool=True<\/code>, the agent also receives a tool for searching the complete scoped transcript. The active context can therefore remain bounded without losing access to an older decision, requirement, or user preference: the agent retrieves the relevant part of the conversation when it needs it instead of carrying every prior message on every invocation.<\/p>\n<h2 class=\"wp-block-heading\">Embeddings and search without hard-coding a provider<\/h2>\n<p class=\"wp-block-paragraph\">Applications can supply precomputed vectors or have Agent Framework call an embedding service during upsert and search. They can generate every vector field or only selected fields, and pass different provider options for document ingestion and query generation. Vector dimensions stay with the model definition, so Agent Framework can validate generated and supplied vectors before they reach the backing store.<\/p>\n<p class=\"wp-block-paragraph\">Search uses the same collection API across integrations, with portable data filters and keyword-hybrid search where supported. Each implementation documents its supported indexes, filters, metrics, and search modes.<\/p>\n<h2 class=\"wp-block-heading\">Available integrations<\/h2>\n<p class=\"wp-block-paragraph\">The current Python integrations are:<\/p>\n<ul class=\"wp-block-list\">\n<li>Azure AI Search<\/li>\n<li>Azure Cosmos DB for NoSQL<\/li>\n<li>Azure DocumentDB<\/li>\n<li>MongoDB<\/li>\n<li>Oracle AI Database 26ai<\/li>\n<li>Redis<\/li>\n<li>SQL Server and Azure SQL<\/li>\n<li>PostgreSQL with pgvector<\/li>\n<li>DuckDB<\/li>\n<li>Qdrant<\/li>\n<li>The core in-memory store for tests and local development<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">The same model and core operations work across integrations, while each database keeps its own features and constraints.<\/p>\n<h2 class=\"wp-block-heading\">Get started<\/h2>\n<p class=\"wp-block-paragraph\">Start with the runnable <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/02-agents\/vector_stores\">vector-store samples<\/a> for models, search, and agent tools. The <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/blob\/main\/python\/samples\/02-agents\/conversations\/vector_store_history_provider.py\">vector-store-backed conversation sample<\/a> demonstrates bounded working context with search over the full conversation.<\/p>\n<p class=\"wp-block-paragraph\">Install the integration package for the store you want to use, and use its README for setup and supported capabilities. We would especially like feedback on the context-provider experience, searchable history, and which integrations you need next. Open an issue in the <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/issues\">Microsoft Agent Framework repository<\/a> and tell us what you are building.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vector stores have been part of the Python experience in Semantic Kernel for some time. With Microsoft Agent Framework, we have ported that work forward rather than starting over. This post focuses on Python. For the .NET equivalent, see Use vector stores in .NET AI apps. The foundation remains familiar: typed record definitions, stores and [&hellip;]<\/p>\n","protected":false},"author":150044,"featured_media":5048,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143,34,19],"tags":[],"class_list":["post-5922","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agent-framework","category-python-2","category-vector-database"],"acf":[],"blog_post_summary":"<p>Vector stores have been part of the Python experience in Semantic Kernel for some time. With Microsoft Agent Framework, we have ported that work forward rather than starting over. This post focuses on Python. For the .NET equivalent, see Use vector stores in .NET AI apps. The foundation remains familiar: typed record definitions, stores and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5922","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/150044"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=5922"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5922\/revisions"}],"predecessor-version":[{"id":5926,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5922\/revisions\/5926"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/5048"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=5922"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=5922"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=5922"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}