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

dox: tự động cập nhật AGENTS.md đúng với code

AGENTS.md sai sau ba tuần khiến agent tin nhầm command và script. Dùng dox để tạo lại file từ repo, rồi review diff như review code trước khi commit.

Vì sao AGENTS.md của bạn sai sau ba tuần

Một file AGENTS.md trở nên lỗi thời vì không có gì liên kết nó với code. Bạn viết file đó một lần, bằng tay, vào ngày repository có một trạng thái nhất định. Sau đó test runner thay đổi, một package được đổi tên, một service bị xóa, còn file vẫn mô tả trạng thái của tháng 6. Không có gì fail vì không có bước build nào đọc file này.

Agent đọc file và tin vào nội dung đó. Đây mới là phần gây thiệt hại. Repository không có AGENTS.md khiến coding agent phải kiểm tra trước khi hành động. Repository có AGENTS.md sai khiến agent ngừng kiểm tra vì nó đã có câu trả lời. Agent chạy command mà file nêu, shell trả về Missing script: "test", rồi agent bắt đầu phỏng đoán. Nhiều khi nó sửa package.json để thêm script mà tài liệu đã hứa sẽ có. File lỗi thời không chỉ âm thầm bị bỏ qua. Nó khiến agent thực hiện một thay đổi mà bạn không muốn.

dox là một cách giải quyết vấn đề này. Đây là một bộ quy tắc dành cho agent, yêu cầu cập nhật tài liệu là một phần của việc hoàn tất công việc. Nhờ đó, file tài liệu được thay đổi trong cùng commit với phần code khiến nội dung cũ trở nên sai.

dox là gì và không phải là gì

dox là một file Markdown duy nhất. Repository là agent0ai/dox, được cấp phép theo MIT, và tính đến ngày 11 August 2026, toàn bộ project chỉ gồm một AGENTS.md 3906-byte, một README, một LICENSE và hai image. Không có package nào để cài đặt và không có runtime.

Điều này quan trọng vì tên gọi “generator” gợi ý một program phân tích code của bạn. Không có thành phần nào phân tích code. dox là một contract mà coding agent đọc: agent của bạn là generator, còn dox là instruction set cho agent biết khi nào phải đọc docs, khi nào phải viết lại chúng và mỗi document phải có cấu trúc ra sao.

File này có ten section, trong đó hai section thực hiện phần việc chính. “Read Before Editing” yêu cầu agent đi từ repository root đến mọi path mà agent dự định chỉnh sửa, đồng thời đọc mọi AGENTS.md trên từng đường dẫn trong session hiện tại, không dựa vào memory. “Update After Editing” quy định rằng mọi thay đổi có ý nghĩa đều phải có một DOX pass, tức là phải chạy bước cập nhật documentation trước khi task được xem là hoàn tất. Pass này cập nhật document gần nhất đang sở hữu phần thay đổi khi purpose, structure, workflow, permissions hoặc user preferences thay đổi.

Các phần còn lại quy định cấu trúc. AGENTS.md con có thứ tự section mặc định: Purpose, Ownership, Local Contracts, Work Guidance, Verification và Child DOX Index. File ở root chứa các rule áp dụng cho toàn project cùng Child DOX Index cấp cao nhất. Agent dùng index này để tìm các document con. “Closeout” là checklist agent chạy ở cuối task: kiểm tra lại các path đã thay đổi theo chain, cập nhật các document sở hữu gần nhất, làm mới mọi index bị ảnh hưởng, xóa các mâu thuẫn, chạy verification hiện có và báo cáo những document mà agent đã chủ ý không chỉnh sửa.

Ghim dox vào một commit cụ thể, không ghim vào main

Repository không có tag và cũng không có release, nên không có số phiên bản để ghim. Hãy ghim vào commit thay thế. AGENTS.md hiện tại là commit f34ec7ad1055d3393887e5a2670e8cb7320c9165, ngày 1 August 2026.

mkdir -p .agent
curl -fsSL -o .agent/dox-f34ec7a.md \
  https://raw.githubusercontent.com/agent0ai/dox/f34ec7ad1055d3393887e5a2670e8cb7320c9165/AGENTS.md
wc -c .agent/dox-f34ec7a.md

