智能对话压缩技术:持久化与上下文管理革新

发布时间:2026/7/23 21:11:00

智能对话压缩技术:持久化与上下文管理革新
会话能恢复不等于会话能无限增长。把AgentState存进 PostgreSQL解决的是应用重启后还能不能接着聊。任务持续几小时甚至几天后另一个问题会慢慢冒出来用户消息、模型回答、工具调用和工具结果越积越多每轮推理都要带上更长的历史。继续原样发送调用会越来越慢token 成本也会增加最后还可能超过模型的上下文窗口。AgentScope Java 的Compaction会把较早的对话整理成一条摘要最近的消息仍保留原文text较早的对话 最近 2 条消息压缩后一条上下文摘要 最近 2 条原始消息摘要会尽量保留当前目标、已确认信息和待办事项。模型不需要重新读取整段历史也能继续处理当前任务。一、持久化保存会话Compaction 控制会话长度AgentStateStore和Compaction操作的是同一份会话状态但职责不同。能力负责什么AgentStateStore保存和恢复AgentStateCompaction缩短AgentState里的历史消息只有 PostgreSQL没有压缩重启后确实能恢复会话但恢复出来的历史仍会继续增长。只有压缩没有持久化当前进程里的上下文变短了应用重启后仍然找不回原来的任务。两者放在一起链路是这样的text从 PostgreSQL 恢复 AgentState- 加入本轮用户消息- 模型推理前检查压缩条件- 较早消息变成摘要最近消息保留原文- 模型继续处理本轮请求- 更新后的 AgentState 写回 PostgreSQL现有 Web Agent 已经有 Workspace、PostgreSQL 状态存储和 SSE 接口。接入上下文压缩不需要改 Controller、Service、事件对象和接口地址也不用新增 Maven 依赖。代码变化集中在三个位置textapplication.yml- 增加压缩参数和摘要提示词DevAgentProperties- 接收新增配置AgentScopeConfiguration- 创建 CompactionConfig并交给 HarnessAgent二、接入 Compaction只改三个位置1. application.yml 增加压缩参数原有模型、Workspace 和数据源配置保持不变只在app.dev-agent下增加compactionyamlapp:dev-agent:compaction:trigger-messages: 6keep-messages: 2summary-prompt: |请把下面的会话整理成一份供后续任务继续使用的上下文摘要。只保留用户目标、已经确认的事实、尚未完成的事项和明确编号。不要补充会话中没有出现的信息。使用下面的结构## 当前目标## 已确认信息## 待处理事项会话内容{messages}trigger-messages: 6的“消息”不是六次提问而是参与推理的非 System 消息。一次普通问答通常包含一条 User 消息和一条 Assistant 消息如果模型调用工具工具调用会放在 Assistant 消息里执行结果还会追加 Tool 消息。keep-messages: 2表示普通情况下保留最近两条消息原文。如果切分位置落在工具调用和工具结果之间框架会调整边界实际保留条数可能变化。这里的阈值只是为了快速触发效果。正式环境更适合结合模型上下文窗口、工具结果大小和任务平均轮数来定。2. DevAgentProperties 接住新配置DevAgentProperties原来只接收 Agent、Workspace 和模型配置。现在增加一个Compaction字段javapublic record DevAgentProperties(NotBlank String name,NotBlank String systemPrompt,NotBlank String projectRoot,NotBlank String workspaceRoot,Valid Compaction compaction,Valid Model model) {public record Compaction(Min(2) int triggerMessages,Min(1) int keepMessages,NotBlank String summaryPrompt) {}}Valid让嵌套配置参与校验Min给消息阈值和保留条数设置下限。应用启动时就能发现明显错误不必等到会话压缩时再报错。3. 把 CompactionConfig 交给 HarnessAgentapplication.yml里的参数不能直接传给HarnessAgent先将它们转换成 AgentScope 使用的CompactionConfigjavaBeanCompactionConfig compactionConfig(DevAgentProperties properties) {DevAgentProperties.Compaction config properties.compaction();return CompactionConfig.builder().triggerMessages(config.triggerMessages()).keepMessages(config.keepMessages()).keepTokens(0).summaryPrompt(config.summaryPrompt()).flushBeforeCompact(false).offloadBeforeCompact(false).build();}现有配置原来明确关闭了压缩java.disableCompaction()现在把它替换成java.compaction(compactionConfig)HarnessAgent的 Bean 方法只需要多接收一个CompactionConfigjavaBeanHarnessAgent devAgent(Model deepSeekModel,DevAgentProperties properties,CompactionConfig compactionConfig,AgentStateStore agentStateStore,ProjectInfoTools projectInfoTools,FileChangeTool fileChangeTool)throws IOException {HarnessAgent agent HarnessAgent.builder()// 省略已有配置.compaction(compactionConfig).build();// 省略工具注册return agent;}完成这三处调整后压缩能力就接进现有 Agent 了配置对象负责接收参数CompactionConfigBean 负责组装框架配置HarnessAgent负责启用。工具注册、权限规则、Workspace 和AgentStateStore都沿用现有实现。这里有三个容易混淆的配置。keepTokens(0)表示按keepMessages保留最近消息。如果设置为大于 0 的值框架会按固定 token 预算保留尾部设置为-1时才是根据模型上下文窗口动态计算。flushBeforeCompact(false)关闭压缩前的长期记忆提取。当前示例只验证会话摘要不把旧对话另外写入 Memory。offloadBeforeCompact(false)关闭压缩前的原始消息归档。如果系统有审计或历史检索要求可以开启它把压缩前的完整消息保存到 Workspace 下的会话 JSONL 文件。三、压缩发生在模型下一次推理前CompactionMiddleware工作在onReasoning阶段。每次模型准备推理时它先检查当前对话是否达到消息数或 token 阈值。触发后会走下面这条链路text取出当前消息- 暂时分离 System 消息- 找出需要摘要的旧消息- 保留最近消息- 调用模型生成摘要- 用“摘要 最近消息”替换旧上下文- 放回 System 消息- 继续本轮推理System 消息不会进入摘要。Workspace 中的AGENTS.md会作为项目规则参与推理但不会被当成旧对话压缩掉。分界点也不是简单按消息下标切开。假设一条 Assistant 消息发起了工具调用下一条 Tool 消息才返回结果如果正好从中间切断后续模型只会看到半段调用链。ConversationCompactor会调整切分位置尽量把工具调用和对应结果放在同一侧。假设压缩前一共有七条消息配置要求保留最近两条。框架会把前五条整理成摘要最近两条仍保留原文text压缩前较早的 5 条消息 最近一条 Assistant 消息 当前 User 消息压缩后前 5 条消息的摘要 最近一条 Assistant 消息原文 当前 User 消息原文框架会把生成的摘要作为一条新消息放进AgentState.context用它替换较早的原始消息。当前问题完成推理后新的回答还会继续追加到这份上下文中并随更新后的AgentState写回 PostgreSQL。生成摘要本身也要调用一次模型。因此阈值太低并不会更省反而可能频繁增加一次额外的模型请求。四、curl用同一个会话触发压缩下面四次请求使用相同的userId和sessionId。第一次给出任务范围bashcurl -sN -X POST http://localhost:8080/dev-agent/ask \-H Content-Type: application/json \-d {userId: context-user-009,sessionId: context-session-009,message: 任务编号是 CTX-009。需要确认 Java 版本、Spring Boot 版本、启动类、源码目录、构建命令和测试命令。只确认收到不要调用工具。}第二次和第三次补充已经确认的信息bashcurl -sN -X POST http://localhost:8080/dev-agent/ask \-H Content-Type: application/json \-d {userId: context-user-009,sessionId: context-session-009,message: 已确认 Java 版本是 17Spring Boot 版本是 4.1.0。只确认收到不要调用工具。}bashcurl -sN -X POST http://localhost:8080/dev-agent/ask \-H Content-Type: application/json \-d {userId: context-user-009,sessionId: context-session-009,message: 已确认启动类是 AgentScopeJavaApplication源码目录是 src/main/java。只确认收到不要调用工具。}前三轮每轮各产生一条 User 消息和一条 Assistant 消息共六条。压缩条件只在下一次模型推理前检查所以第四次请求加入新的 User 消息后框架看到七条消息并触发压缩bashcurl -sN -X POST http://localhost:8080/dev-agent/ask \-H Content-Type: application/json \-d {userId: context-user-009,sessionId: context-session-009,message: 汇总已经确认的信息并列出还没有确认的事项。不要调用工具。}日志会出现类似内容textCompaction triggered: total7 msgs / token 数 tokens, cutoff5, keeping2 msgsCompaction complete: 7 msgs → 1 summary 2 tail 3 total第一行表示压缩开始当前共有 7 条消息前 5 条会被整理成摘要最近 2 条保留原文。第二行表示压缩完成模型接下来看到的历史不再是原来的 7 条消息而是text1 条摘要 最近 2 条原始消息第四轮回答大致如下text已确认- Java 版本17- Spring Boot 版本4.1.0- 启动类AgentScopeJavaApplication- 源码目录src/main/java待确认- 构建命令- 测试命令这说明较早的原文已被摘要替代但任务编号、已确认信息和待办没有丢失。日志里的3 total是压缩刚完成时的消息数第四轮回答生成后也会追加到上下文并随更新后的AgentState写入 PostgreSQL。五、先分清是哪一种上下文变长Compaction解决的是对话轮数越来越多。它会把较早的消息重新整理成摘要因此适合保留当前目标、已经完成的步骤和接下来要做的事。摘要不是原文备份也不能替代业务数据库。订单号、审批状态、发布批次这类不能出错的信息仍然要放进结构化存储信息更合适的位置当前目标、已完成步骤、下一步Compaction摘要项目背景、工具规则、输出要求AGENTS.md用户偏好、长期约定Memory审批状态、订单号、发布批次业务表或结构化状态压缩前的完整对话会话原始日志还有一种情况对话没进行几轮但某个工具一次返回了几万行日志。这时问题不在历史消息太多而在单条工具结果太大。这类结果由ToolResultEvictionMiddleware处理阈值和预览长度通过ToolResultEvictionConfig配置。超过阈值后完整内容会写入 Workspace对话中只留下开头、结尾和文件位置。它和Compaction的区别可以这样理解text聊了很多轮历史消息越来越长- Compaction 把旧对话整理成摘要某个工具一次返回了大量内容- ToolResultEviction 把完整结果转存到文件当前代码没有单独配置ToolResultEvictionConfigHarnessAgent会使用默认规则单条工具结果超过 8 万字符时才转存。四轮测试没有调用工具因此这项能力不会影响测试结果。Web 接口使用streamEvents()输出 SSE。正常情况下每次模型推理前都会先检查压缩条件达到阈值就主动压缩。但如果阈值设得太高直到模型已经因为上下文超限而拒绝请求当前流式调用不会自动压缩后重试。因此SSE 接口要提前留出余量不要把压缩时机卡在模型上限附近。写在最后长会话真正需要保住的不是每一句原话而是任务还能继续执行所需的信息。Compaction把旧消息整理成摘要最近消息保留原文再把新的上下文写回AgentState。PostgreSQL 负责下次把它找回来AGENTS.md继续提供项目规则关键业务状态则留在结构化存储里。几种信息各回各的位置Agent 才不会把所有状态都压在一段越来越长的聊天记录上。AgentScope Java 2.0 系列1. AgentScope Java 2.0 正式版来了Java Agent 不只要会做事还得能稳定运行2. AgentScope Java 2.0 上手用 HarnessAgent 跑通第一个 Web 接口3. AgentScope Java 2.0 核心架构拆解HarnessAgent、ReActAgent、Toolkit 到底是什么4. AgentScope Java2.0 ToolKit 实战不是把方法丢给模型就完事5. AgentScope Java 2.0 AgentEvent 实战让前端看见 Agent 调工具的过程6. AgentScope Java 2.0 Permission 权限实战Agent 写文件前先问你7. AgentScope Java 2.0 Agent状态实战把 Agent 会话存进 PostgreSQL8. AgentScope Java 2.0 Workspace 实战让 Agent 先读懂 AGENTS.md 再回答

