Deprecated & Outdated
Key Points
Things that were canonical in 2024 but should NOT be used in new code in 2026. The .NET AI ecosystem moved fast.
Semantic Kernel-only orchestration → Microsoft Agent Framework
Old (2024): Semantic Kernel as the canonical .NET AI orchestrator. SK Planners. SK ChatHistory. AutoGen for multi-agent.
New (2026): Microsoft Agent Framework (GA April 2026). Replaces SK orchestration + AutoGen. Built on Microsoft.Extensions.AI.
SK still useful for: existing apps; prompt template engine; some plugins. Don't START new projects with SK as the orchestrator. See SK vs Agent Framework.
SK Planners (Sequential, Stepwise, Handlebars) → FunctionChoiceBehavior.Auto
Old: SequentialPlanner, StepwisePlanner, HandlebarsPlanner generated multi-step plans via LLM and executed.
New: FunctionChoiceBehavior.Auto + iteratively-called LLM. The LLM decides when/which tools to call; runtime invokes; repeat. Modern reasoning models do this natively.
Planners are explicitly deprecated. See Deprecated Planners.
OpenAI SDK directly → Microsoft.Extensions.AI
Old: OpenAIClient from Azure.AI.OpenAI (or OpenAI package) used directly.
New: IChatClient abstraction. Wrap the vendor SDK; gain pipeline (caching, telemetry, function calling) + vendor portability.
// Old
var client = new OpenAIClient(apiKey);
var resp = await client.GetChatCompletionsAsync(...);
// New
IChatClient chat = new OpenAIClient(apiKey).AsChatClient("gpt-4o-mini")
.AsBuilder().UseFunctionInvocation().UseLogging(...).Build();
var resp = await chat.GetResponseAsync("Hello");
Custom JSON tools → Function calling via attributes
Old: Hand-written JSON tool schemas; manual dispatch.
New: [Description] + reflection auto-generates schemas. UseFunctionInvocation() middleware auto-dispatches.
[Description("Get current weather for a city")]
async Task<Weather> GetWeather([Description("City name")] string city) => ...;
ChatHistory class → IList
Old: SK's ChatHistory class.
New: IList<ChatMessage> from Microsoft.Extensions.AI. Lighter; vendor-neutral.
BinaryFormatter for state → JSON / MessagePack
Same as elsewhere in .NET — BinaryFormatter removed in .NET 9. For agent state persistence, JSON or MessagePack.
Per-vendor embedding code → IEmbeddingGenerator
// Old
var emb = await openAiClient.GetEmbeddingsAsync(...);
// New
IEmbeddingGenerator<string, Embedding<float>> gen = ...;
var emb = await gen.GenerateAsync(["text"]);
Hand-rolled vector store → Microsoft.Extensions.VectorData
Old: Custom IVectorRepository with provider-specific code.
New: [VectorStoreKey], [VectorStoreVector] attributes; same DTO across Azure AI Search, Cosmos, Qdrant, pgvector. See Microsoft.Extensions.VectorData.
Old function calling formats → JSON Schema strict
OpenAI shifted to strict JSON Schema mode for function calling. Old "best-effort" function definitions superseded.
new ChatOptions { Tools = [AIFunctionFactory.Create(GetWeather)] };
// Schema auto-generated; strict mode default.
Single-vendor agents → MCP-pluggable
Old: Each agent has hard-coded tool implementations per vendor.
New: Tools served via MCP servers (any language). Agent becomes a thin orchestrator; tools are reusable across Claude, ChatGPT, Copilot, custom.
Long-context dump → RAG / structured retrieval
Old: Stuff entire knowledge base into prompt. Token-expensive; LLM accuracy degrades on long context.
New: Retrieve top-K relevant chunks; smaller, focused prompts. Even with 1M+ context windows (Claude, Gemini), retrieval improves quality + cost.
Hardcoded model strings → IChatClientFactory
Old: "gpt-4" literal everywhere.
New: Inject IChatClient via DI; model choice in config. Swap providers via configuration only.
CosmosDB without vector index → Cosmos NoSQL with VectorDistance
Old: Custom indexing of embeddings in Cosmos.
New: Native vector index in Cosmos NoSQL (.NET 9+ preview / GA depending on tier). SELECT TOP 10 ... ORDER BY VectorDistance(c.embedding, @e).
SignalR for streaming chat → IAsyncEnumerable + SSE
Old: SignalR hub for streaming LLM tokens.
New: IChatClient.GetStreamingResponseAsync() returns IAsyncEnumerable. Stream over SSE. Simpler.
await foreach (var update in chat.GetStreamingResponseAsync(prompt, ct))
yield return update.Text ?? "";
"Prompt injection? Trust users" → Defense in depth
Old: Hope nothing bad happens.
New: - Spotlighting (mark user input). - Azure Content Safety Prompt Shields. - Output validation. - Don't give agents raw access to systems without confirmation.
Per-request model picking based on user → Routing as policy
Old: Free-form code branching on model.
New: Centralized policy (cheap → smart escalation; cost cap; tenant tier). Encapsulated routing.
Synchronous batch evals → CI eval pipelines
Old: Eval on demand.
New: Automated eval suite in CI. Track regressions. Tools: Ragas, Prompt Flow, custom.
What to AVOID starting fresh in 2026
- ❌ SK as primary orchestrator.
- ❌ SK Planners.
- ❌ Direct OpenAI SDK (skip the abstraction).
- ❌ Manual function calling JSON.
- ❌
BinaryFormatter. - ❌ Hardcoded model names.
- ❌ "Stuff everything in context" RAG anti-pattern.
- ❌ No prompt injection defense.
- ❌ No telemetry on AI calls.
What to CHOOSE in 2026
- ✅
Microsoft.Extensions.AIeverywhere. - ✅ Microsoft Agent Framework for orchestration.
- ✅ MCP for tools.
- ✅
Microsoft.Extensions.VectorDatafor vector stores. - ✅ Function calling via reflection + auto.
- ✅ OTel GenAI for telemetry.
- ✅ Eval pipelines in CI.