Bỏ qua để đến nội dung

5.4 Codebase Exploration & Context Degradation

Khám phá codebase lớn là một trong những tác vụ ngốn context nhất mà agent chạy trên Claude phải làm. Dù agent đang dò một repository lạ, lần theo chuỗi dependency, hay tìm hiểu hệ thống legacy, các phiên kéo dài đều sinh ra một kiểu hỏng đặc trưng: context degradation. Nó chẳng liên quan gì tới việc cạn token. Model chỉ đơn giản là tuột mất những phát hiện trước đó, khi context đầy dần bởi output khám phá dài dòng.

Context degradation biểu hiện bằng một hành vi rất cụ thể và dễ quan sát: model bắt đầu nói về “pattern điển hình” thay vì các class, method và chuỗi dependency cụ thể mà nó đã phát hiện ở đầu phiên. Sau khi soi vài module, agent có thể nói “cái này theo repository pattern điển hình” thay vì “class OrderRepositorysrc/repos/order.ts cài interface Repository<T> với caching riêng trong method findById”.

Chuyện này xảy ra vì:

  1. Mỗi bước khám phá sinh ra output dài dòng (nội dung file, kết quả tìm kiếm, danh sách thư mục).
  2. Output đó tích tụ trong context hội thoại.
  3. Các phát hiện chính xác từ sớm bị đẩy sâu vào context, trong khi output dài dòng gần đây chiếm ưu thế.
  4. Attention của model dịch về phía output mới và nó tuột mất các tham chiếu cụ thể từ trước.

Điểm mấu chốt: context degradation không phải vấn đề giới hạn token. Tăng context window không sửa được. Model không hề hết chỗ. Nó đang mất dấu các chi tiết cụ thể khi chúng bị chôn dưới output mới hơn và dài dòng hơn.

Cách hạn chế chính cho context degradation là scratchpad file. Agent ghi các phát hiện chính ra file rồi tham chiếu lại file đó cho những câu hỏi sau. Cách này giữ kiến thức bên ngoài context hội thoại, nên nó miễn nhiễm với context degradation.

# 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 nhắc lại phát hiện cũ, nó đọc scratchpad file thay vì trông vào context hội thoại. Hãy coi đây là chiến lược chủ động ngay từ đầu, không phải chiêu cứu vãn khi mọi thứ đã xuống cấp — agent cần được yêu cầu duy trì scratchpad file ngay từ lúc mở phiên khám phá dài.

Spawn subagent cho từng tác vụ điều tra cụ thể là chiến lược hạn chế lớn thứ hai. Thay vì agent chính tự khám phá tất cả (và nhồi context của nó bằng output dài dòng từ mọi lần đọc file và tìm kiếm), hãy giao từng câu hỏi cụ thể cho subagent:

  • “Find all test files for the order service and report their coverage status”
  • “Trace the refund flow from API endpoint to database and list all intermediate services”
  • “Identify all external API integrations and their error handling patterns”

Mỗi subagent chạy trên context riêng, tách biệt. Nó có thể khám phá dài dòng thoải mái mà không làm bẩn context của agent chính. Nó trả về một bản tóm tắt có cấu trúc cho coordinator, và coordinator chỉ giữ lại các phát hiện chính.

Nhiều người đọc ra ngay chuyện chạy song song; nhưng giá trị thật nằm ở context isolation. Context của agent chính giữ được sự sạch sẽ để điều phối ở tầm cao, còn subagent gánh phần khám phá dài dòng.

Khi việc khám phá chia theo phase (Phase 1: hiểu kiến trúc, Phase 2: soi từng component), hãy tóm tắt các phát hiện chính của Phase 1 trước khi spawn subagent Phase 2. Tiêm bản tóm tắt đó vào context ban đầu của các subagent Phase 2.

Cách này tránh vấn đề “cold start”, khi subagent Phase 2 lặp lại việc khám phá của Phase 1 chỉ vì không được cho biết kết quả trước đó. Nó cũng đảm bảo agent Phase 2 có đủ hiểu biết kiến trúc để đặt đúng câu hỏi.

Phase 1 Summary (injected into Phase 2 subagent prompts):
- The system follows a layered architecture: Controllers → Services → Repositories → Database
- The refund flow passes through: RefundController → RefundProcessor → OrderService → PaymentGateway
- Key concern: RefundProcessor has no retry logic for external API failures
- Phase 2 objective: Investigate error handling in RefundProcessor and PaymentGateway

Claude Code có sẵn lệnh /compact dành riêng cho việc giảm mức tiêu thụ context trong các phiên kéo dài. Khi context đầy ứ output 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 hội thoại để giải phóng chỗ mà vẫn giữ lại thông tin chính.

Hãy dùng /compact chủ động trong phiên khám phá dài, đừng đợi tới lúc chạm trần context. Nó sinh ra để bảo vệ chất lượng context, không chỉ số lượng.

