news 2026/9/28 15:50:59

AI Agent框架探秘:拆解 OpenHands 的 Memory 模块与配置骨架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent框架探秘:拆解 OpenHands 的 Memory 模块与配置骨架

1. 为什么长任务里 Memory 总是“断片”

如果你正在用 OpenHands 跑一个跨多轮、跨文件的 AI Agent 任务,大概率遇到过这种场景:第一轮它记住了项目结构,第三轮开始就忘了之前改过哪个文件;或者你明确告诉它“不要动 tests 目录”,下一轮它又把测试文件重写了。这不是模型变笨了,而是 Agent 的 Memory 机制没有把上下文正确地持久化和回注。

OpenHands 的 Memory 模块本质上解决三件事:把对话历史压缩成可检索的片段、把工作区状态(文件、命令输出)沉淀成结构化记忆、在每一轮推理前按相关性把记忆重新拼进 prompt。它不是一个简单的“聊天记录数组”,而是一套带配置骨架的读写链路。理解这套链路,你才能控制 Agent 在长任务里“记住什么、忘掉什么”。

这篇内容聚焦 OpenHands 的 Memory 机制在长任务上下文保持场景下的落地方式,从config.toml与settings.json两个骨架文件切入,梳理 Memory 相关配置项与调用链路,最后交付一段可复制的配置和一次 Memory 读写验证动作。适合已经在本地跑过 OpenHands、想进一步调优 Agent 记忆行为的开发者。读完之后,你应该能自己改配置、验证 Memory 是否生效,并定位常见的“记忆不写入/读不出”问题。

2. TaoToken 前置:给 OpenHands 接一个稳定的模型入口

OpenHands 本身是 Agent 框架,Memory 的压缩、摘要、检索这些动作都要调用 LLM。也就是说,Memory 模块能不能跑通,一半取决于你的模型接入是否稳定。我试过在本地直接填各家原生地址,切换模型时改配置很碎,后来统一走 TaoToken 的 API 入口,OpenHands 侧只需要改base_url和api_key两个字段。

TaoToken 官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数,配置里直接写这个即可。你需要先在控制台创建一个 API Key,OpenHands 的 Memory 摘要模型和主推理模型可以共用同一个 Key,也可以分开配。

这里要强调一点:OpenHands 的 Memory 模块在长任务里会频繁调用模型做摘要,如果模型入口不稳定,表现就是“记忆时有时无”,很容易被误判成 Memory 配置写错了。所以先把模型入口固定下来,再调 Memory,排障路径会清晰很多。

创建 Key 的入口在控制台的 API Keys 页面,模型对话调试可以用模型对话页面先确认 Key 可用,长期跑编码任务建议看 Coding Plan 的额度说明。这几个入口分别是:

  • API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
  • 模型对话:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
  • Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

3. config.toml 与 settings.json 的 Memory 配置骨架

OpenHands 的配置分两层:config.toml管运行时行为,settings.json管 LLM 与 Agent 级参数。Memory 相关项散落在两边,很多人只改了其中一边,结果 Memory 不生效。下面是我本地验证过的骨架,你可以直接复制后改路径和 Key。

3.1 config.toml 里的 Memory 段

[core] # 工作区根目录,Memory 会基于这个路径索引文件状态 workspace_base = "/home/yourname/openhands-workspace" # 缓存目录,Memory 的中间产物落在这里 cache_dir = "/home/yourname/.openhands/cache" [memory] # 开启 Memory 模块 enabled = true # 记忆存储后端,本地调试用 local 即可 backend = "local" # 单条记忆的最大 token,超过会被摘要压缩 max_token_per_memory = 2048 # 每轮推理前召回的记忆条数 recall_top_k = 5 # 摘要模型,建议和主模型分开配,省钱且稳定 summarizer_model = "gpt-4o-mini" # 记忆持久化文件 persist_path = "/home/yourname/.openhands/memory/store.json" [llm] # 统一走 TaoToken 入口 base_url = "https://taotoken.net/api" api_key = "sk-your-taotoken-key" model = "gpt-4o"

这里几个参数值得单独说。max_token_per_memory控制单条记忆的粒度,设太小会导致记忆碎片化,检索时拼不出完整上下文;设太大则每轮 prompt 膨胀,长任务后期容易超上下文。recall_top_k是召回条数,长任务里可以适当调大到 8 到 10,但要注意和主模型的上下文窗口匹配。

3.2 settings.json 里的 Agent Memory 开关

{ "agent": { "memory_enabled": true, "memory_mode": "hybrid", "memory_write_strategy": "on_turn_end", "memory_read_strategy": "relevance", "condenser_enabled": true, "condenser_max_history": 40 }, "llm": { "base_url": "https://taotoken.net/api", "api_key": "sk-your-taotoken-key", "model": "gpt-4o" } }

memory_mode有三个常见取值:conversation只记对话,workspace只记文件与命令状态,hybrid两者都记。长任务建议用hybrid,否则 Agent 会忘记自己改过哪些文件。memory_write_strategy设为on_turn_end表示每轮结束写入,避免中途写入导致状态不一致。condenser_enabled是历史压缩开关,长任务必须开,否则历史会无限增长。

