·

Khi một AI agent (tác tử AI) chỉ làm việc trong một buổi (session) ngắn — vài chục turn, giải quyết một task nhỏ — thì một bản tóm tắt (summary) đơn giản, được cập nhật dần qua incremental summarization, là đủ. Nhưng thực tế của công việc kỹ thuật phần mềm không dừng ở đó. Một dự án refactor lớn có thể kéo dài hai tuần, chạy qua hàng chục session, với hàng trăm quyết định thiết kế, hàng nghìn dòng code thay đổi. Một agent hỗ trợ QA có thể cần nhớ lại các bug đã từng gặp từ ba tháng trước để tránh lặp lại pattern lỗi cũ. Một product manager dùng agent để duy trì tài liệu spec xuyên suốt cả release cycle.

Ở quy mô đó, một bản tóm tắt "phẳng" (flat summary) — nơi mọi thứ từ ngày đầu tiên đến hôm nay đều nằm chung trong một khối text — sẽ sụp đổ theo hai cách. Thứ nhất, nó phình to không kiểm soát: mỗi lần tóm tắt lại, ta phải nhồi thêm thông tin mới vào một khối vốn đã lớn, và cuối cùng bản tóm tắt chính nó lại chiếm quá nhiều token (mã thông tin) trong context window (cửa sổ ngữ cảnh) — thứ nó được sinh ra để tiết kiệm. Thứ hai, nó trộn lẫn thông tin có "tuổi thọ" khác nhau: một quyết định kiến trúc ổn định trong 6 tháng bị xếp cạnh một chi tiết chỉ có ý nghĩa trong 10 phút của session hiện tại, khiến agent khó phân biệt cái gì còn quan trọng và cái gì đã lỗi thời.

Giải pháp là hierarchical context management (quản lý ngữ cảnh theo tầng bậc) — chia trí nhớ của agent thành nhiều tầng (tier), mỗi tầng có "half-life" thông tin khác nhau, và xây một cơ chế để thông tin tự động "thăng cấp" từ tầng chi tiết, dễ bay hơi lên tầng bền vững, cô đọng. Nói cách khác: summary của summary.

The Three-Tier Context Architecture

Mô hình ba tầng là điểm khởi đầu thực tế nhất cho hầu hết dự án, vì nó đủ đơn giản để triển khai bằng tay (hoặc bằng vài dòng script), nhưng đủ mạnh để xử lý các session kéo dài nhiều ngày.

Tier 1 — Raw recent turns (lượt hội thoại gần nhất, giữ nguyên văn): Đây là phần "trí nhớ ngắn hạn" — các message, tool call, tool result gần đây nhất được giữ y nguyên, không nén, không tóm tắt. Lý do giữ nguyên văn: agent cần chi tiết chính xác (tên biến, đường dẫn file, số dòng lỗi, output đầy đủ của một lệnh test) để tiếp tục công việc ngay lập tức mà không bị "tam sao thất bản" qua một lớp tóm tắt. Tier 1 thường chỉ chứa N turn gần nhất (ví dụ 10-20 turn) hoặc giới hạn theo token budget (ví dụ 8.000-15.000 token).

Tier 2 — Rolling session summary (tóm tắt luân chuyển trong phạm vi session): Đây là kết quả của incremental summarization — mỗi khi Tier 1 đầy, các turn cũ nhất bị "đẩy ra" và được nén vào Tier 2. Tier 2 mô tả những gì đã xảy ra trong session hiện tại: các bước đã làm, quyết định đã đưa ra, trạng thái hiện tại của task. Tier 2 sống trong phạm vi một session — khi session kết thúc, nó sẽ được xử lý tiếp (giữ lại, gộp vào Tier 3, hoặc bỏ đi phần không còn giá trị).

Tier 3 — Long-lived project archive (lưu trữ dự án dài hạn): Đây là tầng bền vững nhất — chứa các sự thật (fact) và quyết định (decision) có giá trị xuyên suốt nhiều session, đôi khi xuyên suốt cả đời dự án. Ví dụ: "Dự án dùng PostgreSQL, không dùng MongoDB, quyết định này đã chốt ở tuần 2 sau khi so sánh chi phí vận hành", hoặc "API endpoint /v2/orders đã deprecated, không được đề xuất dùng lại". Tier 3 không quan tâm hôm nay làm gì, nó quan tâm cái gì sẽ còn đúng vào tuần sau, tháng sau.

