LazyBoy2/docs/TEAM.md

116 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 多主 agent 與背景委派
> 瀏覽器工作面更新:預設改為 Docker 共用 Chromium以下 owner-local profile 說明僅適用 `LAZYBOY_BROWSER_SURFACE=local`。目前路由與差異見 [SURFACES.md](SURFACES.md)。
這個模式把長期 agent 身分和一次工作 task 分開。A 可以請 B 處理工作B 也可以另外開臨時 workerB 原有的聊天和其他任務持續運作。主 agent 保留前景聊天,實際工具工作在背景 task 執行。
## 啟動與使用
先設定原本的模型環境變數,編譯後在專案目錄執行:
```bash
cargo build -p lazyboy
./target/debug/lazyboy serve
```
`serve` 是前景執行的常駐服務,請保留這個終端機(或自行交給程序管理器);聊天 CLI 斷線不會停止它。這版不安裝登入自啟服務。服務使用啟動時的模型/金鑰設定。
另一個終端機建立 agent。**建立當下的工作目錄**是該 agent 發起根任務的預設工作區:
```bash
./target/debug/lazyboy agents create daily
./target/debug/lazyboy agents create researcher
./target/debug/lazyboy agents list
./target/debug/lazyboy agent --name daily
```
再開一個終端機:
```bash
./target/debug/lazyboy agent --name researcher
```
名字只是識別,不會自動指定角色。透過各自聊天累積記憶與專長,例如長期在 researcher 討論資料整理。主 agent 能搜尋其他 agent 的公開專長簡介,選擇既有 agent 接單或建立臨時 worker也可以明確說「把這件事交給 researcher」。任務內容須包含必要背景、限制與交付要求。
| 聊天內操作 | 行為 |
| --- | --- |
| 普通文字 | 新聊天,不會默默改掉背景工作 |
| `/tasks` | 查看自己發起或接到的任務 |
| `/task <id>` | 查看狀態、計畫、結果與待回答問題 |
| `/task <id> say <內容>` | 補充這份工作;有待回答問題時,回答該問題 |
| `/task <id> stop` | 停止這份工作及其後代 |
| `/task <id> resume` | 明確恢復已停止任務,先觀察中斷後的狀態;沿用剩餘預算 |
| `/memory [查詢]` | 搜尋自己的記憶,空查詢列出最近筆記 |
| `/memory forget <id>` | 刪除指定筆記並清除衍生專長簡介;不是刪除原始聊天 |
| `/expertise [新簡介]` | 查看或修正自己的公開專長 |
| Ctrl-C | 要求取消目前回覆3 秒內再按一次強制離開 CLI即使服務無回應也有效。背景 task 繼續 |
| `/exit`、EOF | 關閉聊天連線,背景 task 繼續 |
服務未啟動時CLI 顯示 `lazyboy serve` 提示。舊的 `lazyboy agent`、`run`、`chat` 不變,舊 session 不會自動匯入新身分。服務本身收到 Ctrl-C 時會停止工作並清理工具程序。
## 任務與訊息
背景 task 各有 Session、Runtime、InputBroker、計畫與命令瀏覽器 profile 歸發起任務的主 agent 所有,跨任務及委派 worker 重用。既有 agent 接單時只使用自己的私人記憶及委派內容,不複製對方完整聊天。子 task 繼承父 task 的工作區;委派给既有 agent 也不會悄悄切到該 agent 的另一個工作目錄。
協作工具為 `find_agents`、`search_memory`、`delegate_task`、`spawn_agent`、`send_message`、`get_task`、`wait_task`、`cancel_task`。前景不提供檔案、命令、瀏覽器或等待工具,交辦後就能回答下一則聊天。背景沿用原有 28 個工具並加入協作工具。
每個 task 只有一個 parent。同一任務樹可互傳訊息、讀取任務摘要等待只允許等待後代取消只允許自己及後代避免循環等待和誤停兄弟任務。主聊天可管理它發起或接到的 task。`send_message` 不啟動新 task後續交辦建立新的 task。
訊息先寫入 SQLite在模型工具邊界加入 task 對話checkpoint 後才標記送達;已寫進對話但尚未標記的訊息以 ID 去重。定向插話不撤銷已開始的工具,會跳過同批尚未執行的操作。人工回答有獨立的 `user` 來源peer 訊息與子任務回報不能直接充當人工確認。
終態結果與通知排程在同一筆 transaction 保存。子結果送到父 task 信箱;根結果在原主 agent 的對話排入整合回覆並提供持久化事件。CLI 用遞增事件 ID 拉取及確認,斷線重連讀取尚未確認的事件。完成宣告仍是模型根據證據的判斷,不是對所有任務的正確性保證。
## 卡住時選擇其他路線
某一段工作卡住時agent 應說明已嘗試的方法,透過 `report_blocked``options` 提供具體替代路線。例如「由我處理目前視窗的登入」或「先寫不需要登入的文案」,加上停止選項。有互動輸入時會停在選擇點,選擇後更新計畫並沿用原 task沒有互動輸入時才直接回報 blocked。選項可用數字、a/b/c 或自由文字回答。
`browser_handoff` 會把同一個 task 的瀏覽器交給你。已可見的視窗直接帶到前景;原本隱藏時,重開同一份 profile恢復頁籤、cookies、localStorage 與目前頁籤的 sessionStorage。請在工具開出的視窗操作另外開啟的一般 Chrome 視窗不會自動共用這份狀態。視窗切換可能重新載入網頁,仍需觀察當下狀態。
handoff 提供「已完成登入,請檢查」、「登入仍失敗,改做其他部分」與停止等選項。選擇其他路線保留原 task/profile不宣告登入成功。人工交回控制權後模型必須檢查頁面才能判斷登入是否成功。中斷後恢復 handoff 時,會先打開原頁面再詢問。
在 named-agent CLI用畫面提供的 `/task <id> say <選項>` 回答。硬性預算上限與無進展保護仍有效,不會因選擇替代方案而自動補預算。若已到終態,查看 `/task <id>` 並明確恢復原 task避免換一個 worker 卻以為登入狀態會跟過去。
## 預算與資源
- 最多 4 個並行模型請求;背景任務及記憶整理合計最多 2 個,保留前景聊天容量。等待工具、等待子 task 或人工回答都不持有模型額度。
- 每棵根任務樹最多 8 個 task含根根深度 0最多委派到深度 2。禁止委派回任務祖先的 agent另一棵獨立任務仍可反向合作。
- 根任務樹共用 `LAZYBOY_MAX_ROUNDS_TOTAL`,預設 48最後 4 次只供根任務使用。子 task 的請求也計入根計數,不會開一個 agent 就多拿 48 次。恢復不自動補預算;耗盡時需另開有明確範圍的新工作。
- 前景每次回覆最多 12 次模型請求。每個完成聊天回合/持久 agent 的任務最多再排一次記憶整理,失敗不阻擋聊天、不自動重試。這些與根任務執行預算分開計算。
- 同一 canonical 工作區內的工具操作互斥;長指令退出後才釋放鎖。操作不同工作區可並行。活躍指令須先結束或終止,才能等待子 task 或人工回答,避免拿著鎖等待別人工作。
- 每個長期 named agent 有自己的 Docker 電腦(容器、`/workspace`、Chromium profile。開這個 agent 會啟動它的座位並確認桌面就緒。同一 owner 的背景 task 與 computerUse 子 agent 用這台電腦;`delegate_task` 給另一個 named agent 時改用被交辦者的電腦;臨時 `spawn_agent` worker 用發起任務的 owner 座位。同時只有一個 task 持有該座位的瀏覽器handoff 等待期間也不讓其他 worker 操作同一座位。`browser_release` 或任務結束會關閉瀏覽器並釋放使用權,保留登入資料。委派瀏覽器子任務前先 release避免互等。
- 升級首次使用時,固定 profile 優先連結至仍有 handoff 問題的舊 task profile否則採該主 agent 最近使用的 profile保留原資料不合併不同 profile 的登入帳號。沒有舊 profile 才建立新的。一般 Chrome 的登入狀態不會自動匯入。
task 使用 `queued`、`running`、`waiting_input`、`terminal` 狀態;終態另有 done/answer/blocked/budget_exhausted/failed/cancelled/interrupted。停止執行中的 task 先提出取消,工具清理後才進 terminal。沒有連線的人工問題仍保持等待只有明確回答或停止才繼續。
## 保存、恢復與記憶
預設資料在 `~/.lazyboy/team/`,可用 `LAZYBOY_DATA_DIR` 改位置。目錄權限 0700、Unix socket 0600程序鎖保證同一資料目錄只有一個 daemon 寫入。SQLite WAL 保存身分、原始對話、tasks、訊息、事件、client cursor 和記憶整理佇列profiles 也存於該資料目錄。API key 不存入資料庫。
daemon 重啟後,未開始的 queued 工作保留;曾經 running 或 waiting_input 的 task 標示 interrupted未知工具结果補齊**不自動重播**。已開始的前景回覆及記憶整理也不自動重送模型。由 `/task <id> resume` 明確恢復;若父 task 也中斷,先恢復父 task。強制殺死服務可能留下未知外部效果恢復時須重新觀察不能假設操作沒發生。
記憶有來源、時間、類型及 supersedes 關係。使用者陳述、模型推論和工具實際觀察分開記錄;模型的完成摘要不會自動升格為工具驗證。專長只應包含一般領域與經驗,透過模型自動歸納,可能需使用 `/expertise` 修正。檢索用本機 SQLite FTS5另有字串比對支援短中文詞不需要 embedding 或搜尋 API。
前景模型只帶最近 20 個使用者訊息起始的對話段落及目前任務登記表;完整歷史仍保存,較早經驗透過私人記憶搜尋取回。刪筆記不等於刪聊天,未來若重新討論相同內容可能再次形成記憶。
隔離是應用層的記憶存取規則shell 仍有本機使用者權限,不是 agent 間的 OS 安全沙箱。這版限定同機同使用者,不提供網路服務、跨電腦或其他產品協定。
## 驗證與參考
```bash
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo build -p lazyboy
python3 tests/team_flow.py # 本機 mock API、兩個 CLI、真實 Chromium
python3 tests/live_team.py # opt-in目前付費模型背景根任務最多 16 次請求
```
整合涵蓋專長歸納、私人記憶、既有 agent 接單、巢狀子 task、兩個前景對話、產物讀回、定向插話、人工等待、斷線重連、程序取消、瀏覽器隔離與 daemon 崩潰恢復。單元測試驗證循環、深度/數量/預算、回報去重與存取邊界。
參考 [Codex 協作工具原始碼](https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/handlers/multi_agents_spec.rs)、[agent 建立與恢復](https://github.com/openai/codex/blob/main/codex-rs/core/src/agent/control/spawn.rs)、[官方 subagents 說明](https://learn.chatgpt.com/docs/agent-configuration/subagents)。借用委派、信箱、等待與回報概念;多主身分、私人記憶和本機 daemon 是本專案的實作。
主聊天中回覆「登入了」等待接手問題時,主 agent 使用 `answer_task` 轉送這一輪使用者原話;背景報告及 worker 不能假冒人類回答。多個問題指向不明時先釐清。`send_message` 是 agent 訊息,不能解除人類等待。舊快照不能用來判定人類操作後的登入狀態,必須由 worker 重新觀察。明確指定回覆仍可用 `/task <id> say <內容>`
### 延續前次委派
`delegate_task``spawn_agent` 可指定 `continue_from`(已結束的 task ID。runtime 自動附上前次目標、結果與工具證據、計畫、工作區、瀏覽器 URL 以及未解問題/未知操作,並保存來源關聯。接手者可用 `get_task` 讀取來源鏈的公開報告;不複製私人對話或記憶。新任務重新規劃與驗證現況,不繼承操作授權或重播未知工具。仍執行中的工作用訊息調整;等待人類回答時用 `answer_task`。不同 owner 或無關 task tree 不能借此讀取任務。