基於 ECS 的高性能 Agent 框架

進階2/6/2025, 1:26:26 PM
Project89 採用 ArgOS的 ECS(實體-組件-系統)架構,來設計 Agent Framework。其獨特之處在於將系統分為有意識、潛意識和無意識三個層次,每個System獨立運行且無耦合。通過感知、體驗、思考、行動等系統的協同,實現了高度模塊化和高性能的Agent框架。這種架構不僅適用於遊戲開發,在複雜的DefAI場景下也具有潛在優勢。

轉發原文標題:《我在 Project89 內看到下一代 Agent 框架》

先說結論,@project_89 採用一種全新的方式來設計 Agent 框架, 這是一個針對遊戲開發的高性能的 Agent 框架,與目前使用的 Agent 框架相比更加模塊化也有更好的性能。

這篇文章花了很長的時間來寫,試圖讓所有人都懂這個框架相比傳統 Agent 框架在架構上做了什麼升級,前後改了很多次才有了這個版本,但是文中仍然有些部分太過技術,我沒能很好的進一步通俗化,如果你對文章改進有任何建議歡迎留下你的評論。

開發者背景

這是一篇技術博客,所以我們先來看看這個founder的技術實力

Founder在做project89之前做了這個項目:https://github.com/Oneirocom/Magick,也是一款利用AI進行編程的軟件同時shaw也是這個項目排名第四的開發者,在shaw的履歷裡也可以看到這個項目

左上:project89的founder , 右下: lalaune 就是ai16z的shaw

而今天我們主要來介紹下 project89 裡面的高性能 Agent Framework:

https://github.com/project-89/argOS

一、為什麼要用ECS來設計Agent Framework

從遊戲領域的應用來看

目前採用ECS架構的遊戲有:

區塊鏈遊戲:Mud、Dojo

傳統遊戲: 守望先鋒、星際公民等等

而且目前主流的遊戲引擎也在往ECS的方向進化比如Unity

什麼是 ECS

ECS(Entity-Component-System)是一種在遊戲開發與模擬系統中常用的架構模式。它將數據與邏輯徹底分離,以便在大規模可擴展場景下高效管理各種實體及其行為:

Entity(實體)

• 僅僅是一個 ID(數字或字符串),不包含任何數據或邏輯。

• 可以根據需要,掛載不同的組件來賦予它各種屬性或能力。

Component(組件)

• 用來存儲實體的具體數據或狀態。

System(系統)

• 負責執行與某些組件相關的邏輯。

以一個具體的Agent行動的例子來理解這套體系:

在 ArgOS 中將每一個Agent看成一個 Entity,它可以註冊不同的組件,比如在下面這幅圖裡,我們這個Agent擁有以下四個組件:

Agent Component: 主要存儲類似 Agent 名稱,模型名字等等基礎信息

Perception Component: 主要用來存儲感知到的外界數據

Memory Component: 主要用來存儲 Agent Entity的Memory數據,類似做過的事情等等

Action Component: 主要存儲要執行的 Action 數據

System 的工作流程:

  1. 在這個遊戲裡比如感知到了自己面前有一個武器,那麼這個就會調用 Perception System的執行函數來執行更新這個Agent Entity 的Perception Component 裡面的數據
  2. 然後再觸發 Memory System, 同時 調用 Perception Component 和 Memory Component, 把感知到的數據通過Memory持久化到數據庫之後
  3. 然後 Action System 再調用Memory Component 和 Action Component ,從記憶中獲取周邊環境的信息,然後最終執行相應的動作。

接著我們就得到一個每個Component數據 都被更新的 Update Agent Entity

4.所以我們可以看到這裡面System 主要負責定義要對哪些Component 執行對應的處理邏輯。

而且很明顯在 project89 裡面它是一個世界裡面充斥著各種類型的 Agent,比如有些Agent不僅僅擁有以上的基礎能力還有做計劃的能力。

那麼就會如下面這個圖所示:

System的運行流程

但是實際的 system 執行流程不是我們想象的 Perception System執行完之後調用 Memory System 這種傳統做法,不同System之間是不存在調用關係的,每個System都會在一個規定的週期內執行一次,比如:

  • Perception System可能2s執行一次來更新接收到的外界感知,並把它們更新到 Perception Component之中
  • Memory System 可能會是每1s執行一次,從Perception Component 之中提取數據加載到Memory Component之中
  • Plan System可能是每 1000s執行一次,根據接收到的信息判斷自己需不需要根據對應的目標優化制定合理的計劃,然後把這部分更新記錄到 Plan Component之中
  • Action System 可能也是每2s執行一次,這樣可以根據外界的信息及時做出反應,同時如果Plan Component有更新則需要根據這部分數據更新自己的Action Component,進而影響最初做出的Action.

文章到這裡都是基於我對ArgOS 的理解大大簡化了它的架構方便大家更好理解,接下來我們來看真實的ArgOS.

二、ArgOS System 架構

ArgOS之中為了讓 Agent 可以進行更加深度的思考執行更復雜的任務,設計了很多Component,以及很多System.

並且ArgOS之中將System分為“三種層次” (ConsciousnessLevel):

1)有意識(CONSCIOUS) 系統

  • 包含 RoomSystem, PerceptionSystem, ExperienceSystem, ThinkingSystem, ActionSystem, CleanupSystem)
  • 更新頻率通常較高 (如每 10 秒)。
  • 更貼近“實時”或“顯意識”層面的處理,如環境感知、實時思考、執行動作等。

2)潛意識(SUBCONSCIOUS) 系統

  • GoalPlanningSystem, PlanningSystem
  • 更新頻率相對較低 (如每 25 秒)。
  • 處理“思考”的邏輯,如週期性檢查/生成目標和計劃。

3)無意識(UNCONSCIOUS) 系統

  • 目前暫時還沒有啟用
  • 更新頻率更慢(如 50 秒以上),

所以在 ArgOS之中是將不同的System根據ConsciousnessLevel劃分,來規定這個System多久之後執行一次。

為什麼要這麼設計呢?

