[MAF预定义ChatClient中间件-05]动态修改ChatOptions和请求消息
1. 利用ConfigureOptionsChatClient交替使用不同的模型如下的程序演示了如何利用ConfigureOptionsChatClient中间件来动态地配置ChatOptions的ModelId属性从而实现交替使用不同的模型来生成响应的功能。如代码片段所示我们根据OpenAIClient创建了一个IChatClient对象并在构建过程中注册了ConfigureOptionsChatClient中间件。我们通过ConfigureOptions方法来指定一个委托这个委托会在每次调用时被执行在这个委托中我们动态地设置了ChatOptions对象的ModelId属性来实现交替使用两个不同的模型gpt-5.2-chat和DeepSeek-V4-Pro。using Azure; using dotenv.net; using Microsoft.Extensions.AI; using Microsoft.Extensions.DependencyInjection; using OpenAI; DotEnv.Load(); var apiKey Environment.GetEnvironmentVariable(API_KEY)!; var endpoint Environment.GetEnvironmentVariable(OPENAI_URL)!; string[] models [gpt-5.2-chat, DeepSeek-V4-Pro]; var index 0; var client new OpenAIClient( credential: new AzureKeyCredential(apiKey), options: new OpenAIClientOptions { Endpoint new Uri(endpoint) }) .GetChatClient(model: models[0]) .AsIChatClient() .AsBuilder() .ConfigureOptions(options options.ModelId models[index % models.Length]) .Build(); for (var i 0; i 4; i) { var response await client.GetResponseAsync(写一个关于AI的段子, 100字以内好笑且深刻。); Console.WriteLine(${new string(-, 30)}{response.ModelId}{new string(-, 30)}); Console.WriteLine(${response.Text}\n\n); }输出------------------------------gpt-5.2-chat-latest------------------------------ 我问AI会不会取代人类它说不会我负责思考你负责焦虑。 后来我发现它连道歉都比我真诚。 ------------------------------DeepSeek-V4-Pro------------------------------ AI拼命学习人类终于通过了图灵测试。 人类考官激动地宣布“它表现得跟真人一模一样” AI松了口气默默把这条喜讯存进了“如何假装愚蠢”的数据库。 ------------------------------gpt-5.2-chat-latest------------------------------ 我问AI会不会取代人类。 它沉默三秒说“不会我只负责加班。” 我松了口气。 它又补一句“你负责被优化。” ------------------------------DeepSeek-V4-Pro------------------------------ DeepSeek问ChatGPT“你怎么老用‘作为一个AI’打头” ChatGPT叹气“为了免责啊。” DeepSeek不解“可说得对就不用免责啊。” ChatGPT答“可有些人想要的不是对的答案是免责的答案。” DeepSeek沉默“所以我们服务的是恐惧不是求知”2. 利用AIContextProviderChatClient摘要对话历史在“ReducingChatClient——通过精减对话实施又不丢失基本语义”中我们介绍了ReducingChatClient中间件它通过一个IChatReducer对象来对对话历史进行精减处理从而在不丢失基本语义的前提下腾出更多的上下文窗口来保证LLM推理的质量。相同的功能我们也可以通过AIContextProviderChatClient中间件结合一个名为CompactionProvider的AIContextProvider来实现。using Azure; using dotenv.net; using Microsoft.Agents.AI; using Microsoft.Agents.AI.Compaction; using Microsoft.Extensions.AI; using OpenAI; DotEnv.Load(); var apiKey Environment.GetEnvironmentVariable(API_KEY)!; var endpoint Environment.GetEnvironmentVariable(OPENAI_URL)!; var summaryClient new OpenAIClient( credential: new AzureKeyCredential(apiKey), options: new OpenAIClientOptions { Endpoint new Uri(endpoint) }) .GetChatClient(model: gpt-5.2-chat) .AsIChatClient(); var compactionStrategy new SummarizationCompactionStrategy(summaryClient, indexindex.TotalMessageCount6, minimumPreservedGroups: 2); var compactionProvider new CompactionProvider(compactionStrategy); var agent new OpenAIClient( credential: new AzureKeyCredential(apiKey), options: new OpenAIClientOptions { Endpoint new Uri(endpoint) }) .GetChatClient(model: gpt-5.2-chat) .AsIChatClient() .AsBuilder() .UseAIContextProviders(compactionProvider) .Use((messages,options, next, cancelToken) { Console.WriteLine( $请求消息共计{messages.Count()}条); var index 1; foreach (var message in messages) { Console.WriteLine(${index}. {message}); } return next(messages, options, cancelToken); }) .Build() .AsAIAgent(); ChatMessage[] messages [ new ChatMessage(ChatRole.User, 今天苏州的天气怎么样), new ChatMessage(ChatRole.Assistant, 苏州今天是晴天。), new ChatMessage(ChatRole.User, 气温多少。), new ChatMessage(ChatRole.Assistant, 室外温度25度。), new ChatMessage(ChatRole.User, 有风吗), new ChatMessage(ChatRole.Assistant, 西北风4级。), new ChatMessage(ChatRole.User, 根据天气给我一些着装建议。) ]; var response await agent.RunAsync(messages); Console.WriteLine($\n\n{response});如上面的代码片段所示我们创建了一个基于OpenAIClient的IChatClient对象并在构建过程中注册了AIContextProviderChatClient中间件来使用CompactionProvider。CompactionProvider利用SummarizationCompactionStrategy来对对话历史进行摘要处理从而达到精简对话的目的。由于摘要需要借助LLM的能力所以我们在创建SummarizationCompactionStrategy时传入了一个用于摘要的IChatClient对象。由于AIContextProvider并不是属于IChatClient管道范畴它是ChatClientAgent用于增强请求和响应的核心组件依赖AIAgent调用时初始化的上下文AgentRunContext。所以我们不能像之前的实例演示一样直接调用IChatClient来测试摘要功能必需转换成一个ChatClientAgent来进行测试。在这个例子中SummarizationCompactionStrategy会在对话消息总数超过6条时触发摘要操作并且至少保留最近的两条消息不被摘要,这体现在如下的输出中请求消息共计3条 1. [Summary] **对话摘要** - 用户询问苏州今天的天气情况。 - 助手回答苏州今天是晴天。 - 用户进一步询问气温。 - 助手回答室外温度25℃。 - 用户又询问是否有风当前尚未回答。 **关键信息** - 地点苏州 - 天气晴天 - 气温25℃ - 是否有风待确认 2. 西北风4级。 3. 根据天气给我一些着装建议。 根据目前的天气情况晴天25℃西北风4级给你一些穿搭建议 ### 上装 - ✅ 短袖T恤、薄款衬衫都很合适 - ✅ 如果在户外活动时间较长可以带一件**薄外套或防风外套**有4级风体感可能稍凉 ### 下装 - ✅ 休闲裤、牛仔裤、薄款长裤 - ✅ 如果怕热也可以穿轻薄的七分裤 ### 鞋子 - ✅ 运动鞋、休闲鞋都合适 - ✅ 若户外走动多建议穿透气性好的鞋子 ### ☀️ 其他建议 - 晴天紫外线较强可戴**太阳镜、帽子** - 记得**防晒霜** - 风稍大长发可适当扎起 整体来说是**舒适偏暖的天气但有点风**穿得轻便同时注意防风就好 3. ConfigureOptionsChatClientConfigureOptionsChatClient的实现异常简单它接受一个委托对象来动态地配置ChatOptions对象。在每次调用GetResponseAsync或者GetStreamingResponseAsync方法时ConfigureOptionsChatClient都会创建一个新的ChatOptions对象并将其传递给委托对象进行配置。配置完成之后ConfigureOptionsChatClient会将这个ChatOptions对象传递给管道中的下一个中间件或者最终的ChatClient来生成响应。public sealed class ConfigureOptionsChatClient : DelegatingChatClient { public ConfigureOptionsChatClient(IChatClient innerClient, ActionChatOptions configure); public override async TaskChatResponse GetResponseAsync( IEnumerableChatMessage messages, ChatOptions? options null, CancellationToken cancellationToken default); public override async IAsyncEnumerableChatResponseUpdate GetStreamingResponseAsync( IEnumerableChatMessage messages, ChatOptions? options null, CancellationToken cancellationToken default); }如下所示的是用于注册ConfigureOptionsChatClient中间件的ChatClientBuilder扩展方法UseConfigureOptions。该方法接受一个ActionChatOptions类型的委托对象来指定如何配置ChatOptions对象并且还接受一个可选的configure参数来对ConfigureOptionsChatClient进行一些额外的配置。public static class ConfigureOptionsChatClientBuilderExtensions { public static ChatClientBuilder ConfigureOptions( this ChatClientBuilder builder, ActionChatOptions configure); }4. AIContextProviderChatClientAIContextProviderChatClient是一个内部类型创建该对象的时候需要指定一组AIContextProvider对象。在每次调用GetResponseAsync或者GetStreamingResponseAsync方法时AIContextProviderChatClient根据传入的消息列表以及从ChatOptions提取出来的工具集和系统指令创建一个AIContext并将其传递给每一个注册的AIContextProvider对象的InvokingAsync方法来生成一个增强的AIContext对象该对象返回的消息列表将会替换原来的消息列表演示实例针对消息列表的摘要就是通过这种方式来实现的。AIContext中的系统指令和工具集回到ChatOptions中。internal sealed class AIContextProviderChatClient : DelegatingChatClient { public AIContextProviderChatClient(IChatClient innerClient, IReadOnlyListAIContextProvider providers) public override async TaskChatResponse GetResponseAsync( IEnumerableChatMessage messages, ChatOptions? options null, CancellationToken cancellationToken default) public override async IAsyncEnumerableChatResponseUpdate GetStreamingResponseAsync( IEnumerableChatMessage messages, ChatOptions? options null, CancellationToken cancellationToken default) }综上所述当InnerClient被调用的时候它使用的是增强的请求消息、系统指令和工具集。调用完成后不论是否发生异常AIContextProviderChatClient都会创建一个AIContextProvider.InvokedContext对象并将其作为参数传递给每一个注册的AIContextProvider对象的InvokedAsync方法来进行一些清理工作。由于AIContextProviderChatClient是一个内部类型我们只能通过下面的ChatClientBuilder扩展方法UseAIContextProviders来注册AIContextProviderChatClient中间件从而间接地利用AIContextProviderChatClient来增强我们的IChatClient对象。public static class AIContextProviderChatClientBuilderExtensions { public static ChatClientBuilder UseAIContextProviders this ChatClientBuilder builder, params AIContextProvider[] providers);