wc -c phải in ra 3906. Nếu ra số khác, bạn chưa tải đúng file mà hướng dẫn này mô tả, nên hãy đọc file trước khi tin tưởng nó. Nếu nhập sai commit hash, -f sẽ khiến curl dừng với curl: (22) The requested URL returned error: 404 và không ghi nội dung nào, còn wc -c sẽ in ra 0. File bị cắt ngắn còn tệ hơn không có file, vì agent sẽ làm theo một nửa contract mà không biết.

cp .agent/dox-f34ec7a.md AGENTS.md
git add AGENTS.md .agent/dox-f34ec7a.md
git commit -m "Add DOX rules (agent0ai/dox @ f34ec7a)"

cp dùng cho repository chưa có AGENTS.md. Nếu đã có file này, không được ghi đè. Đặt các phần dox bên trên nội dung hiện có, giữ các rule của bạn bên dưới, rồi đọc toàn bộ kết quả một lần từ đầu đến cuối. Hai tài liệu mâu thuẫn nhau sẽ khiến agent làm theo dòng mà nó đọc sau cùng.

Tiếp theo, trong repository, hãy yêu cầu agent thực hiện lượt đầu tiên. README có đúng câu lệnh:

Initialize DOX tree for this project now.

Lệnh này tạo các file AGENTS.md con và các index trỏ đến chúng. Hãy kiểm tra kết quả trước khi tin tưởng:

git status --short
find . -name AGENTS.md -not -path './.git/*' | sort

Mỗi file trong output find phải xuất hiện ở đâu đó bên trên nó trong một Child DOX Index. Một tài liệu con không được index nào nhắc đến có thể bị agent bỏ qua, vì index là cách nó tìm các tài liệu không nằm trực tiếp trên đường dẫn mà nó đang duyệt.

dox có thể thấy gì và không thể biết gì

Agent xây dựng inventory của bạn sẽ đọc repository. Vì vậy, mọi thứ nằm trong repository đều có thể được đưa vào inventory: cấu trúc thư mục, các package manifest và lockfile, các script trong package.json hoặc Makefile hoặc pyproject.toml, file CI workflow, Dockerfile, entry point và CODEOWNERS nếu bạn có file này. Inventory được xây dựng từ các nguồn đó thực sự có thể tự duy trì. Khi một package được chuyển vị trí, lần chạy tiếp theo sẽ chuyển theo dòng mô tả package đó.

Mọi nội dung dưới đây do bạn cung cấp, vì chúng không nằm trong repository để agent đọc:

  • lý do một rule tồn tại; đây là thông tin ngăn agent xóa rule vì cho rằng nó là complexity không cần thiết
  • đường dẫn nào trong hai đường dẫn đang hoạt động là đường dẫn được hỗ trợ, và đường dẫn nào đang chờ xóa
  • mọi thông tin nằm ngoài repository, chẳng hạn như staging environment hoặc lý do một dependency bị ghim lùi 2 version
  • việc bạn dự định làm vào tuần sau; đây là điểm khác biệt giữa một file còn hiện hành và một file thực sự hữu ích

dox hiểu rõ giới hạn này của chính nó. Các rule của dox quy định rằng Work Guidance phải phản ánh standards hiện tại của project hoặc instructions của người dùng. Nếu chưa có nội dung nào, hãy để trống section đó. Verification phải phản ánh một check đã tồn tại. Vì vậy, nếu repository chưa có test framework, section đó vẫn để trống cho đến khi có test framework. File được generate nhưng tự tạo ra một standard sẽ tệ hơn section để trống, vì sau đó agent sẽ thực thi standard do nó tự tạo.

Đừng để ý định do con người viết bị xóa khỏi inventory được sinh tự động

Đây là lỗi khiến nhiều người từ bỏ tài liệu được sinh tự động. Bạn viết một đoạn giải thích rằng hàng đợi job phải luôn chỉ có một consumer. Ba tuần sau, một lần chạy lại ghi đè file và xóa mất đoạn này trong một diff dài 40 dòng, phần lớn chỉ sắp xếp lại tên file, nên không ai phát hiện.

Bạn cần cả hai cơ chế.

