SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-10-21

Cho coding agent chạy trong VM dùng một lần

Chạy coding agent trong VM có thể xóa bỏ để giới hạn blast radius, giữ trạng thái sạch cho từng task và dùng snapshot, VPS để giảm chi phí.

Vì sao VM dùng một lần tốt hơn laptop của bạn

Cấp cho coding agent một VM dùng một lần. Trường hợp xấu nhất là agent phá hỏng một máy mà bạn có thể dựng lại trong mười phút. Agent vẫn có root, vẫn cài được package, vẫn chạy test suite mà không phải xin phép cho từng bước. Khác biệt nằm ở nơi thiệt hại xảy ra. Trên laptop, agent dùng chung home directory với SSH key, profile của browser, các file .env và mọi repository bạn từng clone. Trên một server dùng xong rồi bỏ, agent chỉ có shell, một checkout và không có gì khác đáng để lấy.

Đó là toàn bộ lập luận. Đây là lập luận về sự bất đối xứng, không phải về xác suất. Một agent cẩn thận trên một laptop được quản lý cẩn thận gần như lúc nào cũng ổn. Nhưng một lần xảy ra sự cố, chi phí không chỉ là một commit bị lỗi. Bạn phải restore từ backup, nếu bạn có backup.

Xác định phạm vi ảnh hưởng trước khi tranh luận

Phạm vi ảnh hưởng là tập hợp những thứ mà một process có thể truy cập. Với một agent chạy dưới user thông thường trên máy thông thường của bạn, tập hợp này lớn hơn nhiều so với hình dung của hầu hết mọi người.

Nó bao gồm ~/.ssh/id_ed25519, thường không được mã hóa vì bạn đã chán phải nhập passphrase. Nó bao gồm ~/.aws/credentials và ~/.config/gh/hosts.yml, vốn được thiết kế dưới dạng plain text. Nó bao gồm mọi repository cùng cấp trong ~/code, kể cả những repository có connection string của production trong file env cục bộ. Nó cũng bao gồm shell history, nơi có thể chứa các token bạn từng dán một lần. Nó còn bao gồm network mà laptop của bạn đang kết nối, thường là network gia đình hoặc văn phòng có các service không yêu cầu xác thực.

