Tìm hiểu cách dùng Claude Code để phát hiện documentation drift và giữ README, tài liệu API và runbook khớp với mã bằng cách tạo diff và chỉ ra mâu thuẫn.

Documentation drift là sự tách dần giữa những gì tài liệu nói và những gì mã thực sự làm. Nó bắt đầu từ những sai lệch nhỏ, rồi trở thành sự bối rối kiểu "chúng tôi chắc chắn tuần trước vẫn chạy được".
Trong một đội thực tế, drift trông như thế này: README nói bạn chạy dịch vụ bằng một lệnh, nhưng giờ cần thêm một biến môi trường mới. Tài liệu API hiển thị endpoint với một trường bị đổi tên. Runbook bảo on-call khởi động lại "worker-a", nhưng tiến trình giờ đã tách thành hai dịch vụ.
Drift xảy ra ngay cả khi có ý tốt vì phần mềm thay đổi nhanh hơn thói quen viết tài liệu. Mọi người triển khai sửa lỗi trong áp lực, copy ví dụ cũ, hoặc nghĩ rằng người khác sẽ cập nhật tài liệu sau. Nó cũng lớn lên khi có quá nhiều nơi trông như "nguồn chân lý": file README, tham chiếu API, trang wiki nội bộ, ticket, và kiến thức truyền miệng.
Chi phí thì cụ thể:
Chỉ sửa văn phong không giải quyết drift nếu các sự kiện không đúng. Cách hữu hiệu là coi tài liệu như thứ có thể kiểm chứng: so sánh chúng với mã hiện tại, cấu hình và đầu ra thực tế, rồi gọi ra các mâu thuẫn khi tài liệu hứa hành vi mà mã không còn thực hiện.
Drift thường xuất hiện ở những tài liệu mọi người coi như "tham khảo nhanh". Chúng được cập nhật một lần, rồi mã tiếp tục di chuyển. Bắt đầu với ba loại này vì chúng chứa những cam kết cụ thể bạn có thể kiểm tra.
README bị drift khi các lệnh thường dùng thay đổi. Một flag mới được thêm, một flag cũ bị xóa, hoặc một biến môi trường bị đổi tên, nhưng phần thiết lập vẫn hiển thị thực tế cũ. Đồng đội mới copy-paste hướng dẫn, gặp lỗi và cho rằng dự án hỏng.
Phiên bản tệ nhất là "gần đúng". Một biến môi trường thiếu có thể lãng phí nhiều thời gian hơn một README hoàn toàn lỗi thời, vì mọi người thử nhiều lần biến thể nhỏ thay vì đặt câu hỏi về tài liệu.
Tài liệu API drift khi các trường request hoặc response thay đổi. Ngay cả những thay đổi nhỏ (đổi tên key, mặc định khác, header bắt buộc mới) cũng có thể phá vỡ client. Thường danh sách endpoint đúng nhưng ví dụ sai — và đó chính là thứ người dùng copy.
Các dấu hiệu thường thấy:
Runbook drift khi các bước triển khai, rollback hoặc vận hành thay đổi. Một lệnh lỗi thời, tên service sai, hoặc thiếu bước tiền đề có thể biến một sửa chữa thường thành downtime.
Chúng cũng có thể "đúng nhưng thiếu": các bước vẫn hoạt động, nhưng bỏ qua migration mới, xóa cache, hoặc bật/tắt feature flag. Lúc đó đáp viên làm theo runbook hoàn hảo nhưng vẫn bị bất ngờ.
Claude Code cho documentation drift hoạt động tốt nhất khi bạn coi tài liệu như mã: đề xuất một patch nhỏ, dễ review và giải thích lý do. Thay vì bảo nó "cập nhật README", hãy yêu cầu nó tạo diff so với các file cụ thể. Người review có trước/sau rõ ràng và có thể phát hiện thay đổi ngoài ý nhanh chóng.
Một kiểm tra drift tốt tạo ra hai thứ:
Khi prompt, yêu cầu bằng chứng từ repo: đường dẫn file và chi tiết như route, giá trị cấu hình, hoặc test chứng minh hành vi hiện tại.
Ví dụ mẫu prompt giữ mọi thứ bám sát:
Check these docs for drift: README.md, docs/api.md, runbooks/deploy.md.
Compare them to the current repo.
Output:
1) Contradictions list (doc claim -> repo evidence with file path and line range)
2) Unified diffs for the smallest safe edits
Rules: do not rewrite sections that are still accurate.
Nếu Claude nói "API dùng /v2", hãy yêu cầu nó dẫn chứng bằng cách chỉ tới router, OpenAPI spec, hoặc test tích hợp. Nếu không tìm được bằng chứng, nó nên nói như vậy.
Drift thường bắt đầu từ một thay đổi mã đơn lẻ ảnh hưởng lặng lẽ tới nhiều tài liệu. Hãy để Claude xác định phạm vi trước: gì đã thay đổi, chỗ nào thay đổi, tài liệu nào có thể bị vỡ, và hành động người dùng nào bị ảnh hưởng.
Ví dụ: bạn đổi tên biến môi trường từ API_KEY sang SERVICE_TOKEN. Một báo cáo hữu ích sẽ tìm mọi chỗ xuất hiện tên cũ (README setup, ví dụ API, mục secrets trong runbook), rồi tạo diff chặt chẽ chỉ cập nhật những dòng đó và các lệnh ví dụ sẽ thất bại.
Nếu bạn cho một mô hình xem "tất cả tài liệu" mà không có quy tắc, thường bạn sẽ nhận được văn phong viết lại nhưng vẫn chứa thông tin sai. Một workflow đơn giản giữ thay đổi nhỏ, lặp lại và dễ review.
Bắt đầu với một bộ tài liệu: README, tham chiếu API, hoặc một runbook mà mọi người thực sự dùng. Sửa một khu vực end-to-end sẽ dạy bạn những tín hiệu đáng tin trước khi mở rộng.
Ghi rõ, bằng lời đơn giản, nơi lấy sự kiện cho bộ tài liệu đó.
Khi bạn đã chỉ ra nguồn đó, prompt sẽ sắc nét hơn: "So sánh README với đầu ra CLI hiện tại và giá trị mặc định config, rồi tạo patch."
Thống nhất định dạng đầu ra trước khi chạy kiểm tra đầu tiên. Trộn lẫn định dạng làm khó nhìn thay đổi và lý do.
Một bộ quy tắc đơn giản:
Một thói quen thực tế: thêm một ghi chú nhỏ vào PR tài liệu như "Source of truth checked: routes + tests" để reviewer biết đã so sánh gì. Điều này biến cập nhật tài liệu từ "trông ổn" thành "được xác minh với nguồn thực tế".
Xử mỗi thay đổi mã như một cuộc điều tra tài liệu nhỏ. Mục đích là bắt mâu thuẫn sớm và tạo patch tối thiểu để reviewer tin tưởng.
Bắt đầu bằng chọn file chính xác để kiểm tra và đặt câu hỏi drift rõ ràng. Ví dụ: "Chúng ta có thay đổi biến môi trường, flag CLI, route HTTP, hoặc mã lỗi nào mà tài liệu vẫn nhắc không?" Cụ thể giúp mô hình khỏi viết lại cả phần.
Tiếp theo, yêu cầu Claude Code trích xuất các sự kiện cứng từ mã trước. Bắt nó liệt kê chỉ những mục cụ thể: lệnh người dùng chạy, endpoints và method, trường request/response, key cấu hình, biến môi trường bắt buộc, và bước vận hành được tham chiếu bởi script hoặc config. Nếu không tìm được trong mã, nó nên nói "not found" thay vì đoán.
Rồi yêu cầu một bảng so sánh đơn giản: tuyên bố trong doc, mã hiển thị gì, và trạng thái (match, mismatch, missing, unclear). Điều đó giữ cuộc thảo luận sát thực tế.
Sau đó, yêu cầu diff thống nhất với sửa đổi tối thiểu. Bảo nó chỉ thay những dòng cần thiết để giải quyết mismatches, giữ phong cách hiện có của tài liệu, và tránh thêm cam kết không được mã chứng minh.
Kết thúc bằng một tóm tắt cho reviewer: gì đã thay đổi, tại sao thay đổi, và những thứ cần kiểm tra thêm (ví dụ biến môi trường đổi tên hoặc header bắt buộc mới).
Tài liệu API drift khi mã thay đổi lặng lẽ: route đổi tên, trường trở thành bắt buộc, hoặc dạng lỗi thay đổi. Hậu quả là client bị phá vỡ và mất thời gian debug.
Với Claude Code cho documentation drift, nhiệm vụ là chứng minh API làm gì từ repo, rồi chỉ ra các chỗ tài liệu không khớp. Yêu cầu nó trích xuất danh mục từ routing và handler (path, method, model request/response) và so sánh với những gì tham chiếu API khẳng định.
Tập trung vào thứ người ta hay copy-paste: lệnh curl, header, payload mẫu, mã trạng thái, và tên trường. Trong một prompt, hãy bảo nó kiểm tra:
Khi tìm mismatch, chỉ chấp nhận diff có thể dẫn chứng từ mã (định nghĩa route chính xác, hành vi handler, hoặc schema). Điều này giữ patch nhỏ và dễ review.
Ví dụ: mã bây giờ trả 201 cho POST /widgets và thêm trường name bắt buộc. Tài liệu vẫn hiển thị 200 và bỏ name. Output tốt sẽ nêu cả hai mâu thuẫn và chỉ cập nhật mã trạng thái và JSON ví dụ của endpoint đó, để phần còn lại không bị chạm tới.
Runbook gây hỏng ở cách tốn kém nhất: trông đầy đủ nhưng các bước không còn khớp hệ thống hôm nay. Một thay đổi nhỏ như đổi tên biến môi trường hoặc lệnh deploy mới có thể kéo dài sự cố vì đáp viên làm theo chỉ dẫn không thể hoạt động.
Coi runbook như mã: yêu cầu diff so với repo hiện tại và bắt báo mâu thuẫn. So sánh với thứ hệ thống đang dùng: script, giá trị cấu hình mặc định, và tooling hiện tại.
Tập trung vào điểm thất bại gây mất thời gian nhất trong sự cố:
Thêm các kiểm tra nhanh và đầu ra mong đợi để đáp viên biết họ đi đúng hướng. "Verify it works" là không đủ; hãy cung cấp tín hiệu chính xác mong đợi (dòng trạng thái, chuỗi phiên bản, hoặc response health check).
Nếu bạn build và deploy app trên nền tảng như Koder.ai, điều này càng quan trọng vì snapshot và rollback chỉ hữu dụng khi runbook gọi đúng hành động và phản ánh đường phục hồi hiện tại.
Cách nhanh nhất tạo drift là coi tài liệu là "văn phong đẹp" thay vì tập hợp các khẳng định phải khớp mã.
Một bước sai phổ biến là yêu cầu viết lại trước. Khi bạn bỏ qua kiểm tra mâu thuẫn, bạn có thể kết thúc với văn phong mượt hơn nhưng vẫn mô tả hành vi sai. Luôn bắt đầu bằng hỏi tài liệu khẳng định gì, mã làm gì, và chỗ nào không đồng bộ.
Một lỗi nữa là để mô hình đoán. Nếu hành vi không hiển thị trong mã, test, hay config, coi nó là không rõ. "Có thể" là cách README sinh ra lời hứa và runbook biến thành hư cấu.
Những vấn đề này xuất hiện nhiều trong cập nhật hàng ngày:
Một handler thay đổi từ trả 401 sang 403 cho token hết hạn, và tên header đổi từ X-Token sang Authorization. Nếu bạn chỉ viết lại phần auth, bạn có thể bỏ sót ví dụ API vẫn dùng header cũ, và runbook vẫn bảo on-call theo dõi spike 401.
Khi tạo diff, thêm một dòng quyết định ngắn như: "Auth failures now return 403 to distinguish invalid vs missing credentials." Điều đó ngăn người tiếp theo "sửa" tài liệu về hành vi cũ.
Xử mỗi cập nhật tài liệu như một cuộc audit nhỏ. Mục tiêu là ít bất ngờ hơn khi ai đó làm theo hướng dẫn vào tuần tới.
Trước khi merge, quét README, tài liệu API và runbook để tìm các khẳng định cụ thể và xác minh chúng từng cái một:
Nếu bạn tìm hai hay nhiều khẳng định unknown trong cùng một tài liệu, tạm dừng merge. Hoặc thêm bằng chứng (đường dẫn file và tên hàm) hoặc cắt bớt tài liệu về những gì chắc chắn.
Một đội nhỏ cập nhật auth: thay vì gửi API key như X-API-Key, client giờ gửi token ngắn hạn Authorization: Bearer <token>. Mã được ship, test pass, và đội tiếp tục.
Hai ngày sau, một dev mới làm theo README. README vẫn ghi "set X-API-Key in your environment" và ví dụ curl dùng header cũ. Họ không chạy được local và nghĩ service bị lỗi.
Trong khi đó, tài liệu API cũng cũ. Nó mô tả header cũ và vẫn trả trường user_id, trong khi API giờ trả userId. Văn phong không sai, nhưng mâu thuẫn với mã, nên người đọc copy nhầm.
Rồi một sự cố xảy ra. On-call làm theo runbook bước "rotate the API key and restart workers". Việc đó không giúp vì vấn đề thật sự là xác thực token fail do config đổi. Runbook khiến họ đi sai hướng 20 phút.
Đây là lúc Claude Code cho documentation drift hữu ích nếu nó tạo diff và báo mâu thuẫn, không viết lại toàn bộ. Bạn có thể yêu cầu nó so sánh middleware auth và route handler với đoạn README, ví dụ API và bước trong runbook, rồi đề xuất patch tối thiểu:
- Header: X-API-Key: <key>
+ Header: Authorization: Bearer <token>
- { "user_id": "..." }
+ { "userId": "..." }
Điều quan trọng là nó đánh dấu mismatch, chỉ ra vị trí chính xác và chỉ thay đổi những gì repo chứng minh là lỗi thời.
Tài liệu giữ chính xác khi việc kiểm tra nó trở nên nhàm chán và lặp lại. Chọn tần suất phù hợp với mức rủi ro của thay đổi. Với mã thay đổi nhanh, làm kiểm tra trên mỗi PR. Với dịch vụ ổn định, quét hàng tuần và kiểm tra trước release là đủ.
Coi drift như một test fail, không phải nhiệm vụ viết văn. Dùng Claude Code cho documentation drift để sinh diff nhỏ và danh sách mâu thuẫn, rồi sửa điều nhỏ nhất làm tài liệu đúng trở lại.
Một routine nhẹ:
Lưu các tóm tắt diff dễ tìm sau này. Một ghi chú ngắn như "Docs updated to match new /v2 endpoint, removed deprecated header, updated example response" hữu ích khi ai đó hỏi vì sao tài liệu thay đổi sau vài tháng.
Áp tư duy "snapshot và rollback" cho tài liệu nữa. Nếu một hướng dẫn không chắc, thay đổi nó ở một chỗ, xác minh nhanh, rồi copy bản đã xác nhận sang chỗ khác.
Nếu bạn build nhanh, có thể hữu ích khi sinh app và bản docs đầu tiên cùng nhau trên Koder.ai (koder.ai), rồi export source và giữ thay đổi có thể review trong quy trình repo thông thường. Mục tiêu không phải prose hoàn hảo mà là giữ hành động thực tế (lệnh, endpoint, bước) khớp với mã thực tế.
Documentation drift is when your docs slowly stop matching what the code actually does. It usually starts with tiny changes (a renamed env var, a new required field, a different status code) that never get reflected in the README, API examples, or runbooks.
Because code changes under pressure and docs don’t get the same enforcement.
Common causes:
Start with the docs people actually execute, not the ones that are “nice to have.” A practical order is:
Fixing those first removes the highest-cost failures.
Because polished prose can still be wrong. Drift is mostly about incorrect claims.
A better approach is to treat docs as testable statements: “run this command,” “call this endpoint,” “set this variable,” then verify those claims against the current repo, configs, and real outputs.
Ask for two outputs:
Also require: if it can’t find evidence in the repo, it must say “not found” rather than guessing.
Because reviewers can validate diffs quickly. A diff shows exactly what changed, and it discourages “helpful” rewrites that introduce new promises.
A good default is: one file per diff when possible, and each change gets a one-sentence reason tied to repo evidence.
Require it to cite proof.
Practical rules:
Check the parts people copy-paste:
If the endpoint list is right but examples are wrong, users still fail—so treat examples as high priority.
Runbooks drift when operational reality changes.
High-impact checks:
If responders can’t verify progress, they’ll waste time during incidents.
Use a simple “source of truth” rule per doc type:
Then bake it into workflow: run drift checks on affected docs per PR, and keep edits small and reviewable.