Trước hết, chuyển ý định cần duy trì lâu dài sang một file khác. Các quyết định thiết kế và lý do đằng sau chúng nên đặt trong file DESIGN.md dành cho agent, còn các ghi chú dành cho con người nên đặt ở nơi bạn tách HUMAN.md khỏi AGENTS.md. Khi đó, AGENTS.md chỉ chứa inventory và các contract cục bộ. Đây chính xác là phần nên thay đổi khi code thay đổi.

Tiếp theo, đánh dấu phần ý định bắt buộc phải nằm trong AGENTS.md. Bọc phần đó bằng các marker và coi block này là nội dung do con người quản lý:

## User Preferences

<!-- dox:keep start -->
The jobs queue stays single consumer. Ordering is the reason this service exists.
Deploys ship on Tuesday. A Friday deploy is a human decision, not an agent decision.
<!-- dox:keep end -->

Comment Markdown không hiển thị trên trang, nhưng agent vẫn đọc được. Tiếp theo, hãy biến việc giữ nguyên block này thành một kiểm tra có thể tự động xác minh, để lần chạy nào xóa nó cũng thất bại rõ ràng. Chạy lệnh sau trong CI (continuous integration) cho mọi pull request:

git fetch -q origin main
sed -n '/dox:keep start/,/dox:keep end/p' AGENTS.md > /tmp/keep.head
git show origin/main:AGENTS.md | sed -n '/dox:keep start/,/dox:keep end/p' > /tmp/keep.base
diff -u /tmp/keep.base /tmp/keep.head

diff không in gì và thoát với mã 0 khi block vẫn không thay đổi. Nếu có output, lần chạy đó đã ghi đè nội dung do con người quản lý. Khi đó, một người phải phê duyệt hoặc revert thay đổi. Kiểm tra này vẫn có hiệu lực mà không cần ai phải nhớ thực hiện.

Kích hoạt tạo lại khi có pull request, không chạy theo timer

Thời điểm tốt nhất để cập nhật tài liệu là ngay trong commit khiến tài liệu trở nên sai. Đưa bước chạy DOX vào cùng pull request với thay đổi cấu trúc để diff đủ nhỏ và có thể đọc được.

Một blocking check để bắt buộc việc này:

#!/usr/bin/env bash
set -euo pipefail
git fetch -q origin main
base=$(git merge-base origin/main HEAD)
changed=$(git diff --name-only "$base" HEAD)
if grep -qE '^(src|apps|packages)/' <<<"$changed" && ! grep -q 'AGENTS\.md$' <<<"$changed"; then
  echo "Code changed but no AGENTS.md was touched. Run a DOX pass, or say why not."
  exit 1
fi

Điều chỉnh các path cho phù hợp với repository của bạn. Giá trị của cách này là check sẽ fail ngay trên branch, khi việc sửa còn đơn giản, và fail với lý do mà reviewer có thể xử lý.

Schedule chỉ là phương án dự phòng, không phải cơ chế chính. Một job chạy hằng tuần sẽ bắt được những vấn đề không ai phát hiện trên branch: file bị chuyển trong rebase, package bị xóa khi merge, hoặc tài liệu vẫn tham chiếu đến một directory không còn tồn tại. Chạy job này trên một máy nhỏ, có thể là chính máy bạn dùng để chạy coding agent trên VPS, và để job mở pull request thay vì push vào main.

#!/usr/bin/env bash
set -euo pipefail
cd /srv/src/myapp
git fetch -q origin
git switch -c "dox/refresh-$(date +%Y%m%d)" origin/main
# Your agent CLI goes on the next line, in whatever non-interactive mode it offers.
# Prompt: "Run a DOX pass over this repository. Change AGENTS.md files only."
git add '*AGENTS.md'
git commit -m "dox: refresh AGENTS.md tree" || { echo "nothing to refresh"; exit 0; }
git push -q -u origin HEAD
gh pr create --fill

Comment đó được cố ý để làm placeholder. Mỗi agent có CLI (command line interface) riêng và flag non-interactive riêng. Một command được copy từ web page nhưng không khớp với version bạn đang dùng sẽ fail trong cron, nơi không ai thấy lỗi. Điền command phù hợp rồi chạy script thủ công một lần trước khi lên lịch. || exit 0 cũng quan trọng: git commit thoát với mã khác 0 bằng nothing to commit, working tree clean khi tree đã ở trạng thái hiện tại, và dưới set -e, điều đó sẽ báo một lần chạy thành công là bị lỗi.