相关新闻

深入解析TMS320C2xx DSP架构:从哈佛结构到低功耗设计实战

深入解析TMS320C2xx DSP架构:从哈佛结构到低功耗设计实战

2026/7/23 21:11:00

1. 项目概述:为什么我们需要深入理解C2xx的架构?如果你在嵌入式信号处理领域摸爬滚打过几年,大概率绕不开德州仪器(TI)的TMS320系列DSP。而C2xx系列,特别是像C203、C209、LC203这些型号,可以说是…

Python装饰器底层逻辑与实战代码解析,3分钟掌握高阶用法

Python装饰器底层逻辑与实战代码解析,3分钟掌握高阶用法

2026/7/23 21:01:00

引言 在Python进阶开发中,装饰器是提升代码复用率和保持逻辑整洁的核心工具。很多开发者在面对装饰器时容易陷入概念混淆,其实它的本质非常直观。装饰器本质上是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数。通过这种…

企业级 Java 项目接入大模型的 6 个安全陷阱:我们如何用飞算 Java AI 堵住漏洞?

企业级 Java 项目接入大模型的 6 个安全陷阱:我们如何用飞算 Java AI 堵住漏洞?

2026/7/23 21:01:00

企业级 Java 项目接入大模型的 6 个安全陷阱:我们如何用飞算 Java AI 堵住漏洞? 企业级 Java 项目接入大模型的 6 道安全检查与实战经验 上周给金融系统上线 AI 辅助审批功能时,安全团队当场拦截了 3 次潜在攻击。今天结合实战案例&#xf…