因為ArgOS之中各個system之間的關係極其複雜,如下圖:

1 PerceptionSystem負責從外界或其他實體那裡收集“刺激”(stimuli),並將其更新到代理(Agent)的 Perception 組件中。

判斷刺激是否顯著變化,根據穩定度、處理模式 (ACTIVE/REFLECTIVE/WAITING) 等做相應更新。

最終為後續的 ExperienceSystem、ThinkingSystem 等提供“當前感知”的信息。

2 ExperienceSystem將 PerceptionSystem 收集到的 Stimuli 轉換為更加抽象的“體驗”(Experience)。

會調用 LLM 或規則邏輯 (extractExperiences) 來識別新的體驗,並存儲到 Memory 組件。

去重、篩選、校驗體驗,同時通過 eventBus 觸發“experience”事件給其他系統或外部監聽者。

3 ThinkingSystem智能體自身的“思考”系統。

從 Memory、Perception 等組件裡提取當前狀態,通過 generateThought(…) 與 LLM / 規則邏輯生成“思考結果”(ThoughtResult)。

根據思考結果,可能:

• 更新 Memory 中的 thoughts (思考歷史)。

• 觸發新的 Action(放到 Action.pendingAction[eid])。

• 改變 agent 的外在 Appearance(表情、姿勢等),並生成相關 Stimulus 讓其他實體“看到”變化。

4 ActionSystem若某個 Agent 的 Action.pendingAction 非空,則通過 runtime.getActionManager().executeAction(…) 來真正執行動作。

執行完後將結果寫回 Action.lastActionResult,並通知房間或其他實體。

也會藉此產生 CognitiveStimulus(認知刺激),以便後續系統“知道”該動作已完成,或可以納入記憶。

5 GoalPlanningSystem週期性地評估 Goal.current[eid] 列表中目標的進度,或檢查外部/自身記憶是否出現重大變化 (detectSignificantChanges)。

當需要新目標或進行目標調整時,通過 generateGoals(…) 生成並寫入 Goal.current[eid]。

同時更新在進度中 (in_progress) 的目標,若符合完成或失敗條件就改變狀態,並向相應 Plan 發出完成/失敗信號。

6 PlanningSystem對“已有目標”(Goal.current[eid])生成或更新 Plan(執行計劃)。

如果檢測到某些目標沒有對應的活動中 (active) 計劃,則通過 generatePlan(…) 產生一個包含若干 steps 的執行路線圖,並將其寫入 Plan.plans[eid]。

也會在目標完成或失敗時更新與其關聯的 Plan 狀態,併產生相應認知刺激。

7 RoomSystem處理與房間(Room)相關的更新:

• 獲取房間內的佔用者列表 (occupants),為每位 agent 生成“外觀(appearance)”刺激,讓其他實體“看到”他的外貌或動作。

• 創建房間環境 Stimulus (如貼切的“房間氛圍”信息) 並進行關聯。

確保當 Agent 處於某個空間環境時,其他正在感知該空間的實體可以感知到他的外貌變化。

8 CleanupSystem定期查找並移除標記了 Cleanup 組件的實體。用於回收不再需要的 Stimulus 或其他對象,防止 ECS 中遺留大量無效的實體。

  • 示例:從“看到物體”到“執行動作”的一次循環

下面的場景示例展示了各個 System 如何在一回合(或幾幀)內依次配合完成一次完整流程。

場景準備:世界(World)中存在一個 Agent (EID=1),正在“Active”狀態,且處在某個 Room (EID=100)。

該 Room 裡新出現了一個道具“MagicSword”,生成了相應的 Stimulus。

  1. PerceptionSystem檢測到“MagicSword”的出現,對 Agent(1) 生成 Stimulus (type=“item_appearance”) 並添加到 Perception.currentStimuli[1]。對比上一次 Stimuli Hash,認定“有顯著變化”,“重新激活”代理的 ProcessingState (ACTIVE 模式)。
  2. ExperienceSystem看到 Agent(1) 的 Perception.currentStimuli 非空,於是把“Sword appears”之類的信息抽取為1條或多條新 Experience (type: “observation”)。存儲到 Memory.experiences[1] 裡,併發射「experience」事件。
  3. ThinkingSystem讀取 Memory、Perception 等狀態信息,調用 generateThought:

“我看到了 MagicSword,也許能撿起來看看它能幹什麼…”該思考結果包含一個待執行的 Action:{ tool: “pickUpItem”, parameters: { itemName: “MagicSword” } }

ThinkingSystem 將此 Action 寫入 Action.pendingAction[1]。

若有 appearance 改動(例如“面帶好奇的表情”),則更新 Appearance 併產生視覺刺激。

  1. ActionSystem看到 Action.pendingAction[1] = { tool: “pickUpItem”, parameters: … }。

通過 runtime.getActionManager().executeAction(“pickUpItem”, 1, { itemName: “MagicSword” }, runtime) 執行“拾取”動作邏輯。得到結果:{ success: true, message: “你撿起了魔法劍” },更新到 Action.lastActionResult[1],並觸發「action」事件廣播給房間(100)。

同時產生認知刺激 (type=“action_result”),寫入 Memory 或讓 ThinkingSystem 下個回合捕獲。

  1. GoalPlanningSystem (若該 agent 有目標)週期性地評估 agent 的目標,如果此時 agent 的某個目標是“獲得強力武器”,並檢測到 MagicSword 已到手,可能將該目標標記為完成。如果產生/keySeatTr new changes (比如“新物體出現在房間”影響了 agent 追求的目標?),則根據 detectSignificantChanges 生成新的目標或放棄舊目標。
  2. PlanningSystem (若有相關目標)對“獲得強力武器”這樣已完成或剛生成的目標,檢查是否需要新 Plan 或更新既有 Plan。

如果已完成,則把關聯的 Plan [status] 置為 “completed”;或若目標要擴展後續流程 (“研究魔法劍”),則生成更多步驟。

  1. RoomSystem (每幀或每回合)更新房間(100)中的 Occupants 列表和可見實體。