3.3 两个文件的优先级关系

配置项config.tomlsettings.json实际生效
memory 开关[memory] enabledagent.memory_enabled两者都为 true 才生效
召回条数recall_top_k无以 config.toml 为准
写入时机无memory_write_strategy以 settings.json 为准
模型入口[llm] base_urlllm.base_urlsettings.json 覆盖 config.toml

注意:如果你只改了 config.toml 的[memory]段,但 settings.json 里memory_enabled是 false,Memory 依然不会写入。这是最常见的“配了没效果”原因。

4. 跑通一次 Memory 读写验证

配置写完,别急着跑长任务,先用一个最小动作验证 Memory 是否真的在读写。下面这套流程我在本地反复用过,能快速判断 Memory 链路是否通。

4.1 启动 OpenHands 并确认 Memory 加载

# 进入 OpenHands 项目目录 cd ~/openhands # 用指定配置启动,注意 --config 指向你的 config.toml python -m openhands.server --config ./config.toml --settings ./settings.json

启动日志里应该能看到类似输出:

[Memory] backend=local enabled=True persist_path=/home/yourname/.openhands/memory/store.json [Memory] summarizer_model=gpt-4o-mini recall_top_k=5 [LLM] base_url=https://taotoken.net/api model=gpt-4o

如果enabled=False,回去检查 settings.json 的memory_enabled。如果base_url不是你配的地址,说明 settings.json 没被加载,检查启动参数路径。

4.2 触发一次记忆写入

在 OpenHands 的对话里发一条带明确状态信息的指令,比如:

请在 workspace 下创建 notes.md,写入一行 "project=openhands-memory-test",然后告诉我文件路径。

Agent 执行完后,查看持久化文件:

cat /home/yourname/.openhands/memory/store.json | python -m json.tool | head -40

你应该能看到一条包含notes.md和project=openhands-memory-test的记忆条目。如果没有,说明写入策略没触发,检查memory_write_strategy是否为on_turn_end,以及memory_enabled是否为 true。

4.3 验证记忆召回

新开一轮对话,问一个依赖上一轮状态的问题:

刚才创建的 notes.md 里 project 的值是什么?

如果 Memory 召回正常,Agent 会直接回答openhands-memory-test,而不是重新去读文件或说不知道。你也可以在日志里看到召回记录:

[Memory] recall top_k=5 selected=1 score=0.87 source=notes.md

这一步能过,说明 Memory 的写入、持久化、召回三段链路都通了。接下来再跑长任务,上下文保持会明显稳定。

5. 本篇常见错排查

Memory 配了不生效,原因通常集中在几个点上,我按出现频率排一下。

第一类是配置文件没被加载。OpenHands 启动时如果没显式指定--config和--settings,会走默认路径,你改的文件可能根本没被读。排查方法是看启动日志里的persist_path和base_url是否和你写的一致。

第二类是memory_enabled与[memory] enabled不一致。前面表格里说过,两者必须同时为 true。很多人只改了 config.toml,settings.json 里还是默认 false。

第三类是摘要模型调用失败导致记忆写入中断。Memory 写入时会调用summarizer_model做压缩,如果这个模型的 Key 或地址不对,写入会静默失败。排查方法是单独用模型对话页面测一下summarizer_model是否可用,入口在 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。

第四类是recall_top_k设得过大导致 prompt 超限。长任务后期历史本来就长,召回条数再拉满,主模型直接报上下文超限。建议从 5 开始,逐步加到 8,观察是否稳定。

第五类是持久化文件权限问题。persist_path指向的目录如果不可写,Memory 写入会失败但不一定报错。手动touch一下该路径确认可写。

如果排查到模型接入层的问题,比如 Key 无效、额度不足、地址写错,直接去 API Keys 页面重新生成并核对,接入文档里有完整的字段说明:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 和 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

6. 把 Memory 调稳之后,长任务才真正可用

Memory 模块调通之后,OpenHands 在长任务里的表现会有质的变化:跨轮次的文件状态能保持,之前明确说过的约束不会被遗忘,Agent 不会反复重读同一批文件。这时候你再去看 Coding Plan 的额度消耗,会发现摘要调用其实占了一部分,把summarizer_model换成更轻量的模型能省不少。

如果你准备把 OpenHands 用在持续编码或 Agent 编排场景,建议把 Memory 配置和模型入口一起固化下来,别每次启动都手改。Coding Plan 页面有长期任务的额度说明,可以先看再决定模型组合:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。

最后留一个我踩过的坑:改完 Memory 配置后一定要重启 OpenHands 进程,热加载不会重新读config.toml的[memory]段,这个坑我排查了半小时才发现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 13:11:10

AI 成本焦虑,从 Copilot 开始:用 TaoToken 统一 Key 管住账单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 13:09:47

以太网IO模块与Modbus TCP:从PLC扩展痛点到分布式IO实战

1. 从“PLC柜里堆腿线”到一根网线:以太网IO模块到底解决了什么问题做了这么多年工业现场,我最早对IO扩展这件事是非常抗拒的——不是技术难,而是现场太乱。你要在机架边上加8个输入点,要么拆机架、加扩展模块、改组态、重新下载程…

作者头像 李华