☰
长对话不再失控:OpenHands Software Agent SDK上下文压缩与持久记忆实战
2026/10/14 17:53:40 网站建设 项目流程

【免费下载链接】software-agent-sdk

A clean, modular SDK for building AI agents with OpenHands V1.

项目地址:https://gitcode.com/gh_mirrors/so/software-agent-sdk
点击查看免费下载

长对话一多,AI Agent 就"失忆"、跑偏甚至报错?OpenHands Software Agent SDK 是构建 AI Agent 的模块化开发工具包,内置两大关键机制来驯服长对话:**上下文压缩(Condenser)**自动把冗长的历史摘要成精炼总结,**持久记忆(Persistent Memory)**让 Agent 跨会话记住你的项目决策。本文带你用最少配置上手这两套机制,让 Agent 聊得越久越聪明。

一、长对话为什么会"失控"?🤔

Agent 的每次回复都要把完整对话历史喂给大模型,这带来三个现实问题:

  • 上下文窗口爆仓:消息越堆越多,直到触发模型上限报错;
  • 成本飞涨:每次请求重复携带海量历史 token,费用线性上涨;
  • 注意力稀释:关键信息被淹没在几千条工具调用日志里,Agent 开始答非所问。

SDK 的解法很直观:把"遗忘"变成一种受控操作——用 LLM 生成的摘要替代旧事件,把值得长期保留的知识写入磁盘上的记忆文件。

核心文档可参考 Context 模块说明 和 Condenser 设计文档。

二、机制一:上下文压缩 Condenser

工作原理:摘要替代,而非直接丢弃

OpenHands 的对话历史是一个只追加(append-only)的事件日志,记录了环境中的几乎每次状态变化,这对调试和恢复极其宝贵。那么压缩时如何"遗忘"?

SDK 的做法是在日志中插入一条特殊的Condensation事件(类似 Cassandra/Kafka 中的墓碑记录),标记哪些事件应被摘要替代;再由View类在生成 LLM 请求时实时应用这些标记。压缩策略是:用一条摘要事件替换前半部分历史,后半部分(近期上下文)原样保留——既保住当前任务的连贯性,又让早期关键信息以摘要形式"层层蒸馏"下来。

一键配置:三步接入 LLMSummarizingCondenser

默认的压缩策略由 LLMSummarizingCondenser 实现,官方示例 14_context_condenser.py 给出了完整用法:

condenser = LLMSummarizingCondenser( llm=llm.model_copy(update={"usage_id": "condenser"}), max_size=10, # 事件数超过阈值就触发压缩 keep_first=2, # 永远保留开头的系统提示与首条用户消息 ) agent = Agent(llm=llm, tools=tools, condenser=condenser)

几个常用参数:

参数含义默认值
max_size事件数上限,超过即压缩240
max_tokenstoken 数上限(与事件数取更严格者)不启用
keep_first头部永不压缩的事件数2
minimum_progress单次压缩至少覆盖的历史比例,防止"压缩了个寂寞"0.1

💡 小技巧:压缩用的 LLM 建议传usage_id: "condenser",这样账单能把摘要开销与 Agent 主调用区分开。

软触发 vs 硬触发:失败也有兜底

压缩并非总是"想压就压"。SDK 区分两类触发(见 base.py):

  • 软触发(SOFT):资源上限到了,压缩失败就先用未压缩视图继续,下一步再试;
  • 硬触发(HARD):用户显式调用conversation.condense(),或 Agent 检测到上下文窗口异常、不压缩就无法继续时,SDK 会执行硬上下文重置(hard context reset)——把整个视图 forget-and-summarize,并自动按比例缩小事件字符串重试(最多 5 次),确保对话绝不死锁。

三、机制二:持久记忆 MEMORY.md

压缩解决"单次会话内"的窗口问题,而持久记忆解决"跨会话"的遗忘问题。

双层记忆结构:用户层 + 项目层

55_persistent_memory.py 展示了完整流程:会话 1 让 Agent 把"项目统一用uv管理依赖"这个决策写进项目记忆;会话 2 是一个全新对话,它自动读到这条记忆,无需任何人重复说明。

层级文件位置作用域
用户层~/.openhands/memory/MEMORY.md跨所有项目的个人偏好
项目层<workspace>/.openhands/memory/MEMORY.md当前工作区的决策与约定

加载逻辑在 memory.py 中:两层MEMORY.md索引会在会话启动时拼进系统提示的<MEMORY_CONTEXT>块(项目层放在后面以获得更多模型注意力)。为控制提示体积,默认有6000 字符预算,超出的部分按行从顶部截断并保留"[earlier memory truncated]"标记——日常日志(YYYY-MM-DD.md)则不自动加载,由 Agent 按需读取。

开启持久记忆:一个参数的事

agent_context = AgentContext(load_memory=True) agent = Agent(llm=llm, tools=tools, agent_context=agent_context)

就这么简单 ✅ 记忆默认关闭(opt-in),开启后由 Agent 自己在工作过程中维护这两个文件——系统提示会告诉它如何追加与维护。更多上下文能力(如按关键词触发的 Skill)见 AgentContext 定义。

四、搭配会话持久化:关掉进程,明天接着聊

压缩和记忆之外,SDK 还内置了会话级持久化:给Conversation传persistence_dir参数,事件日志就会落盘;下次用相同 ID 构造Conversation即可无损恢复。10_persistence.py 演示了"运行→序列化→反序列化→继续发消息"的完整闭环,而 14 号示例 则展示了压缩 + 持久化同时工作——恢复后的会话带着摘要而非臃肿历史,继续干活。

五、源码导航与延伸阅读

想深入源码,按此路线阅读效率最高:

  • 上下文总览:openhands-sdk/openhands/sdk/context/README.md
  • 压缩器设计:context/condenser/README.md
  • 摘要压缩实现:llm_summarizing_condenser.py
  • 记忆加载实现:context/memory.py
  • 手动触发压缩 API:conversation/base.py
  • 官方示例:examples/01_standalone_sdk/(14_context_condenser.py、55_persistent_memory.py、10_persistence.py)

六、总结:三个机制,各管一段

  • Condenser(上下文压缩):管"会话内",用摘要滚动替换旧事件,窗口常稳、成本可控;
  • 持久记忆(MEMORY.md):管"会话间",双层记忆文件自动注入系统提示,决策不丢;
  • 会话持久化(persistence_dir):管"进程间",事件日志落盘,随时断点续聊。

三者叠加,Agent 从"聊五分钟就犯迷糊"进化为"长期搭档"。下一步,不妨从 examples/01_standalone_sdk/14_context_condenser.py 跑起来,亲眼看看压缩前后的 LLM 消息变化吧!

【免费下载链接】software-agent-sdk

A clean, modular SDK for building AI agents with OpenHands V1.

项目地址:https://gitcode.com/gh_mirrors/so/software-agent-sdk
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询