HuProt™ 人类蛋白组芯片用于天然产物靶点发现技术研究

HuProt™ 人类蛋白组芯片用于天然产物靶点发现技术研究

2026/7/23 23:31:06

天然产物因其复杂的化学组成和多样化的生物活性,在药物开发和生命科学研究领域持续受到关注。随着研究需求不断提升,仅了解天然产物是否具有功能作用已经难以满足科研要求,进一步明确其直接结合蛋白和作用机制成为研究重点。因此,…

电销团队每日拓客流程的系统化搭建方法:从名单获取到效果复盘

电销团队每日拓客流程的系统化搭建方法:从名单获取到效果复盘

2026/7/23 23:31:06

直接切痛点:针对电销团队效率低下问题,提出四环节标准化流程框架一个高效的每日拓客流程可以拆成四个标准化环节:名单获取、名单分配、集中拨打、每日复盘。每个环节有明确的操作标准和责任人,减少团队在"找名单""…

软件开发团队统一采购MacBook怎么选服务商

软件开发团队统一采购MacBook怎么选服务商

2026/7/23 23:31:06

软件开发团队统一配置MacBook,选择服务商的核心标准不在于价格最低,而在于服务商能否提供从Apple Business Manager(ABM)注册、DEP自动注册、MDM统一管控到全生命周期资产管理的全流程交付能力。神州数码作为Apple中国大陆授权分销…

