如何看到 AI 編碼代理在你的伺服器上執行了什麼

代理正在一台生產伺服器上幹活,終端裡只顯示它在呼叫一個工具。它到底執行了哪條命令,機器又返回了什麼?會話轉錄事後會告訴你。本文講我們如何讓這一切在發生時就可見,最初試過什麼,以及不用我們的應用也能做到同樣效果的方法。

你問一個 DevOps 代理,正式環境的 API 為什麼慢。它開始幹活。終端裡出現一行,說它在呼叫一個工具,然後又一行,又一行。六次呼叫之後,它告訴你磁碟已經用了 97 %,提議清理日誌目錄。

它在那台機器上到底執行了什麼?哪條 du,哪條 find,是不是已經刪了什麼?答案是有的,但它在會話轉錄裡,以 JSON 寫成,你只能事後讀。在筆記本上這沒問題。在生產伺服器上,事後再說「等等,不是那個資料夾」就太晚了。

我們在做 AgentsRoom,一款執行編碼代理的桌面應用,並給代理提供連線你的伺服器、資料庫和叢集的工具。這篇文章講的是我們怎樣讓這些呼叫在發生時就可見:沒成功的那一版,成功那一版背後的數字,以及不用我們的應用怎樣做到同樣的事。

簡短的回答

  • CLI 讓你看到的是工具執行過,而不是另一端的會話。 完整的命令和輸出都進了你磁碟上的轉錄。
  • 要即時看到,必須有東西在每次呼叫開始時就記錄,而不是等會話結束。
  • 每個連線一份日誌行得通。每條命令一個終端分頁行不通。 我們在單個會話裡測到了 166 條遠端命令。
  • 把這份日誌留在你自己的機器上。 生產主機上的一行命令裡有金鑰,也有客戶資料。
  • 不用我們的應用: 一個把每條 shell 命令追加到檔案裡的 Claude Code hook 能解決大部分問題,剩下的交給轉錄。

為什麼在伺服器上只有轉錄不夠

Claude Code、Codex 和其他 CLI 確實什麼都記。Claude Code 在 ~/.claude/projects/ 下為每個會話寫一個 JSONL 檔案,Codex 在 ~/.codex/sessions/ 下寫一個。每次工具呼叫連同輸入和結果都在裡面。

問題不在完整性,而在時機和形式。轉錄是寫給 CLI 的,好讓它能恢復會話。你要等代理停下來才能讀,還得在一行行 JSON 裡翻找。三個代理同時幹活,你就得讀三個檔案。而代理的終端,也就是你真正盯著的地方,每次呼叫只顯示一段摺疊起來的摘要。

對於筆記本上的程式碼,事後再讀是正常的審查流程:提交之前看一眼 diff。伺服器沒有 diff。一條 systemctl restart 或一條 DELETE,執行的那一刻就生效了。

我們最初的嘗試,以及那 166 條命令

我們給代理的第一個遠端工具,會在一個終端分頁裡開啟連線。看起來沒問題:使用者能看到會話。結果它以一種我們沒料到的方式失敗了。

這個工具沒有給代理任何辦法去讀取它剛開啟的分頁裡發生了什麼。於是在一位使用者的專案裡,代理乾脆不用它了。那個會話的統計:我們的連線工具被呼叫了 16 次,而代理透過自己的 shell 工具執行了 166 條 sshpass 命令,代理向使用者要密碼,使用者把密碼貼上進聊天。正式環境的憑證就這樣以明文留在了轉錄裡,每條命令執行時留在 ps aux 裡,還留在 /tmp 下的一個檔案裡。

教訓不是「代理太魯莽」。代理只是做了唯一行得通的事。一個安全但不讓代理完成工作的工具會被繞過,而繞過的結果比沒有工具還糟。

於是我們寫了 ssh_exec:代理傳送一條命令,AgentsRoom 用儲存好的連線執行它,密碼留在應用裡,然後返回輸出和退出碼。代理從頭到尾看不到憑證,也就沒有理由去拼一條 sshpass 命令。

安全問題解決了,可見性問題又來了。如果每次 ssh_exec 都開一個分頁,那個會話就會產生 166 個分頁。所以 ssh_exec 一個都不開,兩個月裡,能看到這些命令的地方又只剩代理的對話。

每個連線一份日誌

