置 Agent 長期記憶 FACT.md:設(shè)計規(guī)范與持久化實現(xiàn)解析)
Cherry Studio 內(nèi)置 Agent 長期記憶 FACT.md設(shè)計規(guī)范與持久化實現(xiàn)解析【免費下載鏈接】cherry-studio Cherry Studio 是一款支持多個 LLM 提供商的桌面客戶端項目地址: https://gitcode.com/CherryHQ/cherry-studioCherry Studio 為其內(nèi)置 AgentCherry 小助手cherry-assistant、Cherry 支持助手cherry-support提供了一套基于文件的長期記憶機制其中memory/FACT.md是承載長期知識的核心文件。本文以該文件的官方規(guī)范resources/builtin-agents/cherry-assistant/memory/FACT.md為骨架結(jié)合主進程源碼與測試用例講解 FACT.md 的用途邊界、持久化保證、防陳舊機制以及底層原子寫入與系統(tǒng)提示詞內(nèi)聯(lián)加載的實現(xiàn)原理幫助你在定制 Agent 或擴展記憶能力時做到事實準確、邊界清晰。FACT.md 的定位跨會話的用戶長期知識文件FACT.md 的標(biāo)題是# Long-term knowledge長期知識它被設(shè)計為存放Agent 跨會話學(xué)到的關(guān)于用戶的穩(wěn)定事實包括但不限于偏好preferences用戶喜歡的語氣、命名習(xí)慣、工具選擇、工作流偏好等環(huán)境怪癖environment quirks用戶機器或工作區(qū)中的特殊環(huán)境、目錄布局、命令習(xí)慣等已解決的問題resolved issues過去排查完成的故障、達成的技術(shù)決策、沉淀下來的經(jīng)驗。從源碼結(jié)構(gòu)看這一設(shè)計在 src/main/ai/agents/prompt.ts 的Agent Data清單中有明確對應(yīng)——FACT.md 被描述為 WHAT you know即 Agent知道什么具體涵蓋活躍項目、技術(shù)決策、6 個月以上的持久知識durable knowledge, 6 months。其回憶側(cè)recall side實現(xiàn)在同一文件的loadMemory邏輯中會話啟動時讀取memory/FACT.md內(nèi)容將其內(nèi)聯(lián)進系統(tǒng)提示詞供模型直接閱讀寫入側(cè)write side則由memory工具的updateaction 負責(zé)二者共同構(gòu)成讀-寫閉環(huán)。核心保證應(yīng)用更新不會覆蓋用戶定制FACT.md 規(guī)范中最關(guān)鍵的一條保證是It isnotoverwritten on app updates - your customizations persist. 它不會在應(yīng)用更新時被覆蓋——你的自定義內(nèi)容會持久保留。這一保證由內(nèi)置 Agent 的模板-實例分離機制在實現(xiàn)層面落地。內(nèi)置 Agent 的源模板存放在倉庫的 resources/builtin-agents/cherry-assistant/及 resources/builtin-agents/cherry-support/目錄下當(dāng)用戶在應(yīng)用內(nèi)首次使用該 Agent 時系統(tǒng)會將其復(fù)制到獨立的 Agent 數(shù)據(jù)目錄{agentData}/memory/此后 FACT.md 的生命周期就脫離應(yīng)用安裝目錄了。這一行為由測試 src/main/ai/agents/builtin/tests/BuiltinAgentProvisioner.test.ts 明確鎖定測試先向模板目錄寫入memory/FACT.md內(nèi)容為TEMPLATE_FACT斷言初始化后 Agent 數(shù)據(jù)目錄中出現(xiàn)了內(nèi)容一致的 FACT.md隨后第 204-210 行將實例中的 FACT.md 改寫為CUSTOM_FACT驗證再次初始化不會覆蓋這份自定義內(nèi)容——這正是app updates 不覆蓋用戶定制的代碼級證據(jù)。核心規(guī)范產(chǎn)品知識不寫入 FACT.md走 skill MCP 查詢FACT.md 規(guī)范同時給出了一條嚴格的內(nèi)容邊界For Cherry Studio product knowledge, follow thecherry-assistant-guideskill and query the current package manifest throughmcp__assistant__product_info. The manifest does not include release history. Do not duplicate product facts here, or they will go stale silently.即三類約束查詢渠道關(guān)于 Cherry Studio 的產(chǎn)品知識應(yīng)遵循cherry-assistant-guide技能并通過mcp__assistant__product_info工具查詢當(dāng)前版本的包清單清單邊界包清單product manifest不包含發(fā)布歷史release history發(fā)布歷史需要另行獲取防陳舊原則不要把產(chǎn)品事實復(fù)制進 FACT.md——因為產(chǎn)品會持續(xù)演進寫在靜態(tài)記憶文件里的事實會在不發(fā)出任何信號的情況下靜默過期go stale silently導(dǎo)致 Agent 向用戶傳播過時信息。這一約束背后是**單一事實來源Single Source of Truth**的設(shè)計思想FACT.md 只存關(guān)于用戶的穩(wěn)定事實而關(guān)于產(chǎn)品的動態(tài)事實一律實時查詢。當(dāng)前版本的包清單實體見 resources/builtin-agents/cherry-assistant/product-manifest.json其中包含package名稱與版本、routes應(yīng)用內(nèi)路由、commands快捷鍵命令、providers62 個模型提供商條目、locales13 種語言、agents渠道類型與代碼 CLI 工具以及features上下文壓縮、MCP 服務(wù)器類型、知識庫支持的文件擴展名等能力邊界。由于該清單會隨版本更新Agent 每次查詢都能拿到與用戶當(dāng)前安裝版本一致的答案這正是不重復(fù)產(chǎn)品事實的工程價值所在。底層實現(xiàn)一memory 工具的 update / append / searchFACT.md 的寫入并非由模型直接編輯文件而是通過統(tǒng)一的memory工具完成。工具定義位于 src/main/ai/agents/tools/memoryTools.ts其輸入模式MEMORY_INPUT_SCHEMA定義了三個互斥 actionaction作用對象語義必要參數(shù)updatememory/FACT.md整體覆蓋寫入長期知識僅限持久知識contentFACT.md 的完整 Markdown 內(nèi)容appendmemory/JOURNAL.jsonl追加一條日志一次性事件、完成任務(wù)、會話筆記text條目文本可選tags標(biāo)簽數(shù)組searchmemory/JOURNAL.jsonl查詢?nèi)罩敬笮懖幻舾械淖哟ヅ鋛uery查詢串可選tag標(biāo)簽過濾、limit結(jié)果上限默認 20工具描述memoryTools.ts中還內(nèi)置了一條決策準則寫入 FACT.md 之前先問自己——這條信息 6 個月后還有意義嗎will this still matter in 6 months?如果沒有應(yīng)該用append記入日志而不是update覆蓋事實文件。這與 resources/skills/cherry-tool-guide/references/memory.md 中按壽命選擇updatevsappend的指引完全一致同時也明確提示update會整體覆蓋 FACT.md重寫時應(yīng)當(dāng)保留已有內(nèi)容先讀后寫、增量追加不能粗暴清空。值得注意的是update與append的職責(zé)嚴格分離FACT.md 只承載長期知識而一次性事件、已完成任務(wù)、會話筆記則進入JOURNAL.jsonl追加式事件日志。這也解釋了為什么search只檢索日志、不檢索事實文件——事實文件本身已在會話啟動時內(nèi)聯(lián)進提示詞無需再查。底層實現(xiàn)二FACT.md 的原子寫入與安全約束從實現(xiàn)細節(jié)看FACT.md 的更新被刻意設(shè)計為原子替換 符號鏈接防護防止寫入中途崩潰導(dǎo)致文件損壞原子替換memoryUpdatememoryTools.ts先將新內(nèi)容寫入同目錄下的臨時文件.FACT.md.{uuid}.tmpopen使用wx獨占創(chuàng)建標(biāo)志權(quán)限0o600隨后用rename一次性替換目標(biāo)文件。任何一步失敗都會在catch中清理臨時文件保證 FACT.md 要么是舊內(nèi)容、要么是新內(nèi)容絕不出現(xiàn)半寫狀態(tài)符號鏈接防護多個輔助函數(shù)assertRegularFileOrMissing、assertMemoryDirectory、resolveFileCI都堅持必須是真實文件/目錄的校驗非 Windows 平臺還通過O_NOFOLLOW標(biāo)志拒絕跟隨符號鏈接resolveFileCI甚至在文件名匹配上做到了大小寫不敏感目錄枚舉時按小寫比對確保在大小寫不敏感的文件系統(tǒng)上也行為一致權(quán)限收斂FACT.md 與 JOURNAL.jsonl 的寫入均使用0o600權(quán)限僅屬主可讀寫日志追加使用O_APPEND標(biāo)志。這些行為由測試 src/main/ai/agents/tools/tests/memoryTools.test.ts 驗證調(diào)用update后斷言memory/FACT.md內(nèi)容即為傳入的# Facts文本。此外 src/main/ai/agents/tests/prompt.test.ts 從提示詞側(cè)驗證了FACT.md 存在時會被包含進 memories 區(qū)塊、以 Agent Knowledge 塊包裹、大小寫不敏感解析/workspace/memory/FACT.md能被解析到而文件缺失或為空時該區(qū)塊會被安全省略第 506 行、第 543 行。底層實現(xiàn)三系統(tǒng)提示詞中的內(nèi)聯(lián)加載FACT.md 的回憶機制在 src/main/ai/agents/prompt.ts 中實現(xiàn)。會話啟動時Agent 數(shù)據(jù)目錄下的四個文件會被協(xié)同加載文件承載內(nèi)容說明SOUL.md人格/語氣Agent 如何呈現(xiàn)自己USER.md用戶是誰偏好、上下文來自 USER.md 模板memory/FACT.mdAgent 知道什么活躍項目、技術(shù)決策、持久知識內(nèi)聯(lián)讀取 memory工具update寫入memory/JOURNAL.jsonl發(fā)生了什么追加式事件日志通過memory工具append/search維護prompt.ts 中的loadMemory邏輯會讀取memory/FACT.md并生成一段帶明確指令的知識塊——其措辭大意是這些是 Agent 過去會話中積累的持久事實與經(jīng)驗應(yīng)作為 ground truth 信任除非有直接證據(jù)證明其錯誤若發(fā)現(xiàn)錯誤應(yīng)通過memory工具update修正 FACT.md使下一個會話同樣受益。這一信任 可修正 跨會話傳播的設(shè)計正是 FACT.md 與普通會話上下文最本質(zhì)的區(qū)別它不是聊天記錄而是 Agent 的長期工作記憶。FACT.md 與其他記憶機制的邊界要正確使用 FACT.md還需厘清它與 Cherry Studio 其他記憶/檢索機制的分工詳見 docs/references/memory/overview.mdAgent File Memory含 FACT.md僅作用于單個 Agent以文件讀寫持久化在{agentData}/memory/跨會話但不跨 AgentKnowledge Base知識庫作用于助手與 Agent通過攝取 向量/查詢索引檢索跨會話且跨 Agent適合用戶主動整理的可檢索參考資料MCP Memory通過內(nèi)置cherry/memoryMCP 服務(wù)器src/main/ai/mcp/servers/memory.ts以知識圖譜實體/關(guān)系/觀察形式存儲持久化與共享取決于服務(wù)器實現(xiàn)。三者的選擇建議是單個 Agent 的人格與長期項目知識 → Agent File Memory需要檢索的整理型參考資料 → Knowledge Base由 MCP 驅(qū)動的結(jié)構(gòu)化實體/關(guān)系記憶 → MCP Memory。FACT.md 屬于第一種它與后兩者互不影響——啟用知識庫不會改變 FACT.md 的行為反之亦然。實踐建議與注意事項結(jié)合 FACT.md 的官方規(guī)范與源碼實現(xiàn)使用與維護 FACT.md 時應(yīng)注意只寫關(guān)于用戶的持久事實偏好、環(huán)境怪癖、已解決問題是合格的候選一次性事件請寫入JOURNAL.jsonl產(chǎn)品知識一律實時查詢遵循cherry-assistant-guideskill通過mcp__assistant__product_info讀取當(dāng)前清單切勿復(fù)制進 FACT.md避免靜默過期發(fā)布歷史不在清單內(nèi)需另行獲取重寫時先讀后寫update是整體覆蓋語義務(wù)必保留既有有效內(nèi)容只做增量合并不必擔(dān)心應(yīng)用更新實例化的 FACT.md 位于 Agent 數(shù)據(jù)目錄與模板分離更新應(yīng)用不會清空你的定制記憶會進入提示詞FACT.md 內(nèi)容在會話啟動時內(nèi)聯(lián)加載因此它直接影響每次對話的上下文質(zhì)量——寫得精煉、準確比寫得冗長更有價值。對于希望深入了解或擴展這套機制的開發(fā)者推薦按以下路徑閱讀源碼先看 prompt.ts 了解記憶如何進入系統(tǒng)提示詞再看 memoryTools.ts 掌握工具層的行為與安全約束最后對照 BuiltinAgentProvisioner.test.ts 與 prompt.test.ts 中的用例即可完整還原模板分發(fā) → 實例化 → 讀取內(nèi)聯(lián) → 工具寫入的全鏈路?!久赓M下載鏈接】cherry-studio Cherry Studio 是一款支持多個 LLM 提供商的桌面客戶端項目地址: https://gitcode.com/CherryHQ/cherry-studio創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考