若 agent(1) 外觀改變(比如 Appearance.currentAction = “holding sword”),就創建新的「appearance」視覺刺激,讓其他在同房間的 Agent2, Agent3 知道“agent1 拿起了劍”。

  1. CleanupSystem移除已標記(Cleanup)的實體或刺激。若拾取後“MagicSword”這個 Stimulus 不再需要保留,可以在 CleanupSystem 中刪除對應 Stimulus 實體。
  2. 通過這些系統的銜接,AI Agent 就實現了:

• 感知環境變化(Perception) → 記錄或轉化為內在經驗(Experience) → 自我思考並決策(Thinking) → 付諸行動(Action) → 動態調整目標與計劃(GoalPlanning + Planning) → 同步環境(Room) → 及時回收無用實體(Cleanup)

三、ArgOS整體架構解析

1、核心架構分層

2、組件(Component)分類

在 ECS 中,每個實體 (Entity) 可擁有若干組件 (Component)。根據在系統中的性質和生命週期,大致可以將組件分為以下幾類:

1 核心身份類 (Identity-Level Components)

• Agent / PlayerProfile / NPCProfile 等

• 用來唯一標識實體、存放核心角色或單位信息,一般需要持久化到數據庫。

2 行為與狀態類 (Behavior & State Components)

• Action, Goal, Plan, ProcessingState 等

• 代表了實體當前要做的事情或目標,以及對外部命令、內部思維的響應狀態。

• 包含 pendingAction, goalsInProgress, plans, 以及在隊列中的思考或任務等。

• 通常為中/短期狀態,很多會隨著遊戲回合或業務週期動態變化。

• 是否需要落庫視情況而定。如果希望斷點續跑,可能定期寫入數據庫。

3 感知與記憶類 (Perception & Memory Components)

• Perception, Memory, Stimulus, Experience 等

• 記錄了實體感知到的外部信息 (Stimuli),以及感知後提煉成的體驗 (Experiences)。

• Memory 往往可積累大量數據,例如對話記錄、事件歷史等;常常需要做持久化。

• Perception 可能是實時或臨時信息,多為短期內有效,可根據需求決定是否寫入數據庫(比如只存重要的感知事件)。

4 環境與空間類 (Room, OccupiesRoom, Spatial, Environment, Inventory 等)

• 代表房間、環境、位置、物品容器等信息。

Room.id、OccupiesRoom、Environment 等字段常常需要持久化,如房間首頁描述、地圖結構等。

• 不斷變化的組件 (比如 Entity 在不同房間之間移動) 可以做事件式或定期寫入。

5 外觀與交互類 (Appearance, UIState, Relationship 等)

• 記錄實體對外的“可見”或“交互”部分,如 Avatar, pose, facialExpression, 與其他實體的社交關係網絡等。

• 一部分可只在內存中處理(實時表現),另一部分(比如關鍵社交關係)可能要持久化。

6 輔助或運維類 (Cleanup, DebugInfo, ProfilingData 等)

• 用於標記哪些實體需要回收 (Cleanup)、或者記錄調試信息 (DebugInfo) 以便在監控和分析時使用。

• 一般只在內存中存在,很少會同步到數據庫 unless 日誌或審計需要。

3、System架構

上面已經介紹

4、Manager 架構

有了Component和 System 之外我們其實還缺少一個資源管理者,比如如何訪問數據庫,當狀態更新有衝突怎麼處理等等。

左側 Systems (PerceptionSystem、ExperienceSystem、ThinkingSystem 等):

• 每個系統在 ECS 循環中被 SimulationRuntime 調度執行,查詢並處理自己關心的實體(通過組件條件)。

• 在執行邏輯時,需要和 Managers 進行交互,例如:

  • 調用 RoomManager (RM) 查詢/更新房間信息。
  • 使用 StateManager (SM) 獲取或保存世界/代理狀態,如 Memory、Goal、Plan 等。
  • 藉助 EventBus (EB) 對外廣播或監聽事件。
  • 在某些需要自然語言處理或提示語時,調用 PromptManager (PM)。

右側 Managers (EventBus、RoomManager、StateManager、EventManager、ActionManager、PromptManager 等):

• 提供系統級功能,基本不主動“驅動”邏輯,而是被 Systems 或 Runtime 調用。

• 典型示例:

  • ActionManager 專門管理動作(Action)的註冊與執行。
  • EventManager / EventBus 用於事件發佈與訂閱機制。
  • RoomManager 管理 rooms、佈局與 occupant。
  • StateManager 負責ECS與數據庫或存儲的同步。
  • PromptManager 提供LLM Prompt模板、上下文管理等擴展。
  • 中間的 SimulationRuntime (R):

• 是所有 Systems 的“調度者”,啟動或停止不同層級(Conscious/Subconscious等)的系統循環;

• 也在構造階段創建 Managers 並傳給各 System 使用。

  • CleanupSystem:

• 特別注意它還和 ComponentSync (CS) 交互,用於在回收實體時同步移除組件或事件訂閱。

結論:

每個 System 會在需要時通過對應的 Manager 讀寫數據或調用服務,而 Runtime 則在更高層面統一調度所有 System 與 Manager 的生命週期及行為。

5、 如何向量與數據庫進行交互

在 ECS 中,Systems 是真正執行邏輯的地方,而數據庫讀寫可以通過一個“持久化管理器 (PersistenceManager / DatabaseManager)”或“狀態管理器 (StateManager)”來完成。大致流程可如下:

1 啟動或加載時 (Initial Load)

• StateManager / PersistenceManager 從數據庫加載 Agents、Rooms、Goals 等核心持久化組件的數據,創建對應實體 (Entities) 並初始化相關組件字段。

• 例如,讀取一批 agent 記錄插入 ECS 世界,給他們初始化 Agent、Memory、Goal 等組件。

2 ECS 運行時 (Systems Update Loop)

• 系統在每個幀 (或回合) 內做事情:PerceptionSystem 收集“感知”並寫到 Perception 組件 (多為短期不落庫)。