Mỗi lần chạy đều tốn token vì “Read Before Editing” khiến agent phải đọc toàn bộ chuỗi trong mỗi task. Đó là trade-off, và bạn nên theo dõi chi phí này nếu bạn đã tính chi phí các lần chạy của agent.

Monorepo: nhiều contract, một index

Một file AGENTS.md ở root trong repository có 40 package sẽ tạo ra một diff regenerate mà không ai đọc, đồng thời phần lớn nội dung không liên quan đến việc agent đang làm. dox giải quyết vấn đề này bằng Child DOX Index: root chứa các rule áp dụng trên toàn repo và trỏ đến các file con, còn mỗi boundary bền vững tự quản lý file riêng. Cách sắp xếp cây thư mục đó và những tool nào thực sự đọc file lồng nhau được trình bày trong các file AGENTS.md lồng nhau cho monorepo.

Điểm dox thay đổi là phạm vi review. Một pull request chỉ chạm vào packages/api phải tạo ra diff tài liệu bên trong packages/api, không ở nơi nào khác:

git diff --stat -- '*AGENTS.md'

Nếu command đó liệt kê 6 file cho một thay đổi chỉ liên quan đến một package, cây thư mục đang sai. Hoặc các boundary quá rộng, hoặc một rule thuộc về root đã bị copy vào mọi thư mục con. dox nêu cách sửa trực tiếp: rule tổng quát đặt trong tài liệu của parent, chi tiết cụ thể đặt trong tài liệu của child. Rule bị lặp là nguyên nhân khiến một lần chạy thông thường rewrite mọi thứ. Nếu cùng một bộ rule thực sự áp dụng cho nhiều repository độc lập, đó là một vấn đề khác; khi đó, chia sẻ agent skill giữa các repository là tool phù hợp hơn.

Xem diff như xem code

Rất dễ duyệt một diff tài liệu được tạo tự động mà không đọc kỹ. Đây là cách các file sai được phát hành. Hãy đọc diff với mức độ thận trọng như khi xem code được tạo tự động và kiểm tra 4 điểm sau.

  • một command mà file hiện đã nêu, bạn nên tự chạy command đó trước khi merge. Hướng dẫn build bịa đặt là lỗi thường gặp nhất.
  • một dòng bị xóa nhưng chứa chủ đích của tài liệu. Thêm nội dung thường không gây mất mát. Mất mát thường xảy ra ở phần bị xóa.
  • một absolute path, hostname, internal URL hoặc chuỗi có dạng credential
  • một mục inventory cho thứ không còn tồn tại; ls sẽ xác nhận việc này trong một giây

Sau đó kiểm tra kích thước bằng wc -l AGENTS.md. File root dài hơn 200 dòng là dấu hiệu nên tách file, vì giá trị cốt lõi của chain là agent chỉ đọc phần nhỏ có liên quan thay vì đọc toàn bộ.

Khi có lỗi

Pass đã xóa block intent của bạn. Lệnh kiểm tra diff ở trên sẽ in ra các dòng đã bị xóa. Khôi phục file từ điểm phân nhánh bằng git restore --source=origin/main AGENTS.md, rồi chạy lại pass với instruction cụ thể hơn, nêu rõ những section mà pass được phép chỉnh sửa.

Cả hai branch đều regenerate file. Bạn sẽ thấy CONFLICT (content): Merge conflict in AGENTS.md và các conflict marker <<<<<<< HEAD bên trong file. Không chỉnh sửa marker bằng tay. File này được generate, nên cách xử lý đúng là chạy một pass mới trên merged tree.

Agent hoàn toàn bỏ qua file. Kiểm tra filename mà tool thực sự đọc. Nếu tool đọc một file khác, trỏ nó đến cùng nội dung bằng ln -s AGENTS.md CLAUDE.md rồi commit symlink. Như vậy bạn chỉ giữ một source, thay vì hai document dần lệch nhau. Nếu filename đã đúng nhưng các rule vẫn bị bỏ qua, hãy chạy quy trình chẩn đoán vì sao coding agent bỏ qua instruction của bạn trước khi viết lại document.