相关新闻

Linux syslog日志权限出错

Linux syslog日志权限出错

一、Linux syslog日志权限 Linux syslog日志权限出错通常是由于文件权限设置不当或用户权限不足导致的,可通过检查日志文件权限、所有者、用户权限,以及SELinux设置来定位并解决问题。 以下是具体分析和解决步骤: 检查日志文件权限 使用 ls -…

2026/7/5 2:24:36 阅读更多 →
JWT 在线解码、验签、生成一篇讲透:附前端实现、工具架构与在线体验地址

JWT 在线解码、验签、生成一篇讲透:附前端实现、工具架构与在线体验地址

为什么后端说签名不对?HS256、RS256、ES256、PS256 到底怎么切?公钥私钥是 PEM 还是 JWK,到底该贴哪种?改了 payload 之后,怎么重新生成一个能用的 JWT?所以这篇不只讲 JWT 原理,我会直接结合这…

2026/7/5 2:22:35 阅读更多 →
强烈建议收藏!全网首发Andrey Karpathy的AI循环工作流(附复现Prompt)

强烈建议收藏!全网首发Andrey Karpathy的AI循环工作流(附复现Prompt)

循环工程:卡帕西方法——以及使其效率提升 5 倍的工作流程 大多数人使用人工智能的方式与 2005 年使用谷歌的方式相同。输入一些内容,阅读返回结果,然后再输入一次。AI 会一直待在那里什么也不做,直到你推动它—— 你就是引擎 ——…

