Trong Phần 1, chúng ta đã nắm vững nguyên tắc cốt lõi: Model là người lái, Harness là cỗ xe và vòng lặp Agent Loop nguyên bản. Tuy nhiên, khi một tác nhân AI bắt đầu làm việc trên một dự án thực tế với hàng nghìn dòng code, nó lập tức đâm sầm vào chướng ngại vật lớn nhất của LLM: Sự Phân Tâm Ngữ Cảnh (Attention Dilution) và Tràn Cửa Sổ Ngữ Cảnh (Context Window Bloat).
Nếu bạn liên tục nhồi hàng chục kết quả lệnh shell, hàng nghìn dòng log và toàn bộ tài liệu API vào cùng một danh sách messages[], mô hình sẽ bắt đầu "quên" mục tiêu ban đầu, suy luận lộn xộn và ảo giác cú pháp. Bài viết này sẽ mổ xẻ 3 vũ khí kỹ thuật tối thượng của Claude Code để giải quyết triệt để bài toán này: Cô lập tác vụ con với Subagents, Nạp kỹ năng động theo chuẩn SKILL.md và Cắt tỉa ngữ cảnh Context Compaction.
1. Hiểm Họa Của "Attention Dilution" & Context Bloat
Mặc dù các mô hình ngôn ngữ lớn hiện nay hỗ trợ cửa sổ ngữ cảnh lên tới 200.000 hoặc 1.000.000 token, nghiên cứu của Anthropic (2025–2026) chỉ ra rằng hiệu quả giải quyết vấn đề của mô hình suy giảm mạnh khi ngữ cảnh bị ô nhiễm:
Căn Bệnh 1: Ô Nhiễm Lịch Sử
Noise-to-Signal Collapse
Các kết quả dump dữ liệu lớn (như lệnh grep tìm thấy 500 dòng hoặc stack trace dài) biến ngữ cảnh thành một đống rác nhiễu, đẩy chỉ dẫn quan trọng của User ra xa.
Căn Bệnh 2: Phân Tâm Cơ Chế Chú Ý
Attention Dilution
Cơ chế tự chú ý (Self-Attention) của Transformer phải chia sẻ trọng số cho quá nhiều token không liên quan, dẫn đến việc bỏ sót các ràng buộc nghiệp vụ then chốt.
Căn Bệnh 3: Bùng Nổ Chi Phí & Độ Trễ
Latency & Token Cost
Mỗi lượt gọi LLM sau đó phải gửi lại toàn bộ lịch sử khổng lồ, khiến thời gian phản hồi tăng từ 2 giây lên 30 giây và tiêu tốn ngân sách API gấp 10-20 lần.
2. Subagents: Cơ Chế Khởi Tạo Ngữ Cảnh Sạch (Context Isolation)
Đột phá kiến trúc lớn nhất của Claude Code để xử lý công việc nặng là Subagents. Thay vì để Agent chính tự mình đọc 20 file và chạy 10 script kiểm thử, Agent chính ủy quyền tác vụ đó cho một Subagent chuyên biệt:
Fresh Messages List: Subagent được khởi tạo với một danh sách tin nhắn hoàn toàn mới:
Tự do thực thi sâu: Subagent có thể chạy 10–20 vòng lặp Tool Use (đọc file, tìm kiếm grep, chạy unit test) trong không gian ngữ cảnh riêng biệt của nó mà không hề làm bẩn danh sách tin nhắn của Agent chính.
Thu gọn kết quả trả về: Khi hoàn thành, Subagent chỉ trả về một bản tóm tắt súc tích (1-2 đoạn văn hoặc một JSON kết quả) cho Agent chính. Toàn bộ 50.000 token trung gian bị tiêu hủy ngay khi Subagent đóng lại.
3. Dynamic Skill Loading: Chuẩn Hóa SKILL.md On-Demand
Trong các framework cũ, lập trình viên thường nhồi toàn bộ tài liệu dự án, quy ước code và hướng dẫn công cụ vào System Prompt ngay từ đầu. Điều này làm lãng phí 20.000–30.000 token vô ích trong khi Agent có thể không cần dùng tới.
Claude Code tiên phong phương pháp Dynamic Skill Loading (Nạp kỹ năng động theo nhu cầu):
Bước 1: Khai Báo Danh Mục (Catalog)
Minimal Metadata
Hệ thống chỉ nạp một bảng tóm tắt cực ngắn (Tên kỹ năng + Mô tả 1 dòng) vào System Prompt ban đầu (tiêu tốn chưa tới 200 token).
Bước 2: Kích Hoạt Khi Cần Thiết
On-Demand Injection
Chỉ khi Agent nhận diện thấy bài toán đòi hỏi kỹ năng chuyên sâu (ví dụ: tối ưu SQL hoặc viết test Playwright), Agent mới gọi tool nạp file SKILL.md tương ứng.
Bước 3: Định Dạng Chuẩn SKILL.md
YAML Frontmatter
File SKILL.md chứa metadata ở phần đầu (name, description, required tools) và nội dung Markdown chi tiết gồm hướng dẫn từng bước và code mẫu.
---
name: playwright-testing
description: Hướng dẫn viết và chạy kiểm thử giao diện E2E bằng Playwright Chromium
tools: [bash, view_file, write_to_file]
---
# Playwright Testing Best Practices
1. Luôn sử dụng headless mode khi chạy trong CI/CD.
2. Đặt timeout mặc định 10.000ms cho các thao tác mạng.
3. Chụp ảnh màn hình khi phát hiện lỗi thất bại để debug trực quan.
4. Context Compaction & Quản Trị Bộ Nhớ Dài Hạn (Memory)
Khi phiên làm việc kéo dài hàng giờ với hàng trăm câu hỏi, Claude Code áp dụng kỹ thuật Context Compaction (Cắt tỉa & nén ngữ cảnh):
Tool Result Snip: Tự động rút gọn các output câu lệnh shell cũ. Ví dụ: một kết quả git status từ 10 bước trước chỉ còn giữ lại 3 dòng tóm tắt.
Auto Memory (CLAUDE.md): Agent chủ động ghi chú các phát hiện kiến trúc quan trọng, quyết định kỹ thuật hoặc lỗi đã sửa vào file tài liệu dự án để tái sử dụng vĩnh viễn ở các phiên sau mà không cần hỏi lại người dùng.
5. Sơ Đồ Kiến Trúc Phân Lập Ngữ Cảnh & Nạp Kỹ Năng Động
Sơ đồ sau đây mô tả rõ cơ chế phân tách không gian bộ nhớ giữa Orchestrator chính, các Subagents độc lập và kho kỹ năng SKILL.md:
6. Triển Khai Code Python: SkillLoader & Subagent Spawning
Dưới đây là mã nguồn Python triển khai cơ chế nạp kỹ năng động từ file SKILL.md và khởi tạo Subagent độc lập:
import os
import yaml
classSkillLoader:
"""
Bộ nạp kỹ năng động theo chuẩn SKILL.md của Anthropic Claude Code
"""def__init__(self, skills_dir: str = ".claude/skills"):
self.skills_dir = skills_dir
self.catalog = {}
self.index_skills()
defindex_skills(self):
"""Quét danh mục metadata cực nhẹ (chỉ đọc Frontmatter)"""ifnot os.path.exists(self.skills_dir):
returnfor root, _, files in os.walk(self.skills_dir):
for file in files:
if file.lower() == "skill.md":
path = os.path.join(root, file)
meta, _ = self.parse_skill_file(path)
if meta and"name"in meta:
self.catalog[meta["name"]] = {
"description": meta.get("description", ""),
"path": path
}
defparse_skill_file(self, file_path: str):
"""Bóc tách YAML frontmatter và phần thân Markdown"""with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
if content.startswith("---"):
parts = content.split("---", 2)
if len(parts) >= 3:
meta = yaml.safe_load(parts[1])
body = parts[2].strip()
return meta, body
return {}, content
defget_catalog_summary(self) -> str:
"""Tạo bản tóm tắt danh mục kỹ năng để nạp vào System Prompt ban đầu"""
lines = ["KHO KỸ NĂNG KHẢ DỤNG (Gọi tool load_skill để nạp khi cần):"]
for name, info in self.catalog.items():
lines.append(f"- {name}: {info['description']}")
return"\n".join(lines)
defload_skill_content(self, skill_name: str) -> str:
"""Nạp nội dung chi tiết của kỹ năng vào ngữ cảnh khi Agent yêu cầu"""if skill_name in self.catalog:
_, body = self.parse_skill_file(self.catalog[skill_name]["path"])
return body
return f"Lỗi: Không tìm thấy kỹ năng '{skill_name}'"defspawn_subagent(llm_client, task_prompt: str, available_tools: list) -> str:
"""
Khởi tạo Subagent với danh sách tin nhắn hoàn toàn mới (Fresh messages list)
"""
subagent_messages = [
{"role": "system", "content": "Bạn là một Subagent chuyên trách. Hãy giải quyết tác vụ cụ thể và trả về kết quả tóm tắt súc tích nhất."},
{"role": "user", "content": task_prompt}
]
# Chạy vòng lặp nội tại của SubagentwhileTrue:
resp = llm_client.chat_completion(messages=subagent_messages, tools=available_tools)
subagent_messages.append(resp["message"])
tool_calls = resp["message"].get("tool_calls", [])
ifnot tool_calls:
# Trả về kết quả cuối cùng cho Agent cha, vứt bỏ toàn bộ lịch sử trung gianreturn resp["message"]["content"]
for tc in tool_calls:
# Thực thi công cụ và nạp kết quả vào subagent_messages...pass
💡
TỔNG KẾT BÀI HỌC: Quản trị ngữ cảnh là kỹ năng sống còn của kỹ sư Harness. Bằng cách kết hợp Subagents cô lập và Skill Loading on-demand, bạn giải phóng mô hình khỏi gánh nặng token rác. Trong Phần 3 tiếp theo, chúng ta sẽ bước lên cấp độ quy trình phát triển phần mềm chuẩn mực (Agentic SDLC): Chuyển dịch từ "Vibe Coding" sang "Agentic Engineering", áp dụng mô hình Command → Agent → Skill và kỹ thuật cô lập nhánh lập trình song song bằng Git Worktrees!
⚡
Biên Soạn: Học Viện Giao Dịch — Hàng Hóa Plus
Chuỗi bài giảng Harness Engineering được phát triển dựa trên các nghiên cứu chuyên sâu về kiến trúc tác nhân lập trình AI của Anthropic Claude Code và shareAI-lab.