Tree xuất hiện các child mà không ai index. So sánh output của find . -name AGENTS.md với các entry trong index của những document parent. Một child không được index nào nhắc đến là child mà agent có thể đi thẳng qua.

Khi generator là quá mức cần thiết

Một package, một test command và hai người đều hiểu repository: hãy viết 20 dòng đó bằng tay. Một file AGENTS.md dài 20 dòng không xuống cấp đủ nhanh để biện minh cho việc duy trì tree, index, CI check và job chạy hằng tuần. Hãy đọc lại file này khi thay đổi quá trình build. Đó là toàn bộ chi phí bảo trì, và chi phí này nhỏ hơn chi phí của cả hệ thống hỗ trợ xung quanh.

dox đáng dùng khi repository có những ranh giới mà không một người nào có thể ghi nhớ đầy đủ: nhiều package với các quy tắc khác nhau, hoặc những contributor tham gia mà chưa có bối cảnh cần thiết. Giá trị không nằm ở phần text được generate. Giá trị nằm ở việc tài liệu trở thành thứ mà một pull request có thể bị fail vì không đáp ứng, và đó là lý do duy nhất khiến bất kỳ file nào trong repository còn được cập nhật.

FAQ

Tôi có cần cài đặt gì để dùng dox không?

Không. dox là một file Markdown duy nhất, được cấp phép MIT, và tính đến ngày 11 August 2026, repository không có package hay bản release nào. Bạn chép nội dung của nó vào AGENTS.md của project, rồi coding agent sẽ tuân theo các quy tắc từ đó. Hãy pin commit bạn đã chép, f34ec7ad1055d3393887e5a2670e8cb7320c9165 tại thời điểm viết tài liệu, và ghi rõ commit đó trong commit message để sau này biết cây mã nguồn của bạn được xây dựng theo version quy tắc nào.

Làm thế nào để ngăn một lần tạo lại xóa các quy tắc tôi viết thủ công?

Tách riêng mục đích và danh mục. Đặt phần giải thích lâu dài trong một tài liệu riêng. Đặt mọi nội dung bắt buộc phải nằm trong AGENTS.md vào một block được đánh dấu. Sau đó kiểm tra block này trong CI: trích xuất nó từ branch và từ origin/main bằng sed, so sánh hai bản bằng diff, rồi cho build fail nếu có bất kỳ khác biệt nào. Khi đó, một người sẽ duyệt hoặc revert thay đổi, thay vì thay đổi lọt qua mà không ai nhận ra bên trong một diff lớn.

Bao lâu nên tạo lại AGENTS.md một lần?

Ngay trong pull request làm cho nó trở nên sai. Thay đổi cấu trúc và tài liệu của thay đổi đó nên nằm trong cùng một diff, vì đây là thời điểm duy nhất người duyệt có đủ context để kiểm tra cả hai. Một lần chạy theo lịch hằng tuần là phương án dự phòng cho tình trạng drift đã lọt qua một branch. Lần chạy này nên mở pull request thay vì commit trực tiếp vào main.

Các lệnh build nên nằm trong AGENTS.md ở root hay trong document con?

Nằm trong document gần nhất sở hữu các lệnh đó. Các quy tắc áp dụng trên toàn repo và index của các document con nằm ở root. Lệnh chỉ áp dụng cho một package nằm trong AGENTS.md của package đó. dox giải quyết xung đột theo khoảng cách: document gần hơn sẽ kiểm soát các chi tiết cục bộ, và document con không được làm yếu một quy tắc của document cha. Việc chép cùng một lệnh vào mọi document con khiến một lần chạy thông thường phải rewrite toàn bộ cây.

dox có đáng dùng cho một repository nhỏ không?

Thông thường là không. Một package với một lệnh test và AGENTS.md dài hai mươi dòng sẽ drift chậm, và bạn có thể sửa nó ngay trong phút đầu tiên phát hiện ra. dox đáng với chi phí bỏ ra khi repository có nhiều boundary với các quy tắc khác nhau, hoặc có những contributor thiếu background cần thiết, vì khi đó chuỗi document đang đảm nhận phần việc mà không một người nào có thể tự đảm nhận hết.