程序守衛

你的代理會留下程序。
AgentsRoom 把它們找出來。

AI 程式設計代理每呼叫一個工具,就會在系統裡啟動一個真實程序。絕大多數幾秒就結束了。有些永遠不會結束,而這樣的程序同時跑上幾個,就足以把一台機器的記憶體填滿。

程序守衛掃描代理的子程序,把吃你記憶體的標出來,單獨一個也好,一大群也好,指出該由哪個代理負責,並讓你打斷它。不會有任何東西在你不知情的時候被終止。

程序守衛
掃描:每分鐘 1 次
Full-Stack Dev 的子程序
ripgrep18 MB
71%
tsc --noEmit1.4 GB
96%
search6.4 GB
3%
node2.1 GB
0%
2 個卡住的程序
佔用 6.4 GB,CPU 0%
已卡住 23 分鐘,毫無進展
由 Full-Stack Dev 啟動
結束該程序
夠久就測量。夠大,或者一次太多,就上報。記憶體立刻回來

程序守衛真正在看的東西:一個代理啟動了哪些程序,其中哪些已經不幹活了。

AI 程式設計代理不是一個程序。它每呼叫一次工具,就在你的機器上啟動一個真實程序:一次搜尋、一次建置、一次型別檢查、一輪測試、一個腳本。把這個數字乘上幾個並行工作的代理,再乘上一整天,你會得到幾百個從生到死你一眼都沒看見的程序。

它們幾乎都會結束。麻煩的是不會結束的那些。一次搜尋的匹配模式把正則引擎撐爆了,它既不崩潰也不變慢:它先申請記憶體,被擠進壓縮記憶體,然後餘生就在不停地缺頁,而核心在旁邊為它換出好幾個 GB。它永遠不會結束。也永遠不會有人殺掉它。而如果啟動它的代理被關掉,它就變成一個整台機器上再沒人負責的孤兒程序。

所以變慢是悄悄爬上來的。沒有哪一刻突然崩掉,只有一整天緩慢的累積,而恰恰是這個形狀讓人怪錯了物件:以為是過熱,是代理開太多,是應用記憶體洩漏。在我們實測的那次會話裡,應用自己是 91 個程序佔 2.8 GB,八個代理 CLI 加起來 1.6 GB。兩個都不是問題所在。

程序守衛是那張安全網。它盯著代理留下的東西,告訴你哪個卡住了、是誰啟動的,然後讓你把它結束掉。根本原因會一直變:換個工具,換個匹配模式,換個供應商。而這張網不需要跟著變。

跑 AI 代理的機器為什麼會變慢

下面的數字來自一台 16 GB 筆記本上跑著八個代理的實測會話。這裡沒有一個是估算值。

機器已經開了五個半小時。完全沒有散熱問題:沒有記錄到任何降頻,電池 30.6 攝氏度。8 核上的平均負載在 17 到 21 之間,CPU 有 56% 的時間待在核心態,空閒只剩 1.5%。這個比例才是破綻。真正在幹活的機器,時間花在使用者態程式碼上;系統時間佔 56% 的機器,是一個除了壓縮、解壓和換出記憶體之外什麼都沒幹的核心。

七個卡住的搜尋程序每個佔著 3.9 到 8.0 GB,在一台只有 16 GB RAM 的機器上一共佔了 41.8 GB。交換空間用掉 23.5 GB 中的 22.3 GB,開機以來往交換空間寫了大約 993 GB。結束這七個程序,15.5 GB 立刻回來了,沒有重啟任何一個代理,也沒有重啟應用。

沒人能靠手工抓住這件事,是因為常用工具在這上面撒謊。在 macOS 上,一個卡住的程序實際佔著 8 GB,卻可能只顯示 20 MB 的常駐記憶體,因為它碰過的一切都進了記憶體壓縮器。我們實測過一個還活著的程序:常駐記憶體 4.7 GB,真實佔用 14 GB。虛擬記憶體大小也幫不上忙:在這個平台上連 launchd 都報告約 440 GB 的虛擬大小,拿它來篩等於把整台機器都標出來。

一個工作日,八個代理,16 GB09:14
機器記憶體一切正常
交換空間11%
實測的一次會話,不是示意圖。15.5 GB 立刻回來

