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

5.1 Context Window Management

Context window management là nền móng của mọi hệ thống Claude chạy ổn định. Mọi hội thoại nhiều lượt, mọi pipeline multi-agent, mọi tác vụ trích xuất tài liệu dài đều phụ thuộc vào thứ bạn cho phép đi vào context window. Làm sai thì hậu quả rất cụ thể: agent hỗ trợ khách hàng quên mất số tiền hoàn, pipeline nghiên cứu rơi mất citation, hệ thống trích xuất mất độ chính xác đúng ở những field quan trọng nhất.

Khi hội thoại dài ra, chiến lược hay gặp là tóm tắt các lượt cũ để giải phóng token budget. Đây là một cái bẫy. Progressive summarisation phá hủy một cách có hệ thống chính những thông tin quan trọng nhất trong hệ thống giao tiếp khách hàng và xử lý dữ liệu: giá trị số, ngày tháng, phần trăm, và các kỳ vọng khách hàng nói ra.

Diễn biến thường là thế này. Khách liên hệ hỗ trợ về một khoản hoàn tiền:

Turn 3: "I'd like a refund of $247.83 for order #8891 placed on March 3rd"

Sau khi tóm tắt, nó thành:

Summary: "Customer wants a refund for a recent order"

Số tiền, mã đơn, ngày đặt — ba dữ kiện agent cần để xử lý hoàn tiền — biến mất. Và đây không phải trường hợp hi hữu. Đó chính là thứ mà summarisation làm với dữ liệu giao dịch theo mặc định.

Cách sửa: persistent case facts block. Trích các dữ kiện giao dịch (số tiền, ngày, mã đơn, trạng thái) ra một block có cấu trúc, được đưa vào mọi prompt, nằm ngoài phần lịch sử bị tóm tắt. Block này không bao giờ bị tóm tắt. Nó tồn tại qua mọi lượt bất kể lịch sử hội thoại bị xử lý thế nào.

{
"caseFactsBlock": {
"customerId": "C-4421",
"issues": [
{
"orderId": "#8891",
"orderDate": "2024-03-03",
"refundAmount": "$247.83",
"status": "pending_refund",
"itemDescription": "Wireless headphones — defective"
}
]
}
}

Với phiên nhiều vấn đề — khách nêu vài chuyện trong cùng một hội thoại — hãy trích và lưu dữ liệu từng issue có cấu trúc vào một lớp context riêng. Mỗi issue có entry riêng với order ID, số tiền và trạng thái. Cách này tránh việc các issue lẫn vào nhau trong lúc tóm tắt.

Model xử lý thông tin ở đầu và cuối input dài một cách đáng tin cậy. Những phát hiện nằm chôn ở giữa một context dài có thể bị bỏ sót hoặc bị coi nhẹ. Đây là hiện tượng đã được ghi nhận rõ ở large language model và nó ảnh hưởng trực tiếp tới cách bạn sắp xếp input tổng hợp.

Cách sửa nằm ở cấu trúc, không nằm ở prompt. Đặt phần tóm tắt các phát hiện chính ở đầu input tổng hợp. Tổ chức kết quả chi tiết bằng section header rõ ràng xuyên suốt. Nếu bạn đưa cho synthesis agent output của ba research subagent, hãy mở đầu bằng section “Key Findings Summary”, rồi mới tới các output chi tiết với ranh giới section rõ ràng.

## Key Findings Summary
- Source A: 12% market growth in renewable sector (2023)
- Source B: Patent filings increased 34% year-on-year
- Source C: Regulatory framework delayed until Q3 2025
## Detailed Findings
### Source A: Market Analysis Report
[Full details here...]
### Source B: Patent Database Analysis
[Full details here...]
### Source C: Regulatory Review
[Full details here...]

Tool result là kẻ ngốn context budget thầm lặng. Một lần tra cứu đơn hàng có thể trả về hơn 40 field: timestamp audit nội bộ, mã kho, ID hãng vận chuyển, định danh trung tâm fulfilment và hàng chục field khác chẳng liên quan gì tới yêu cầu hoàn tiền. Bạn cần 5 field. 35 field còn lại ngốn token ở mọi lượt sau đó, khi lịch sử hội thoại lớn dần.