Điểm mấu chốt của mô hình ba tầng: mỗi tầng có một "chu kỳ nén" (compression cycle) khác nhau. Tier 1 → Tier 2 xảy ra liên tục, gần như mỗi vài turn. Tier 2 → Tier 3 xảy ra hiếm hơn — cuối session, hoặc khi Tier 2 vượt ngưỡng kích thước. Vì tách bạch chu kỳ, ta tránh được việc nén lại thông tin đã ổn định (tốn token vô ích) và tránh được việc thông tin tạm thời bị "đóng băng" quá sớm vào bộ nhớ dài hạn (gây rác trong Tier 3).

Mẹo:
- Đặt ngân sách token rõ ràng cho từng tầng ngay từ đầu (ví dụ Tier 1: 12k token, Tier 2: 3k token, Tier 3: 2k token) — đừng để tầng nào phình tự do.
- Tier 3 nên được review bằng con người (hoặc bằng một agent riêng đóng vai "biên tập viên") định kỳ, vì sai sót ở tầng này sẽ ảnh hưởng đến mọi session sau.
- Đừng vội thêm Tier 3 cho task chỉ kéo dài một buổi làm việc — overhead thiết kế và duy trì tầng lưu trữ chỉ đáng giá khi dự án thực sự kéo dài qua nhiều session.

Designing the Project Archive (Tier 3)

Project archive không phải là một "đống ghi chú", nó là một tài liệu có cấu trúc, được thiết kế để agent (và con người) đọc nhanh, hiểu đúng, và không hiểu sai quyết định nào đã "chốt" và quyết định nào còn mở.

Nguyên tắc thiết kế quan trọng nhất: mỗi mục trong archive phải trả lời được câu hỏi "còn đúng không?" — nếu một thông tin có khả năng thay đổi trong tuần tới, nó không thuộc Tier 3, nó thuộc Tier 2 (hoặc Tier 1).

Dưới đây là một template thực tế cho Project Archive, có thể áp dụng cho hầu hết dự án phần mềm:


## Project Identity
- **Purpose**: One-paragraph description of what this project does and for whom.
- **Repo / Path**: Root path or repo URL.
- **Primary stack**: Language, framework, key infra (e.g., Node.js + Postgres + AWS).
- **Owner / Stakeholders**: Who to check with for scope decisions.

## Architectural Decisions (Stable)
<!-- Only decisions that are settled and unlikely to change. Include the "why", not just the "what". -->
- **DB choice**: PostgreSQL over MongoDB — chosen 2026-03-02 for relational integrity on order data. See ADR-004.
- **Auth**: JWT with 15-min access token + rotating refresh token. Do not switch to session cookies (breaks mobile SDK compatibility).
- **Service boundary**: `billing-service` owns all invoice logic; `orders-service` must not write to the `invoices` table directly.

## Completed Milestones
- [x] 2026-02-10 — Auth service migrated to JWT.
- [x] 2026-03-15 — Order search endpoint rewritten for pagination (P95 latency 1.2s → 180ms).
- [x] 2026-04-01 — Removed legacy `/v1/orders` endpoint after client migration completed.

## Current Project State
- **Active branch/feature**: `feature/invoice-batching`, ~70% complete.
- **Last verified working state**: All tests green as of 2026-06-30 commit `a1b2c3d`.
- **In progress**: Batch invoice generation job — retry logic still WIP.

## Known Issues / Technical Debt
- `legacy/report-generator.js` has no test coverage — treat changes here as high-risk.
- Rate limiter on `/checkout` is hardcoded to 100 req/min; needs to be config-driven before Black Friday traffic.
- Duplicate validation logic exists in both `OrderForm.tsx` and `orderValidator.ts` — flagged for consolidation, not yet scheduled.

## Constraints & Non-Negotiables
- Must remain PCI-DSS compliant — never log full card numbers, even in debug mode.
- No breaking changes to public API without a deprecation window of at least 60 days.
- All DB migrations must be reversible (must ship a `down` migration).

## Patterns & Standards Established
- All new services expose a `/healthz` endpoint returning `{status, version, uptime}`.
- Error responses follow `{ error: { code, message, details } }` shape across all APIs.
- Test files live next to source files as `*.test.ts`, not in a separate `__tests__` tree.