【Springboot毕设全套源码+文档】基于springboot大学生勤工助学系统的设计与实现(丰富项目+远程调试+讲解+定制)

【Springboot毕设全套源码+文档】基于springboot大学生勤工助学系统的设计与实现(丰富项目+远程调试+讲解+定制)

2026/7/23 23:31:06

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

Linux进阶篇04:GRUB2 深度配置与内核参数

Linux进阶篇04:GRUB2 深度配置与内核参数

2026/7/23 23:31:06

实验环境:VirtualBox 虚拟机,Rocky Linux 9,Legacy BIOS (非 UEFI)。 前置知识:已完成Rocky 9 启动流程学习,理解 GRUB2 是启动流程的第二阶段。 核心目标:掌握 /etc/default/grub 配置文件的修改逻辑&…

鸿蒙 ArkTS 实战:随身行李称重的限重解析、物品清单、启用状态与剩余重量

鸿蒙 ArkTS 实战:随身行李称重的限重解析、物品清单、启用状态与剩余重量

2026/7/23 23:21:05

鸿蒙 ArkTS 实战:随身行李称重的限重解析、物品清单、启用状态与剩余重量 前言 随身行李称重是一个基于 ArkTS 和 ArkUI 声明式 UI 的鸿蒙单页项目,入口文件位于 entry/src/main/ets/pages/Index.ets。 本文围绕 随身行李重量管理 场景,拆解…