Hãy trim output tool dài dòng xuống chỉ còn field liên quan, trước khi chúng tích tụ trong context. Bỏ qua bước này thì hệ thống nhiều lượt sẽ từ từ chết đuối trong tool output cũ. Đây không phải thứ có cũng được.

def trim_order_result(raw_result, relevant_fields=None):
if relevant_fields is None:
relevant_fields = [
"order_id", "order_date", "total_amount",
"return_eligible", "item_description"
]
return {k: v for k, v in raw_result.items() if k in relevant_fields}

Việc trim này nên xảy ra trong hook PostToolUse hoặc ngay trong phần cài đặt tool, trước khi kết quả đi vào lịch sử hội thoại. Một khi dữ liệu dài dòng đã nằm trong context, nó ở đó mãi cho mọi lượt sau.

Claude API là stateless. Mỗi request phải mang theo toàn bộ lịch sử hội thoại. Bỏ bớt message cũ thì model mất mạch hội thoại. Không có session state phía server, nên mỗi lượt phải tự mang theo mọi thứ model cần để bám theo câu chuyện.

Điều này tạo ra căng thẳng với giới hạn context: bạn cần lịch sử đầy đủ để giữ mạch, nhưng lịch sử phình ra sau mỗi lượt. Persistent case facts block giải quyết chuyện này bằng cách tách dữ kiện quan trọng khỏi phần tường thuật có thể tóm tắt — bạn tóm tắt mạch hội thoại mà vẫn giữ nguyên mọi chi tiết giao dịch.

Trong hệ thống multi-agent, agent tuyến trên thường trả về chuỗi suy luận dài dòng và nội dung thô mà agent tuyến dưới không cần. Khi một research subagent gửi toàn bộ quá trình suy nghĩ của nó cho synthesis agent có context budget hạn chế, synthesis agent phí token vào phần suy luận nó không dùng được.

Sửa agent tuyến trên để trả về dữ liệu có cấu trúc — dữ kiện chính, citation, relevance score — thay vì nội dung và chuỗi suy luận dài dòng. Yêu cầu subagent đính kèm metadata (ngày tháng, vị trí nguồn, bối cảnh phương pháp) trong output có cấu trúc để tuyến dưới tổng hợp chính xác.

{
"findings": [
{
"claim": "Renewable energy investment grew 12% in 2023",
"source": "IEA World Energy Report 2024",
"sourceUrl": "https://example.com/report",
"relevanceScore": 0.92,
"publicationDate": "2024-01-15"
}
]
}

Token không phải lợi ích duy nhất. Output có cấu trúc từ tuyến trên giúp agent tuyến dưới xử lý findings mà không phải parse lại một đống văn xuôi.

Prompt caching là nửa còn lại của bài toán kinh tế context. Thay vì cắt bớt thứ model nhìn thấy, bạn tránh trả tiền xử lý lại những phần không đổi. Đánh dấu một prefix ổn định bằng breakpoint cache_control, API sẽ lưu phần prefix đã xử lý đó rồi dùng lại ở request kế tiếp, tính phí phần token cache chỉ bằng một phần nhỏ giá input.

Cache khớp từ đầu prompt, theo từng prefix, nên bố cục quyết định bạn có hit hay không. Đặt phần nội dung cố định lên trước: system instruction, tool definition, tài liệu tham chiếu dài. Đặt breakpoint cache_control ở cuối khối tĩnh đó. Phần biến động — message mới nhất của người dùng và mọi thứ đổi theo từng request — đặt sau breakpoint.

Khối tĩnh thuộc về tham số system ở cấp cao nhất, không phải trong messages. Messages API không có role "system" cho input message — messages chỉ nhận lượt "user""assistant".

response = client.messages.create(
model="claude-sonnet-5",
max_tokens=4096,
system=[
{"type": "text", "text": LONG_STATIC_INSTRUCTIONS},
{"type": "text", "text": REFERENCE_DOC,
"cache_control": {"type": "ephemeral"}},
],
messages=[
{"role": "user", "content": dynamic_user_message},
],
)

Sai thứ tự là mất sạch lợi ích. Nếu nội dung động nằm trước khối tĩnh, prefix đổi ở mọi request, không khớp được gì, và mỗi lần gọi đều trả giá đầy đủ. Breakpoint ephemeral sống khoảng năm phút kể từ lần dùng cuối; breakpoint {"type": "ephemeral", "ttl": "1h"} sống một tiếng nhưng chi phí ghi cao hơn. Một request mang tối đa bốn breakpoint.

