魅力程序猿

  • 首页
  • Java
  • Android
  • APP
    • 扑克计分器
    • Video Wallpaper
  • 联系我
  • 关于我
  • 资助
道子
向阳而生
  1. 首页
  2. AI技术
  3. 正文

[MAF预定义ChatClient中间件-04]ReducingChatClient——通过精减对话实施又不丢失基本语义

2026年6月8日 12点热度 0人点赞 0条评论

📰 来源: 博客园


绝大部分的Agent都采用对话的方式来和用户进行交互,所以对话的内容就成了Agent决策的基础,对话历史也成为占据LLM上下文窗口的主要内容。LLM推理的质量并非与上下文的丰富程度成正向关系,有时候过多的上下文信息反而会干扰Agent的判断,导致它做出错误的决策。ReducingChatClient就是为了解决这个问题而设计的一个中间件,它通过精减对话内容来帮助Agent更好地理解用户的意图,从而做出更准确的决策。为上下文窗口腾出更多空间也是保证可靠性的一种基本的手段。

1. 利用ReducingChatClient摘要对话内容

如下的程序演示了如何利用ReducingChatClient来部分对话内容进行摘要,保证在不丢失基本语义的前提下,腾出更多的上下文窗口。如代码片段所示,我们基于OpenAIClient创建了一个IChatClient对象,并在此基础上利用ChatClientBuilder注册了ReducingChatClient中间件,并指定了一个SummarizingChatReducer对象来提供基于摘要的队对话精减功能。我们在创建SummarizingChatReducer对象的时候,传入了一个用于对摘要进行生成的ChatClient对象,该对象依然是基于OpenAIClient创建的,并且使用了相同的模型来生成摘要。我们还为SummarizingChatReducer对象指定了targetCount和threshold两个参数,前者表示我们希望在摘要之后保留多少条消息,后者则是一个阈值,用于触发摘要操作的阈值(超过targetCount+threshold)。

using Azure;
using dotenv.net;
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: "DeepSeek-V4-Pro")
    .AsIChatClient();

var client = new OpenAIClient(
    credential: new AzureKeyCredential(apiKey),
    options: new OpenAIClientOptions { Endpoint = new Uri(endpoint) })
    .GetChatClient(model: "gpt-5.2-chat")
    .AsIChatClient()
    .AsBuilder()
    .UseChatReducer(reducer: new SummarizingChatReducer(chatClient:summaryClient, targetCount: 3, threshold:1))
    .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();

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 client.GetResponseAsync(messages);
Console.WriteLine($"\n\n{response}");

为了查看经过ReducingChatClient精减之后的对话历史,我们在ChatClientBuilder中注册了一个简单的中间件来输出当前传入的消息列表。IChatClient管道构建成功之后,我们调用GetResponseAsync方法并指定了一组消息(共7条)来模拟一段对话的历史。由于我们在ReducingChatClient中指定了targetCount为3,并且threshold为1,必然会触发摘要操作。摘要完成后,保留了最后三条消息,只对对前4条消息进行了摘要,这一切体现在如下的输出中:

请求消息共计4条
1. 用户询问了今天苏州的天气情况,助手回答为晴天。随后用户进一步询问气温,助手回答室外温度为25度。对话围绕苏州当日的天气状况和具体气温展开,内容简洁明确。
2. 有风吗?
3. 西北风4级。
4. 根据天气,给我一些着装建议。


今天苏州**晴天,25℃,西北风4级**,体感会比较清爽,风稍微有点明显。给你一些穿搭建议:

### 👕 上衣
- **短袖T恤、薄衬衫**都可以
- 如果怕风,建议带一件**薄外套/防风夹克**

### 👖 下装
- **牛仔裤、休闲裤**都合适
- 不怕冷的话也可以穿**薄款长裙/半裙**

### 👟 鞋子
- 运动鞋、休闲鞋都很舒服
- 风有点大,尽量避免太轻薄易飘的穿搭

### 🌞 其他建议
- 晴天紫外线可能偏强,出门可以**戴太阳镜、涂防晒**
- 风力4级骑车会有点顶风,注意安全

整体来说是**舒适偏清爽型天气**,穿得轻松一点就好 👍

2. IChatReducer

ReducingChatClient的核心是IChatReducer接口,我们可以称之为精简器。它定义了一个ReduceAsync方法,用于对传入的消息列表进行精减处理。我们可以通过实现IChatReducer接口来定义自己的消息精减策略,从而满足不同场景下的需求。

public interface IChatReducer
{
	Task<IEnumerable<ChatMessage>> ReduceAsync(
        IEnumerable<ChatMessage> messages, 
        CancellationToken cancellationToken);
}

2.1 SummarizingChatReducer

SummarizingCh


🔗 原文链接: 点击阅读原文

标签: AI 人工智能 技术博客
最后更新:2026年6月8日

daozi

这个人很懒,什么都没留下

点赞
< 上一篇

文章评论

您需要 登录 之后才可以评论
搜索
联系方式

QQ群:179730949
QQ群:114559024
欢迎您加入Android大家庭
本人QQ:136049925

赐我一丝安慰
给我一点鼓励

COPYRIGHT © 2023 魅力程序猿. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备15000477号