Khôi phục sau crash bằng structured state manifest

Phần tiêu đề “Khôi phục sau crash bằng structured state manifest”

Phiên khám phá dài có thể hỏng vì crash, mất mạng, hoặc cạn context. Không có cơ chế khôi phục thì toàn bộ tiến độ khám phá mất sạch.

Cách sửa là lưu state có cấu trúc. Mỗi agent xuất state hiện tại ra một vị trí file đã biết (manifest). Manifest này gồm:

  • Đã khám phá những gì (file đã đọc, tìm kiếm đã chạy)
  • Các phát hiện chính tới thời điểm này
  • Phase hiện tại và bước kế tiếp
  • Mọi câu hỏi còn treo hoặc vấn đề chưa xử lý
{
"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 resume, coordinator nạp manifest này và tiêm vào prompt của agent. Agent làm tiếp từ chỗ đã dừng mà không lặp lại phần khám phá cũ.

Một agent hỗ trợ năng suất developer đang khám phá một codebase lạ. Sau khi soi vài module, nó bắt đầu nói về ‘repository pattern điển hình’ thay vì tên class và chuỗi dependency cụ thể mà nó đã phát hiện trước đó. Cách hạn chế hiệu quả nhất là gì?

  • A. Tăng context window của model để giữ được nhiều output khám phá hơn hẳn trong suốt quá trình
  • B. Cho agent duy trì scratchpad file ghi lại các phát hiện chính và tham chiếu lại cho những câu hỏi sau
  • C. Khởi động lại phiên với context sạch và yêu cầu agent khám phá codebase hiệu quả hơn lần này
  • D. Nạp sẵn toàn bộ cấu trúc codebase vào context ban đầu để việc khám phá đỡ phải tìm lại
Đáp án & giải thích

Đúng: B

  • A — Context degradation không phải chuyện cạn token — đó là chuyện model tuột mất phát hiện cũ khi output dài dòng tích tụ. Window lớn hơn không sửa được.
  • B — Scratchpad file giữ kiến thức bên ngoài context hội thoại, chống trực tiếp context degradation bằng cách giữ các phát hiện quan trọng luôn truy cập được bất kể context ra sao.
  • C — Khởi động lại là mất sạch kiến thức đã tích luỹ mà không chạm tới gốc rễ context degradation. Không có scratchpad file thì đâu lại vào đấy.
  • D — Cách này ngốn context budget ngay trước khi khám phá và không giải quyết việc xuống cấp trong phiên. Vấn đề là output dài dòng tích tụ, không phải thiếu context ban đầu.

Năm câu trắc nghiệm theo format đề thi về Codebase Exploration & Context Degradation. Chọn đáp án trước, rồi mở phần giải thích.

Một agent hỗ trợ năng suất developer đang khám phá một codebase lạ. Sau khi soi vài module, nó bắt đầu nói về ‘repository pattern điển hình’ thay vì tên class và chuỗi dependency cụ thể mà nó đã phát hiện trước đó. Cách hạn chế hiệu quả nhất là gì?

  • A. Cho agent giữ scratchpad file ghi lại các phát hiện chính và đọc lại sau
  • B. Tăng context window của model để chứa nhiều output khám phá hơn
  • C. Khởi động lại phiên và yêu cầu agent khám phá hiệu quả hơn
  • D. Nạp sẵn toàn bộ cấu trúc codebase vào context ban đầu trước khi bắt đầu khám phá
Đáp án & giải thích

Đúng: A

  • A đúng vì: scratchpad file giữ kiến thức bên ngoài context hội thoại, chống trực tiếp context degradation bằng cách giữ các phát hiện quan trọng luôn truy cập được bất kể context ra sao.
  • B sai vì: context degradation không phải chuyện cạn token. Đó là chuyện model tuột mất phát hiện cũ khi output dài dòng tích tụ. Window lớn hơn rồi cũng đầy ứ output dài dòng.
  • C sai vì: khởi động lại là mất sạch kiến thức đã tích luỹ mà không chạm tới gốc rễ. Không có scratchpad file thì đâu lại vào đấy.
  • D sai vì: nạp sẵn ngốn context budget ngay trước khi khám phá và không giải quyết việc xuống cấp trong phiên.

Một agent khám phá codebase giao việc điều tra cho ba subagent. Context của agent chính giữ được sạch trong khi subagent gánh phần đọc file và tìm kiếm dài dòng. Lợi ích chính của pattern giao việc này là gì?

  • A. Chạy song song — ba subagent điều tra cùng lúc, giảm thời gian thực tế
  • B. Giảm chi phí — subagent dùng model tier rẻ hơn cho việc đọc file thông thường
  • C. Context isolation — context của agent chính không bị nhồi output khám phá dài dòng
  • D. Xử lý lỗi — subagent hỏng không làm sập agent chính
Đáp án & giải thích

Đúng: C

  • A sai vì: chạy song song là lợi ích phụ, còn giá trị chính khi khám phá codebase là giữ context agent chính sạch.
  • B sai vì: chọn model tier là chuyện riêng. Giao việc để cô lập context vẫn áp dụng bất kể mỗi agent chạy model nào.
  • C đúng vì: giao việc cho subagent khi khám phá codebase trước hết là để context isolation. Agent chính giữ context điều phối tầm cao, còn subagent gánh output dài dòng trong context riêng của chúng.
  • D sai vì: xử lý lỗi là lợi ích của structured error propagation, không phải mục đích chính của việc giao việc ở đây.

Một agent hoàn tất Phase 1 của việc khám phá codebase (tổng quan kiến trúc) và sắp spawn subagent cho Phase 2 (soi chi tiết từng component). Giữa hai phase nên có gì?

  • A. Subagent nên bắt đầu từ đầu và khám phá lại kiến trúc để kiểm chứng kết quả Phase 1
  • B. Kết quả Phase 1 nên được tóm tắt và tiêm vào prompt của subagent Phase 2
  • C. Output dài dòng của Phase 1 nên được chuyển thẳng cho subagent Phase 2 để có context đầy đủ
  • D. Subagent Phase 2 nên đọc log hội thoại Phase 1 từ nơi lưu trữ
Đáp án & giải thích

Đúng: B

  • A sai vì: khám phá lại kiến trúc là làm trùng việc và phí context budget của Phase 2 cho thứ đã biết.
  • B đúng vì: tiêm summary cho agent Phase 2 bối cảnh kiến trúc mà không kèm output dài dòng. Cách này tránh vấn đề cold start khi agent Phase 2 lặp lại việc khám phá của Phase 1.
  • C sai vì: chuyển output dài dòng là phá hỏng ý nghĩa của context isolation. Agent Phase 2 sẽ khởi động với context đã đầy nhiễu từ Phase 1.
  • D sai vì: log hội thoại đầy đủ chứa output khám phá dài dòng làm bẩn context Phase 2. Bản tóm tắt mới là cơ chế chuyển giao đúng.

Trong một phiên khám phá codebase kéo dài, context của agent đang đầy dần bởi nội dung file và kết quả tìm kiếm. Khi nào nên dùng lệnh /compact?

  • A. Chỉ khi agent chạm trần context và không xử lý được input mới nữa
  • B. Chỉ khi agent tự báo rằng nó đang mất dấu các phát hiện trước đó
  • C. Vào cuối phiên để tạo một bản tóm tắt sạch cho phiên sau
  • D. Chủ động trong phiên để giữ chất lượng context trước khi chạm giới hạn
Đáp án & giải thích

Đúng: D

  • A sai vì: đợi tới lúc chạm trần nghĩa là agent đã xuống cấp từ trước đó rồi. /compact nên dùng trước khi chất lượng đi xuống.
  • B sai vì: tới lúc agent tự báo mất dấu thì context degradation đã ảnh hưởng output một lúc lâu rồi. Dùng chủ động sẽ tránh được chuyện này.
  • C sai vì: chỉ dùng /compact ở cuối là bỏ lỡ cơ hội giữ chất lượng suốt phiên. Tới cuối thì đã xuống cấp mất rồi.
  • D đúng vì: /compact là công cụ giữ chất lượng context một cách chủ động, không chỉ là chuyện số lượng. Dùng nó trong phiên dài trước khi xuống cấp bắt đầu.

Một phiên khám phá codebase crash sau 45 phút điều tra. Agent đã phát hiện được các chuỗi dependency quan trọng và những lỗ hổng test coverage. Không có cơ chế khôi phục nào thì chuyện gì xảy ra?

  • A. Model giữ lại các phát hiện từ phiên đó và có thể làm tiếp ở phiên mới
  • B. Toàn bộ tiến độ khám phá mất sạch và phải làm lại từ đầu
  • C. Các phát hiện được lưu trong bộ nhớ dài hạn của model cho các phiên sau
  • D. Lịch sử hội thoại được tự động lưu và có thể resume
Đáp án & giải thích

Đúng: B

  • A sai vì: Claude API là stateless. Không có bộ nhớ session nào tồn tại qua các lần gọi API hay các phiên riêng biệt.
  • B đúng vì: không có cơ chế khôi phục sau crash (structured state manifest) thì mất sạch tiến độ. Chính vì vậy agent nên xuất state ra file manifest ở các checkpoint đều đặn.
  • C sai vì: LLM không có bộ nhớ dài hạn xuyên phiên. Mỗi phiên bắt đầu từ đầu trừ khi state được lưu lại một cách tường minh.
  • D sai vì: lịch sử hội thoại không tự động được lưu khi dùng qua API. Phải lưu state tường minh (file manifest).