Building an AI Agent Platform on .NET 10
Why we built an AI agent platform on .NET 10: the architecture, the Microsoft.Extensions.AI abstractions, pgvector for RAG, and the trade-offs.
We built AIML.chat's backend on .NET 10 because the platform needed a fast, statically typed, long-term-supported runtime with first-class AI abstractions — and the Microsoft.Extensions.AI libraries gave us provider-swappable chat and embedding interfaces without locking us to one vendor. This is the reasoning behind that choice and the architecture it produced.
The shape of the problem
An AI agent platform is mostly plumbing around a model: ingest a site's content, chunk and embed it, store the vectors, retrieve the right chunks for a query, assemble a prompt, stream the response, and record analytics — all multi-tenant, all under quota. The model call is a small part; the reliability, the data layer, and the throughput are most of the work. That favors a runtime that is fast, strongly typed, and boring in the good sense: predictable performance, mature tooling, and a long support horizon so the foundation does not shift under a young product.
.NET 10 LTS fit that brief. The static typing catches whole classes of bugs before they ship, the performance handles concurrent streaming without drama, and the long-term-support window means we are not rewriting the core to chase a runtime.
AI abstractions without lock-in
info
Microsoft.Extensions.AI gives us IChatClient and IEmbeddingGenerator as provider-neutral interfaces. We code against those, and the concrete provider is a configuration detail — swappable without touching feature code.
This mattered more than any single model's quality. Models and prices change monthly; an agent platform that hard-codes one provider is betting the company on that provider's roadmap. By coding to the abstractions, we keep the chat model and the embedding model as config, so we can change either as the market moves. The same discipline applies to billing, which sits behind an IBillingProvider interface so the payment vendor never leaks into business logic.
RAG on PostgreSQL and pgvector
For retrieval we chose PostgreSQL with the pgvector extension rather than a dedicated vector database. The reasoning was operational simplicity: one database for relational data and vectors means one thing to run, back up, and reason about, which is the right trade-off for a small team optimizing for shipping speed. pgvector's cosine similarity search handles top-k retrieval well, and an HNSW index keeps it fast as a site's chunk count grows. When a single site crosses a large chunk threshold, a per-site index keeps queries quick without over-engineering the common case.
Vertical slices over layered architecture
The codebase is organized as vertical slices — one folder per feature, each holding its endpoint, handler, validators, and DTOs — rather than horizontal layers. For a product racing toward a clear goal, that structure keeps each feature self-contained and easy to change, and avoids the ceremony of a deeply layered architecture that pays off only at a scale we may never need. We hand-rolled a tiny CQRS dispatcher instead of pulling in a heavier library, on the rule that we would adopt something bigger only if the handler count actually demanded it. The theme throughout is choosing the simplest thing that holds up, and revisiting only when reality forces it.
Getting started
You can try the platform these choices produced on the AIML.chat free plan: index your content and see grounded, cited answers. Read why we chose .NET over Python for AI, why MCP over custom tool APIs, and compare tiers on the pricing page.
Why .NET 10 instead of Python for an AI product?+
The work is mostly reliable, concurrent plumbing around model calls. Static typing, performance, and an LTS support window favored .NET; the AI abstractions closed the ecosystem gap.
Why PostgreSQL and pgvector over a dedicated vector database?+
Operational simplicity — one database for relational data and vectors is one less thing to run and reason about, which suits a small team optimizing for shipping speed.
How do you avoid AI vendor lock-in?+
We code against Microsoft.Extensions.AI's provider-neutral interfaces, so the chat and embedding providers are configuration details we can swap without touching feature code.
Related reading
Get the AIML.chat newsletter
Practical tips on AI docs assistants, RAG, and growing with content — a couple of emails a month. No spam, unsubscribe anytime.
Double opt-in — we'll email you to confirm.