## Do Not Revisit (Closed Decisions)
- Considered GraphQL for the public API in 2026-01, rejected in favor of REST — team lacks GraphQL ops experience, do not re-propose without new evidence.
- Considered switching ORM from Prisma to Drizzle — rejected 2026-04, migration cost judged too high for the benefit. Do not re-raise this quarter.

Vài lưu ý khi thiết kế template cho dự án của bạn:

  • Mục "Do Not Revisit" là phần dễ bị bỏ qua nhất nhưng lại tiết kiệm token nhiều nhất về lâu dài. Không có nó, agent (hoặc thậm chí đồng nghiệp mới join) sẽ liên tục đề xuất lại những ý tưởng đã bị bác bỏ, buộc bạn phải giải thích lại lý do — tốn cả token và tốn thời gian con người.
  • "Known Issues" khác "Current Project State" — issue là thứ tồn tại lâu dài chưa được xử lý (technical debt), state là "hiện tại đang làm gì" và sẽ thay đổi liên tục. Nhầm hai mục này khiến archive nhanh lỗi thời.
  • Ghi ngày (date) cho mọi quyết định quan trọng. Khi agent đọc "quyết định này đã chốt ngày X", nó biết được độ "cũ" của thông tin và có thể ưu tiên thông tin gần đây hơn nếu có mâu thuẫn.

Mẹo:
- Giới hạn Project Archive dưới khoảng 1.500-2.500 token toàn văn — nếu vượt, đó là dấu hiệu cần tách nhỏ theo subsystem (xem phần "Scaling the Hierarchy" ở dưới).
- Dùng checkbox (- [x]) cho milestone để agent (và con người) quét nhanh bằng mắt, không cần đọc câu chữ đầy đủ.
- Mỗi khi archive được cập nhật, cân nhắc giữ lịch sử qua git (archive là một file .md commit vào repo) — bạn sẽ có "diff" của trí nhớ dự án theo thời gian, rất hữu ích khi cần audit lại vì sao một quyết định thay đổi.

The Compression Cascade: How Information Flows Up the Hierarchy

Cascade là quá trình thông tin "leo" từ tầng chi tiết lên tầng cô đọng, theo từng bước nén riêng biệt — không nén trực tiếp từ Tier 1 lên Tier 3, mà luôn đi qua Tier 2 như một bước trung gian.

Bước 1 — Tier 1 → Tier 2 (nén liên tục, trong lúc session đang chạy): Đây chính là incremental summarization đã đề cập ở topic trước. Khi Tier 1 vượt ngưỡng (ví dụ 15.000 token hoặc 20 turn), các turn cũ nhất bị lấy ra, đưa qua một lời gọi tóm tắt (summarization call), và kết quả được gộp (merge) vào Tier 2 hiện có — không phải ghi đè, mà là hợp nhất, giữ lại thông tin cũ còn giá trị và bổ sung thông tin mới.

Bước 2 — Tier 2 → Tier 3 (nén định kỳ, theo trigger): Đây là bước "distill sâu hơn" — không xảy ra liên tục như bước 1, mà xảy ra khi có trigger cụ thể. Ba trigger phổ biến nhất:

  1. Trigger theo thời điểm kết thúc session — khi user đóng phiên làm việc (hoặc sau X phút không hoạt động), hệ thống tự động chạy một lượt "distill" Tier 2 hiện tại, tách ra: (a) phần fact/decision đủ ổn định để đẩy vào Tier 3, và (b) phần chi tiết tạm thời có thể bỏ.
  2. Trigger theo kích thước — khi Tier 2 vượt một ngưỡng token (ví dụ 4.000 token), hệ thống chủ động nén Tier 2 sớm, không chờ đến cuối session, để tránh Tier 2 tự nó trở thành một "flat summary" phình to.
  3. Trigger theo cột mốc — khi một milestone được hoàn thành (ví dụ: một PR được merge, một feature được đánh dấu "done"), đó là điểm tự nhiên để chốt lại các quyết định liên quan thành entry cố định trong Tier 3, vì từ giờ chúng khó có khả năng thay đổi.