ExperienceSystem 把新的“認知體驗”寫入 Memory.experiences,若是關鍵體驗可能同時調用 StateManager 做立即存儲,或打上“needsPersistence”標記以便後續批量寫入。

ThinkingSystem / ActionSystem / GoalPlanningSystem 等根據組件內容做決策並更新 ECS 中的字段。

如果某些組件 (比如 Goal.current) 發生重大變更且需要持久化(例如新的長遠目標),通過組件監聽或系統事件,通知 StateManager 將該字段寫入數據庫。

3 定期或事件驅動的持久化 (Periodic or Event-Driven)

• 可以在系統中的某些關鍵點(如目標計劃發生更新或Agent發生重要事件)時,調用 PersistenceManager.storeComponentData(eid, “Goal”) 這類接口進行落庫。

• 也可以在 CleanupSystem 或定時器裡,讓 StateManager 掃描含有“needsPersistence”標記的組件或實體,一次性寫回數據庫。

• 此外,日誌或審計數據(如動作歷史、思考日誌)也可在這裡進行歸檔存儲。

4 退出或斷點保存 (Manual or Shutdown Save)

• 當服務器或進程要關閉時,通過 StateManager.saveAll() 將還沒寫入的數據統一寫入數據庫,以確保下次加載能恢復 ECS 狀態。

• 對於一些單機/離線場景,也可以手動觸發存檔。

  • 完整示例流程

以下給一個簡單的場景,演示組件和數據庫交互的可能方式:

1 啟動時:StateManager.queryDB(“SELECT * FROM agents”) → 得到一批 agent 記錄,依次為每條記錄創建 Entity (EID=x),並給其初始化 Agent、Memory、Goal 等組件字段。

同時從 “rooms” 表裡加載房間信息,創建 Room 實體。

2 運行階段:PerceptionSystem 在某個房間檢測到事件“MagicSword 出現”,寫入 Perception.currentStimuli[eid]。ExperienceSystem 將 Stimuli 轉化為 Experience,賦值到 Memory.experiences[eid]。ThinkingSystem 通過 Memory、Goal 等信息決定執行下一步行動,生成 Action.pendingAction[eid]。ActionSystem 執行該動作後,將結果寫到 Memory 或 Action.lastActionResult。若這是一次重大劇情事件,會把 Memory.experiences[eid] 的最新部分標記為 needsPersistence。StateManager 在一段時間後發現 Memory.experiences[eid] 帶有 “needsPersistence”,則將其寫入數據庫(INSERT INTO memory_experiences …)。

3 停止或斷點:基於 ECS 或系統調度,在“服務器關閉”時調用 StateManager.saveAll(),把仍在內存中的關鍵組件字段(Agent, Memory, Goal 等)它們的最新狀態寫進數據庫。下次重啟時,就能從數據庫中加載並恢復 ECS 的世界狀態。

• 將組件分類,既方便在項目中清晰地管理實體數據,也能幫助我們控制“需要持久化”與“僅在內存中存在”的數據邊界。

• 與數據庫的交互通常由一個專門的 Manager(如 StateManager)來處理,Systems 在需要讀寫數據庫時通過它進行操作,避免在 System 裡直接寫 SQL 或類似底層語句。

• 這樣能同時享受到 ECS 在邏輯上的高效與靈活,以及數據庫帶來的持久化、斷點續跑與數據統計分析優勢。

四、架構創新點

整個架構的亮點在於:

  • 每個System都是獨立運行的,不會跟其他的System之間有調用關係,因此即便我們希望實現Agent的“感知環境變化(Perception) → 記錄或轉化為內在經驗(Experience) → 自我思考並決策(Thinking) → 付諸行動(Action) → 動態調整目標與計劃(GoalPlanning + Planning) → 同步環境(Room) → 及時回收無用實體(Cleanup) ” 能力的時候,各個System在功能上會有很多互相依賴的點,但是我們依然可以通過ECS架構把整體結構成各個互不相關的System,每個System依然可以獨立運行,不會跟其他的System有人和耦合關係。

    我想這也是為什麼Unity這幾年越來越往ECS架構遷移最主要的原因。

  • 而且比如我現在只是希望一個Agent擁有一些基本能力,我只需要在定義Entity的時候減少註冊一些Component以及減少註冊System就可以輕易的實現,都不用改幾行代碼。

如下圖:

  • 同時如果你在開發過程中希望增加新的功能,也不會對其他的System有任何影響,可以很輕易的把自己希望的功能加載進去。

    另外當前這種架構的性能其實會比傳統面向對象架構的性能強很多,這在遊戲圈是一個公認的事實,因為ECS的設計更加適合進行併發,那麼當我們在複雜的Defai場景下,採用ECS架構也有可能會更有優勢,特別是希望採用Agent做量化交易的場景下,ECS也會有用武之地(不僅僅是在Agent遊戲場景下)。

  • 將System 分成有意識、潛意識和無意識來區分不同類型的System應該在多久後執行一次,是極其高明的設計,已經是一個很具象的人的能力了

從我個人的觀點來看,這是一個極其模塊化,性能極其優秀的框架,同時代碼質量也很高並且包含了很好的設計文檔,不過可惜的是 $project89 項目一直缺少對這個框架的宣傳,因此我才花了很長的時間(4天)寫了這篇文章,我覺得好的東西還是值得被發現,明天應該還會發一個英文版本,希望能有更多的遊戲團隊或者 Defai 團隊開到這個框架,為大家提供一種新的潛在的架構選擇!

聲明:

  1. 本文轉載自【0xhhh】,轉發原文標題:《我在 Project89 內看到下一代 Agent 框架》。著作權歸屬原作者【0xhhh】,如對轉載有異議,請聯繫 Gate Learn 團隊,團隊會根據相關流程儘速處理。
  2. 免責聲明:本文所表達的觀點和意見僅代表作者個人觀點,不構成任何投資建議。
  3. 文章其他語言版本由 Gate Learn 團隊翻譯, 除非另有說明,否則不得複製、傳播或抄襲經翻譯文章。

基於 ECS 的高性能 Agent 框架

