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