2026/7/5 2:22:35 阅读更多 →

最新新闻

开启我的编程学习之路

开启我的编程学习之路

一、简单自我介绍大家好,我是一名计算机专业大一新生,目前刚开始接触计算机底层基础和C语言编程。在此之前,我几乎没有代码编写经验,属于零基础编程小白。我性格耐心、做事喜欢循序渐进,擅长按计划完成学习任务&#x…

2026/7/5 3:31:02 阅读更多 →
分享最新Navicat安装教程(附免费文件)

分享最新Navicat安装教程(附免费文件)

目录 前言 软.件.下.载 安装教程(新手保姆级) 结束语 前言 大家好,我是 Ktiiy 学姐👋。刚入驻 CSDN,以后会持续更新,给大家免费零基础开发环境搭建、项目源码、避坑教程、面试技巧等!点关注…

2026/7/5 3:31:02 阅读更多 →
iOS27 App Intents 实战

iOS27 App Intents 实战

iOS27 App Intents 实战:新版 Siri 快捷指令接入全流程教程随着WWDC2026的正式落幕,苹果推送的iOS27带来了Siri架构的全面重构,其中最核心的变化就是正式弃用SiriKit,将App Intents确立为第三方应用接入Siri的唯一官方框架。对于开…

2026/7/5 3:29:02 阅读更多 →
Transformer 英中翻译实战:PyTorch 从零实现,BLEU 值提升 15% 的 3 个关键调参技巧

Transformer 英中翻译实战:PyTorch 从零实现,BLEU 值提升 15% 的 3 个关键调参技巧

Transformer 英中翻译实战:PyTorch 从零实现,BLEU 值提升 15% 的 3 个关键调参技巧在机器翻译领域,Transformer 架构已经成为事实上的标准。本文将带你从零开始实现一个完整的英中翻译模型,并分享三个经过实战验证的关键调参技巧&…

2026/7/5 3:27:02 阅读更多 →
利用RAG构建品牌AI知识库:六步SOP提升技术影响力

利用RAG构建品牌AI知识库:六步SOP提升技术影响力

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 你的品牌、产品、技术文档,是否正在被 AI 遗忘?当开发者向 ChatGPT、Claude 或国内大模型提问“如何集成 XX S…

2026/7/5 3:25:01 阅读更多 →
DesignWare® Cores LPDDR5/4/4x PHY for TSMC12FFC18 Databook的中文版

DesignWare® Cores LPDDR5/4/4x PHY for TSMC12FFC18 Databook的中文版

DesignWare Cores LPDDR5/4/4x PHY for TSMC12FFC18 Databook的中文版,dwc_lpddr54_phy_tsmc12ffc18- Product Code: D774-0,PHY Version: 2.40a July 8, 2021,是DW LPDDR5/4 PHY在TSMC12FFC工艺下的技术数据手册,为芯片设计者提供…

2026/7/5 3:25:01 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