同一次會話,逐小時看:那些再也沒人用的大塊記憶體,以及釋放之後發生了什麼。

41.8 GB
被 7 個卡住的程序佔用,機器只有 16 GB
95%
交換空間已用,23.5 GB 中的 22.3 GB
21
8 核上的平均負載,系統時間佔 56%
993 GB
五個半小時裡寫入交換空間的量

而且這些程序有四個特性,保證它們明天還在。

它們永遠不會結束

它們自己的記憶體在交換空間裡,於是時間全花在缺頁上而不是計算上。而且它們並不是閒著:我們實測的那些失控程序,每一個都在燒掉一個核的 10% 到 19%,而且堆得越多,每個分到的越少。這個迴圈沒有出口,再等下去也不會變。

它們也永遠不會死

工具呼叫沒有超時。對於一個已經閒了五十分鐘的程序,機器上沒有任何東西持有意見。它會一直待在那裡,直到有人殺掉它,或者機器重啟。

它們比自己的代理活得久

關掉代理分頁,程序可能活下來。而這層關係斷掉的方式,每個系統都不一樣:經典 Unix 會把它過繼給 init,Linux 桌面會過繼給你的 systemd 使用者管理器,Windows 則根本不過繼,只留下一個指向早已不存在的父程序的編號。所以程序守衛從不去看父程序。它在關係還在的時候就記住自己認領了什麼,凡是從活著的程序樹裡消失的,一律當作孤兒程序處理,三個系統上做法完全相同。我們實測的七個裡,有兩個已經是這個狀態。

它們會越堆越多

每跑一輪校驗多一個,每碰上一次倒黴的搜尋多一個,而每當一個代理把一條只是慢的命令當成卡住了、又重新跑一遍,就再多一個。我們實測到十二個型別檢查同時在跑,由六個代理啟動,其中兩個各自手上就掛著三個。所以變慢在一天之內只增不減,所以重啟看起來像是解決了問題。它什麼都沒解決,只是把計數清零了。

程序守衛做什麼

它盯著你的代理派生出來的程序,而且對自己願意碰哪些,管得刻意地窄。

測的是真實記憶體

不是常駐記憶體,那個值會把一個卡住的程序少算好幾個 GB。程序守衛讀的是真實佔用,把壓縮頁和換出頁都算進去,所以一個顯示 20 MB、實際抱著 8 GB 的程序會露出本來面目。

測處理器,但從不相信它

處理器佔用是兩次掃描之間的速率,不是系統工具報出來的那個整個生命週期的平均值,所以一個先猛幹一陣、然後卡死的程序照樣會被抓到。它換來的只是給還在幹活的東西抬高門檻,絕不是一張免死金牌:一個燒掉五分之一個核的失控程序,恰恰是這個守衛的第一版會漏掉的東西。

抓得住孤兒程序

一個活得比啟動它的代理還久的程序,憑這一點本身就會被報出來,因為再沒有別人會來回收它。歸屬關係是在程序還掛在樹上的時候記下來的,那是唯一能確認它的時刻。

一鍵結束

狀態列裡的提示條會列出每個卡住的程序,連同派生它的代理、記憶體、存活時間和 CPU。結束其中一個,會連它自己派生的東西一起終止。記憶體立刻回來,你的代理照常執行。

macOS、Windows 和 Linux

要把記憶體說清楚,每個系統都需要不同的測法:macOS 看壓縮頁,Linux 看常駐加換出,Windows 看私有提交。三個都已經實現,不是計劃中。

幾乎不花什麼代價

每分鐘一次程序快照,在一台跑著 824 個程序的機器上實測約 40 毫秒。昂貴的記憶體探測只在已經有東西看起來卡住時才跑,而只要沒有代理在活動,掃描根本不會發生。

看見一群,不只看冒尖的那個

十二個各佔 1.4 GB 的型別檢查,在一台 16 GB 的機器上就是 16.8 GB,而它們每一個都落在一個合理的閾值以下。當你的代理啟動的這些程序加起來填滿機器實體記憶體的一半,大小就不再一個一個單獨判斷了。

點名該負責的代理

同一個代理名下有兩條以上被標記的命令時,它們會被歸到這個代理的頭像下面,附上它們合起來佔了多少,以及一條說明它們陷入了什麼迴圈的警告。一條命令是意外,一次好幾條就是行為模式。