Ví dụ cụ thể: Giả sử một agent đang hỗ trợ dev refactor authentication flow. Tier 2 sau 3 giờ làm việc đang chứa: "Đã thử JWT với access token 1h, gặp vấn đề refresh trên mobile, đã đổi sang access token 15 phút + refresh token rotation, đã viết test cho refresh flow, test pass, đang review code với reviewer B, reviewer B yêu cầu thêm rate-limit cho endpoint refresh". Khi session kết thúc (trigger 1), một lời gọi distill được thực hiện với prompt tương tự:

You are compressing a session summary into a project archive.

SESSION SUMMARY (Tier 2):
[...paste current Tier 2 content...]

CURRENT PROJECT ARCHIVE (Tier 3):
[...paste current Tier 3 content...]

Task:
1. Identify which facts/decisions in the session summary are now STABLE
   (unlikely to change, relevant beyond this session) — merge these into
   the appropriate Tier 3 sections (Architectural Decisions, Known Issues,
   Completed Milestones, etc.). Update existing entries rather than
   duplicating if they cover the same topic.
2. Identify which facts are TRANSIENT (only relevant to continue exactly
   where this session left off) — keep these as a short "carry-over" note,
   NOT added to the permanent archive.
3. Output the updated Tier 3 archive in full, plus a 2-3 sentence
   carry-over note for the next session.

Be conservative: only promote to Tier 3 what you're confident will still
be true and relevant in a week.

Kết quả: Tier 3 được cập nhật với "Auth: JWT access token 15 phút + refresh token rotation (đổi từ 1h do vấn đề mobile)" trong mục Architectural Decisions, và "Rate-limit cho endpoint refresh — do reviewer B yêu cầu, chưa triển khai" vào Known Issues. Phần "đang review với reviewer B" — vốn chỉ có ý nghĩa trong ngày hôm đó — không được đưa vào Tier 3, chỉ giữ trong carry-over note ngắn cho session kế tiếp (hoặc bỏ hẳn nếu review đã xong).

Chú ý dòng cuối của prompt: "be conservative". Đây là nguyên tắc sống còn của cascade — nén sai chiều (đẩy thông tin tạm thời lên Tier 3) độc hại hơn nhiều so với nén thiếu (bỏ sót một thông tin có thể lấy lại từ Tier 1/2 nếu cần), vì rác trong Tier 3 sẽ đeo bám project archive vĩnh viễn cho đến khi có ai dọn tay.

Mẹo:
- Luôn cho model thấy Tier 3 hiện tại khi distill Tier 2 → Tier 3, để nó merge/update entry cũ thay vì tạo bản trùng lặp.
- Log lại mỗi lần cascade chạy (timestamp, trigger nào kích hoạt, kích thước trước/sau) — giúp bạn tinh chỉnh ngưỡng trigger theo thời gian.
- Nếu phát hiện Tier 3 bị "rác" (chứa thông tin đã lỗi thời hoặc sai), coi đó là bug cần fix ngay ở prompt distill, không chỉ sửa tay entry đó — vì lỗi sẽ lặp lại ở lần cascade kế tiếp.

Multi-Agent Hierarchical Context: Orchestrator and Subagent Patterns

Khi công việc được chia cho nhiều agent — một orchestrator (điều phối) giao task cho các subagent (tác tử con) chuyên biệt — bài toán context lại thêm một chiều phức tạp mới: orchestrator cần giữ toàn bộ hierarchy (cả ba tầng), nhưng mỗi subagent chỉ nên nhận một phần rất nhỏ, đã được chưng lọc (distilled), phù hợp đúng với task của nó.

Lý do không thể đưa cả ba tầng cho mọi subagent: (1) tốn token — nếu orchestrator gọi 5 subagent, mỗi subagent nhận toàn bộ Tier 1+2+3 thì chi phí token nhân 5 lần cho thông tin phần lớn không liên quan đến task cụ thể của subagent đó; (2) gây nhiễu — một subagent chuyên viết unit test không cần biết chi tiết cuộc thảo luận về chiến lược pricing của sản phẩm, việc nhận thông tin dư thừa làm tăng khả năng model bị phân tâm hoặc suy luận sai (một dạng lost-in-the-middle).

Pattern chuẩn: orchestrator đóng vai "người biên tập" — nó đọc toàn bộ Tier 1/2/3 hiện có, rồi soạn ra một context package (gói ngữ cảnh) riêng cho từng subagent, chỉ chứa thông tin subagent đó cần để hoàn thành task, không hơn.

Dưới đây là một template context-handoff cụ thể, dùng để brief một subagent:

=== CONTEXT PACKAGE FOR SUBAGENT ===

## Project Context (Key Facts)
- Stack: Node.js + Express + PostgreSQL.
- Convention: error responses use { error: { code, message, details } }.
- Constraint: no breaking changes to public API without 60-day deprecation.

## Current Session State
- We are mid-way through adding a batch invoice export feature.
- The export endpoint (`POST /invoices/export`) has been scaffolded but
  has no test coverage yet.

## Your Task
Write unit tests for `src/services/invoiceExportService.ts`, covering:
1. Successful export of a valid date range.
2. Empty result when no invoices match the range.
3. Error handling when the date range exceeds 1 year (should throw
   `InvalidRangeError`).
Use the existing test patterns in `src/services/__tests__/orderService.test.ts`
as a style reference.

## Relevant Files
- src/services/invoiceExportService.ts (implementation, read-only reference)
- src/services/__tests__/orderService.test.ts (pattern reference)
- src/errors/InvalidRangeError.ts (error class to use)

## Constraints
- Do not modify invoiceExportService.ts itself — tests only.
- Do not add new npm dependencies; use the existing test stack (Vitest).
- Keep test file under 200 lines; split into a second file if it grows
  beyond that.

=== END CONTEXT PACKAGE ===

Vài nguyên tắc khi soạn context package:

  • "Project Context" chỉ nên lấy từ Tier 3, không lấy trực tiếp từ Tier 1 — vì Tier 3 đã được lọc để chỉ còn thông tin ổn định, phù hợp đưa cho một subagent chạy độc lập, không có "trí nhớ" về các turn trước.
  • "Current Session State" lấy từ Tier 2, nhưng chỉ phần liên quan đến task được giao — không copy nguyên cả Tier 2.
  • "Your Task" phải cụ thể, có tiêu chí hoàn thành rõ ràng — subagent không có quyền truy cập ngược lại vào lịch sử hội thoại của orchestrator để "hỏi lại cho rõ", nên mọi mơ hồ ở đây sẽ khiến subagent tự suy đoán và dễ lệch hướng.
  • Sau khi subagent hoàn thành, kết quả trả về cho orchestrator cũng nên được nén lại trước khi ghép vào Tier 1/2 của orchestrator — đừng để toàn bộ log chi tiết (bao gồm các lần thử-sai của subagent) tràn ngược vào context chính.

Mẹo:
- Đừng để subagent tự đọc trực tiếp Tier 3 archive dạng file thô nếu file đó dài — orchestrator nên trích đúng phần liên quan, giữ context package dưới ngưỡng vài trăm token khi có thể.
- Đặt tên rõ cho từng section trong context package (giống template trên) để cả model và con người review sau này dễ audit xem subagent đã được brief đúng và đủ chưa.
- Với các subagent lặp lại nhiều lần cho cùng loại task (ví dụ "viết test", "review code"), hãy chuẩn hoá template context package thành một hàm/prompt tái sử dụng, không soạn tay mỗi lần.

Context Inheritance: What Each Tier Passes Down

Câu hỏi thực dụng nhất khi vận hành hệ thống ba tầng: chính xác thì cái gì đi qua ranh giới nào, và cái gì bị lọc bỏ ở mỗi ranh giới?

Từ Tier 1 sang Tier 2 (khi các turn cũ bị đẩy ra):
- Được giữ: kết quả cuối cùng của một hành động (ví dụ: "đã sửa bug X trong file Y bằng cách Z"), quyết định đã đưa ra, lỗi đã gặp và cách xử lý.
- Bị lọc bỏ: toàn bộ nội dung chi tiết của tool call/tool result thô (log dài, output đầy đủ của một lệnh build), các bước dò tìm/thử-sai trung gian không dẫn đến kết quả cuối, các câu chào hỏi/xác nhận không mang thông tin.
- Định dạng: từ hội thoại (dialogue) sang văn xuôi tóm tắt (narrative summary) hoặc danh sách gạch đầu dòng theo timeline.