微服务进阶:服务网格与Istio

微服务进阶:服务网格与Istio

2026/7/23 3:40:08

541|微服务进阶:服务网格与Istio 上篇文章我们聊了微服务的基本概念和拆分方法。 但微服务多了,问题也多了: 服务之间怎么通信? 怎么监控每个服务的调用链路? 熔断、限流、重试怎么做? 安全认证怎么统一? 以前这些都靠SDK库(比如Hystrix、Feign),每个服务都要集成…

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

2026/7/23 4:40:05

一、零售门店全域协同业务背景与行业痛点 1.1 门店超级终端设备矩阵(连锁便利店/商超标准配置) 自助收银Kiosk一体机:顾客结算、自助核销优惠券、商品素材预览;运营折叠平板:店长后台商品上新、图片录入、活动配置、…

噗叽短视频界面分析

噗叽短视频界面分析

2026/7/23 1:54:13

1 和小红书类似,可以采用类似判断方法------------其实他比小红书好判断,因为他没有图片,控件位置几乎是固定的,都不用判断------------2 因为他没有点赞按钮------------而且几乎所有控件位置都是完全一样的,所以我就…

企业级AI搜索落地选型实战手册(含LLM+RAG+Hybrid架构对比矩阵与ROI测算模板)

企业级AI搜索落地选型实战手册(含LLM+RAG+Hybrid架构对比矩阵与ROI测算模板)

2026/7/23 0:09:56

更多请点击: https://kaifayun.com 第一章:企业级AI搜索落地选型实战手册(含LLMRAGHybrid架构对比矩阵与ROI测算模板) 企业级AI搜索系统落地成败,核心在于技术选型与业务价值的精准对齐。盲目堆砌大模型能力或过度依赖…

TM4C129LNCZAD外设实战:LCD、比较器与PWM寄存器配置详解

TM4C129LNCZAD外设实战:LCD、比较器与PWM寄存器配置详解

2026/7/23 0:09:56

1. 项目概述与核心价值在嵌入式系统开发,尤其是基于ARM Cortex-M内核的微控制器项目中,深入理解并熟练配置芯片的片上外设,是从“点亮LED”迈向“实现复杂系统功能”的关键一步。Tiva™ TM4C129LNCZAD作为TI公司Cortex-M4F家族中的高性能成员…

AtomCode `fmt_dur` 争议溯源:两个函数、三段演进、四个事实

AtomCode `fmt_dur` 争议溯源:两个函数、三段演进、四个事实

2026/7/23 0:09:56

一、快速声明与争议背景本文是对 AtomCode 终端 spinner 时长显示 fmt_dur 相关说法的事实性核验。2026 年 7 月 CSDN 上出现两篇互相矛盾的博文,近期又有 AI 在对话中输出格式描述 XhYm / YmZs / Zs。本文基于 AtomCode 仓库 main4677ddfa 及全分支 Git 历史给出可…