我們在 2026 年 10 月 29 日發布的版本(AgentsRoom 1.242.0)守住一條規則:不按命令開分頁。取而代之,每次呼叫都進入一份日誌,每個連線一份。

  • 右側面板的活動分頁,在檔案、更改和測試旁邊,用卡片列出代理碰過的連線(最後一條命令、代理、時間、狀態),並在時間線上顯示最近 40 次呼叫。可以按代理篩選,也能搜尋命令、連線名和輸出。
  • 一個連線的日誌讀起來像終端:代理 · 時間,然後 $ 命令,然後是輸出,然後是 已完成 · 退出碼 0 · 1.2 s。SSH 輸出即時滾動,只要你不往上翻,檢視就一直跟著底部。一個按鈕就能把整份日誌複製成文字。
  • 代理標題欄裡的膠囊,代理碰過的每台伺服器、每個資料庫或叢集各一個,呼叫進行中帶一個綠點。點一下就開啟對應的日誌。
  • 代理工作中徽章,出現在伺服器、資料庫和 Kubernetes 視窗裡該連線所在的行上,只在呼叫執行時顯示。

日誌是唯讀的。想自己在機器上敲命令,入口仍然是伺服器視窗裡的 SSH 分頁。完整的功能頁面是 AI 代理的 SSH 連線,資料庫那一側見 資料庫連線。

哪些會被記錄,哪些不會

呼叫進入日誌原因
ssh_exec(SSH、AWS SSM、WinRM)是主要場景:遠端機器上的一條命令,沒有自己的分頁
ssh_transfer是往伺服器複製或從伺服器複製檔案,是對那台伺服器的操作
db_query、db_schema是代理寫的原樣 SQL,以及結果的前幾行
kube_kubectl是顯示為帶引數的 kubectl 命令列
commands_run、ssh_connect否它們本來就會開啟一個可以盯著看的終端分頁
代理自己的 shell 工具(直接敲的 ssh、psql、kubectl)否不經過 AgentsRoom:在代理的終端和轉錄裡

最後一行是老實交代的侷限。日誌只看得到經過我們工具的東西。如果你希望每個遠端操作都出現在那裡,工具就必須是代理更省事的那條路,這正是那 166 條命令給的教訓。

還有一個細節:只有 SSH 會在命令執行時流式輸出,因為它走的是你機器上一個真正的終端。WinRM、SQL 和 kubectl 的結果在呼叫結束時才出現。

保留這份日誌的代價

我們的使用者會同時跑很多代理:一台機器上 18 個專案裡有 45 個代理,另一台上有 48 個主控台。任何按代理或按輸出塊計算的東西都會被這個數字放大,所以日誌有硬性上限:

  • 每個專案 120 次呼叫,最舊的先丟。
  • 每次呼叫 32,000 個字元的輸出,保留末尾,因為錯誤和退出碼都在那裡。
  • 每次呼叫 2,000 個字元的命令或 SQL。
  • 即時輸出每次呼叫每 120 ms 一條更新訊息,絕不是每個終端輸出塊一條。
  • 空閒時沒有定時器。 只要沒有代理呼叫遠端工具,日誌就零開銷。

記錄只發生在一個點:所有 CLI 的工具呼叫都要經過的那座橋。所以無論是 Claude Code、Codex、Antigravity CLI,還是應用執行的其他任何 CLI,它都一樣工作,不需要按提供商寫程式碼。

我們選擇的界限:什麼都不離開這台機器

日誌儲存在桌面應用的記憶體裡,退出應用就消失。它不會同步到我們的伺服器,這在我們這裡並不常見:AgentsRoom 裡幾乎所有其他東西都會跟著你的帳戶在不同電腦間同步。

這個偏偏不同步,是有意為之。在伺服器上執行 env 的輸出裡有金鑰。對客戶表的一條 SELECT 裡有客戶資料。一個為了讓這些東西可見而做的工具,不應該再順手把它們複製到別的地方。

手機可以在代理的資料頁裡跟著看同一份日誌(行動應用 2.47 及以上)。資料流透過端到端加密的鏈路從你的電腦傳到你的手機,金鑰在發出之前就被遮蓋(API 金鑰、KEY=value 鍵值對、URL 裡的密碼、令牌),伺服器上什麼都不儲存。同一次呼叫也照舊能在代理的對話裡讀到。

Claude Code 審計日誌是另一回事

如果你搜過「Claude Code 審計日誌」,大概會找到 Anthropic 面向 Claude Enterprise 的 Compliance API:活動流、審計日誌事件,以及登入了 Enterprise 帳戶的本地會話的會話轉錄。它是為管理員和合規團隊做的,覆蓋整個組織,而且是事後查閱。

它回答的是「公司裡誰用 Claude 做了什麼」。它不回答「我的代理此刻在資料庫伺服器上執行哪條命令」。兩者可以共存,如果你所在的公司有合規要求,不管第二件事用什麼,第一件事你大概都需要。

如果你不用 AgentsRoom

用 CLI 已經提供的東西,你就能拿到其中很大一部分。

在每條 shell 命令開始時就記錄下來。 Claude Code hook 可以在每次工具呼叫之前執行一條命令。hook 指南里給出了這種寫法:在 Bash 工具上掛一個 PreToolUse hook,把 jq -r .tool_input.command 的結果寫進日誌檔案。在第二個終端裡對這個檔案執行 tail -f,代理每發出一條命令你都能立刻看到,ssh 命令列也包括在內。