Từ Tier 2 sang Tier 3 (khi cascade distill chạy):
- Được giữ: chỉ những gì được đánh giá là "stable" — quyết định kiến trúc, milestone hoàn tất, constraint mới phát hiện, pattern/convention mới được thiết lập.
- Bị lọc bỏ: trạng thái "đang làm gì" tạm thời (ai đang review, đang chờ CI chạy), các nhánh suy nghĩ đã bị loại bỏ trong quá trình ra quyết định (không cần giữ "đã cân nhắc A rồi mới chọn B" trừ khi đó là quyết định quan trọng đáng ghi vào "Do Not Revisit"), chi tiết cách làm (implementation detail) không ảnh hưởng đến session tương lai.
- Định dạng: từ narrative summary sang cấu trúc bảng/mục cố định (theo template Project Archive) — Tier 3 nên có cấu trúc cứng hơn Tier 2 vì nó cần được tra cứu (lookup) nhanh, không cần đọc tuần tự.

Từ Tier 3 xuống (khi bắt đầu session mới, hoặc khi brief cho subagent):
- Được truyền xuống: toàn bộ hoặc một phần liên quan của Project Identity, Architectural Decisions, Constraints, và Do Not Revisit — đây là "nền" bắt buộc để bất kỳ agent nào (orchestrator session mới, hoặc subagent) không đi lại vết cũ.
- Bị lọc/không truyền: Known Issues không liên quan đến task hiện tại, milestone lịch sử không liên quan.

Một cách nhìn khác về inheritance: thông tin đi lên (Tier 1→2→3) bị lọc theo tiêu chí "còn quan trọng không?" (importance filter), còn thông tin đi xuống (Tier 3→session mới, hoặc Tier 3→subagent) bị lọc theo tiêu chí "có liên quan đến việc đang làm không?" (relevance filter). Hai bộ lọc này khác nhau, và nhầm lẫn giữa chúng là nguồn lỗi phổ biến — ví dụ giữ một milestone cũ trong context của subagent chỉ vì nó "quan trọng" nhưng thực ra không liên quan gì đến task hiện tại của subagent đó.

Mẹo:
- Viết rõ hai bộ tiêu chí lọc (importance filter cho đi lên, relevance filter cho đi xuống) thành một phần của prompt distill/brief, đừng để model tự suy luận ngầm.
- Định kỳ kiểm tra xem có thông tin "leak" sai chiều không — ví dụ chi tiết implementation tạm thời bị lẫn vào Tier 3, hoặc constraint quan trọng ở Tier 3 bị bỏ sót khi brief subagent.
- Khi không chắc một fact nên ở Tier 2 hay Tier 3, hỏi: "Nếu quay lại dự án này sau 2 tuần nghỉ, tôi có cần biết điều này không?" — nếu có, nó thuộc Tier 3.

Implementing a Session Boundary Protocol

Ranh giới giữa hai session (session boundary) là thời điểm dễ mất thông tin nhất nếu không có quy trình rõ ràng — và cũng là thời điểm tốt nhất để dọn dẹp, cô đọng context trước khi nó tích tụ thành nợ. Dưới đây là một protocol cụ thể, áp dụng được cho cả agent chạy tự động và workflow có con người tham gia.

Session-start (khi bắt đầu một session mới):

  1. Load Tier 3 archive đầy đủ vào system prompt hoặc context đầu tiên — đây là "bối cảnh nền" bắt buộc.
  2. Load carry-over note từ lần distill cuối của session trước (phần thông tin tạm thời được giữ lại có chủ đích, ví dụ "đang giữa việc sửa test X, còn 2 case chưa pass").
  3. Không load lại toàn bộ Tier 1/2 cũ của session trước — chúng đã hoàn thành vai trò và đã được cô đọng, load lại là lãng phí token.
  4. Xác nhận với user (nếu có con người tham gia) bằng một câu tóm tắt ngắn: "Session trước: đã hoàn thành refactor auth, còn lại rate-limit cho refresh endpoint chưa làm. Tiếp tục từ đây?" — điều này giúp bắt lỗi ngay nếu archive bị sai hoặc thiếu.

Trong session: Tier 1 và Tier 2 hoạt động như bình thường theo cascade đã mô tả — không cần can thiệp thêm ở đây trừ khi Tier 2 vượt ngưỡng kích thước (trigger giữa session).