進階2/6/2025, 1:26:26 PM
Project89 採用 ArgOS的 ECS(實體-組件-系統)架構,來設計 Agent Framework。其獨特之處在於將系統分為有意識、潛意識和無意識三個層次,每個System獨立運行且無耦合。通過感知、體驗、思考、行動等系統的協同,實現了高度模塊化和高性能的Agent框架。這種架構不僅適用於遊戲開發,在複雜的DefAI場景下也具有潛在優勢。

轉發原文標題:《我在 Project89 內看到下一代 Agent 框架》

先說結論,@project_89 採用一種全新的方式來設計 Agent 框架, 這是一個針對遊戲開發的高性能的 Agent 框架,與目前使用的 Agent 框架相比更加模塊化也有更好的性能。

這篇文章花了很長的時間來寫,試圖讓所有人都懂這個框架相比傳統 Agent 框架在架構上做了什麼升級,前後改了很多次才有了這個版本,但是文中仍然有些部分太過技術,我沒能很好的進一步通俗化,如果你對文章改進有任何建議歡迎留下你的評論。

開發者背景

這是一篇技術博客,所以我們先來看看這個founder的技術實力

Founder在做project89之前做了這個項目:https://github.com/Oneirocom/Magick,也是一款利用AI進行編程的軟件同時shaw也是這個項目排名第四的開發者,在shaw的履歷裡也可以看到這個項目

左上:project89的founder , 右下: lalaune 就是ai16z的shaw

而今天我們主要來介紹下 project89 裡面的高性能 Agent Framework:

https://github.com/project-89/argOS

一、為什麼要用ECS來設計Agent Framework

從遊戲領域的應用來看

目前採用ECS架構的遊戲有:

區塊鏈遊戲:Mud、Dojo

傳統遊戲: 守望先鋒、星際公民等等

而且目前主流的遊戲引擎也在往ECS的方向進化比如Unity

什麼是 ECS

ECS(Entity-Component-System)是一種在遊戲開發與模擬系統中常用的架構模式。它將數據與邏輯徹底分離,以便在大規模可擴展場景下高效管理各種實體及其行為:

Entity(實體)

• 僅僅是一個 ID(數字或字符串),不包含任何數據或邏輯。

• 可以根據需要,掛載不同的組件來賦予它各種屬性或能力。

Component(組件)

• 用來存儲實體的具體數據或狀態。

System(系統)

• 負責執行與某些組件相關的邏輯。

以一個具體的Agent行動的例子來理解這套體系:

在 ArgOS 中將每一個Agent看成一個 Entity,它可以註冊不同的組件,比如在下面這幅圖裡,我們這個Agent擁有以下四個組件:

Agent Component: 主要存儲類似 Agent 名稱,模型名字等等基礎信息

Perception Component: 主要用來存儲感知到的外界數據

Memory Component: 主要用來存儲 Agent Entity的Memory數據,類似做過的事情等等

Action Component: 主要存儲要執行的 Action 數據

System 的工作流程:

  1. 在這個遊戲裡比如感知到了自己面前有一個武器,那麼這個就會調用 Perception System的執行函數來執行更新這個Agent Entity 的Perception Component 裡面的數據
  2. 然後再觸發 Memory System, 同時 調用 Perception Component 和 Memory Component, 把感知到的數據通過Memory持久化到數據庫之後
  3. 然後 Action System 再調用Memory Component 和 Action Component ,從記憶中獲取周邊環境的信息,然後最終執行相應的動作。

接著我們就得到一個每個Component數據 都被更新的 Update Agent Entity

4.所以我們可以看到這裡面System 主要負責定義要對哪些Component 執行對應的處理邏輯。

而且很明顯在 project89 裡面它是一個世界裡面充斥著各種類型的 Agent,比如有些Agent不僅僅擁有以上的基礎能力還有做計劃的能力。

那麼就會如下面這個圖所示:

System的運行流程

但是實際的 system 執行流程不是我們想象的 Perception System執行完之後調用 Memory System 這種傳統做法,不同System之間是不存在調用關係的,每個System都會在一個規定的週期內執行一次,比如:

  • Perception System可能2s執行一次來更新接收到的外界感知,並把它們更新到 Perception Component之中
  • Memory System 可能會是每1s執行一次,從Perception Component 之中提取數據加載到Memory Component之中
  • Plan System可能是每 1000s執行一次,根據接收到的信息判斷自己需不需要根據對應的目標優化制定合理的計劃,然後把這部分更新記錄到 Plan Component之中
  • Action System 可能也是每2s執行一次,這樣可以根據外界的信息及時做出反應,同時如果Plan Component有更新則需要根據這部分數據更新自己的Action Component,進而影響最初做出的Action.

文章到這裡都是基於我對ArgOS 的理解大大簡化了它的架構方便大家更好理解,接下來我們來看真實的ArgOS.

二、ArgOS System 架構

ArgOS之中為了讓 Agent 可以進行更加深度的思考執行更復雜的任務,設計了很多Component,以及很多System.

並且ArgOS之中將System分為“三種層次” (ConsciousnessLevel):

1)有意識(CONSCIOUS) 系統

  • 包含 RoomSystem, PerceptionSystem, ExperienceSystem, ThinkingSystem, ActionSystem, CleanupSystem)
  • 更新頻率通常較高 (如每 10 秒)。
  • 更貼近“實時”或“顯意識”層面的處理,如環境感知、實時思考、執行動作等。

2)潛意識(SUBCONSCIOUS) 系統

  • GoalPlanningSystem, PlanningSystem
  • 更新頻率相對較低 (如每 25 秒)。
  • 處理“思考”的邏輯,如週期性檢查/生成目標和計劃。

3)無意識(UNCONSCIOUS) 系統

  • 目前暫時還沒有啟用
  • 更新頻率更慢(如 50 秒以上),

所以在 ArgOS之中是將不同的System根據ConsciousnessLevel劃分,來規定這個System多久之後執行一次。

為什麼要這麼設計呢?

因為ArgOS之中各個system之間的關係極其複雜,如下圖:

1 PerceptionSystem負責從外界或其他實體那裡收集“刺激”(stimuli),並將其更新到代理(Agent)的 Perception 組件中。

判斷刺激是否顯著變化,根據穩定度、處理模式 (ACTIVE/REFLECTIVE/WAITING) 等做相應更新。

最終為後續的 ExperienceSystem、ThinkingSystem 等提供“當前感知”的信息。

2 ExperienceSystem將 PerceptionSystem 收集到的 Stimuli 轉換為更加抽象的“體驗”(Experience)。

會調用 LLM 或規則邏輯 (extractExperiences) 來識別新的體驗,並存儲到 Memory 組件。

去重、篩選、校驗體驗,同時通過 eventBus 觸發“experience”事件給其他系統或外部監聽者。

3 ThinkingSystem智能體自身的“思考”系統。

從 Memory、Perception 等組件裡提取當前狀態,通過 generateThought(…) 與 LLM / 規則邏輯生成“思考結果”(ThoughtResult)。

根據思考結果,可能:

• 更新 Memory 中的 thoughts (思考歷史)。

• 觸發新的 Action(放到 Action.pendingAction[eid])。

• 改變 agent 的外在 Appearance(表情、姿勢等),並生成相關 Stimulus 讓其他實體“看到”變化。

4 ActionSystem若某個 Agent 的 Action.pendingAction 非空,則通過 runtime.getActionManager().executeAction(…) 來真正執行動作。

執行完後將結果寫回 Action.lastActionResult,並通知房間或其他實體。

也會藉此產生 CognitiveStimulus(認知刺激),以便後續系統“知道”該動作已完成,或可以納入記憶。

5 GoalPlanningSystem週期性地評估 Goal.current[eid] 列表中目標的進度,或檢查外部/自身記憶是否出現重大變化 (detectSignificantChanges)。

當需要新目標或進行目標調整時,通過 generateGoals(…) 生成並寫入 Goal.current[eid]。

同時更新在進度中 (in_progress) 的目標,若符合完成或失敗條件就改變狀態,並向相應 Plan 發出完成/失敗信號。

6 PlanningSystem對“已有目標”(Goal.current[eid])生成或更新 Plan(執行計劃)。

如果檢測到某些目標沒有對應的活動中 (active) 計劃,則通過 generatePlan(…) 產生一個包含若干 steps 的執行路線圖,並將其寫入 Plan.plans[eid]。

也會在目標完成或失敗時更新與其關聯的 Plan 狀態,併產生相應認知刺激。

7 RoomSystem處理與房間(Room)相關的更新:

• 獲取房間內的佔用者列表 (occupants),為每位 agent 生成“外觀(appearance)”刺激,讓其他實體“看到”他的外貌或動作。

• 創建房間環境 Stimulus (如貼切的“房間氛圍”信息) 並進行關聯。

確保當 Agent 處於某個空間環境時,其他正在感知該空間的實體可以感知到他的外貌變化。

8 CleanupSystem定期查找並移除標記了 Cleanup 組件的實體。用於回收不再需要的 Stimulus 或其他對象,防止 ECS 中遺留大量無效的實體。

  • 示例:從“看到物體”到“執行動作”的一次循環

下面的場景示例展示了各個 System 如何在一回合(或幾幀)內依次配合完成一次完整流程。

場景準備:世界(World)中存在一個 Agent (EID=1),正在“Active”狀態,且處在某個 Room (EID=100)。

該 Room 裡新出現了一個道具“MagicSword”,生成了相應的 Stimulus。

  1. PerceptionSystem檢測到“MagicSword”的出現,對 Agent(1) 生成 Stimulus (type=“item_appearance”) 並添加到 Perception.currentStimuli[1]。對比上一次 Stimuli Hash,認定“有顯著變化”,“重新激活”代理的 ProcessingState (ACTIVE 模式)。
  2. ExperienceSystem看到 Agent(1) 的 Perception.currentStimuli 非空,於是把“Sword appears”之類的信息抽取為1條或多條新 Experience (type: “observation”)。存儲到 Memory.experiences[1] 裡,併發射「experience」事件。
  3. ThinkingSystem讀取 Memory、Perception 等狀態信息,調用 generateThought:

“我看到了 MagicSword,也許能撿起來看看它能幹什麼…”該思考結果包含一個待執行的 Action:{ tool: “pickUpItem”, parameters: { itemName: “MagicSword” } }

ThinkingSystem 將此 Action 寫入 Action.pendingAction[1]。

若有 appearance 改動(例如“面帶好奇的表情”),則更新 Appearance 併產生視覺刺激。

  1. ActionSystem看到 Action.pendingAction[1] = { tool: “pickUpItem”, parameters: … }。

通過 runtime.getActionManager().executeAction(“pickUpItem”, 1, { itemName: “MagicSword” }, runtime) 執行“拾取”動作邏輯。得到結果:{ success: true, message: “你撿起了魔法劍” },更新到 Action.lastActionResult[1],並觸發「action」事件廣播給房間(100)。

同時產生認知刺激 (type=“action_result”),寫入 Memory 或讓 ThinkingSystem 下個回合捕獲。

  1. GoalPlanningSystem (若該 agent 有目標)週期性地評估 agent 的目標,如果此時 agent 的某個目標是“獲得強力武器”,並檢測到 MagicSword 已到手,可能將該目標標記為完成。如果產生/keySeatTr new changes (比如“新物體出現在房間”影響了 agent 追求的目標?),則根據 detectSignificantChanges 生成新的目標或放棄舊目標。
  2. PlanningSystem (若有相關目標)對“獲得強力武器”這樣已完成或剛生成的目標,檢查是否需要新 Plan 或更新既有 Plan。

如果已完成,則把關聯的 Plan [status] 置為 “completed”;或若目標要擴展後續流程 (“研究魔法劍”),則生成更多步驟。

  1. RoomSystem (每幀或每回合)更新房間(100)中的 Occupants 列表和可見實體。

