# Microsoft.Extensions.VectorData & DataIngestion — Official Vector Store Abstractions

> **Scope:** stacks=["dotnet"]
> **Layer:** 1 (on-keyword)
> **Keywords:** microsoft extensions vectordata, vectorstorecollection, vector store abstraction, data ingestion, ingestion pipeline, semantic kernel connectors exception, pgvector connector, vectorstorewriter
> **Read by Claude in:** plan (when choosing a RAG storage backend) + implement (when deciding whether to adopt VectorData over custom pgvector)

**Verified against:** Microsoft.Extensions.VectorData.Abstractions **10.9.0** + CommunityToolkit.VectorData.PgVector **1.0.1** + Microsoft.Extensions.DataIngestion **10.9.0-preview.1.26411.16** — nenhum deles está no `framework/ai-pin.json` (que cobre os 5 pacotes de agente), portanto **todas as versões acima foram apuradas na API do nuget.org em 2026-09-08** e são citadas com essa data, não como pin. **Verificação documental**, sem cláusula `provado por`: o ai-kit **não referencia nem exercita** VectorData — o pacote não está no `Morph.AiKit.csproj`, cujos cinco `PackageReference` são exatamente os do pin (medido 2026-09-08). Aqui nem a régua fraca do restore existe. Last-verified: 2026-09-08.

---

## O que é

`Microsoft.Extensions.VectorData.Abstractions` is the official, GA, provider-agnostic abstraction over vector stores — the vector-store equivalent of `IChatClient` for chat models. Core API:

```csharp
VectorStoreCollection<TKey, TRecord> collection = new SomeVectorStore<TKey, TRecord>(...);

await collection.CreateCollectionAsync();
await collection.UpsertAsync(record);

await foreach (var result in collection.SearchAsync(queryText, top: 5))
{
    var record = result.Record;
}
```

A single `VectorStoreCollection<TKey, TRecord>` shape works identically whether the backing store is in-memory, SQLite, Postgres (pgvector), Qdrant, Azure AI Search, Cosmos DB, or SQL Server — switching backends is a constructor swap, not a rewrite.

`Microsoft.Extensions.DataIngestion` is a companion library (still **preview**) that provides the ETL building blocks around it: `IngestionDocumentReader` (Markdown/MarkItDown/Markdig), `IngestionChunker<T>` (header, section, `SemanticSimilarityChunker`), chunk/document enrichers (`SummaryEnricher`, `SentimentEnricher`, `KeywordEnricher`, `ImageAlternativeTextEnricher`), and `VectorStoreWriter<T>` — chained together via `IngestionPipeline<T>`.

---

## A pegadinha de nomenclatura (crítico — leia antes de tudo)

> **Atualização de 2026-09-08 — a pegadinha mudou de forma.** Os conectores concretos **saíram** dos nomes `Microsoft.SemanticKernel.Connectors.*` e passaram a `CommunityToolkit.VectorData.*` (repositório `github.com/CommunityToolkit/AI`). Medido na API do nuget.org em 2026-09-08:
>
> | Pacote | Última versão | Publicada | Estável? |
> |---|---|---|---|
> | `Microsoft.SemanticKernel.Connectors.PgVector` | `1.74.0-preview` | 2026-03-20 | **Nunca teve versão estável**; parou aí |
> | `CommunityToolkit.VectorData.PgVector` | **`1.0.1`** | **2026-08-31** | **Sim** |
> | `CommunityToolkit.VectorData.InMemory` | `1.0.1` | 2026-08-31 | Sim |
>
> Os dois carregam o **mesmo título e a mesma descrição** ("Postgres (with pgvector extension) provider for Microsoft.Extensions.VectorData"), trocando apenas o autor — *"by Semantic Kernel"* → *"by the .NET Community Toolkit"*. É a mesma peça, com outro dono e outro nome.
>
> **Use `CommunityToolkit.VectorData.PgVector` 1.0.1.** O pacote com nome de Semantic Kernel é caminho morto: última versão em março de 2026, e preview.
>
> *Fronteira do que foi medido:* a substituição acima é medida (existência, versões, datas, título e descrição, apurados na API do nuget.org em 2026-09-08). Que a página do NuGet **exiba um aviso de rename** não foi confirmado nem pelo `.nuspec` da 1.74.0-preview nem pelos metadados de deprecação da registration API — a afirmação aqui é a substituição, não o aviso.

