你有没有遇到过这种情况:开发时用 Ollama 跑本地模型,上线要切 Azure OpenAI,备选路径还得兼容 Anthropic,结果每换一次后端就要把调用代码从头改到尾,配置反而成了最没用东西。
这不是个例。一位开发者此前用 OpenAI 的原始嵌入调用搭了个语义搜索接口,几个月后又用 Ollama 搞了个本地优先的助手,两个项目干得是同一件事——发消息、收回复、偶尔流式输出、再让模型调个函数——但代码长得完全不一样。原因很简单,OpenAIClient 和 OllamaApiClient 没有一个共同的形状,换了提供商就等于换了套调用方式。
![]()
这个痛点,正是 Microsoft.Extensions.AI(MEAI)要终结的。它并不是又一个庞大的 SDK 去和各个厂商的官方库抢地盘,而是在那些库的前面加了一层轻量的、与提供商无关的抽象接口,再附上一套依赖注入友好的中间件——缓存、日志、遥测、自动工具调用——不管你后端接的是哪个模型,这些中间件的表现完全一致。
这套抽象的核心非常薄。Microsoft.Extensions.AI.Abstractions 包里只有契约:IChatClient、IEmbeddingGenerator,以及还在实验阶段的 IImageGenerator。库作者只要依赖它,就能让自己的提供商 SDK 接入整个生态。而应用只需要引用 Microsoft.Extensions.AI 主包,它会把抽象拉进来的同时,装上真正干活的部分:中间件管道、DI 注册扩展、自动函数调用机制。
接入方式也简单。只需要两行 nuget:
dotnet add package Microsoft.Extensions.AIdotnet add package Microsoft.Extensions.AI.Ollama
每个接入的提供商——OpenAI、Azure OpenAI、Azure AI Inference、Ollama(通过 OllamaSharp)——都会暴露同一个抽象下的 IChatClient 或 IEmbeddingGenerator。开发者在构造函数里换个实现,所有调用点完全不用动。
最小化用法只有三行代码:
IChatClient client = new OllamaApiClient(new Uri("http://localhost:11434/"), "phi3:mini");Console.WriteLine(await client.GetResponseAsync("What is AI?"));
而真实的对话管理也不过是把消息记录维护成一个 ChatMessage 列表,每次把历史喂回去即可。模型返回的回复会被自动附加到历史里,下一轮接着用:
List history = [];while (true) { Console.Write("Q: "); history.Add(new(ChatRole.User, Console.ReadLine()!)); ChatResponse response = await client.GetResponseAsync(history); Console.WriteLine(response); history.AddMessages(response);}
这套机制的核心价值就是把“换模型”从一个需要重写调用点的工程动作,降级成一个配置层面的变动。中间件和调用逻辑彻底解耦了模型提供商,让日志、缓存、遥测这些横切能力一次配置、处处生效,不再随模型而变。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.