若 agent(1) 外觀改變(比如 Appearance.currentAction = “holding sword”),就創建新的「appearance」視覺刺激,讓其他在同房間的 Agent2, Agent3 知道“agent1 拿起了劍”。

  1. CleanupSystem移除已標記(Cleanup)的實體或刺激。若拾取後“MagicSword”這個 Stimulus 不再需要保留,可以在 CleanupSystem 中刪除對應 Stimulus 實體。
  2. 通過這些系統的銜接,AI Agent 就實現了:

• 感知環境變化(Perception) → 記錄或轉化為內在經驗(Experience) → 自我思考並決策(Thinking) → 付諸行動(Action) → 動態調整目標與計劃(GoalPlanning + Planning) → 同步環境(Room) → 及時回收無用實體(Cleanup)

三、ArgOS整體架構解析

1、核心架構分層

2、組件(Component)分類

在 ECS 中,每個實體 (Entity) 可擁有若干組件 (Component)。根據在系統中的性質和生命週期,大致可以將組件分為以下幾類:

1 核心身份類 (Identity-Level Components)

• Agent / PlayerProfile / NPCProfile 等

• 用來唯一標識實體、存放核心角色或單位信息,一般需要持久化到數據庫。

2 行為與狀態類 (Behavior & State Components)

• Action, Goal, Plan, ProcessingState 等

• 代表了實體當前要做的事情或目標,以及對外部命令、內部思維的響應狀態。

• 包含 pendingAction, goalsInProgress, plans, 以及在隊列中的思考或任務等。

• 通常為中/短期狀態,很多會隨著遊戲回合或業務週期動態變化。

• 是否需要落庫視情況而定。如果希望斷點續跑,可能定期寫入數據庫。

3 感知與記憶類 (Perception & Memory Components)

• Perception, Memory, Stimulus, Experience 等

• 記錄了實體感知到的外部信息 (Stimuli),以及感知後提煉成的體驗 (Experiences)。

• Memory 往往可積累大量數據,例如對話記錄、事件歷史等;常常需要做持久化。

• Perception 可能是實時或臨時信息,多為短期內有效,可根據需求決定是否寫入數據庫(比如只存重要的感知事件)。

4 環境與空間類 (Room, OccupiesRoom, Spatial, Environment, Inventory 等)

• 代表房間、環境、位置、物品容器等信息。

Room.id、OccupiesRoom、Environment 等字段常常需要持久化,如房間首頁描述、地圖結構等。

• 不斷變化的組件 (比如 Entity 在不同房間之間移動) 可以做事件式或定期寫入。

5 外觀與交互類 (Appearance, UIState, Relationship 等)

• 記錄實體對外的“可見”或“交互”部分,如 Avatar, pose, facialExpression, 與其他實體的社交關係網絡等。

• 一部分可只在內存中處理(實時表現),另一部分(比如關鍵社交關係)可能要持久化。

6 輔助或運維類 (Cleanup, DebugInfo, ProfilingData 等)

• 用於標記哪些實體需要回收 (Cleanup)、或者記錄調試信息 (DebugInfo) 以便在監控和分析時使用。

• 一般只在內存中存在,很少會同步到數據庫 unless 日誌或審計需要。

3、System架構

上面已經介紹

4、Manager 架構

有了Component和 System 之外我們其實還缺少一個資源管理者,比如如何訪問數據庫,當狀態更新有衝突怎麼處理等等。

左側 Systems (PerceptionSystem、ExperienceSystem、ThinkingSystem 等):

• 每個系統在 ECS 循環中被 SimulationRuntime 調度執行,查詢並處理自己關心的實體(通過組件條件)。

• 在執行邏輯時,需要和 Managers 進行交互,例如:

  • 調用 RoomManager (RM) 查詢/更新房間信息。
  • 使用 StateManager (SM) 獲取或保存世界/代理狀態,如 Memory、Goal、Plan 等。
  • 藉助 EventBus (EB) 對外廣播或監聽事件。
  • 在某些需要自然語言處理或提示語時,調用 PromptManager (PM)。

右側 Managers (EventBus、RoomManager、StateManager、EventManager、ActionManager、PromptManager 等):

• 提供系統級功能,基本不主動“驅動”邏輯,而是被 Systems 或 Runtime 調用。

• 典型示例:

  • ActionManager 專門管理動作(Action)的註冊與執行。
  • EventManager / EventBus 用於事件發佈與訂閱機制。
  • RoomManager 管理 rooms、佈局與 occupant。
  • StateManager 負責ECS與數據庫或存儲的同步。
  • PromptManager 提供LLM Prompt模板、上下文管理等擴展。
  • 中間的 SimulationRuntime (R):

• 是所有 Systems 的“調度者”,啟動或停止不同層級(Conscious/Subconscious等)的系統循環;

• 也在構造階段創建 Managers 並傳給各 System 使用。

  • CleanupSystem:

• 特別注意它還和 ComponentSync (CS) 交互,用於在回收實體時同步移除組件或事件訂閱。

結論:

每個 System 會在需要時通過對應的 Manager 讀寫數據或調用服務,而 Runtime 則在更高層面統一調度所有 System 與 Manager 的生命週期及行為。

5、 如何向量與數據庫進行交互

在 ECS 中,Systems 是真正執行邏輯的地方,而數據庫讀寫可以通過一個“持久化管理器 (PersistenceManager / DatabaseManager)”或“狀態管理器 (StateManager)”來完成。大致流程可如下:

1 啟動或加載時 (Initial Load)

• StateManager / PersistenceManager 從數據庫加載 Agents、Rooms、Goals 等核心持久化組件的數據,創建對應實體 (Entities) 並初始化相關組件字段。

• 例如,讀取一批 agent 記錄插入 ECS 世界,給他們初始化 Agent、Memory、Goal 等組件。

2 ECS 運行時 (Systems Update Loop)

• 系統在每個幀 (或回合) 內做事情:PerceptionSystem 收集“感知”並寫到 Perception 組件 (多為短期不落庫)。

ExperienceSystem 把新的“認知體驗”寫入 Memory.experiences,若是關鍵體驗可能同時調用 StateManager 做立即存儲,或打上“needsPersistence”標記以便後續批量寫入。

