在本教程中,我們使用 Letta 構建一個有狀態的工程 Copilot,用來演示代理式記憶(agentic memory)如何超越傳統的基於提示詞的對話。我們從可檢查的核心記憶塊(core memory blocks)入手,這些記憶塊可以由 agent 自主更新;隨後將這些塊暴露出來,以便進行程式化的狀態同步,並支援多個 agent 之間共享訪問。我們進一步用歸檔向量記憶(archival vector memory)擴充套件該架構,以實現語義檢索;新增一個自定義的服務端工具,用於確定性的風險估算;使用流式輸出觀察 agent 的執行過程;利用服務端訊息歷史實現持久會話;並透過 .af 匯出實現可移植性。這些元件共同展示了一種實用的記憶架構,其中持久狀態、檢索、工具、多 agent 協作和執行軌跡作為一個整合化的代理式系統協同工作。
首先我們安裝並初始化 Letta 客戶端,然後新增相容性輔助函式來處理不同 Letta 版本之間的 API 差異。我們用 flex 輔助函式依次嘗試多種呼叫形式,並在全部失敗時丟擲明確的錯誤;動態選擇可用模型時,優先嚐試 openai/gpt-4.1、openai/gpt-4o-mini、anthropic/claude-sonnet-4-20250514,若都不可用則回退到模型列表中的第一個控制代碼。隨後我們建立一個有狀態的工程 Copilot,併為其配置結構化的核心記憶塊:persona(人格設定,說明我是 Mnemo,一個簡潔、具體、絕不編造事實的工程 Copilot,不知道就直說然後去查)、human(關於所合作工程師的持久事實:姓名、角色、技術棧、偏好、工作風格,每當瞭解到穩定資訊時更新)、project_state(正在交付的專案的即時狀態:里程碑、阻塞項、決策及其理由,保持密集且最新,刪除過時內容)、lessons(來之不易的教訓和絕不再犯的錯誤,僅追加,每行一條)。建立後我們列印 agent 的 id,並匯出初始核心記憶,以建立 agent 的持久上下文基線。
接下來演示自我編輯記憶:我們告訴 Copilot「我是 Priya,Northwind 的資深工程師,我們將在 11 月 14 日釋出 Halo,一個 Rust 攝取服務。我討厭冗長的解釋——給我要點或程式碼,不要長篇大論。當前阻塞項:Kafka 消費者在負載下大約每 4 分鐘就發生一次再均衡。」隨後補充更新:「我們把再均衡追溯到 5 秒的 max.poll.interval.ms 加上緩慢的批次提交。決定:把提交移出輪詢迴圈。另外記住我們已經試過調大 session.timeout.ms,沒有效果——不要再建議這個。」兩輪對話後我們再次匯出核心記憶,觀察哪些資訊移動到了哪個塊中。這展示了 agent 如何自主決定將持久事實寫入 human、決策寫入 project_state、失敗教訓寫入 lessons。
第三步展示應用程式程式碼可以直接寫入上下文視窗。我們從塊中讀取當前的 project_state,然後追加一行:「[CI 09:41Z] main 變紅:integration/kafka_rebalance_test 失敗(已復現不穩定 x3)。」然後問 agent「開始今天工作之前有什麼我應該知道的嗎?」以驗證它能利用外部注入的狀態。
第四步演示兩個 agent 之間的共享記憶。我們建立一個只讀的 policies 塊(包含不可協商的工程政策:1. 不允許直接推送到 main;2. 每個修復都必須附帶回歸測試;3. 客戶資料絕不離開歐盟區域),以及一個可讀寫的 team_scratchpad 塊,供 Copilot 和審查者 agent 共享,雙方讀寫時以自己名字為字首。我們將這兩個塊附加到 Copilot 上,然後建立 reviewer agent(人格設定為 Argus,一個偏執的資深審查者,專門尋找其他人跳過的失敗模式,並按編號引用團隊政策),讓它共享這兩個塊。我們讓 Copilot 把再均衡問題的擬定修復寫入 team_scratchpad(限制 4 行),列印審查者看到的共享塊內容,然後讓 reviewer 讀取並審查該修復、引用其違反的政策,並把裁決追加到同一個塊中。最後我們列印審查者回復後的共享塊內容,以及附加到該塊上的 agent 列表,驗證多 agent 之間的持久工作上下文交換。
第五步進入歸檔記憶:我們批次載入帶標籤的工程知識,然後用語義搜尋檢索相關資訊,而不依賴精確的關鍵詞匹配。知識條目包括:2024-08-02 的事後覆盤(Halo 在部署期間消費者組再均衡時丟失了 120 萬事件,根因是輪詢迴圈內的提交阻塞超過了 max.poll.interval.ms)、ADR-017(Halo 使用至少一次投遞,基於 (tenant_id, event_id) 的冪等寫入;因吞吐量原因拒絕了透過 Kafka 事務實現精確一次)、以及一條運維手冊(排空 Halo 節點的方法)。隨後我們允許 agent 在回答運維問題時自主查詢這些歸檔知識。
最後我們建立並附加一個自定義的服務端工具 estimate_release_risk,用於確定性的風險估算。該函式接收 open_bugs(P0/P1 未解決缺陷數)、days_to_deadline(距釋出日的剩餘天數)和 test_coverage(0.0 到 1.0 的覆蓋率),透過 pressure = open_bugs / max(days_to_deadline, 1) 計算壓力,score = max(0.0, min(100.0, 100 * (1 - exp(-1.4 * pressure)) * (1.3 - test_coverage))),並給出裁決:低於 35 為 SHIP,低於 70 為 SLIP ONE WEEK,否則為 DO NOT SHIP,返回格式如 risk_score=… verdict=…。我們將該工具 upsert 並附加到 Copilot,列印已附加的工具和 agent 工具列表,然後要求 agent 用「9 個未解決的 P0/P1 缺陷、距 11 月 14 日還有 12 天、覆蓋率 0.61」呼叫該工具評分,並把裁決記錄到 project_state 中。
綜上,本教程展示了持久狀態、檢索、工具、多 agent 協作和執行軌跡如何作為整合化的代理式系統協同運作。此外還涉及透過流式輸出觀察 agent 執行、使用服務端訊息歷史保持持久會話,以及透過 .af 匯出實現可移植的 agent 工作流。需要說明的是,教程中的輔助函式針對多種 API 變體做了相容處理,因此在實際執行時可能需要根據所用的 Letta 客戶端版本調整呼叫形式;示例中的模型控制代碼和嵌入模型(openai/text-embedding-3-small)也取決於賬戶可用性。