需要輸出時就讀轉錄。 hook 給你的是命令,不是伺服器回答了什麼。這部分在 ~/.claude/projects/ 下的會話檔案裡(Codex 則是 ~/.codex/sessions/),每次呼叫的完整結果都在。

在伺服器上給代理開一個專用帳戶。 用專用使用者,每個連線在伺服器的認證日誌裡都能追溯到人。如果你的伺服器跑著 auditd,給這個使用者的 execve 加一條規則,就能在伺服器一側記錄它啟動的每個程序,代理繞不過去。

讓憑證遠離代理。 如果唯一的連線方式是一個代理必須向你要的密碼,你就會在聊天裡看到 sshpass 命令列。用一個代理永遠讀不到的金鑰,或者用一個替它保管秘密的工具。我們另寫了一篇指南,講如何把金鑰交給代理而不寫進提示詞。

這套做法給不了你的,是把三者串起來:哪個代理、在哪個連線上、產生了什麼即時輸出,都在一個地方。這正是我們做的那部分。

大家真正會問的問題

Claude Code 在遠端伺服器上幹活時,我能即時看到它在做什麼嗎?

終端裡你能看到工具呼叫,以及呼叫結束後的一段簡短結果。完整的命令和輸出會寫進你磁碟上的會話轉錄,你只能事後去讀。要在發生時就看到,需要有東西在每次呼叫開始時就把它記下來:一個把每條 Bash 命令寫進日誌檔案的 Claude Code hook,或者一個替代理執行遠端呼叫並即時展示的應用,AgentsRoom 的活動分頁做的就是這件事。

Claude Code 把它執行過的命令記錄在哪裡?

記錄在會話轉錄裡,也就是 ~/.claude/projects/ 下的 JSONL 檔案,每個專案一個資料夾,每個會話一個檔案。每次工具呼叫佔一行,包含輸入和結果。Codex 在 ~/.codex/sessions/ 下也為每個會話儲存類似的檔案。兩者都是完整的,但兩者都是寫給 CLI 用來恢復會話的,不是給人瀏覽的。

這和 Claude Code 審計日誌是一回事嗎?

不是。人們用這個名字搜尋的審計日誌,是 Anthropic 在 Enterprise 方案中透過 Compliance API 提供的組織級記錄:活動流、審計事件,以及已登入會話的轉錄,由管理員事後查閱。它回答的是組織裡誰做了什麼。即時檢視一台伺服器上的命令,是另一種工具,服務的是另一類人。

為什麼不為代理執行的每條命令開一個終端分頁?

我們走過這條路,也做了測量:一個處理生產故障的代理在一個會話裡發出了 166 條遠端命令。每條命令一個分頁,十分鐘後分頁列就沒法用了。行得通的做法是每個連線一份日誌,每次呼叫是一條記錄,包含命令、即時輸出、退出碼和耗時。

AgentsRoom 會把命令和輸出傳送到伺服器嗎?

不會。日誌儲存在桌面應用的記憶體裡,每個專案最多 120 次呼叫,退出應用就消失。手機可以在代理的資料頁裡跟著看(行動應用 2.47 及以上):資料流透過端到端加密的鏈路從你的電腦傳到你的手機,金鑰會被遮蓋,伺服器上什麼都不儲存。

活動分頁不顯示代理的哪些命令?

只記錄經過 AgentsRoom 工具的呼叫:ssh_exec、ssh_transfer、db_query、db_schema 和 kube_kubectl。代理用自己的 shell 工具執行的命令,比如直接敲的 ssh 或 psql 命令列,會出現在它的終端和轉錄裡,但不在日誌裡。commands_run 和 ssh_connect 是有意排除的,因為它們本來就會開啟一個你可以盯著看的終端分頁。

一句話總結

在伺服器上幹活的代理需要你給它兩樣東西:一種不經過你密碼就能工作的方式,以及一種讓你在它幹活時就能看到它在做什麼的方式。只有前者沒有後者,你只能事後讀 JSON。只有後者沒有前者,代理會繞過去,往聊天裡貼 sshpass 命令列。

我們最後做成的是每個連線一份日誌,有上限,留在你自己的機器上。想試試的話,AgentsRoom 可以免費下載,SSH 連線頁面一步步展示了設定方法。如果你更想只用 CLI,就從 PreToolUse hook 加一個 tail -f 開始:五分鐘就能搞定,你再也不用納悶最後那六次工具呼叫到底幹了什麼。

下載 AgentsRoom

在一個視窗中執行你所有專案的所有 AI 代理。

免費下載 AgentsRoom

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

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

獲取擴充功能
Chrome Web Store

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

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

繼續閱讀