ThinkingSystem / ActionSystem / GoalPlanningSystem 等根據組件內容做決策並更新 ECS 中的字段。

如果某些組件 (比如 Goal.current) 發生重大變更且需要持久化(例如新的長遠目標),通過組件監聽或系統事件,通知 StateManager 將該字段寫入數據庫。

3 定期或事件驅動的持久化 (Periodic or Event-Driven)

• 可以在系統中的某些關鍵點(如目標計劃發生更新或Agent發生重要事件)時,調用 PersistenceManager.storeComponentData(eid, “Goal”) 這類接口進行落庫。

• 也可以在 CleanupSystem 或定時器裡,讓 StateManager 掃描含有“needsPersistence”標記的組件或實體,一次性寫回數據庫。

• 此外,日誌或審計數據(如動作歷史、思考日誌)也可在這裡進行歸檔存儲。

4 退出或斷點保存 (Manual or Shutdown Save)

• 當服務器或進程要關閉時,通過 StateManager.saveAll() 將還沒寫入的數據統一寫入數據庫,以確保下次加載能恢復 ECS 狀態。

• 對於一些單機/離線場景,也可以手動觸發存檔。

  • 完整示例流程

以下給一個簡單的場景,演示組件和數據庫交互的可能方式:

1 啟動時:StateManager.queryDB(“SELECT * FROM agents”) → 得到一批 agent 記錄,依次為每條記錄創建 Entity (EID=x),並給其初始化 Agent、Memory、Goal 等組件字段。

同時從 “rooms” 表裡加載房間信息,創建 Room 實體。

2 運行階段:PerceptionSystem 在某個房間檢測到事件“MagicSword 出現”,寫入 Perception.currentStimuli[eid]。ExperienceSystem 將 Stimuli 轉化為 Experience,賦值到 Memory.experiences[eid]。ThinkingSystem 通過 Memory、Goal 等信息決定執行下一步行動,生成 Action.pendingAction[eid]。ActionSystem 執行該動作後,將結果寫到 Memory 或 Action.lastActionResult。若這是一次重大劇情事件,會把 Memory.experiences[eid] 的最新部分標記為 needsPersistence。StateManager 在一段時間後發現 Memory.experiences[eid] 帶有 “needsPersistence”,則將其寫入數據庫(INSERT INTO memory_experiences …)。

3 停止或斷點:基於 ECS 或系統調度,在“服務器關閉”時調用 StateManager.saveAll(),把仍在內存中的關鍵組件字段(Agent, Memory, Goal 等)它們的最新狀態寫進數據庫。下次重啟時,就能從數據庫中加載並恢復 ECS 的世界狀態。

• 將組件分類,既方便在項目中清晰地管理實體數據,也能幫助我們控制“需要持久化”與“僅在內存中存在”的數據邊界。

• 與數據庫的交互通常由一個專門的 Manager(如 StateManager)來處理,Systems 在需要讀寫數據庫時通過它進行操作,避免在 System 裡直接寫 SQL 或類似底層語句。

• 這樣能同時享受到 ECS 在邏輯上的高效與靈活,以及數據庫帶來的持久化、斷點續跑與數據統計分析優勢。

四、架構創新點

整個架構的亮點在於:

  • 每個System都是獨立運行的,不會跟其他的System之間有調用關係,因此即便我們希望實現Agent的“感知環境變化(Perception) → 記錄或轉化為內在經驗(Experience) → 自我思考並決策(Thinking) → 付諸行動(Action) → 動態調整目標與計劃(GoalPlanning + Planning) → 同步環境(Room) → 及時回收無用實體(Cleanup) ” 能力的時候,各個System在功能上會有很多互相依賴的點,但是我們依然可以通過ECS架構把整體結構成各個互不相關的System,每個System依然可以獨立運行,不會跟其他的System有人和耦合關係。

    我想這也是為什麼Unity這幾年越來越往ECS架構遷移最主要的原因。

  • 而且比如我現在只是希望一個Agent擁有一些基本能力,我只需要在定義Entity的時候減少註冊一些Component以及減少註冊System就可以輕易的實現,都不用改幾行代碼。

如下圖:

  • 同時如果你在開發過程中希望增加新的功能,也不會對其他的System有任何影響,可以很輕易的把自己希望的功能加載進去。

    另外當前這種架構的性能其實會比傳統面向對象架構的性能強很多,這在遊戲圈是一個公認的事實,因為ECS的設計更加適合進行併發,那麼當我們在複雜的Defai場景下,採用ECS架構也有可能會更有優勢,特別是希望採用Agent做量化交易的場景下,ECS也會有用武之地(不僅僅是在Agent遊戲場景下)。

  • 將System 分成有意識、潛意識和無意識來區分不同類型的System應該在多久後執行一次,是極其高明的設計,已經是一個很具象的人的能力了

從我個人的觀點來看,這是一個極其模塊化,性能極其優秀的框架,同時代碼質量也很高並且包含了很好的設計文檔,不過可惜的是 $project89 項目一直缺少對這個框架的宣傳,因此我才花了很長的時間(4天)寫了這篇文章,我覺得好的東西還是值得被發現,明天應該還會發一個英文版本,希望能有更多的遊戲團隊或者 Defai 團隊開到這個框架,為大家提供一種新的潛在的架構選擇!

聲明:

  1. 本文轉載自【0xhhh】,轉發原文標題:《我在 Project89 內看到下一代 Agent 框架》。著作權歸屬原作者【0xhhh】,如對轉載有異議,請聯繫 Gate Learn 團隊,團隊會根據相關流程儘速處理。
  2. 免責聲明:本文所表達的觀點和意見僅代表作者個人觀點,不構成任何投資建議。
  3. 文章其他語言版本由 Gate Learn 團隊翻譯, 除非另有說明,否則不得複製、傳播或抄襲經翻譯文章。
Bắt đầu giao dịch
Đăng ký và giao dịch để nhận phần thưởng USDTEST trị giá
$100
$5500