A pegadinha original — abaixo — continua valendo para **projeto legado** que ainda referencia o nome antigo, e para quem tropeça no nome ao ler código existente.

The concrete vector-store **connectors** — the packages that actually implement `VectorStoreCollection` against a real backend — **used to** ship under `Microsoft.SemanticKernel.Connectors.*` package names (`Microsoft.SemanticKernel.Connectors.PgVector`, `.Qdrant`, `.SqlServer`, `.CosmosNoSQL`, `.InMemory`, etc.), even though `Microsoft.Extensions.VectorData.Abstractions` itself has been transferred out of the Semantic Kernel repo into `dotnet/extensions` and is fully independent of SK orchestration.

Microsoft's own docs are explicit about this:

> "Despite the inclusion of 'SemanticKernel' in the package names, these providers have nothing to do with Semantic Kernel and are usable anywhere in .NET, including Agent Framework." — [Data ingestion - .NET | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/ai/conceptual/data-ingestion)

**Exceção explícita à regra "Forbidden" de `ai-agents-setup`:** the ban on `Microsoft.SemanticKernel.*` in `ai-agents-setup` §1/§7 targets the SK **orchestration** surface — `Kernel`, `KernelFunction`, `[KernelFunction]`, `ChatHistory`, `Kernel.InvokePromptAsync()`. It does **not** apply to `Microsoft.SemanticKernel.Connectors.*` packages when used purely as `Microsoft.Extensions.VectorData` backend connectors — those carry zero SK orchestration code. Never import the `Microsoft.SemanticKernel` core package itself; that remains forbidden.

---

## Maturidade atual (verificado 2026-07-06)

> Tabela **reapurada em 2026-09-08** na API do nuget.org. Cada linha traz a versão exata e a data — nenhum destes pacotes está no `framework/ai-pin.json`, então a data de apuração é o que dá validade ao número.

| Package | Versão (apurada 2026-09-08) | Status |
|---------|------------------------------|--------|
| `Microsoft.Extensions.VectorData.Abstractions` | **10.9.0** (publicada 2026-08-11) | **GA** — é a camada de abstração |
| `Microsoft.Extensions.AI` / `Microsoft.Extensions.AI.Abstractions` | **10.9.0** (no ai-pin) | **GA** |
| `CommunityToolkit.VectorData.PgVector` (Postgres/pgvector connector) | **1.0.1** (publicada 2026-08-31) | **Estável** — é o conector recomendado hoje |
| `CommunityToolkit.VectorData.InMemory` / demais conectores | **1.0.1** (2026-08-31) | Estável; confira cada um antes de adicionar |
| `Microsoft.SemanticKernel.Connectors.PgVector` | `1.74.0-preview` (2026-03-20) | **Caminho morto** — nunca teve versão estável e não avança desde março/2026 |
| `Microsoft.Extensions.DataIngestion` | **`10.9.0-preview.1.26411.16`** | **Preview** — sem versão estável |

> **Cuidado com o número que o conector declara.** `CommunityToolkit.VectorData.PgVector` 1.0.1 depende de `Microsoft.Extensions.VectorData.Abstractions` **10.8.2** — esse é o **piso da dependência**, não a versão corrente da abstração, que é 10.9.0. Citar 10.8.2 como "a versão do VectorData" é ler o `.nuspec` do conector como se fosse o do pacote.

Preview packages are subject to breaking API changes before GA (see the rename `PostgresVectorStoreRecordCollection` → `PostgresCollection` as precedent).

---

## Decision matrix — custom pgvector vs VectorData

**O critério, em uma frase:** a abstração se paga quando **a troca de store é plausível**; o SQL cru se paga quando **já funciona e é testado**. Nada aqui manda migrar o que está de pé.

