原理)
ESP-Claw 記憶管理器深潛上下文持久化與會話壓縮的實現(xiàn)原理【免費下載鏈接】esp-clawESP-Claw, a Chat Coding AI agent framework for IoT devices項目地址: https://gitcode.com/gh_mirrors/es/esp-claw在資源受限的 ESP32 芯片上運行 AI 智能體最大的挑戰(zhàn)之一是如何讓設(shè)備記住對話。開源項目ESP-Claw一款面向 IoT 設(shè)備的Chat Coding AI 智能體框架內(nèi)置了完整的記憶管理器Memory Manager它解決了兩個核心問題上下文持久化——把每一輪對話安全地寫入 Flash 存儲以及會話壓縮——在存儲空間耗盡前自動瘦身歷史讓智能體能無限對話而不撐爆內(nèi)存。這篇文章將帶你逐層拆解 ESP-Claw 記憶管理器的四層架構(gòu)、會話壓縮算法和異步記憶提取機制即使你只熟悉 C 語言基礎(chǔ)也能看懂這套精巧的嵌入式記憶設(shè)計。為什么嵌入式 AI 代理需要專門的記憶管理器云端大模型服務(wù)通常把對話歷史放在內(nèi)存里但 ESP32 只有幾十 KB 到幾 MB 的 RAM 和有限的 Flash 寫入壽命。ESP-Claw 的記憶管理器代碼位于 components/claw_modules/claw_memory/因此設(shè)計了四套互補的記憶分別應(yīng)對不同尺度的記憶需求記憶層級存儲介質(zhì)生命周期典型內(nèi)容會話歷史數(shù)據(jù)文件 二進(jìn)制索引單次會話完整的用戶/助手消息流長期記憶JSONL 記錄 索引跨會話永久用戶偏好、持久事實畫像記憶Markdown 文件永久Agent 人設(shè)與用戶畫像摘要標(biāo)簽JSON 索引隨長期記憶可檢索的記憶標(biāo)簽?zāi)夸浬舷挛某志没瘮?shù)據(jù)文件 二進(jìn)制索引的雙文件設(shè)計會話歷史是整個系統(tǒng)的地基。每當(dāng)核心引擎完成一輪對話就會通過 claw_core_context_persist.c 中的三個入口把消息交給記憶層用戶消息claw_core_persist_context_user_messages_if_configured工具調(diào)用輪claw_core_persist_context_tool_round_if_configured助手工具調(diào)用 工具結(jié)果各一條記錄最終回答claw_core_persist_context_final_if_configured此調(diào)用會標(biāo)記輪次完成可能觸發(fā)壓縮真正的落盤邏輯在 claw_memory_session.c 中它采用了類似 SQLite 的數(shù)據(jù)文件 索引文件雙文件結(jié)構(gòu)session_id ← 數(shù)據(jù)文件每行一條 JSON 記錄 session_id.idx ← 索引文件8 字節(jié)文件頭 10 字節(jié)/條的定長索引索引文件頭攜帶魔數(shù)0x58444843CHDX和版本號每條索引只包含 4 個字段——偏移量、長度、記錄類型、后端格式全部打包packed成 10 字節(jié)。這種設(shè)計讓系統(tǒng)無需解析整份歷史就能通過偏移量隨機定位任意一條記錄讀取成本極低。每條記錄有四種類型USER用戶消息、ASSISTANT_FINAL最終回答、ASSISTANT_TOOL工具調(diào)用、TOOL_RESULT工具結(jié)果。寫入時系統(tǒng)會把消息截斷到max_message_chars默認(rèn) 4096 字符并做 UTF-8 邊界保護(hù)確保不會在存儲中留下半截漢字。更值得注意的是容錯設(shè)計如果數(shù)據(jù)文件和索引文件不成對只有一個存在或索引損壞系統(tǒng)不會崩潰而是記錄警告后自動重建文件對session_history_recreate_file保證會話歷史永遠(yuǎn)可讀。會話壓縮150KB 閾值下的輪次瘦身算法對話越久歷史文件越大。ESP-Claw 設(shè)定了150KBCLAW_MEMORY_SESSION_SIZE_LIMIT的會話上限一旦某輪對話結(jié)束后文件超限就會觸發(fā)壓縮流程session_history_compact_if_needed算法分為三步第一步輪次切分。系統(tǒng)掃描索引以每條USER記錄作為分界點把歷史切成若干輪次turn并標(biāo)記每輪是否完成是否含ASSISTANT_FINAL以及是否含工具記錄。第二步保留策略。壓縮規(guī)則非??酥啤槐A羧悆?nèi)容所有USER消息和ASSISTANT_FINAL最終回答對話主干最近1 個已完成的工具輪次的全部工具記錄CLAW_MEMORY_SESSION_COMPACT_TOOL_TURNS 1保留少量工具細(xì)節(jié)供模型參考尚未完成的最后一輪的全部記錄避免刪掉進(jìn)行中的上下文。其余舊的工具調(diào)用和工具結(jié)果記錄全部丟棄——它們通常占?xì)v史體積的大頭但對后續(xù)對話價值最低。第三步原地重寫。系統(tǒng)按保留清單把記錄重新打包寫入文件頭部用ftruncate截斷兩個文件索引偏移量全部重建。整個過程是原子的——先驗證新大小不超限再落盤最后刷新文件。如果壓縮后仍超過 150KB比如用戶消息本身就極長系統(tǒng)會寫入一個.blocked標(biāo)記文件并主動向用戶推送提示請發(fā)送/session new開啟新會話用/session delete刪除舊會話。這種優(yōu)雅降級避免了在存儲邊緣反復(fù)寫入造成的 Flash 磨損。長期記憶異步 LLM 自動提取 語義去重會話歷史是短期記憶而跨會話的長期記憶由 claw_memory.c 和 claw_memory_extract.c 共同維護(hù)。最亮眼的設(shè)計是異步自動提取請求開始 ──→ 創(chuàng)建提取任務(wù)入隊 ──→ 獨立工作線程調(diào)用 LLM ↓ 階段筆記回調(diào)等待任務(wù)完成把提取結(jié)果合并進(jìn)上下文系統(tǒng)初始化一個名為claw_mem_extract的獨立 FreeRTOS 任務(wù)6KB 棧、優(yōu)先級 5、隊列長度 4它持有獨立的 LLM 運行時。每當(dāng)一次請求開始就復(fù)制一份用戶文本生成任務(wù)放入隊列工作線程用一套精心設(shè)計的系統(tǒng)提示詞位于claw_memory_auto_extract_prepare_with_runtime讓 LLM 從用戶消息中只提取持久性的用戶事實返回{intent: none|forget|replace, memories: [...]}的 JSON。這套提示詞里有很多防呆規(guī)則比如用戶說忘了我剛才說的→intentforget不存任何記憶用戶在糾正一個舊事實 →intentreplace只存修正后的事實涉及 Agent 人設(shè)、語氣、角色扮演的指令 → 一律不存那屬于畫像記憶歸soul.md管提問、請求、閑聊 → 不提取每次最多提取 3 條記憶且關(guān)鍵詞必須能在原文中找到出處grounding防止 LLM 編造。提取出的記憶進(jìn)入存儲前還要過語義去重關(guān)系統(tǒng)把記憶內(nèi)容規(guī)范化后取前 36 字符作為指紋claw_memory_build_item_key完全相同直接跳過若兩條記憶互為子串且都超過 12 字符也判定為重復(fù)。這樣我不吃辣和我討厭吃辣的不會在 Flash 里各占一條。每條記憶在 Flash 上的落地包含四個文件定義于 claw_memory_internal.h文件作用MEMORY.md人類可讀的記憶清單按訪問熱度排序memory_records.jsonl追加式記錄日志每次變更一行memory_index.json摘要標(biāo)簽?zāi)夸? 關(guān)鍵詞倒排索引memory_digest.log變更摘要日志store/recall/forget 審計長期記憶注入上下文時只注入摘要標(biāo)簽?zāi)夸沜law_memory_long_term_provider而不是記憶全文——提示詞會明確要求模型需要細(xì)節(jié)時再調(diào)用memory_recall工具按標(biāo)簽精確檢索。這種目錄 按需檢索模式把系統(tǒng)提示詞的 token 消耗壓到了最低非常適合小模型。會話與長期記憶如何協(xié)同工作一次完整請求的記憶流轉(zhuǎn)如下示意請求開始會話歷史提供者claw_memory_session_history_provider帶REQUEST_START_ONLY標(biāo)志把磁盤上的歷史重新載入為消息數(shù)組畫像提供者注入user.md/soul.md/identity.md長期記憶提供者注入標(biāo)簽?zāi)夸洝U埱筇幚砟P突谕暾舷挛幕卮鹂赡苡|發(fā)工具調(diào)用。輪次結(jié)束核心引擎持久化本條最終回答持久化回調(diào)檢查文件是否超 150KB超限則執(zhí)行會話壓縮。后臺并行異步提取線程在后臺分析用戶消息提取到的長期記憶在下一次階段筆記回調(diào)時合并注入。畫像記憶claw_memory_profile.c則是最簡單的三份 Markdown設(shè)計soul.mdAgent 靈魂/價值觀、identity.md身份卡片、user.md用戶畫像每次請求原樣拼接進(jìn)系統(tǒng)提示詞。關(guān)鍵參數(shù)速查這些宏定義集中在 claw_memory_internal.h 頂部決定了記憶管理器的行為邊界調(diào)優(yōu)時值得關(guān)注參數(shù)默認(rèn)值含義CLAW_MEMORY_SESSION_SIZE_LIMIT150 KB會話歷史上限超過觸發(fā)壓縮CLAW_MEMORY_SESSION_COMPACT_TOOL_TURNS1壓縮時保留的最近工具輪次數(shù)CLAW_MEMORY_MAX_ACTIVE_ITEMS128長期記憶最大活躍條目數(shù)超出按熱度淘汰CLAW_MEMORY_MAX_SUMMARIES3每條記憶最多掛 3 個摘要標(biāo)簽CLAW_MEMORY_AUTO_EXTRACT_MAX_ITEMS3單次自動提取最多落盤 3 條記憶CLAW_MEMORY_RECALL_DEFAULT_LIMIT8memory_recall默認(rèn)返回條數(shù)當(dāng)活躍記憶超過 128 條時claw_memory_trim_to_capacity會按容量分訪問次數(shù) × 3 更新時間的每小時增量淘汰得分最低的記憶——常用且新的記憶得以存活這正是嵌入式版的記憶遺忘曲線。源碼導(dǎo)讀路徑如果你想動手閱讀或修改建議按以下順序接口總覽claw_memory.h —— 全部公開 API 與四個上下文提供者的聲明會話持久化與壓縮claw_memory_session.c —— 重點看session_history_analyze_turns和session_history_rewrite_compacted長期記憶讀寫claw_memory.c 與 claw_memory_storage.c異步提取claw_memory_extract.c系統(tǒng)提示詞與 claw_memory_session.c 開頭的任務(wù)/隊列代碼核心側(cè)持久化入口claw_core_context_persist.c小結(jié)ESP-Claw 的記憶管理器用不到幾 KB 的常駐內(nèi)存在 ESP32 上實現(xiàn)了完整的對話不失憶能力雙文件索引讓歷史讀寫高效150KB 輪次壓縮讓會話可以無限延長異步 LLM 提取 語義去重讓長期記憶自動積累又不膨脹目錄式注入 按需檢索讓 token 預(yù)算花在刀刃上。這套設(shè)計對任何想在資源受限設(shè)備甚至邊緣服務(wù)器上構(gòu)建有記憶 AI 智能體的開發(fā)者都是一份值得借鑒的完整方案。【免費下載鏈接】esp-clawESP-Claw, a Chat Coding AI agent framework for IoT devices項目地址: https://gitcode.com/gh_mirrors/es/esp-claw創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考