Một agent hỗ trợ khách hàng xử lý phiên có nhiều vấn đề. Sau vài lượt, agent nói ‘yêu cầu hoàn tiền gần đây của bạn’ thay vì khoản hoàn $247.83 cho đơn #8891. Lịch sử hội thoại đang được tóm tắt giữa các lượt để kiểm soát độ dài context. Cách sửa hiệu quả nhất là gì?

  • A. Tăng kích thước context window để chứa vừa toàn bộ lịch sử hội thoại và không bao giờ cần chạy summarisation
  • B. Lưu toàn bộ lịch sử hội thoại vào database bên ngoài rồi truy xuất các lượt liên quan khi agent cần nhớ lại chi tiết cũ
  • C. Yêu cầu model giữ nguyên văn mọi giá trị số mỗi khi nó tóm tắt lịch sử hội thoại
  • D. Trích dữ kiện giao dịch (số tiền, ngày, mã đơn) vào một persistent case facts block đưa vào mọi prompt, nằm ngoài phần lịch sử bị tóm tắt
Đáp án & giải thích

Đúng: D

  • A — Cách này chỉ hoãn vấn đề chứ không giải quyết — rồi context cũng đầy, và summarisation vẫn phá hủy chi tiết.
  • B — Thêm phức tạp hạ tầng mà không chạm tới vấn đề cốt lõi: dữ kiện nào phải có mặt trong mọi prompt.
  • C — Chỉ dẫn bằng prompt cho việc tóm tắt không đáng tin — model vẫn nén chi tiết theo xác suất.
  • D — Đánh trúng bẫy progressive summarisation bằng cách đảm bảo dữ liệu số và dữ liệu giao dịch quan trọng không bao giờ bị cô đọng lại.

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

Một agent hỗ trợ khách hàng xử lý phiên có nhiều vấn đề. Sau vài lượt, agent nói ‘yêu cầu hoàn tiền gần đây của bạn’ thay vì khoản hoàn $247.83 cho đơn #8891. Lịch sử hội thoại đang được tóm tắt giữa các lượt. Cách sửa hiệu quả nhất là gì?

  • A. Tăng kích thước context window để khỏi phải tóm tắt
  • B. Yêu cầu model giữ nguyên mọi giá trị số khi tóm tắt
  • C. Giữ một case facts block nằm ngoài phần lịch sử bị tóm tắt
  • D. Lưu toàn bộ hội thoại vào database bên ngoài rồi truy xuất lượt liên quan khi cần
Đáp án & giải thích

Đúng: C

  • A sai vì: tăng context window chỉ hoãn vấn đề. Rồi nó cũng đầy, và summarisation vẫn phá hủy chi tiết.
  • B sai vì: chỉ dẫn bằng prompt cho việc tóm tắt không đáng tin. Model vẫn nén chi tiết theo xác suất.
  • C đúng vì: persistent case facts block đánh trúng bẫy progressive summarisation, đảm bảo dữ liệu số và giao dịch quan trọng không bao giờ bị cô đọng.
  • D sai vì: thêm phức tạp hạ tầng mà không chạm tới vấn đề cốt lõi là dữ kiện nào phải có mặt trong mọi prompt.

Một synthesis agent gộp output của ba subagent thành báo cáo cuối. Các phát hiện quan trọng từ subagent thứ hai liên tục bị bỏ sót khỏi bản tổng hợp. Cả ba subagent đều cho output chất lượng tốt. Bạn nên xem chỗ nào trước?

  • A. Vị trí output của subagent thứ hai trong input tổng hợp — có thể nó bị chôn ở giữa
  • B. Context window của synthesis agent — có thể nó đang cạn token
  • C. Prompt của subagent thứ hai — có thể nó format output sai
  • D. Thiết lập temperature của synthesis agent — có thể nó quá sáng tạo nên bỏ qua chi tiết
Đáp án & giải thích