| Situation | Use |
|-----------|-----|
| Default production RAG on Neon/Postgres (this framework's default stack), **already implemented and tested** | **`ai-agents-rag-custom-pgvector`** — framework-owned raw SQL, zero external connector, already the checklisted default. **Não se migra o que funciona** (item D4 da elevação-9) |
| **Projeto novo** onde a escolha do store ainda não foi cravada, e trocá-lo depois deve custar pouco | `Microsoft.Extensions.VectorData.Abstractions` 10.9.0 + `CommunityToolkit.VectorData.PgVector` 1.0.1 — hoje **ambos estáveis**, o que remove o argumento "é preview" que existia em julho/2026 |
| Project needs genuine portability across >1 vector backend (a client contract requires swapping Postgres for Qdrant or Azure AI Search later) | `Microsoft.Extensions.VectorData` + o conector correspondente — document the choice in `decisions.md` |
| Prototyping, tests, or demos where an in-memory store is enough | `CommunityToolkit.VectorData.InMemory` 1.0.1 |
| Ingestão em pipeline (reader → chunker → writer) hoje | Só com `Microsoft.Extensions.DataIngestion`, que **continua preview**: registre a aceitação e um lembrete de revisitar no GA |

Do not migrate the existing `ai-agents-rag-custom-pgvector` implementation to VectorData as a default — that would rewrite a working, tested, framework-owned implementation for no functional gain. **O que mudou desde a verificação anterior:** o argumento *"o conector é preview"* **caiu** (o `CommunityToolkit` é estável desde 2026-08-31); o argumento *"não se reescreve o que funciona"* **permanece**, e é ele que sustenta o default hoje.

---

## Exemplo mínimo (backend GA — sem depender de pacote preview)

```csharp
using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;

// embeddingGenerator wired via the project's Model Registry `embeddings` alias
// (see ai-agents-providers-model-registry) — any IEmbeddingGenerator works here.
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator = /* from Model Registry */;

VectorStoreCollection<string, KnowledgeChunk> collection =
    new SomeGaBackedVectorStore<string, KnowledgeChunk>(
        connectionOptions,
        "kb_chunks",
        new VectorStoreCollectionOptions { EmbeddingGenerator = embeddingGenerator });

await collection.EnsureCollectionExistsAsync();
await collection.UpsertAsync(chunk);

await foreach (var result in collection.SearchAsync(question, top: 5))
{
    Console.WriteLine(result.Record.Content);
}

public sealed record KnowledgeChunk
{
    [VectorStoreKey] public required string Id { get; init; }
    [VectorStoreData] public required string Content { get; init; }
    [VectorStoreVector(1536)] public required ReadOnlyMemory<float> Embedding { get; init; }
}
```

> Replace `SomeGaBackedVectorStore` with the connector matching the chosen backend — verify its current package name and GA/preview status via context7 before adding it to a project, per the maturity table above.

---

## Microsoft.Extensions.DataIngestion (preview) — pipeline pattern para adoção futura

Not adopted as default today (preview), but documented so a future migration is straightforward once it reaches GA:

```csharp
IngestionDocumentReader reader = new MarkdownReader();

IngestionChunker<string> chunker = new SemanticSimilarityChunker(
    embeddingGenerator,
    new IngestionChunkerOptions(TiktokenTokenizer.CreateForModel("gpt-5")));

using VectorStoreWriter<string> writer = new(vectorStore, dimensionCount: 1536);

using IngestionPipeline<string> pipeline = new(reader, chunker, writer)
{
    ChunkProcessors = { summaryEnricher },
};

await foreach (var result in pipeline.ProcessAsync(new DirectoryInfo("./knowledge-base"), searchPattern: "*.md"))
{
    Console.WriteLine($"Completed '{result.DocumentId}'. Succeeded: {result.Succeeded}.");
}
```

This maps conceptually onto the existing custom pattern: `IngestionDocumentReader` ≈ the project's document loading step, `IngestionChunker<T>` ≈ the strategies in `data-vector-search-rag-chunking`, `VectorStoreWriter<T>` ≈ `EmbeddingService` + the `kb_embeddings` insert in `ai-agents-rag-custom-pgvector`. `IngestionPipeline<T>.ProcessAsync` returns `IAsyncEnumerable<IngestionResult>` — a single document failure does not abort the whole run (partial success by design).

---

## Anti-patterns

| Anti-pattern | Why it's wrong | Right way |
|--------------|----------------|-----------|
| Refusing to add a VectorData connector because of the "Forbidden: Microsoft.SemanticKernel.*" rule | The rule targets SK orchestration, not VectorData connectors — see the naming-trap section above | Read this standard's exception note before treating any `Microsoft.SemanticKernel.Connectors.*` package as forbidden |
| **Adding `Microsoft.SemanticKernel.Connectors.PgVector` in a new project** | Caminho morto: `1.74.0-preview` de 2026-03-20, sem versão estável | `CommunityToolkit.VectorData.PgVector` 1.0.1 |
| **Citar `Microsoft.Extensions.VectorData.Abstractions` 10.8.2 como "a versão atual"** | 10.8.2 é o **piso da dependência** declarado pelo conector; a corrente é 10.9.0 | Ler a versão no pacote da abstração, não no `.nuspec` de quem depende dela |
| Migrating the working custom pgvector implementation to VectorData "because it's official" | Reescreve uma implementação testada sem ganho funcional. Note que o motivo mudou: já **não** é mais "porque é preview" | Keep `ai-agents-rag-custom-pgvector` as the default; adopt VectorData per the decision matrix |
| Treating `Microsoft.Extensions.DataIngestion` as production-ready | Continua preview em 2026-09-08 (`10.9.0-preview.1.26411.16`), sem versão estável | Track it for future adoption; do not wire it into a shipped feature today |
| Importing `Microsoft.SemanticKernel` (the core orchestration package) to "just get the vector store types" | Pulls in the full SK orchestration surface this framework has deliberately moved away from | Import only `Microsoft.Extensions.VectorData.Abstractions` + the specific `*.Connectors.*` package needed |

---

## Checklist (verifiable by morph-eval)

- [ ] If `Microsoft.SemanticKernel.Connectors.*` appears in a `.csproj`, it is used only for `VectorStoreCollection`/`VectorStore` types — no `Kernel`, `KernelFunction`, or `ChatHistory` usage anywhere in the project.
- [ ] No plain `Microsoft.SemanticKernel` (core) package reference.
- [ ] If VectorData was chosen over custom pgvector, the reason is recorded in `decisions.md` per the decision matrix.
- [ ] No new `Microsoft.SemanticKernel.Connectors.*` reference — new work uses `CommunityToolkit.VectorData.*`.
- [ ] If a preview package (`Microsoft.Extensions.DataIngestion`, or any `*-preview` connector) was adopted, `decisions.md` records the preview-acceptance and a revisit-at-GA note.
- [ ] Every VectorData/ingestion `PackageReference` carries an exact version — these packages are **not** in `framework/ai-pin.json`, so the project's own `decisions.md` (or a comment) states when the version was checked.
- [ ] Embedding model/dimensions consistent between the `VectorStoreVector(N)` attribute and the chosen embedding model.

---

## References

- `ai-agents-rag-custom-pgvector` — the default, GA-quality custom RAG implementation this standard complements
- `ai-agents-setup` — the `Microsoft.SemanticKernel.*` "Forbidden" rule this standard carves an exception into
- `ai-agents-providers-model-registry` — `embeddings` alias, `IEmbeddingGenerator` wiring
- `data-vector-search-rag-chunking` — chunk strategies (conceptual counterpart to `IngestionChunker<T>`)
- Data ingestion - .NET | Microsoft Learn: https://learn.microsoft.com/en-us/dotnet/ai/conceptual/data-ingestion
- AI and Vector Data Extensions GA announcement: https://devblogs.microsoft.com/dotnet/ai-vector-data-dotnet-extensions-ga/
- Introducing Data Ingestion Building Blocks (Preview): https://devblogs.microsoft.com/dotnet/introducing-data-ingestion-building-blocks-preview/
- Vector stores overview: https://learn.microsoft.com/en-us/dotnet/ai/vector-stores/overview
- `CommunityToolkit.VectorData.*` — repositório https://github.com/CommunityToolkit/AI (apurado 2026-09-08)

---

*MORPH-SPEC by Polymorphism Tech — ai-agents/vector-data-extensions.md v2.0 (2026-09-08)*