打斷代理,不只是打斷程序

在代理這一輪還沒結束的時候結束它的程序,等於遞給它一個錯誤,而它會對這個錯誤做出反應,通常就是把命令再跑一遍。有一個按鈕改為向代理的終端傳送 Ctrl+C:這一輪就此結束,什麼都不會重跑,代理也仍然開著。

讓它不至於狼來了的兩條規則

一個會標記你建置的守衛,是你一週之內就關掉的守衛,所以門檻是刻意抬高的。凡是活得比你設的閾值更久的代理子程序,都會被測出真實記憶體,一旦佔用超過你允許的量就上報。還在使用處理器的程序必須佔到那個量的兩倍,正是這一條讓一次漫長而正當的建置不被打擾。

處理器佔用決定的是這道門檻的高度,它不是一道閘門。這個守衛的第一版要求一個程序先閒下來,才肯去看它的記憶體,那是錯的。一次把正則引擎撐爆的搜尋並不閒:它一邊燒掉五分之一個核,一邊讓核心為它換出好幾個 GB。更糟的是,這類程序堆得越多,每個能分到的處理器越少,於是盲區最大的時候恰恰是最開始,也就是結束掉一個代價最小的時候。

第二條規則的存在,是因為按程序逐個設的門檻看不見一群。十二個各佔 1.4 GB 的型別檢查,單看每一個都合理,合起來在一台 16 GB 的機器上卻是致命的。所以當代理啟動的所有東西加起來達到機器實體記憶體的一半時,不管每一個各自多重,它們全部都會被上報。這一組裡的任何東西都絕不會被自動結束:它們本來就低於你設的上限,被標出來只是因為旁邊的鄰居。

它怎麼工作

四步,每分鐘一次,而且最貴的那步幾乎從不執行。

01

給機器拍一張便宜的快照

每分鐘,程序守衛給所有執行中的程序拍一張快照,然後沿著每個代理終端往下走整棵程序樹。在一台跑著 824 個程序的機器上實測成本約 40 毫秒。只要沒有代理在執行,這一步根本不發生。

02

圈出嫌疑物件

從那張快照裡,它保留每一個活得比你設的閾值更久的代理子程序。篩選就這一條,不會因為還在使用處理器就被排除:以前那個版本的守衛漏掉失控程序,正是這麼漏的。正常使用下這份名單是空的,因為代理的工具呼叫幾秒就結束了。

03

只測看起來卡住的那幾個

只有對這份短名單,程序守衛才會付出真實記憶體測量的代價,把壓縮頁和換出頁算進去。測不出來的程序絕不會被標記:不知道不等於判決。

04

報告,然後讓你決定

狀態列出現一個提示條,一條通知只提醒你一次。你開啟列表,看到這個程序是什麼、佔了多少、卡了多久、由哪個代理啟動,然後你想結束就結束。

安全邊界

它永遠不會碰的東西

一個能結束程序的工具,必須把什麼算自己的事定得很窄。下面這些限制是結構性的,不是需要你記得去開啟的選項。

  • 代理 CLI 本身。 無論你用哪個供應商,程序守衛都會保護應用啟動那個終端時用的可執行檔案。這個名字是從啟動動作本身讀出來的,不是來自一份寫死的清單,所以同一個 CLI 的子程序同樣受保護,無論巢狀多深。
  • 你的開發命令終端。 一個閒著的開發伺服器滿足失控程序的每一條判據:佔記憶體、活得久、不用處理器。它同時也是你真正希望它一直跑著的那個程序。只有代理終端會被監視,所以你的開發伺服器從來不在畫面裡。
  • Shell 和應用自己的管道。 終端輔助程序,以及代理所在的 shell,在設計上就被排除。只有位於代理 CLI 之下的工具程序才有可能成為候選。
  • 任何不是它認領的東西。 唯一能結束程序的那條路徑,會拒絕一切不是程序守衛從某個代理自己的程序樹裡撿到的程序。它沒法變成一個終止你機器上別的東西的手段。

而且除非你主動要求,否則沒有任何東西會被自動結束。預設情況下程序守衛只報告它發現了什麼,由你來決定,因為只有你知道一個又大又安靜的程序是不是本該如此。就算你把自動終止開啟,它也不會去碰還在使用處理器的東西,也不會去碰那些僅僅因為鄰居佔了多少才被標出來的東西。

