Khám phá codebase & suy giảm ngữ cảnh
Những điều bạn cần biết
Khám phá một codebase lớn là một trong những tác vụ tiêu tốn ngữ cảnh nhiều nhất mà một agent dựa trên Claude thực hiện. Dù agent đang khám phá một repository chưa quen thuộc, truy vết các chuỗi dependency, hay tìm hiểu các hệ thống cũ, các phiên làm việc kéo dài sẽ tạo ra một kiểu thất bại đặc thù: suy giảm ngữ cảnh (context degradation). Đây không phải là chuyện hết token. Đó là chuyện mô hình mất khả năng nắm bắt các phát hiện trước đó khi ngữ cảnh đầy dần lên bởi các đầu ra khám phá dài dòng.
Suy giảm ngữ cảnh
Suy giảm ngữ cảnh biểu hiện thành một hành vi cụ thể, có thể quan sát được: mô hình bắt đầu nhắc đến "các mẫu hình điển hình" thay vì các lớp, phương thức, và chuỗi dependency cụ thể mà nó đã phát hiện ra trước đó trong phiên làm việc. Sau khi khảo sát vài module, agent có thể nói "cái này theo mẫu hình repository điển hình" thay vì "lớp OrderRepository tại src/repos/order.ts triển khai interface Repository<T> cơ sở với cơ chế cache tùy chỉnh trong phương thức findById."
Điều này xảy ra vì:
- Mỗi bước khám phá tạo ra đầu ra dài dòng (nội dung file, kết quả tìm kiếm, danh sách thư mục).
- Đầu ra này tích tụ trong ngữ cảnh hội thoại.
- Các phát hiện chính xác trước đó bị đẩy sâu hơn vào trong ngữ cảnh, trong khi đầu ra dài dòng gần đây hơn lại chiếm ưu thế.
- Sự chú ý của mô hình chuyển sang đầu ra gần đây và nó mất đi các tham chiếu cụ thể đến các phát hiện trước đó.
Điểm mấu chốt cần hiểu là suy giảm ngữ cảnh không phải là vấn đề giới hạn token. Tăng kích thước cửa sổ ngữ cảnh không giải quyết được vấn đề này. Mô hình không hết chỗ chứa — nó đang mất dấu các chi tiết cụ thể khi chúng bị chôn vùi dưới đầu ra mới hơn, dài dòng hơn.
File nháp (scratchpad)
Biện pháp giảm thiểu chính cho suy giảm ngữ cảnh là các file nháp (scratchpad). Agent ghi các phát hiện chính vào một file và tham chiếu đến nó cho các câu hỏi tiếp theo. Điều này lưu giữ kiến thức bên ngoài ngữ cảnh hội thoại, khiến nó miễn nhiễm với suy giảm ngữ cảnh.
markdownCopy
# Exploration Scratchpad — Order Service
## Key Classes
- `OrderRepository` (src/repos/order.ts) — implements Repository<T>, custom findById caching
- `OrderService` (src/services/order.ts) — orchestrates OrderRepository + PaymentGateway
- `RefundProcessor` (src/services/refund.ts) — depends on OrderService.getOrderWithItems()
## Dependency Chain
RefundProcessor → OrderService → OrderRepository → PostgreSQL
RefundProcessor → PaymentGateway → Stripe API
## Critical Findings
- RefundProcessor has no retry logic for Stripe API failures
- OrderRepository caches by orderId but cache invalidation on status change is missing
- Test coverage: OrderService has 87% coverage, RefundProcessor has 12%Khi agent cần tham chiếu đến những phát hiện trước đó, nó đọc file nháp thay vì dựa vào ngữ cảnh hội thoại. Đây là một chiến lược có chủ đích, không phải một phương án dự phòng — agent nên được chỉ dẫn để duy trì file nháp ngay từ đầu bất kỳ phiên khám phá kéo dài nào.
Ủy quyền cho subagent
Việc sinh ra các subagent cho những tác vụ khảo sát cụ thể là biện pháp giảm thiểu quan trọng thứ hai. Thay vì để agent chính tự thực hiện toàn bộ việc khám phá (làm đầy ngữ cảnh của nó bằng đầu ra dài dòng từ mỗi lần đọc file và tìm kiếm), hãy ủy quyền các câu hỏi cụ thể cho subagent:
- "Tìm tất cả các file test cho order service và báo cáo trạng thái mức độ bao phủ của chúng"
- "Truy vết luồng hoàn tiền từ điểm cuối API đến cơ sở dữ liệu và liệt kê tất cả các service trung gian"
- "Xác định tất cả các tích hợp API bên ngoài và cách chúng xử lý lỗi"
Mỗi subagent hoạt động với ngữ cảnh riêng, độc lập. Nó có thể khám phá dài dòng mà không làm ô nhiễm ngữ cảnh của agent chính. Nó trả về một bản tóm tắt có cấu trúc cho bộ điều phối, vốn chỉ giữ lại những phát hiện chính.
Điều này không chỉ là về song song hóa — mà còn là về cách ly ngữ cảnh. Ngữ cảnh của agent chính vẫn sạch sẽ cho việc điều phối ở tầng cao, trong khi subagent xử lý phần khám phá dài dòng.
Tiêm bản tóm tắt giữa các giai đoạn
Khi việc khám phá diễn ra theo từng giai đoạn (Giai đoạn 1: hiểu kiến trúc, Giai đoạn 2: khảo sát các thành phần cụ thể), hãy tóm tắt các phát hiện chính từ Giai đoạn 1 trước khi sinh ra các subagent cho Giai đoạn 2. Tiêm những bản tóm tắt này vào ngữ cảnh ban đầu của các subagent Giai đoạn 2.
Điều này ngăn ngừa vấn đề "khởi động lạnh", nơi các subagent Giai đoạn 2 lặp lại việc khám phá của Giai đoạn 1 vì chúng không được cung cấp các phát hiện trước đó. Nó cũng đảm bảo rằng các agent Giai đoạn 2 có hiểu biết về kiến trúc cần thiết để đặt đúng câu hỏi.
Tóm tắt Giai đoạn 1 (được tiêm vào prompt của các subagent Giai đoạn 2): - Hệ thống tuân theo kiến trúc phân tầng: Controllers → Services → Repositories → Database - Luồng hoàn tiền đi qua: RefundController → RefundProcessor → OrderService → PaymentGateway - Mối quan tâm chính: RefundProcessor không có logic thử lại cho các lỗi API bên ngoài - Mục tiêu Giai đoạn 2: Khảo sát cách xử lý lỗi trong RefundProcessor và PaymentGateway
Lệnh /compact
Claude Code cung cấp lệnh /compact được thiết kế riêng để giảm mức sử dụng ngữ cảnh trong các phiên làm việc kéo dài. Khi ngữ cảnh đầy lên bởi đầu ra khám phá dài dòng — nội dung file, kết quả tìm kiếm, danh sách thư mục — /compact tóm tắt cuộc hội thoại để giải phóng dung lượng trong khi vẫn giữ lại thông tin quan trọng.
Hãy sử dụng /compact một cách chủ động trong các phiên khám phá kéo dài, không chỉ khi bạn chạm giới hạn ngữ cảnh. Đây là một công cụ để duy trì chất lượng ngữ cảnh, không chỉ là số lượng ngữ cảnh.
Phục hồi sau sự cố nhờ bản kê khai trạng thái có cấu trúc
Các phiên khám phá kéo dài có thể thất bại do phiên bị sập, gián đoạn mạng, hoặc cạn kiệt ngữ cảnh. Không có cơ chế phục hồi, toàn bộ tiến độ khám phá sẽ bị mất.
Cách khắc phục là duy trì trạng thái có cấu trúc. Mỗi agent xuất trạng thái hiện tại của nó ra một vị trí file đã biết (một bản kê khai — manifest). Bản kê khai này bao gồm:
- Những gì đã được khám phá (các file đã đọc, các lượt tìm kiếm đã thực hiện)
- Các phát hiện chính đã phát hiện được cho đến nay
- Giai đoạn hiện tại và các bước tiếp theo
- Bất kỳ câu hỏi còn treo hoặc vấn đề chưa giải quyết nào
jsonCopy
{
"sessionId": "explore-order-service-001",
"phase": 2,
"exploredPaths": [
"src/repos/order.ts",
"src/services/order.ts",
"src/services/refund.ts"
],
"keyFindings": {
"architecture": "Layered: Controllers → Services → Repositories → DB",
"criticalIssue": "RefundProcessor has no retry logic for Stripe API failures",
"testCoverage": {"OrderService": "87%", "RefundProcessor": "12%"}
},
"nextSteps": [
"Investigate PaymentGateway error handling",
"Review RefundProcessor test files",
"Check cache invalidation logic in OrderRepository"
]
}Khi tiếp tục lại, bộ điều phối tải bản kê khai này và tiêm nó vào các prompt của agent. Agent sẽ tiếp tục từ nơi nó đã dừng lại mà không lặp lại việc khám phá trước đó.
Khái niệm chính
Suy giảm ngữ cảnh không phải là vấn đề giới hạn token — đó là chuyện mô hình mất khả năng nắm bắt các phát hiện cụ thể khi đầu ra dài dòng tích tụ. File nháp lưu giữ các phát hiện chính bên ngoài ngữ cảnh. Ủy quyền cho subagent cách ly phần khám phá dài dòng. Bản kê khai phục hồi sau sự cố ngăn ngừa mất tiến độ giữa các phiên làm việc.
Bẫy thi
Bẫy thi: Tăng kích thước cửa sổ ngữ cảnh để giải quyết suy giảm ngữ cảnh
Suy giảm ngữ cảnh không phải chuyện hết token. Đó là chuyện mô hình mất dấu các chi tiết cụ thể khi đầu ra dài dòng tích tụ. Một cửa sổ lớn hơn vẫn sẽ bị lấp đầy bởi đầu ra dài dòng.
Bẫy thi: Cho rằng ủy quyền cho subagent chỉ là về song song hóa
Lợi ích chính của việc ủy quyền cho subagent trong khám phá codebase là cách ly ngữ cảnh — giữ ngữ cảnh của agent chính sạch sẽ trong khi subagent xử lý phần khám phá dài dòng.
Bẫy thi: Khởi động lại một phiên làm việc để khắc phục suy giảm ngữ cảnh mà không lưu trạng thái
Khởi động lại làm mất toàn bộ kiến thức đã tích lũy. Hãy dùng file nháp và bản kê khai trạng thái để lưu giữ các phát hiện trước khi khởi động lại, sau đó tiêm chúng vào phiên mới.
Bẫy thi: Chỉ dùng /compact khi chạm giới hạn ngữ cảnh
/compact nên được dùng một cách chủ động trong các phiên làm việc kéo dài để duy trì chất lượng ngữ cảnh, không chỉ như một phương án cuối cùng khi ngữ cảnh đã cạn kiệt.
Tình huống luyện tập
Không tìm thấy câu hỏi luyện tập "q-5-4-001".
Bài tập thực hành
Xây dựng một bộ khám phá codebase chịu được suy giảm ngữ cảnh
Bạn sẽ học được gì
- Nhận diện suy giảm ngữ cảnh là vấn đề chất lượng chú ý, không phải vấn đề giới hạn token
- Triển khai file nháp để lưu giữ các phát hiện chính bên ngoài ngữ cảnh hội thoại
- Sử dụng ủy quyền cho subagent để cách ly ngữ cảnh, không chỉ để song song hóa
- Thiết kế phục hồi sau sự cố qua bản kê khai trạng thái có cấu trúc để tăng khả năng chịu lỗi của phiên làm việc
- Áp dụng tiêm bản tóm tắt giữa các giai đoạn khám phá để ngăn ngừa việc lặp lại do khởi động lạnh
Các bước
Vì sao: Ủy quyền cho subagent chủ yếu là về cách ly ngữ cảnh, không phải song song hóa. Ngữ cảnh của agent chính vẫn sạch sẽ cho việc điều phối tầng cao, trong khi subagent xử lý phần khám phá dài dòng. Điều này trực tiếp ngăn ngừa suy giảm ngữ cảnh bằng cách giữ nội dung file và kết quả tìm kiếm dài dòng ra khỏi ngữ cảnh của bộ điều phối.
Bạn sẽ thấy: Một hàm điều phối sinh ra các subagent với các prompt khảo sát cụ thể, tập trung. Mỗi subagent trả về một bản tóm tắt có cấu trúc (phát hiện chính, đường dẫn file, tên lớp) thay vì đầu ra thô, dài dòng. Ngữ cảnh của bộ điều phối nên vẫn sạch sẽ.
Vì sao: File nháp là biện pháp giảm thiểu chính cho suy giảm ngữ cảnh. Chúng lưu giữ kiến thức bên ngoài ngữ cảnh hội thoại, khiến nó miễn nhiễm với sự chuyển hướng chú ý khiến mô hình nhắc đến các mẫu hình điển hình thay vì tên lớp và đường dẫn file cụ thể mà nó đã phát hiện ra trước đó.
Bạn sẽ thấy: Một agent ghi các phát hiện có cấu trúc vào một file nháp sau mỗi bước khám phá và đọc file nháp vào đầu mỗi bước tiếp theo. File nháp nên chứa tên lớp cụ thể, đường dẫn file, và chuỗi dependency, không phải các bản tóm tắt.
Vì sao: Tiêm bản tóm tắt ngăn ngừa vấn đề khởi động lạnh, nơi các subagent Giai đoạn 2 lặp lại việc khám phá của Giai đoạn 1 vì chúng không được cung cấp các phát hiện trước đó. Nó đảm bảo các agent Giai đoạn 2 có hiểu biết về kiến trúc cần thiết để đặt đúng câu hỏi mà không phải khám phá lại cấu trúc hệ thống.
Bạn sẽ thấy: Một tài liệu tóm tắt Giai đoạn 1 nắm bắt kiến trúc tổng thể, các mối quan tâm chính, và các mục tiêu khảo sát cụ thể cho Giai đoạn 2. Bản tóm tắt này được tiêm vào prompt ban đầu của mọi subagent Giai đoạn 2.
Vì sao: Các phiên khám phá kéo dài có thể thất bại do sập phiên, gián đoạn mạng, hoặc cạn kiệt ngữ cảnh. Không có cơ chế phục hồi, toàn bộ tiến độ sẽ bị mất. Bản kê khai trạng thái có cấu trúc cho phép bộ điều phối tiếp tục từ điểm kiểm tra cuối cùng thay vì khởi động lại từ đầu.
Bạn sẽ thấy: Một file kê khai định dạng JSON chứa ID phiên, giai đoạn hiện tại, đường dẫn đã khám phá, phát hiện chính, và các bước tiếp theo. Khi tiếp tục lại, bộ điều phối tải bản kê khai này và tiêm nó vào prompt của agent để việc khám phá tiếp tục từ nơi đã dừng lại.
Vì sao: Điều này xác nhận rằng biện pháp giảm thiểu bằng file nháp thực sự hiệu quả chống lại suy giảm ngữ cảnh. Triệu chứng có thể quan sát được là mô hình nhắc đến các mẫu hình điển hình thay vì các lớp và đường dẫn cụ thể. Bạn cần xác nhận rằng file nháp ngăn ngừa được sự suy giảm này.
Bạn sẽ thấy: Hai lần chạy so sánh: một lần không có file nháp, nơi agent suy giảm thành các tham chiếu chung chung sau khi khám phá 4-5 module, và một lần có file nháp, nơi agent duy trì được tên lớp và đường dẫn file cụ thể xuyên suốt toàn bộ phiên làm việc.