Cách xem agent lập trình AI của bạn chạy gì trên máy chủ của bạn
Agent của bạn đang ở trên một máy chủ production và terminal chỉ nói rằng nó đang gọi một công cụ. Nó đã chạy lệnh nào, và máy đã trả lời gì? Transcript cho bạn biết điều đó khi mọi chuyện đã xong. Đây là cách chúng tôi làm cho nó hiện ra ngay khi đang diễn ra, những gì chúng tôi đã thử trước, và cách có được điều tương tự mà không cần ứng dụng của chúng tôi.
Bạn hỏi một agent DevOps vì sao API production chạy chậm. Nó bắt tay vào việc. Trong terminal của nó, bạn thấy một dòng nói rằng nó đang gọi một công cụ, rồi một dòng nữa, rồi thêm một dòng nữa. Sáu lệnh gọi sau, nó báo cho bạn biết ổ đĩa đã đầy 97 % và đề nghị dọn thư mục log.
Thực ra nó đã chạy gì trên máy đó? du nào, find nào, nó đã xóa thứ gì chưa? Câu trả lời có tồn tại, nhưng nó nằm trong transcript của phiên, viết bằng JSON, và bạn đọc nó khi mọi chuyện đã rồi. Trên laptop thì không sao. Trên một máy chủ production, khi mọi chuyện đã rồi thì quá muộn để nói "khoan, đừng đụng thư mục đó".
Chúng tôi làm ra AgentsRoom, một ứng dụng desktop chạy các agent lập trình và cho chúng công cụ để tiếp cận máy chủ, cơ sở dữ liệu và cluster của bạn. Đây là câu chuyện về cách chúng tôi làm cho các lệnh gọi đó hiện ra ngay khi chúng diễn ra, phiên bản đã không hoạt động, những con số đằng sau phiên bản hoạt động, và cách có được điều tương tự nếu bạn không dùng ứng dụng của chúng tôi.
Câu trả lời ngắn
- CLI cho bạn thấy một công cụ đã chạy, chứ không cho thấy phiên ở phía bên kia. Lệnh đầy đủ và đầu ra của nó đi vào transcript trên ổ đĩa của bạn.
- Muốn theo dõi trực tiếp, phải có thứ gì đó ghi lại từng lệnh gọi ngay khi nó bắt đầu, chứ không phải khi phiên kết thúc.
- Mỗi kết nối một nhật ký thì được. Mỗi lệnh một tab terminal thì không. Chúng tôi đã đếm được 166 lệnh từ xa trong một phiên duy nhất.
- Giữ nhật ký đó trên máy của bạn. Một dòng lệnh trên host production mang theo bí mật và dữ liệu khách hàng.
- Không dùng ứng dụng của chúng tôi: một hook của Claude Code ghi nối mọi lệnh shell vào một tệp đưa bạn đi gần hết chặng đường, và transcript lo phần còn lại.
Vì sao transcript là không đủ trên máy chủ
Claude Code, Codex và các CLI khác đều ghi lại mọi thứ. Claude Code viết một tệp JSONL cho mỗi phiên dưới ~/.claude/projects/, Codex viết dưới ~/.codex/sessions/. Mọi lệnh gọi công cụ đều nằm trong đó, kèm đầu vào và kết quả.
Vấn đề không nằm ở độ đầy đủ, mà ở thời điểm và hình thức. Transcript được viết cho CLI, để nó tiếp tục được một phiên. Bạn đọc nó khi agent đã dừng, bằng cách lục qua từng dòng JSON. Khi ba agent làm việc cùng lúc, bạn đọc ba tệp. Còn terminal của agent, nơi bạn thực sự đang nhìn, chỉ hiện một bản tóm tắt thu gọn của mỗi lệnh gọi.
Với code trên laptop, đọc lại sau là vòng review bình thường: bạn xem diff trước khi commit. Một máy chủ không có diff. Một lệnh systemctl restart hay DELETE có hiệu lực ngay khi nó chạy.
Những gì chúng tôi thử trước, và 166 lệnh
Công cụ từ xa đầu tiên chúng tôi làm cho agent mở một kết nối trong một tab terminal. Nhìn thì có vẻ đúng: người dùng thấy được phiên. Nó thất bại theo một cách chúng tôi không ngờ tới.
Công cụ đó không cho agent cách nào đọc được những gì xảy ra trong tab nó vừa mở. Vậy là trong dự án của một người dùng, agent ngừng dùng nó. Con số trong phiên đó: 16 lệnh gọi tới công cụ kết nối của chúng tôi, và 166 lệnh sshpass chạy qua công cụ shell của chính agent, với việc agent hỏi người dùng mật khẩu và người dùng dán nó vào khung chat. Thông tin đăng nhập production rốt cuộc nằm dưới dạng văn bản thuần trong transcript, trong ps aux lúc mỗi lệnh chạy, và trong một tệp dưới /tmp.
Bài học không phải là "agent liều lĩnh". Agent đã làm điều duy nhất hiệu quả. Một công cụ an toàn mà không cho agent làm được việc của nó sẽ bị lách qua, và đường lách còn tệ hơn là không có công cụ nào.
Vì thế chúng tôi viết ssh_exec: agent gửi một lệnh, AgentsRoom chạy nó trên kết nối đã lưu với mật khẩu được giữ trong ứng dụng, rồi trả về đầu ra và mã thoát. Agent không bao giờ thấy thông tin đăng nhập và chẳng có lý do gì để dựng một dòng sshpass.
Điều đó giải quyết vấn đề bảo mật nhưng lại tạo ra một vấn đề về khả năng quan sát. Nếu mỗi ssh_exec mở một tab, phiên đó đã sinh ra 166 tab. Nên ssh_exec không mở tab nào, và suốt hai tháng, nơi duy nhất để thấy các lệnh đó, một lần nữa, là cuộc hội thoại của agent.
Mỗi kết nối một nhật ký
Phiên bản chúng tôi phát hành ngày 29 tháng 10 năm 2026 (AgentsRoom 1.242.0) giữ một quy tắc: không có tab cho từng lệnh. Thay vào đó, mọi lệnh gọi đều vào một nhật ký, mỗi kết nối một nhật ký.
- Tab "Hoạt động" của bảng bên phải, cạnh "Tệp", "Thay đổi" và "Kiểm thử", liệt kê các kết nối mà agent đã chạm tới dưới dạng thẻ (lệnh cuối, agent, thời điểm, trạng thái) và 40 lệnh gọi gần nhất trên một dòng thời gian. Nó lọc theo agent và tìm kiếm trong lệnh, tên kết nối và đầu ra.
- Nhật ký của một kết nối đọc như một terminal:
agent · giờ, rồi$ lệnh, rồi đầu ra, rồiHoàn tất · mã thoát 0 · 1,2 s. Đầu ra SSH cuộn vào trực tiếp và khung xem bám theo phía dưới cho đến khi bạn cuộn lên. Một nút sao chép toàn bộ nhật ký dưới dạng văn bản. - Các nhãn nhỏ ở phần đầu của agent, mỗi nhãn cho một máy chủ, cơ sở dữ liệu hoặc cluster mà agent đó đã chạm tới, với một chấm xanh trong lúc có lệnh gọi. Một cú nhấp mở nhật ký đó.
- Huy hiệu "Agent đang làm việc" trên dòng của kết nối trong các cửa sổ "Máy chủ", "Cơ sở dữ liệu" và Kubernetes, chỉ trong lúc một lệnh gọi đang chạy.
Nhật ký chỉ để đọc. Muốn tự gõ vào máy, tab SSH của cửa sổ "Máy chủ" vẫn là lối vào. Trang tính năng đầy đủ là kết nối SSH cho agent AI, và phần cơ sở dữ liệu nằm ở kết nối cơ sở dữ liệu.
Những gì được ghi lại, và những gì không
| Lệnh gọi | Trong nhật ký | Vì sao |
|---|---|---|
ssh_exec (SSH, AWS SSM, WinRM) | Có | Trường hợp chính: một lệnh trên máy từ xa, không có tab riêng |
ssh_transfer | Có | Một tệp được sao chép tới hoặc từ một máy chủ là một hành động trên máy chủ đó |
db_query, db_schema | Có | Câu SQL đúng như agent đã viết, và những dòng đầu của kết quả |
kube_kubectl | Có | Hiển thị dưới dạng dòng kubectl kèm các tham số |
commands_run, ssh_connect | Không | Chúng vốn đã mở một tab terminal mà bạn có thể theo dõi |
Công cụ shell của chính agent (ssh, psql, kubectl gõ trực tiếp) | Không | Nó không đi qua AgentsRoom: nó nằm trong terminal và transcript của agent |
Dòng cuối là giới hạn mà chúng tôi nói thẳng. Nhật ký thấy những gì đi qua công cụ của chúng tôi. Nếu bạn muốn mọi hành động từ xa đều hiện ở đó, công cụ phải là con đường dễ hơn đối với agent, đó chính là bài học của 166 lệnh.
Thêm một chi tiết: chỉ SSH truyền đầu ra trong lúc lệnh đang chạy, vì nó đi qua một terminal thật trên máy của bạn. Kết quả của WinRM, SQL và kubectl xuất hiện khi lệnh gọi kết thúc.
Giữ nhật ký tốn bao nhiêu
Người dùng của chúng tôi chạy rất nhiều agent cùng lúc: 45 agent trên 18 dự án ở một máy, 48 console ở một máy khác. Bất cứ thứ gì tính theo từng agent hay từng mẩu đầu ra đều bị nhân lên theo những con số đó, nên nhật ký có các giới hạn cứng:
- 120 lệnh gọi mỗi dự án, cái cũ nhất bị bỏ trước.
- 32.000 ký tự đầu ra mỗi lệnh gọi, giữ phần cuối, nơi có lỗi và mã thoát.
- 2.000 ký tự lệnh hoặc SQL mỗi lệnh gọi.
- Một thông điệp cập nhật mỗi lệnh gọi mỗi 120 ms cho đầu ra trực tiếp, không bao giờ một thông điệp cho mỗi mẩu đầu ra terminal.
- Không có bộ hẹn giờ khi rảnh. Khi không agent nào gọi công cụ từ xa, nhật ký không tốn gì cả.
Việc ghi diễn ra ở một điểm duy nhất: cây cầu mà mọi lệnh gọi công cụ của mọi CLI đều đi qua. Đó là lý do nó hoạt động y như nhau với Claude Code, Codex, Antigravity CLI hay bất kỳ CLI nào khác mà ứng dụng chạy, không cần code riêng cho từng nhà cung cấp.
Giới hạn chúng tôi chọn: không có gì rời khỏi máy
Nhật ký được giữ trong bộ nhớ của ứng dụng desktop và biến mất khi bạn thoát. Nó không được đồng bộ lên máy chủ của chúng tôi, điều khá bất thường với chúng tôi: gần như mọi thứ khác trong AgentsRoom đều theo tài khoản của bạn qua các máy tính.
Cái này thì không, và là có chủ ý. Đầu ra của một lệnh env trên máy chủ chứa bí mật. Một câu SELECT trên bảng khách hàng chứa dữ liệu khách hàng. Một công cụ được làm ra để khiến những thứ đó hiện ra không nên đồng thời sao chép chúng sang một nơi mới.
Điện thoại có thể theo dõi cùng nhật ký đó từ hồ sơ của agent (ứng dụng di động 2.47 trở lên). Luồng dữ liệu đi từ máy tính đến điện thoại của bạn qua kết nối mã hóa đầu cuối, các bí mật được che trước khi rời máy (API key, cặp KEY=value, mật khẩu trong URL, token), và không có gì được lưu trên máy chủ. Cùng lệnh gọi đó vẫn đọc được trong cuộc hội thoại của agent, như trước.
Audit log của Claude Code là một chuyện khác
Nếu bạn đã tìm "Claude Code audit log", có lẽ bạn đã gặp Compliance API của Anthropic dành cho Claude Enterprise: một luồng hoạt động, các sự kiện audit log và, với các phiên cục bộ đã đăng nhập vào tài khoản Enterprise, transcript của phiên. Nó được làm cho quản trị viên và nhóm compliance, nó bao quát cả tổ chức, và bạn đọc nó khi mọi chuyện đã rồi.
Nó trả lời câu "ai trong công ty đã làm gì với Claude". Nó không trả lời câu "agent của tôi đang chạy lệnh nào trên máy chủ cơ sở dữ liệu ngay lúc này". Hai thứ có thể cùng tồn tại, và nếu bạn làm ở một công ty có yêu cầu compliance, có lẽ bạn cần cái thứ nhất bất kể bạn dùng gì cho cái thứ hai.
Nếu bạn không dùng AgentsRoom
Bạn có thể có được phần lớn điều này với những gì các CLI đã cung cấp sẵn.
Ghi log mọi lệnh shell ngay khi nó bắt đầu. Hook của Claude Code có thể chạy một lệnh trước mỗi lệnh gọi công cụ. Hướng dẫn về hook đưa ra mẫu: một hook PreToolUse trên công cụ Bash chuyển jq -r .tool_input.command vào một tệp log. Chạy tail -f trên tệp đó ở một terminal thứ hai và bạn thấy từng lệnh ngay khi agent gửi nó đi, kể cả các dòng ssh.
Đọc transcript khi bạn cần đầu ra. Hook cho bạn lệnh, không cho bạn biết máy chủ đã trả lời gì. Để có điều đó, tệp phiên dưới ~/.claude/projects/ (hoặc ~/.codex/sessions/ với Codex) có kết quả đầy đủ của mọi lệnh gọi.
Cho agent một tài khoản riêng trên máy chủ. Một người dùng riêng giúp mọi kết nối đều truy được nguồn gốc trong log xác thực của máy chủ, và nếu máy chủ của bạn chạy auditd, một quy tắc trên execve cho người dùng đó sẽ ghi lại từng tiến trình nó khởi chạy, ở phía máy chủ, nơi agent không thể bỏ qua.
Giữ thông tin đăng nhập ngoài tầm với của agent. Nếu cách duy nhất để kết nối là một mật khẩu mà agent phải hỏi bạn, bạn sẽ thấy các dòng sshpass trong khung chat. Hãy dùng một khóa mà agent không bao giờ đọc, hoặc một công cụ giữ bí mật thay cho nó. Chúng tôi đã viết một hướng dẫn riêng về cách đưa bí mật cho agent mà không đặt nó vào prompt.
Điều mà cách thiết lập này không cho bạn là mối liên kết giữa ba thứ: agent nào, trên kết nối nào, với đầu ra trực tiếp nào, ở cùng một chỗ. Đó là phần chúng tôi đã xây.
Những câu hỏi mọi người thực sự hỏi
Có thể xem Claude Code đang làm gì trên một máy chủ từ xa trong lúc nó làm việc không?
Trong terminal, bạn thấy lệnh gọi công cụ và, khi nó xong, một kết quả rút gọn. Lệnh đầy đủ và đầu ra của nó được ghi vào transcript của phiên trên ổ đĩa của bạn, thứ bạn đọc sau đó. Để theo dõi ngay khi nó diễn ra, bạn cần một thứ ghi lại từng lệnh gọi ngay lúc nó bắt đầu: một hook trong Claude Code ghi mọi lệnh Bash vào một tệp log, hoặc một ứng dụng thay agent chạy các lệnh gọi từ xa và hiển thị chúng trực tiếp, đó chính là việc tab Hoạt động của AgentsRoom làm.
Claude Code lưu dấu vết các lệnh nó đã chạy ở đâu?
Trong transcript của phiên, một tệp JSONL nằm dưới ~/.claude/projects/, mỗi dự án một thư mục và mỗi phiên một tệp. Mỗi lệnh gọi công cụ là một dòng kèm đầu vào và kết quả của nó. Codex giữ một tệp tương tự cho mỗi phiên dưới ~/.codex/sessions/. Cả hai đều đầy đủ, và cả hai đều được viết để CLI tiếp tục một phiên, không phải để một người đọc lướt.
Đây có phải là audit log của Claude Code không?
Không. Audit log mà mọi người tìm dưới cái tên đó là các bản ghi ở cấp tổ chức mà Anthropic cung cấp trong gói Enterprise qua Compliance API: một luồng hoạt động, các sự kiện audit và, với các phiên đã đăng nhập, transcript, được một quản trị viên đọc sau đó. Chúng trả lời câu hỏi ai đã làm gì trong tổ chức. Một góc nhìn trực tiếp vào các lệnh trên một máy chủ là một công cụ khác, cho một người khác.
Sao không mở một tab terminal cho mỗi lệnh agent chạy?
Chúng tôi đã thử hướng đó và đo đạc: một agent xử lý sự cố production đã bắn ra 166 lệnh từ xa trong một phiên duy nhất. Mỗi lệnh một tab khiến thanh tab vô dụng chỉ sau mười phút. Cách hiệu quả là mỗi kết nối một nhật ký, trong đó mỗi lệnh gọi là một mục với lệnh, đầu ra trực tiếp, mã thoát và thời lượng của nó.
AgentsRoom có gửi các lệnh và đầu ra của chúng lên một máy chủ không?
Không. Nhật ký nằm trong bộ nhớ của ứng dụng desktop, giới hạn ở 120 lệnh gọi mỗi dự án, và biến mất khi bạn thoát ứng dụng. Điện thoại có thể theo dõi nó từ hồ sơ của agent (ứng dụng di động 2.47 trở lên): luồng dữ liệu đi từ máy tính đến điện thoại của bạn qua kết nối mã hóa đầu cuối, các bí mật được che, và không có gì được lưu trên máy chủ.
Tab Hoạt động không hiển thị những lệnh nào của agent?
Chỉ những lệnh gọi đi qua công cụ của AgentsRoom mới được ghi lại: ssh_exec, ssh_transfer, db_query, db_schema và kube_kubectl. Một lệnh mà agent chạy bằng công cụ shell của chính nó, chẳng hạn một dòng ssh hay psql gõ thẳng, nằm trong terminal và transcript của nó nhưng không có trong nhật ký. commands_run và ssh_connect được cố ý bỏ ra ngoài, vì chúng vốn đã mở một tab terminal mà bạn có thể theo dõi.
Bản rút gọn
Một agent trên máy chủ cần hai thứ từ bạn: một cách làm việc không dính đến mật khẩu của bạn, và một cách để bạn thấy nó làm gì ngay trong lúc nó làm. Có cái thứ nhất mà thiếu cái thứ hai, bạn sẽ phải đọc JSON khi mọi chuyện đã rồi. Có cái thứ hai mà thiếu cái thứ nhất, nó sẽ bị lách qua bởi một agent dán các dòng sshpass.
Cuối cùng chúng tôi có mỗi kết nối một nhật ký, có giới hạn, giữ trên máy của bạn. Nếu muốn thử, AgentsRoom tải về miễn phí, và trang kết nối SSH hướng dẫn thiết lập từng bước. Nếu bạn thích chỉ dùng CLI của mình, hãy bắt đầu với hook PreToolUse và một lệnh tail -f: mất năm phút và bạn sẽ không bao giờ phải băn khoăn sáu lệnh gọi công cụ vừa rồi là gì nữa.
Tải AgentsRoom
Chạy tất cả agent AI của bạn, trên mọi dự án, trong một cửa sổ duy nhất.
Ứng dụng đồng hành: theo dõi agent khi đi đường
Sử dụng Claude, Codex, Antigravity CLI hoặc nhà cung cấp AI khác.
Gửi lỗi và yêu cầu thẳng vào backlog công khai của bạn.
Đọc thêm
Giữ Claude Code tiếp tục chạy sau khi SSH mất kết nối: công thức tmux
Giữ Claude Code tiếp tục chạy sau khi SSH mất kết nối bằng tmux. Kết nối lại đúng tiến trình cũ, kiểm tra độ bền của phiên và dùng tùy chọn phải tự bật trong AgentsRoom.
Đọc bài viếtBảy agent AI làm việc thay chúng tôi mỗi đêm: agent định kỳ ngoài việc viết code, kèm prompt
Một người dùng hỏi chúng tôi dùng agent AI vào việc gì ngoài viết code. Từ ngày 28 tháng 8, bảy agent định kỳ khởi động mỗi tối trên một chiếc Mac mini: một CEO trực ca, một đội SEO, một product manager, một người sửa bug, một đội mạng xã hội, một người giữ tài liệu và một người báo cáo gửi email tóm tắt 25 dòng. 33 đêm, 31 email buổi sáng, 51 bug được sửa kèm link commit, 7 bài blog bằng 20 ngôn ngữ. Mỗi agent làm gì, chúng giao việc cho nhau thế nào mà không nói chuyện với nhau, mô hình nào làm việc nào, bốn quy tắc mà prompt của chúng phải học, và chính các prompt đó, sẵn để sao chép.
Đọc bài viếtCách Đưa Một Bí Mật Cho AI Coding Agent Mà Không Bỏ Nó Vào Prompt
Một agent cần khóa Stripe hay mật khẩu cơ sở dữ liệu để chạy lệnh của nó. Bạn dán giá trị đó vào khung chat và nó rơi vào tệp transcript trên đĩa, sang phía nhà cung cấp mô hình, đôi khi vào cả một commit. Quy tắc chúng tôi rút ra sau ba lần tự mình làm hỏng : một bí mật đến được agent qua biến môi trường, và không qua đường nào khác.
Đọc bài viết