Session-end (khi kết thúc session, hoặc phát hiện sắp hết session — ví dụ user chuẩn bị đóng terminal, hoặc agent tự nhận diện task đã hoàn thành):

  1. Chạy cascade distill Tier 1+Tier 2 → Tier 3 cập nhật, dùng prompt distill đã mô tả ở phần trước.
  2. Sinh carry-over note — 2-4 câu, mô tả chính xác "điểm dừng" để session sau tiếp tục ngay không cần dò lại.
  3. Ghi log/version cho Tier 3 — nếu archive lưu dưới dạng file, commit thay đổi (có message rõ ràng, ví dụ "chore: update project archive — auth refactor decisions").
  4. Xóa/giải phóng Tier 1 và Tier 2 cũ — không cần giữ lại nguyên văn (nếu cần audit sâu, dùng log hệ thống riêng, không giữ trong context hierarchy).
  5. Xác nhận lại với user bản Tier 3 mới trước khi coi là "chốt" — đặc biệt quan trọng khi archive được nhiều agent/nhiều người cùng cập nhật, để tránh một bản distill sai lặng lẽ ghi đè thông tin đúng.

Một tình huống thực tế cần lưu ý: session không phải lúc nào cũng kết thúc "sạch sẽ" — user có thể đóng kết nối đột ngột giữa lúc đang làm. Vì vậy nên có thêm một auto-checkpoint (điểm lưu tự động): sau mỗi N turn hoặc mỗi X phút, chạy nhẹ một bản distill tạm (không cần đầy đủ như session-end) để nếu session bị ngắt bất ngờ, ta vẫn có một bản Tier 2/carry-over gần nhất, không mất trắng toàn bộ tiến độ.

Mẹo:
- Biến session-end distill thành một bước bắt buộc trong quy trình (ví dụ một lệnh/script riêng, không dựa vào việc "nhớ chạy tay"), vì đây là bước dễ bị bỏ quên nhất khi công việc dồn dập.
- Carry-over note nên trả lời được 3 câu hỏi: đang làm gì, đã xong đến đâu, bước tiếp theo cụ thể là gì — tránh viết mơ hồ như "đang tiếp tục công việc".
- Với dự án có nhiều người/nhiều agent cùng cập nhật Tier 3, coi archive như code — review qua pull request nếu có thể, đừng để ghi đè tự do không kiểm soát.

Scaling the Hierarchy: When to Add a Fourth Tier

Mô hình ba tầng đủ dùng cho phần lớn dự án đơn lẻ, kể cả dự án chạy nhiều tháng, miễn là nó có một phạm vi (scope) tương đối gọn. Nhưng có những tình huống ba tầng bắt đầu bộc lộ giới hạn:

  • Dự án rất lớn, nhiều tháng, nhiều subsystem — khi Project Archive (Tier 3) của một dự án có 5-6 subsystem độc lập (ví dụ: billing, auth, notifications, reporting...) thì một archive duy nhất chứa tất cả sẽ phình to trở lại đúng vấn đề mà hierarchy được thiết kế để giải quyết — mọi lần cần context cho subsystem "auth" vẫn phải tải luôn cả phần "billing" không liên quan.
  • Kiến thức xuyên nhiều dự án (cross-project) — một tổ chức có nhiều dự án dùng chung convention, chung hạ tầng, chung bài học (ví dụ: "không dùng thư viện X vì đã gây incident ở dự án Y"). Thông tin này không thuộc về một Project Archive cụ thể nào, nó cần một nơi bền vững hơn cả Tier 3.

Đây là lúc Tier 4 — Organizational/Cross-Project Knowledge Base (cơ sở tri thức tổ chức hoặc xuyên dự án) trở nên hợp lý. Tier 4 có đặc điểm:

  • Phạm vi: không gắn với một project cụ thể, mà là toàn tổ chức hoặc toàn team.
  • Nội dung: convention chung (coding standard, security policy), bài học từ incident/postmortem, danh sách công nghệ đã được đánh giá và quyết định dùng/không dùng ở cấp tổ chức, thông tin về các service chung (internal API, thư viện nội bộ).
  • Chu kỳ cập nhật: rất chậm — có thể tính bằng tuần/tháng, không phải theo session. Thường được cập nhật thủ công hoặc qua một quy trình review nghiêm ngặt hơn Tier 3, vì phạm vi ảnh hưởng rộng hơn nhiều.
  • Cách dùng trong hierarchy: khi bắt đầu một project mới (hoặc một session mới trong project lớn), agent load Tier 4 liên quan (ví dụ chỉ phần convention áp dụng cho stack đang dùng) trước khi load Tier 3 của project cụ thể — Tier 4 đóng vai trò "nền" chung, Tier 3 là "nền" riêng của project.

