ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

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

AI Agent框架探秘:拆解 OpenHands 的 Memory 模块与配置实践 1. OpenHands Memory 模块到底解决什么问题如果你正在用 OpenHands 搭 AI Agent大概率遇到过这种尴尬第一轮对话里 Agent 记住了项目路径、依赖版本、你偏好的代码风格第二轮换个任务它就像失忆一样从头问起。这不是模型笨而是 Memory 模块没配对。OpenHands 的 Memory 模块本质上是给 Agent 装一个「可插拔的记事本」——它决定哪些信息进短期上下文、哪些落盘成长期记忆、哪些在任务切换时被压缩或丢弃。我试过把 Memory 当成单纯的向量库来用结果 Agent 在长任务里反复读取同一份文件摘要token 烧得飞快。后来才明白 OpenHands 的 Memory 是分层设计的工作记忆Working Memory负责当前 session 的即时上下文长期记忆Long-term Memory通过外部存储做跨 session 持久化而配置层则决定两者的读写策略。对开发者来说真正要动手改的是config.toml里的 memory 段和 embedding 通道。这篇面向正在搭建 AI Agent 的开发者给出可直接复制的config.toml骨架、TaoToken 统一 Key/API 通道的接入示例以及 Memory 读写验证动作。跑通之后你的 Agent 就能在多次任务之间保持记忆连续性而不是每次从零开始。2. TaoToken 前置统一 Key 与 API 通道OpenHands 的 Memory 模块在做 embedding 和摘要压缩时需要调用模型接口。如果你同时用多家模型Key 管理会变得很乱。TaoToken 提供统一 Key 和 API 通道把模型对话、embedding、coding plan 等入口收敛到一个 base_url 下配置时只需要改一处。官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 地址不加 UTMhttps://taotoken.net/api你需要先拿到 API Key然后把它写进 OpenHands 的环境变量或config.toml。注意不要把 Key 硬编码进代码仓库用.env或系统环境变量注入。2.1 获取 API Key进入控制台创建 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys创建后复制 Key形如sk-xxxx。这个 Key 同时用于模型对话和 embedding 请求不需要为每个模型单独申请。2.2 确认模型与通道在模型对话页可以测试 Key 是否可用https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat如果你打算长期跑编码类 Agent可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan接入文档在这里配置字段有疑问时对照查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc3. 可复制配置config.toml 骨架与 Memory 参数OpenHands 的配置文件通常放在项目根目录或~/.openhands/config.toml。下面这份骨架可以直接拿去改重点看[memory]和[llm]两段。# config.toml [core] workspace_base ./workspace max_iterations 50 cache_dir ./cache [llm] # TaoToken 统一通道 base_url https://taotoken.net/api api_key ${TAOTOKEN_API_KEY} model claude-sonnet-4-20250514 temperature 0.2 max_output_tokens 4096 [memory] # 工作记忆当前 session 保留的最近消息条数 working_memory_size 20 # 长期记忆是否启用持久化 enable_long_term true # 持久化后端local / redis / sqlite backend sqlite # sqlite 文件路径 storage_path ./memory/openhands_memory.db # embedding 模型走同一个 TaoToken 通道 embedding_model text-embedding-3-small embedding_base_url https://taotoken.net/api embedding_api_key ${TAOTOKEN_API_KEY} # 记忆压缩阈值超过多少 token 触发摘要 summarize_threshold 8000 # 检索返回的 top-k 记忆片段 retrieval_top_k 5 [agent] # 是否在任务切换时保留记忆 persist_memory_across_tasks true # 记忆写入策略always / on_task_end / manual memory_write_policy on_task_end几个参数的实际影响我按踩过的坑说明working_memory_size设太大上下文会膨胀模型响应变慢设太小Agent 会忘记刚看过的文件内容。20 到 30 是比较稳的区间。summarize_threshold决定什么时候把旧消息压缩成摘要。如果你跑的是长任务比如重构一个模块这个值可以调到 12000避免频繁摘要丢失细节。memory_write_policy设为on_task_end时只有任务结束才落盘。如果你希望 Agent 在任务中途也能记住关键决策改成always但写入频率会上升。backend选sqlite适合本地开发零依赖。如果多 Agent 共享记忆换成redis把storage_path改成 Redis 连接串。3.1 环境变量注入不要把 Key 写进 toml。在 shell 里导出export TAOTOKEN_API_KEYsk-你的实际KeyWindows PowerShell$env:TAOTOKEN_API_KEYsk-你的实际Key然后启动 OpenHands 时它会自动读取。4. 验证请求Memory 读写链路跑通配置写完必须验证 Memory 真的在读写而不是只加载了配置。下面分三步启动、写入、检索。4.1 启动并检查 Memory 初始化python -m openhands.core.main --config config.toml启动日志里应该出现类似[Memory] backendsqlite path./memory/openhands_memory.db [Memory] long_termenabled embedding_modeltext-embedding-3-small [LLM] base_urlhttps://taotoken.net/api modelclaude-sonnet-4-20250514如果看到long_termdisabled说明enable_long_term没生效检查 toml 缩进和字段名。4.2 写入一条记忆在 OpenHands 交互界面里发一条带明确事实的消息比如记住本项目使用 Python 3.11依赖管理用 uv测试框架是 pytest。任务结束后检查 sqlitesqlite3 ./memory/openhands_memory.db SELECT id, substr(content,1,80), created_at FROM memories ORDER BY id DESC LIMIT 5;应该能看到刚写入的记录。如果没有检查memory_write_policy是否为on_task_end且任务确实结束了。4.3 检索验证新开一个 session问本项目用什么测试框架Agent 应该回答pytest而不是说不知道。如果答错说明检索没命中。可以手动调 embedding 接口确认通道正常curl https://taotoken.net/api/v1/embeddings \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:text-embedding-3-small,input:本项目使用 pytest}返回里应该有data[0].embedding数组。如果报 401Key 不对报 404base_url 路径写错注意是https://taotoken.net/api而不是带/v1的旧写法。5. 本篇常见错排查5.1 Memory 写入成功但检索不到最常见原因是 embedding 维度和检索时不一致。比如写入时用了text-embedding-3-small1536 维检索时配置成了别的模型。检查config.toml里embedding_model在读写两侧是否一致。另一个原因是retrieval_top_k太小相关记忆排在 top-k 之外。临时调到 10 测试确认能命中后再调回去。5.2 启动报 base_url 连接失败先确认网络能访问https://taotoken.net/api。如果公司网络有出口限制联系运维放行。不要改成其他非官方地址配置里只认这个 base_url。如果报model not found去模型对话页确认你用的模型名是否在当前 Key 的可用列表里https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat5.3 sqlite 文件锁冲突多进程同时跑 OpenHands 时sqlite 会报database is locked。本地开发建议单进程需要并发就换backend redis并在storage_path填 Redis 连接串例如redis://localhost:6379/0。5.4 记忆膨胀导致响应变慢跑了几十个任务后memories表可能上万条。加一个定期清理策略比如只保留最近 30 天的记忆DELETE FROM memories WHERE created_at datetime(now, -30 days);或者在config.toml里加max_memory_entries 5000让 OpenHands 自动淘汰旧记录。5.5 接入文档对照字段含义拿不准时直接查接入文档比猜字段名快https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc6. 把记忆链路固定下来Memory 模块配好之后建议把config.toml纳入版本管理但 Key 用环境变量注入。每次改完配置跑一遍第 4 节的写入和检索验证确认链路没断。如果你要长期跑编码类 AgentCoding Plan 通道在长任务下的稳定性更好可以在这里了解https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_planKey 管理入口https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys最后一步实操建议把memory_write_policy先设为always跑三个连续任务观察 sqlite 里记录的增长曲线和 Agent 的召回准确率再决定是否改回on_task_end。这个调参过程比看文档更能让你理解 Memory 模块的真实行为。
返回列表