它什麼時候值回票價

下面每一條都是真實發生過的情況,沒有一條是假設。

下午六點比早上九點更卡的機器

沒有哪一刻突然壞掉,只有一整天穩定的下滑。這個形狀幾乎總是卡住的程序堆積出來的,也是最難靠手工診斷的一種,因為隨便挑哪個瞬間看都不像有問題。

幾個代理同時在幹活

你跑的代理越多,工具呼叫就越多,其中某一次卡死的機會也越多。單次呼叫的失敗率很小;乘上一整天的並行工作,它就不小了。

一次再也沒回來的搜尋

一個撐爆正則引擎的匹配模式,會為一個幾百 KB 的檔案申請好幾個 GB。代理在等它,你在等代理,而機器替這兩頭付帳。

你關了代理,程序還在

關掉一個分頁不一定釋放任何東西。一個早已脫離的程序會帶著它的記憶體留下來,同時失去和應用裡任何可見事物的最後一點聯絡。

一台 16 GB 的筆記本

在 RAM 充裕的機器上,幾個卡住的程序能藏很久。在 16 GB 的筆記本上它們很快就把交換空間頂滿,而一旦系統開始壓縮記憶體,你的每一個代理都會同時變慢。

在怪罪應用之前

機器爬得動不了,而 AgentsRoom 正開著,應用就是最顯眼的嫌疑物件。手裡有逐個程序的真實數字,還有每個程序是由哪個代理啟動的,猜測就變成了可以真正核實的東西。

你說了算

界限由你來定

預設值刻意保守。下面這些都在設定的終端一欄裡,而且每一項都可以由代理透過 AgentsRoom 的 MCP 工具讀取和修改。

監視代理的子程序
預設開啟。關掉它,掃描就一次都不會跑,永遠不會。
超過記憶體閾值才報告
預設兩個 GB。低於這個數,一個卡住的程序不值得打斷你。RAM 充裕的工作站可以調高,記憶體緊張的筆記本可以調低。
存活時間達到下限之後
預設五分鐘。不到這個時間的程序根本不會被測量,正是它讓代理那些幾秒就結束的日常工具呼叫徹底不進入視野。
自動結束卡住的程序
預設關閉,這是一個明確的產品決定,不只是謹慎。程序守衛下的是一個判斷,而只有你知道一個又大又安靜的程序是不是本該如此。開啟它,它就自己動手,事後給你一條通知。

處理器閾值沒有開放出來,機器算作飽和的那個臨界點也一樣。這兩個值都曾經錯過一次,是靠測量真實發生的事故而不是靠口味修好的,所以給任何一個加上滑塊,多半只會把盲區重新放回去。

常見問題

這是不是說 AgentsRoom 會拖慢我的電腦?

不是,而這恰恰是這個功能存在的原因。在我們實測的那次會話裡,應用是 91 個程序佔 2.8 GB,八個代理 CLI 加起來 1.6 GB。那 41.8 GB 是被卡死的工具程序佔著的。AgentsRoom 剛好是唯一能同時看到每個代理和它派生的每個程序的地方,所以也是唯一能做出判定的地方。

它會不會把我的建置或者測試殺掉?

它絕不會不問你就結束一個。它可能會上報:一次建置要麼佔到你閾值的兩倍,預設是四個 GB,要麼屬於一群加起來填滿你機器一半記憶體的代理程序。但自動終止絕不會碰一個還在使用處理器的程序,也絕不會碰一個僅僅因為鄰居佔了多少才被標出來的程序。兩種情況下你看到的都是一行記錄、真實數字和一個按鈕,你不按就什麼都不會發生。

它會監視我的開發伺服器嗎?

不會,以後也不會。一個閒著的開發伺服器滿足失控程序的每一條判據:佔著很多記憶體、已經跑了好幾個小時、兩次請求之間不用處理器。只有代理終端的子程序會被監視,所以你的開發命令在設計上就在範圍之外。

它會不會把代理本身給終止了?

不會。無論你用哪個供應商,代理 CLI 都受保護,而這個保護依據的是應用啟動那個終端時用的可執行檔案,不是一份已知名字的清單。Shell 和應用自己的終端輔助程序同樣被排除在外。