Không điều nào trong số đó đòi hỏi agent phải có ý đồ xấu. Chỉ cần một command sai nhưng được thực thi với sự tự tin. rm -rf "$BUILD_DIR"/* khi BUILD_DIR chưa được set, khiến nó được expand thành /* và vượt qua cơ chế từ chối mặc định của GNU rm đối với việc xóa chính /, một git clean -xfd trong sai directory, một docker system prune -af --volumes kéo theo cả database cục bộ, hoặc một chmod -R 777 hữu ích trên home directory. Agent được train bằng chính Internet đã dạy những command đó cho mọi người khác.

Cơ chế bảo vệ bạn không phải là khả năng phán đoán của agent. Đó là việc máy đang chứa thiệt hại là một máy mà bạn đã chấp nhận có thể mất.

Chi phí rất đơn giản, và đó chính là điểm cần thấy

Một VPS nhỏ chỉ tốn vài dollar mỗi tháng. Khôi phục laptop của developer mất một ngày, và đó là trường hợp thuận lợi: bạn phát hiện sự cố ngay lập tức và đã có backup.

Hãy tự tính bằng các con số của bạn. Lấy mức phí theo giờ, nhân với số giờ cần để cài lại operating system, khôi phục home directory, rotate SSH key, rotate personal access token và re-clone 20 repository. So sánh kết quả đó với chi phí 12 tháng của server nhỏ nhất mà provider cung cấp. Điểm hòa vốn nằm ở mức chưa đến 1 sự cố trong vài năm, và sự cố không cần nghiêm trọng mới vượt qua mức này. Chỉ một buổi chiều bị mất vì local environment bị hỏng cũng đã đủ trả chi phí cho cả năm.

Nửa còn lại của phép tính là snapshot. Tạo snapshot trước khi chạy một tác vụ rủi ro sẽ biến một kết quả xấu từ “khôi phục toàn bộ môi trường làm việc” thành “rollback rồi thử prompt khác”. Laptop bạn đang dùng để viết nội dung này không có tùy chọn đó, vì bạn không thể tạo snapshot cho một máy đang được dùng làm máy làm việc.

Bức tranh tính đến tháng 10/2026

Có 3 câu trả lời thực tế cho câu hỏi “agent nên chạy ở đâu”, và chúng cùng đánh đổi giữa 2 yếu tố: ranh giới cô lập mạnh đến đâu và bạn chấp nhận thiết lập phức tạp đến mức nào.

Một micro VM cục bộ. Các tool thuộc nhóm này khởi động một máy ảo thực sự trên phần cứng của bạn, mount repository vào đó và cho agent quyền root bên trong. clawk là ví dụ hiện tại. Thông điệp chính của nó đúng với luận điểm của bài viết này: cung cấp cho coding agent một Linux VM dùng tạm, không phải laptop của bạn. Tính đến tháng 10/2026, tool này hỗ trợ macOS 14 trở lên trên Apple silicon, đồng thời có hỗ trợ Linux thử nghiệm thông qua Firecracker và được cài bằng brew install clawkwork/tap/clawk. Chạy clawk trong một repository để khởi động sandbox và gắn agent vào đó, chạy clawk down để dừng sandbox và clawk destroy để xóa sandbox. Ranh giới cô lập ở đây là hypervisor nên khá mạnh. Hạn chế là VM chạy trên máy bạn thường xuyên mang theo, nên nó tranh chấp bộ nhớ với các ứng dụng khác và sẽ dừng khi bạn gập máy.

Một container. Docker là lựa chọn mà hầu hết mọi người đã cài sẵn, và nó thực sự hữu ích.

docker run --rm -it -v "$PWD:/work" -w /work --network none ubuntu:24.04 bash

--rm xóa container khi thoát, còn --network none không cấp network cho container. Đây là thiết lập mặc định tốt cho một lần build hoặc test. Cần hiểu rõ những gì cách này không làm được: container dùng chung kernel với host, nên lỗi kernel có thể tạo đường thoát, và ranh giới cô lập biến mất ngay khi bạn thêm --privileged hoặc mount /var/run/docker.sock để agent có thể “dùng Docker”. Mount Docker socket vào container tương đương với việc cấp cho container quyền root trên host.

Một VPS thông thường có thể rebuild. Không cần tool mới, có ranh giới kernel thực sự, có snapshot từ provider và vẫn tiếp tục chạy khi bạn tắt laptop. Đây là mô hình được mô tả trong phần còn lại của hướng dẫn này. Đây cũng là mô hình phù hợp với các phiên chạy agent dài, vì một job mất 4 giờ không quan tâm bạn đã về nhà hay chưa.

Mô hình VPS: cấp cho agent một user riêng

Hãy bắt đầu với một máy chủ đã được harden. 10 phút đầu tiên trên một VPS mới bao gồm các phần không riêng cho agent: cập nhật hệ thống, đăng nhập bằng user không phải root, SSH chỉ dùng key và firewall.

Sau đó tạo một account chỉ dành cho agent. Khi có lỗi bên trong account này, lỗi đó sẽ không thể tác động đến phần khác trên server.

sudo adduser --disabled-password --gecos "" agent
sudo install -d -m 700 -o agent -g agent /home/agent/work
sudo -u agent -H bash -lc 'id; ls -la ~'

--disabled-password có nghĩa là không có password để đoán, và bạn truy cập account bằng sudo -u agent hoặc SSH key. Lưu ý rằng agent cố ý không thuộc group sudo. Agent có sudo sẽ có quyền root. root có thể đọc file của mọi user khác, nên lớp phân tách bạn vừa tạo chỉ còn mang tính hình thức. Nếu agent thực sự cần cài package, đó là lý do để dùng một server riêng do nó sở hữu, không phải để cấp sudo cho nó trên một server dùng chung. Các quy tắc chung được nêu trong nguyên tắc đặc quyền tối thiểu cho user Linux trên VPS.

Hãy kiểm tra ranh giới quyền trước khi tin tưởng account này. Với tư cách user agent, hãy thử liệt kê thư mục home của chính account đó:

sudo -u agent ls /home/you

Bạn phải thấy ls: cannot open directory '/home/you': Permission denied. Nếu thấy danh sách file, thư mục home của bạn có thể được các user khác đọc. Khi đó agent có thể đọc mọi nội dung trong thư mục này chưa được khóa riêng, chẳng hạn như file .env có quyền đọc cho mọi user. Khắc phục bằng sudo chmod 700 /home/you. Private SSH key của bạn không phải là thứ mà bài kiểm tra này bảo vệ: ssh sẽ bỏ qua private key file mà user khác có thể truy cập. Vì vậy, mọi key thực sự hoạt động với bạn vốn đã không thể được agent đọc, bất kể thư mục home của bạn có mode nào.

Để credential hoàn toàn bên ngoài máy

Mục đích của một máy dùng tạm sẽ mất đi nếu bạn sao chép secret production lên đó. Quy tắc rất đơn giản: trên máy đó không được có credential nào mà bạn không muốn rotate ngay trong chiều nay.

Với git, hãy forward SSH agent thay vì sao chép key. Private key vẫn nằm trên laptop của bạn, chỉ các yêu cầu ký mới đi qua kết nối.

ssh -A agent@203.0.113.10
ssh -T git@github.com

Lệnh thứ hai phải trả lời Hi yourname! You've successfully authenticated, but GitHub does not provide shell access.. Điều đó chứng minh git push sẽ hoạt động dù server không có file key. Sau đó chạy ls -la ~/.ssh trên máy đó và xác nhận không có private key nào trong đó.

Agent forwarding có một điểm cần lưu ý, hãy nói rõ: trong khi bạn đang kết nối, bất kỳ ai có root trên server đó đều có thể dùng socket được forward để authenticate với tư cách của bạn. Trên server mà người dùng duy nhất khác là bạn, đây là đánh đổi có thể chấp nhận. Trên máy dùng chung thì không, và deploy key chỉ có phạm vi trong một repository là lựa chọn tốt hơn. Các lựa chọn được trình bày trong Kiến thức cơ bản về quản lý SSH key.

Với API key, hãy cấp cho agent một key riêng với spending limit riêng, lưu trong file do user agent sở hữu với mode 600. Khi máy bị hủy, hãy revoke key đó thay vì phải đoán xem nó đã bị lộ hay chưa. Theo dõi model spend riêng cho từng key cũng là cách giữ cho các con số trong Kiểm soát chi phí AI agent trên VPS luôn có thể dự đoán.

Giới hạn các network mà agent có thể truy cập

Cô lập filesystem chỉ là một nửa của ranh giới bảo vệ. Nửa còn lại là egress: process được phép kết nối đến đâu. Linux có thể lọc traffic outbound theo user đã tạo process, phù hợp chính xác với mô hình này.

sudo iptables -A OUTPUT -m owner --uid-owner agent -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -j REJECT

Các rule được đọc theo thứ tự, vì vậy REJECT cuối cùng sẽ bắt mọi kết nối mà các dòng trước đó không cho phép. Hãy chạy thử với tư cách agent:

sudo -u agent curl -sS -m 5 http://example.com

Lệnh này phải fail ngay với lỗi curl: (7) Failed to connect to example.com, sau đó là thông báo có thể khác nhau tùy phiên bản curl, vì rule reject trả lời ngay thay vì để connection bị treo. HTTPS request đến cùng host vẫn phải thành công.

Có 2 giới hạn cần nói rõ. Thứ nhất, các rule này sẽ mất sau lần reboot tiếp theo nếu bạn không lưu chúng bằng sudo apt install -y iptables-persistent rồi sudo netfilter-persistent save. Thứ hai, bộ lọc này áp dụng cho port và address, không áp dụng cho hostname. Rule cho phép port 443 sẽ cho phép truy cập mọi HTTPS host trên internet. Như vậy đủ để truy cập model API, nhưng cũng đủ để truy cập một pastebin. Muốn có domain allow-list thực sự, traffic phải đi qua một proxy có thể đọc hostname được yêu cầu. Cách này phức tạp hơn mức mà hầu hết môi trường của một developer làm việc một mình mong muốn. Chỉ nên tuyên bố đúng phạm vi bạn đã triển khai: kiểm soát egress ở cấp port trên một máy mà bạn đã chuẩn bị tinh thần để mất.

Khôi phục trạng thái sạch giữa các tác vụ

Trạng thái sạch cho từng tác vụ là một lợi ích thường bị đánh giá thấp. Một agent đã xử lý ticket trước đó trong 3 giờ có thể để lại các package đã cài, migration mới áp dụng dở dang, một node_modules cũ và một git working tree chứa các thay đổi chưa được ai review. Tác vụ tiếp theo kế thừa toàn bộ số đó, còn bạn phải dùng thời gian review để xác định phần nào thuộc về lần chạy nào. Agent có phạm vi hẹp hơn sẽ để lại ít thứ hơn ngay từ đầu. Kết hợp một máy có thể hủy với skill hướng agent đến thay đổi nhỏ nhất nhưng vẫn hoạt động sẽ giữ cả diff và trạng thái còn sót lại ở mức đủ nhỏ để review.

Cách đơn giản và ít tốn kém là tạo checkout mới cho mỗi tác vụ.

sudo -u agent -H bash -lc 'rm -rf ~/work/repo && git clone git@github.com:you/repo.git ~/work/repo'

Cách chắc chắn hơn là tạo snapshot của provider một lần, ngay sau khi thiết lập máy và trước khi agent chạm vào máy. Khôi phục snapshot đó sẽ đưa toàn bộ system, bao gồm cả các package, về trạng thái đã biết. Hầu hết provider cung cấp tính năng này trong control panel hoặc qua API, thay vì dưới dạng command chạy trên máy, nên các bước cụ thể phụ thuộc vào provider của bạn. Hãy tạo snapshot khi máy vẫn chưa có thay đổi đáng kể.

Lưu mọi thứ bạn cần giữ bên ngoài máy có thể hủy. Điều này chủ yếu có nghĩa là push branch thay vì giữ chúng cục bộ. Nếu máy vẫn chứa thứ bạn sẽ tiếc nếu mất, hãy backup đúng cách bằng restic backup trên VPS. Một máy có thể hủy chỉ hữu ích nếu việc hủy nó thực sự không gây vấn đề.

Nếu muốn có nhiều môi trường cô lập mà không phải trả tiền cho nhiều server, bạn có thể dùng một VPS lớn hơn để chạy trực tiếp các guest VM. Virtualisation lồng nhau trên VPS giải thích cách hoạt động, bao gồm cách kiểm tra provider có cho phép hay không. Isolation có tác động theo cả hai hướng. Nếu muốn 2 agent trên cùng một máy phối hợp với nhau thay vì bị cô lập hoàn toàn, một session Claude Code có thể gửi text trực tiếp cho session khác thay vì để mọi lần bàn giao đều phải đi qua bạn.

Khi một laptop được bảo vệ cẩn thận thực sự là đủ

Hãy nhìn nhận điều này một cách thẳng thắn, vì nói quá về việc cô lập sẽ khiến mọi người không còn lắng nghe.

Nếu bạn kiểm tra từng command trước khi chạy, laptop là đủ. Prompt yêu cầu cấp quyền là một cơ chế kiểm soát thực sự, và chạy Claude Code an toàn trên server giải thích từng mức quyền thực sự chặn những gì. Nếu công việc của bạn chỉ nằm trong một repository và máy không chứa credential production nào, blast radius vốn đã nhỏ. Nếu các phiên agent ngắn và có người giám sát, thời gian phơi nhiễm cũng ngắn.

Câu trả lời thay đổi ngay khi bạn bỏ qua các prompt. Đây là điều đáng cân nhắc vì auto mode hiện là mặc định của Claude Code và bản cài đặt mới không còn hỏi trước khi chỉnh sửa file hoặc chạy command. Các lần chạy không có người giám sát, job chạy qua đêm và mọi workflow trong đó bạn approve một plan rồi rời đi đều loại bỏ bước kiểm tra của con người vốn đang thực hiện việc containment. Khi đó, máy phải tự thực hiện việc này. Điều tương tự áp dụng cho mọi thứ mở rộng phạm vi truy cập của agent, bao gồm chạy coding agent trên VPS qua nhiều repository cùng lúc.

Quyết định này thực ra không phụ thuộc vào mức độ bạn tin model. Nó phụ thuộc vào những gì đang ở bên cạnh model khi model mắc lỗi.

FAQ

Container có đủ mức cô lập cho coding agent không?

Với hầu hết công việc thì có, nhưng phải đáp ứng 2 điều kiện. Container không được chạy với --privileged và không được mount /var/run/docker.sock vào trong, vì một trong hai điều này đều tạo đường dẫn để process lên root trên host. Container dùng chung kernel với host nên ranh giới cô lập yếu hơn virtual machine. Nếu agent chạy code không đáng tin cậy tải từ Internet, hãy ưu tiên một VM thực hoặc một server riêng.

Agent có cần sudo trên server không?

Không. Cấp sudo cho agent sẽ vô hiệu hóa mức cô lập đã thiết lập, vì root có thể đọc dữ liệu của mọi account khác trên máy. Tạo user cho agent mà không cấp sudo, rồi chỉ cho user đó quyền ghi vào thư mục làm việc riêng. Nếu tác vụ thực sự cần cài package, hãy cấp cho agent một máy hoàn chỉnh do nó sở hữu thay vì cấp root trên máy dùng chung.

Làm thế nào để cho agent push lên git mà không đặt SSH key của tôi trên máy?

Forward SSH agent bằng ssh -A khi kết nối. Các yêu cầu ký được truyền qua kết nối, còn private key vẫn ở trên laptop của bạn, nên ssh -T git@github.com có thể xác thực và git push hoạt động mà không cần private key trên server. Lưu ý rằng root trên server đó có thể sử dụng socket được forward trong lúc bạn đang kết nối, vì vậy hãy dùng deploy key giới hạn theo repository trên mọi máy bạn chia sẻ với người khác.

Agent cần VPS có cấu hình bao nhiêu?

Công việc của agent chủ yếu là chỉnh sửa file, chạy build và chạy test, nên hãy chọn cấu hình máy theo yêu cầu của build thay vì theo model. Model được host chạy trên phần cứng của nhà cung cấp, nên chỉ tạo network traffic và gần như không tạo tải cục bộ. Bản thân agent vẫn đặt ra mức tối thiểu: tính đến ngày 20 tháng 10 năm 2026, yêu cầu hệ thống của Claude Code liệt kê 4 GB RAM là mức tối thiểu. Hãy bắt đầu với 4 GB ngay cả khi chỉ làm việc với script, và nâng lên 8 GB nếu repository build container hoặc compile tác vụ đáng kể.

Bao lâu nên destroy và rebuild máy một lần?

Hãy rebuild khi trạng thái máy không còn giải thích được, và tối thiểu là mỗi khi có khả năng một credential trên máy đã bị lộ. Tạo checkout mới giữa các tác vụ sẽ xử lý tình trạng thay đổi tích lũy hằng ngày, còn snapshot được tạo trước lần chạy agent đầu tiên sẽ cung cấp một system image sạch để khôi phục. Nếu rebuild có vẻ tốn kém, đó là dấu hiệu cho thấy có thứ quan trọng đang nằm trên một máy mà bạn gọi là disposable.

Bài viết này có hữu ích không?