Với dự án nhiều subsystem, một biến thể khác của "tầng thứ tư" không phải là tổ chức, mà là chia Tier 3 theo subsystem — mỗi subsystem có Project Archive riêng (billing-archive.md, auth-archive.md...), và có thêm một archive cấp cao (root-archive.md) chỉ chứa thông tin liên-subsystem (cross-cutting) như kiến trúc tổng thể, quy ước chung giữa các service. Về bản chất đây vẫn là thêm một tầng phân cấp, chỉ khác là chia theo chiều ngang (subsystem) thay vì theo chiều dọc (thời gian).

Khi nào tầng thứ tư là overkill? Nếu bạn đang cân nhắc thêm Tier 4 chỉ vì Tier 3 "trông có vẻ lớn" nhưng chưa vượt ngưỡng token gây vấn đề thực sự (ví dụ vẫn dưới 3.000-4.000 token), hoặc nếu dự án chỉ có 1-2 subsystem, thì thêm tầng chỉ tạo overhead duy trì (thêm file, thêm quy trình sync) mà không giải quyết vấn đề thực. Dấu hiệu đáng tin để quyết định thêm tầng: Tier 3 hiện tại đã vượt ngưỡng token gây khó đọc/khó tải, HOẶC bạn nhận thấy hơn 50% nội dung Tier 3 không liên quan đến task đang làm trong một session điển hình (dấu hiệu cần chia theo subsystem), HOẶC bạn thấy mình đang copy-paste convention giữa nhiều Project Archive của các dự án khác nhau (dấu hiệu cần Tier 4 cấp tổ chức).

Mẹo:
- Đừng thiết kế Tier 4 "phòng trước" khi chưa có nhu cầu thật — bắt đầu với 3 tầng, chỉ mở rộng khi có dấu hiệu cụ thể đã nêu trên.
- Nếu tổ chức đã có công cụ quản lý tri thức riêng (wiki nội bộ, Confluence, Notion), cân nhắc để Tier 4 trỏ tới đó thay vì tạo hệ thống riêng — agent chỉ cần biết cách truy vấn (query) nguồn đó khi cần, không cần duy trì bản sao.
- Khi chia Tier 3 theo subsystem, luôn giữ một root-archive nhỏ làm "bản đồ" chỉ đến các archive con — tránh tình trạng agent không biết archive nào cần đọc cho task hiện tại.

Summary

Hierarchical context management giải quyết bài toán mà một bản tóm tắt phẳng không thể: giữ trí nhớ agent hoạt động tốt qua nhiều ngày, nhiều session, nhiều task, mà không để context window bị nghẹt hoặc bị lẫn thông tin cũ với mới. Mô hình ba tầng — Tier 1 (raw turn, giữ nguyên văn), Tier 2 (rolling session summary), Tier 3 (project archive dài hạn) — cho phép mỗi loại thông tin được nén ở đúng nhịp độ của nó.

Compression cascade là cơ chế đẩy thông tin đi lên qua các tầng, kích hoạt bởi trigger cụ thể (hết session, vượt ngưỡng kích thước, đạt milestone), luôn ưu tiên "conservative" — chỉ đẩy lên Tier 3 những gì thực sự ổn định. Trong kiến trúc multi-agent, orchestrator giữ toàn bộ hierarchy còn subagent chỉ nhận context package đã chưng lọc, súc tích, đúng phạm vi task. Context inheritance làm rõ nguyên tắc lọc thông tin ở mỗi ranh giới: đi lên lọc theo "còn quan trọng không", đi xuống lọc theo "có liên quan không". Một session boundary protocol rõ ràng — load Tier 3 + carry-over khi bắt đầu, distill và chốt Tier 3 khi kết thúc — đảm bảo không session nào "mất trí nhớ" hoặc để lại rác cho session sau. Và khi dự án đủ lớn, đủ phức tạp, một tầng thứ tư (tổ chức, hoặc chia theo subsystem) mở rộng mô hình mà không phải thiết kế lại từ đầu.

Với một hệ thống hierarchy được thiết kế tốt, agent của bạn có thể "nhớ" một dự án kéo dài hàng tháng với chi phí token gần như không đổi qua thời gian — thay vì phình to vô hạn như khi chỉ dùng một bản tóm tắt duy nhất.