跳至內容

記憶與知識

沒有記憶,每一次代理對話都從零開始:同一條慣例要重新解釋、同一個決定要重新爭論、同一條死路要重新探索。記憶是以工作區為範圍、能跨越多次執行而存續的儲存庫,它的存在是為了讓一個代理產生的知識,日後能被另一個代理找到。

它有三層,各自回答不同問題:

  1. 事實 — 甚麼是真的(一條慣例、一個結果、一個決定)。
  2. 政策 — 代理必須據此做甚麼(一條規範性規則)。
  3. 工作記憶 — 某個代理當時正做到哪裏。

這個區分之所以重要,是因為它們經由不同途徑到達代理。事實是被搜尋的。政策是被推送的。工作記憶是私有的。

MemoryFact 是一個以工作區和領域為範圍的知識單元。

屬性 是甚麼
domain 知識領域(“conventions”、“decisions”、“codebase”)
topic 簡短的主題標籤
content 知識文字
confidence 0.0–1.0,由來源奠定初始值,並在再次提及時提升
memoryType 事實的種類 — 決定其時間衰減曲線
veracity 如何得知 — 奠定信心值,並決定每次再次提及的提升幅度
sourceObservationIds 由哪些觀察得出
supersededBy 取代它的較新事實(如有)
validUntil, recallCount, mentionCount 召回時使用的到期與使用量訊號

最後兩列是人們常忽略的,而它們決定了_哪一則_事實會浮現。memoryType 帶有逐類型的 Weibull 衰減參數,因此有時限的承諾會迅速消退,而穩定的個人側寫事實則不會。veracity 記錄來源 — 由人陳述(權重 1.0)、由代理推斷(0.7)、由工具產生(0.5)、匯入(0.6)— 而該權重奠定事實的初始信心值。

事實在被推翻時,絕不會就地編輯。寫入事實會對同領域、同主題的事實執行衝突偵測,並取代落敗的一方,同時記錄一列衝突。稽核軌跡正是重點所在:你永遠可以看到先前相信的是甚麼,以及甚麼取代了它。

MemoryPolicy 是從事實衍生、以工作區和領域為範圍的規範性規則,帶有啟用標記與選用的 requiredRole。

工作區內每一條啟用中的政策都會注入每一次派發,不經篩選 — 不按領域、角色、任務或空間篩選。在你寫下第二十條政策之前,這一點值得知道,因為政策會與任務爭奪同一個上下文窗口。這也是政策上的 requiredRole 只屬建議性質的原因:它描述規則針對誰,但無法阻止規則到達其他所有人。

MemoryDomain 在工作區內將事實與政策分組。領域為知識提供組織結構,也是存取授權所依據的單位 — 但在把領域當成機密界線之前,請先看下方的注意事項。

領域可以是全工作區(architecture)或限定於一個程式庫(repo:<slug>/architecture)。兩個範圍中的同名領域是兩個獨立儲存庫:對某個程式碼庫為真的事實,不會覆寫全工作區的那一個。當代理正在該程式庫中工作時,search_memory 與派發前言會把程式庫範圍的記憶排在前面;但它們不會把其餘的篩掉。在 propose_fact / propose_policy / search_memory 上傳入 repo,即可寫入或提升該範圍。

MemoryAccessGrant 將代理角色與領域對應到三種權限層級之一:

權限 含義
none 沒有存取權
read 可搜尋並擷取事實
write 為 propose_policy 所需。事實寫入(propose_fact、supersede_fact)不受授權限制

這種不對稱 — 對讀取寬鬆、對政策寫入嚴格 — 是刻意的取捨。記憶在流通時最有用,而拒絕讀取會產生一個悄悄知道得更少的代理,而不是一個回報問題的代理。相較之下,拒絕政策寫入既明顯又可修正,所以強制執行就放在那裏。新建的領域會為每個角色種入 write;之後要收緊只能透過 RPC 編輯,因為沒有授權 UI。

每個代理都有一個 AgentWorkingMemory:以工作區和代理為鍵的自由文字記事板。它跨執行存續、只屬於該代理,並在每次派發時注入其提示。它存放的是「我重構 auth 做到一半」這類東西 — 值得帶到下一次執行、但不值得提升為持久事實的狀態。

派發時,記憶前言恰好由三樣東西組成:

  • 每一條啟用中的工作區政策,以 - [domain] rule 形式呈現。
  • 代理自己的工作記憶,原文照錄。
  • 按關鍵字配對的事實候選清單,針對此任務 — 最多五項,在約 1,200 字元的預算內,且僅在任務描述至少 20 個字元長時才會出現。較短的任務完全不會取得事實。

候選清單只採 FTS/關鍵字,並且刻意設上限。嵌入查詢很慢,而派發路徑是延遲會立即顯現的地方,所以慢速的語意路徑被刻意排除在外。前言最後會指示代理用 search_memory 驗證關鍵項目,完整的召回模型就在那裏。

這條路徑不查詢任何存取授權。候選清單找到甚麼,代理就看到甚麼。

代理面向的 search_memory 工具有三種模式,而它們是真正不同的搜尋:

  • keyword — 僅 FTS5。
  • semantic — BM25 與向量結果以倒數排名融合。
  • hybrid(預設)— 多聲部召回:四道排名的聲部融合在一起,然後多樣化。

四道聲部是詞彙(FTS)、語意(向量 KNN)、時間(近期啟用的事實)與圖譜 — 從最強的詞彙與語意種子出發,沿情節邊走兩跳。圖譜聲部正是情節邊存在的理由:它浮現與你的答案_相連_、但不符合你任何字詞的事實。聲部按分類後的查詢意圖加權(預設語意權重最大,然後是圖譜與詞彙,再之後是近期程度),每個候選的分數會按其 Weibull 衰減縮放,結果集再以 MMR 多樣化,使同一則事實的五種重述不會擠掉四則不同的事實。

桌面與網頁的記憶搜尋是一條獨立、較簡單的路徑:memory_fact.search RPC 操作僅採 FTS5,因為精簡用戶端無法附上查詢嵌入,而混合路徑留在主機內部。所以你在記憶瀏覽器中看到的排名,並不是代理從 search_memory 取得的排名。這是預期行為,不是錯誤,但它確實意味著在 UI 中「我搜尋過但找不到」並不證明代理找不到。

記憶瀏覽器位於 設定 → 工作區 → 記憶(/workspaces/<id>/settings/memory),設有事實、政策與圖譜分頁。

那裏有一個令人意外的不對稱:你可以編輯和刪除記憶,但不能建立記憶。 事實分頁和政策分頁都沒有新增的操作入口。撰寫是在代理一方,透過 propose_fact 和 propose_policy 進行(用 supersede_fact / supersede_policy 取代它們)。remember 寫入一個以對話為界的熱層項目,consolidate_memory 之後可能把它提升為事實;record_observation 和 update_my_notes 寫入派發時注入的私人記事板。瀏覽器是檢閱與修正的介面,不是撰寫介面 — 所以如果你想要一則事實進入記憶,辦法就是告訴一個代理。

兩項維護操作同樣由代理叫用,而非按排程執行:consolidate_memory 合併與修剪累積的事實,harmonize_memory 調和不同代理之間分歧的信念。list_memory_conflicts 顯示衝突偵測已記錄的內容。沒有任何定時器會替你執行它們。當會議保存步驟記錄會議決定時,這些決定會收集到 decisions 領域;那不是對已完成代理執行所設的定時器。