Đúng: A

  • A đúng vì: hiệu ứng lost-in-the-middle khiến model có thể bỏ sót phát hiện nằm giữa input dài. Hãy đặt phần tóm tắt các phát hiện chính lên đầu.
  • B sai vì: vấn đề là attention theo vị trí, không phải dung lượng context.
  • C sai vì: đề đã nói cả ba subagent cho output chất lượng tốt, nên format không phải nguyên nhân.
  • D sai vì: temperature ảnh hưởng độ ngẫu nhiên, không ảnh hưởng thiên lệch attention theo vị trí.

Một tool tra cứu đơn hàng trả về 42 field mỗi kết quả. Agent hỗ trợ chỉ cần 5 field để xử lý hoàn tiền. Sau 8 lượt, phản hồi của agent chậm hơn và kém chính xác hơn. Nguyên nhân gốc là gì?

  • A. Model đang chạm trần output token
  • B. Model cần temperature cao hơn để giữ độ sáng tạo trong hội thoại dài
  • C. Tool tra cứu đơn hàng trả về dữ liệu cũ sau nhiều lần gọi
  • D. Tool result không được trim đang ngốn hết context budget
Đáp án & giải thích

Đúng: D

  • A sai vì: giới hạn output token ảnh hưởng độ dài phần sinh ra, không ảnh hưởng khả năng hiểu. Vấn đề nằm ở phần input context bị tiêu thụ.
  • B sai vì: temperature không giải quyết chuyện ngốn context budget.
  • C sai vì: dữ liệu cũ sẽ gây thông tin sai, chứ không làm phản hồi chậm và kém chính xác trên mọi chủ đề.
  • D đúng vì: mỗi kết quả 42 field không trim đều nằm lại trong lịch sử hội thoại. Qua 8 lượt là 336 field (chỉ 40 trong số đó có ích) đang ngốn token.

Một developer xây agent hỗ trợ nhiều lượt. Họ chỉ đưa 3 message cuối vào mỗi API request để tiết kiệm token. Người dùng phản ánh agent ‘quên’ bối cảnh từ đoạn trước của hội thoại. Vì sao?

  • A. Cơ chế attention của model không xử lý nổi hội thoại dài quá 3 lượt
  • B. Claude API là stateless, nên mọi request phải mang theo lịch sử đầy đủ
  • C. System prompt cần yêu cầu model ghi nhớ các lượt trước
  • D. Developer nên dùng model khác có bộ nhớ dài hạn tốt hơn
Đáp án & giải thích

Đúng: B

  • A sai vì: model xử lý được hội thoại dài. Vấn đề là các message cũ không được gửi đi.
  • B đúng vì: API là stateless. Không có session state phía server. Bỏ message cũ nghĩa là model đơn giản là không có chúng.
  • C sai vì: model không thể nhớ message nó chưa từng nhận. Chỉ dẫn trong prompt không cứu được context thiếu.
  • D sai vì: mọi model qua API đều stateless. Vấn đề nằm ở cách cắt lịch sử của developer, không phải ở model.

Một pipeline nghiên cứu multi-agent có các research agent tuyến trên đẩy findings xuống một synthesis agent tuyến dưới. Synthesis agent cho ra bản tóm tắt mơ hồ, không có con số hay citation cụ thể. Các research agent lại cho output chi tiết và chính xác. Bạn nên đổi gì?

  • A. Cho agent tuyến trên trả về dữ liệu có cấu trúc thay vì chuỗi suy luận dài dòng
  • B. Giảm số agent tuyến trên để synthesis agent có ít input phải xử lý hơn
  • C. Cho synthesis agent context window lớn hơn để chứa hết output nghiên cứu
  • D. Thêm một bước summarisation giữa research và synthesis để nén output nghiên cứu
Đáp án & giải thích

Đúng: A

  • A đúng vì: tối ưu agent tuyến trên đảm bảo tuyến dưới nhận dữ liệu có cấu trúc và liên quan, thay vì chuỗi suy luận dài dòng làm phí context budget.
  • B sai vì: giảm agent là giảm độ phủ nghiên cứu. Vấn đề nằm ở format output, không phải khối lượng.
  • C sai vì: nhiều chỗ chứa hơn cũng vô ích nếu input là chuỗi suy luận dài dòng chôn mất dữ kiện chính.
  • D sai vì: thêm summarisation nhiều khả năng sẽ phá hủy đúng những con số và citation cụ thể, làm vấn đề tệ hơn.