什麼是孤兒程序,為什麼要特別對待它?

父程序已經退出的程序,會失去和啟動它的那個代理之間的關聯,也就再沒人會來清理它。這層關係怎麼斷,取決於系統:經典 Unix 會把它過繼給 init,Linux 桌面會過繼給你的 systemd 使用者管理器,Windows 則不做任何過繼,只留下一個已經失效的父程序編號。所以 AgentsRoom 從不去檢查父程序。它在程序還掛在樹上的時候就記下歸屬關係,那是唯一能確認它的時刻,而凡是從活著的程序樹裡消失的,一律當作孤兒程序處理,三個系統上完全一樣。

監視本身要花多少代價?

每分鐘一次程序快照,在一台跑著 824 個程序的機器上實測約 40 毫秒。更貴的那次記憶體測量只對已經看起來卡住的程序執行,也就是說正常使用下它不會執行。而且只要沒有代理在活動,這個掃描根本不存在。

為什麼不直接看活動監視器裡的記憶體那一列?

因為在 macOS 上,那一列把問題少算了一個數量級。一個被擠進壓縮記憶體的程序,可能抱著 8 GB 卻只顯示 20 MB 常駐記憶體。我們實測過一個還活著的程序:常駐 4.7 GB,真實佔用 14 GB。虛擬記憶體大小也好不到哪去:連繫統程序都會報出好幾百 GB。

它對 Claude Code、Codex 這些都管用嗎?

管用。程序守衛對任何具體的工具或供應商一無所知。它盯的是你啟動的那個代理終端的子程序,而它要保護的 CLI 是從啟動動作本身讀出來的。多接一個供應商,這裡什麼都不用改。

在 Windows 和 Linux 上也能用嗎?

能用。要讓記憶體說實話,每個平台都需要不同的測法:macOS 看壓縮頁,Linux 看常駐加換出,Windows 看私有提交。三個都已經實現。

它會不問我就結束程序嗎?

除非你把那個開關開啟,否則不會。預設情況下它把發現的東西報告給你,連同代理、記憶體、存活時間和處理器佔用,由你決定。自動終止是一個設定項,出廠就是關著的。

我結束了某個程序,那個代理會怎麼樣?

代理照常執行。它那次工具呼叫會收到一個錯誤,而不是永遠掛在那裡,這正是你想要的結果:反正那個程序本來也不會結束。什麼都不會被重啟,上下文也不會丟。

它能解決根本原因嗎?

不能,它也不打算解決。原因是會變的:今天是某個工具,明天是另一個匹配模式,下個月是另一個供應商。這是一張安全網,它被設計成在遇到誰都沒見過的原因時依然管用。

十二個程序,沒有一個超過我設的閾值。它會說點什麼嗎?

會,而規則改掉正是因為這種情況。在一台 16 GB 的機器上實測:六個代理啟動了十二個型別檢查,每個 0.84 到 1.72 GB,全都遠低於 2 GB 的閾值,加起來 15.4 GB,交換空間滿了,機器沒法用了。一個一個地看,每一個都沒問題。一旦總和超過你實體記憶體的一半,它們就會全部被上報,並按啟動它們的代理歸到一組。

「打斷代理」到底做了什麼?

它向那個代理的終端傳送 Ctrl+C,和你自己按下去的是同一個按鍵。代理當前這一輪就此結束,然後等你:它沒有被關掉,會話完好無損,你機器上別的任何東西都不會被碰。這個按鈕存在,是因為在代理還在處理的時候只結束程序,治的只是症狀:代理收到一個錯誤,往往就把命令再跑一遍。

你可能還喜歡

別再為沒人用的程序買單

AgentsRoom 免費下載,程序守衛從第一次啟動就是開著的。

免費下載 AgentsRoom

配套應用:隨時隨地監控你的 Agent

使用 Claude、Codex、Antigravity CLI 或其他 AI 提供商。

獲取擴充功能
Chrome Web Store

把 Bug 和需求直接傳送到您的公開待辦清單。

多專案管理
多供應商
多代理執行
即時狀態
檔案差異與提交
行動應用
即時預覽
代理團隊
瀏覽器自動化
Backlog 驅動開發
提示詞庫
技能庫
檢視所有功能