Mọi vấn đề khi sử dụng một mô hình LLM đều có thể quy về tới ngữ cảnh. Quá ít, quá dài (tôi hay gọi là quá nhiều “nhiễu”) đều gây ra những tác dụng phụ không mong muốn.
“Kỹ thuật ngữ cảnh là việc chọn lọc những gì mô hình nhìn thấy để có thể có được kết quả tốt hơn.”
Prompt engineering là một tập con của kỹ thuật ngữ cảnh, harnessing là một nghách nhỏ của kỹ thuật ngữ cảnh. Và nói chung thì kỹ thuật ngữ cảnh nổi lên như một vấn đề gai góc trước mắt khi chúng ta đi vào lãnh vực của các agent. Vấn đề đó dc giải quyết thông qua các tính năng nền tảng tới từ các công cụ như rules, skills… và sau đó là tập hợp các phương pháp / quy trình / kỹ thuật mà chúng ta áp dụng.
Số lượng phương pháp / tính năng / quy trình / công cụ (cũng như số lượng biến thể của chúng) để quản lý ngữ cảnh của các tác nhân AI hiện tại đang tăng rất nhanh. Mục đích của note này là để giới thiệu ngắn gọn về những thứ mà (khả năng là) sẽ không thay đổi quá nhiều sau vài ngày tới.
Ngữ cảnh của coding agent – chúng là gì?
Về cơ bản, phép tạo sinh của LLM đc thực hiện bằng các phép nhân ma trận. Tất cả các ma trận tham gia vào các phép nhân đó chính là ngữ cảnh. Chúng tới từ nhiều nguồn, nhưng chúng ta có thể chia category ra.

Các prompts có thể tái sử dụng
Theo nghĩa rộng, chat, md… gì thì cũng thành prompt. Và hầu hết engine ngữ cảnh nào cũng sẽ gợi ý chúng ta tổ chức một đống các file markdown cho chúng. Và nếu phân loại ra thì ta sẽ có yêu cầu (instruction) và hướng dẫn/quy ước (guidance) – tuy đôi khi sẽ có chồng lấn, nhưng nói chung tư duy theo lối đó sẽ mạch lạc hơn.
Các giao diện ngữ cảnh (context interface)
Tool calling, web search, mcp, skills… có thể dc xếp vào nhóm này. Tôi thậm chí chấp nhận cả sub agent vào nhóm này. Chúng dc description bởi system prompt / hoặc resuable prompt – và gợi ý cho LLM sử dụng (xác suất cả thôi) khi chúng nó thấy hợp lý.
Reasoning để ra quyết định sử dụng một giao diện cũng sẽ sinh ra nhiễu trong ngữ cảnh, và việc một giao diện tống nhiều ngữ cảnh thêm vào trong ngữ cảnh sẵn có cũng ko phải là thứ LLM quyết định được. Vậy nên cần có chiến lược hợp lý để guidance sử dụng giao diện một cách hợp lý cho một yêu cầu cụ thể.
Một trong những giao diện quan trọng nhất đối với một coding agent đó là chính code base. Vậy nên việc code base được tổ chức theo một cách thân thiện với AI cũng là một điều đáng lưu tâm.
Nên cho load thêm context bằng cách nào?
Có thể cho LLM làm – đây hầu như là điều kiện tiên quyết để có thể ủy nhiệm không giám sát công việc cho các agent. Tuy nhiên ta sẽ cần chấp nhận rằng khi đó ta đang chơi trò chơi xác suất về việc LLM có tải ngữ cảnh mà chúng ta mong đợi hay không (suy cho cùng thì 99% cũng ko đồng nghĩa với chắc chắn).
Cũng có thể thủ công (chẳng hạn dùng slash command) – giúp chúng ta điều phối ngữ cảnh tốt hơn, nhưng làm giảm mức độ tự động hóa.
Điều phối bằng phần mềm – một phương án “lai” – có mức độ tự động hóa đáng kể, và cũng loại bỏ đáng kể mức độ không chắc chắn. Chẳng hạn hook của Claude Code.
Giữ bao nhiêu ngữ cảnh thì hợp lý?
Câu trả lời sẽ luôn ko phải là nhiều hay ít, lớn hay nhỏ.
Theo tôi thì sẽ có hai khía cạnh của một ngữ cảnh hợp lý: sự đơn giản – và không chỉ thế, nó còn phải ít “nhiễu”.
Các mô hình hiện tại cho phép hoạt động với cửa sổ ngữ cảnh rất lớn, nhưng điều đó không đồng nghĩa với việc ta có thể tùy tiện tống bất kỳ thứ gì vào đó.
Ít nhiễu là tiên quyết, ngữ cảnh mở rộng có thể được điều phối ở mức độ nhất định bởi chính LLM, nhưng một khi nhiễu xuất hiện trong bối cảnh, nó có thể triệu gọi thêm những lời gọi bổ sung thêm nhiễu, và nhiễu cũng làm suy giảm hiệu năng reasoning trên các mảnh ngữ cảnh đúng trọng tâm.
Ảo tưởng kiểm soát
Không thể nói về kiểm soát ngữ cảnh mà không nói thêm rằng luôn cần nhớ rằng tới cuối cùng, việc bổ sung ngữ cảnh được thực thi như thế nào vẫn hoàn toàn phụ thuộc vào sự diễn giải của LLM – nghĩa là thuần túy bài toán xác suất. Kỹ thuật có thể / và chỉ có thể gây ảnh hưởng tới xác suất.
Claude Code cung cấp những tính năng nào để (hi vọng) kiểm soát (được) ngữ cảnh
Ta có thể hình dung rõ hơn một chút bức tranh về nỗ lực kiểm soát ngữ cảnh, thông qua việc xem xét những tính năng mà một mô hình (và phần mềm kèm theo) cung cấp cho việc đó. Claude Code hẳn là một ứng viên sáng giá.
CLAUDE.md
Tập tin này có thể xếp vào nhóm guidance, nó luôn dc tải mỗi khi bắt đầu một phiên chat – ngon ko cần phải copy paste một đống prompt mồi để build ngữ cảnh ban đầu nữa – trade off là nó có thể chứa nhiễu cho một số phiên (dự đoán rất dễ: hễ dài là có vấn đề rồi) – vậy nên nó chỉ nên chứa các quy ước chung được sử dụng lặp đi lặp lại một cách rất thường xuyên cho toàn bộ dự án. Chẳng hạn:
- Đây là dự án…
- Chạy shell command gì cũng qua docker, đừng có chạy tại host
- Có yarn, đừng có dùng npm
Về cơ bản, các mô hình coding khác con nào cũng sẽ có một tệp giống như vậy, chỉ khác nhau cái tên (và khả năng trong tương lai gần chúng ta sẽ đạt được tới sự thống nhất).
Rules (.claude/rules/)
Rule là những guidance mà sẽ được con người phân lập một cách có chủ ý theo topic, và theo scope (khớp path) – Claude Code sẽ tải chúng khi tải các tệp khớp với path – rất hữu dụng để giảm nhiễu, tránh bloat ngữ cảnh, và cũng rất hữu dụng để giảm kích thước CLAUDE.md.
Một ví dụ tiêu biểu: guidance “Khi viết kịch bản bash, các biến nên được tham chiếu là ${var} chứ không phải $var.” sẽ được cho khớp với path patern */.sh.
Slash command
Slash command (mấy lệnh gạch chéo) về cơ bản là instruction, và được Claude Code tải khi con người ra quyết định sử dụng command – rất thích hợp cho các tác vụ thường dùng – review, commit, test… Claude Code đã cho tiến hóa slash command thành thứ gọi là Skill.
Skills
Skill có thể được sử dụng đa dạng mục đích: guidance, instruction, document… và bởi đa dạng các tác nhân: con người, LLM, subagent của LLM. Về cơ bản thì chúng chứa guidance hoặc instruction mà ta muốn LLM tải khi tự nó nhận thấy là thích hợp để tải, nhưng cũng có thể kích hoạt thủ công như một slash command. Ví dụ:
- Truy cập JIRA (trong guidance sẽ mô tả cách, và ví dụ cho cách, để sử dụng cli nhằm truy cập JIRA)
- Quy ước phát triển React component
- Cách tích hợp API abcxyz
Nội dung: Hướng dẫn, chỉ dẫn, tài liệu, kịch bản,…
Ai quyết định việc tải lên: LLM (dựa trên mô tả kỹ năng) hay Con người
Khi nào nên sử dụng: Ở dạng đơn giản nhất, chức năng này dùng để hướng dẫn hoặc chỉ dẫn mà bạn chỉ muốn “tải lười” khi cần thiết cho nhiệm vụ đang thực hiện. Nhưng bạn có thể đặt bất kỳ tài nguyên và tập lệnh bổ sung nào bạn muốn vào thư mục của kỹ năng và tham chiếu chúng từ thư mục chính SKILL.mdđể tải.
Ví dụ về các trường hợp sử dụng:
- Truy cập JIRA (kỹ năng ví dụ mô tả cách nhân viên có thể sử dụng giao diện dòng lệnh để truy cập JIRA)
- “Các quy ước cần tuân theo đối với các thành phần React”
- “Cách tích hợp API XYZ”
Subagent (~/.claude/agents/)
Subagent là các tiến trình LLM chạy trong cửa sổ ngữ cảnh riêng – đây là điểm tối quan trọng để hình dung về chúng – về cơ bản chúng là agent (tiền tố sub gợi ý nên rằng chúng được spawn bởi tiến trình LLM chính tương tự như cách một process spawn một sub process).
Ngữ cảnh riêng mang ý nghĩa gì? Nghĩa là tiến trình chính có thể định hình nhiệm vụ / công việc, và subagent có thể mở rộng ngữ cảnh để hoàn thành mục tiêu đó mà không gây bloat cửa sổ ngữ cảnh tại tiến trình chính, bên cạnh đó, việc đề ra một mục tiêu công việc đúng trọng tâm thì dễ quản lý chất lượng hơn hẳn với việc triển khai công việc đó, nghĩa là có thể tạo ra một ngữ cảnh ban đầu đầy đủ, phong phú, tập trung, ít nhiễu, chất lượng cao hơn để thực thi hiệu quả hơn, so với khi cho thực thi tại tiến trình chính.
Ví dụ:
- Tạo bộ kiểm thử cho thứ vừa được (hoặc sắp được) build.
- Review mã nguồn bởi một “bên thứ ba”.
MCP Servers
MCP servers là những chương trình máy chủ có khả năng truy vấn vào các nguồn dữ liệu và trả lại cho các agent kết quả truy vấn – điểm quan trọng là chúng nó thốt ra câu trả lời theo giao thức Model Context Protocol. Tác nhân nào dùng? Chắc chắn là LLM rồi.
MCP server là một công cụ hữu hiệu để offloading sự phức tạp thuật toán khi truy vấn vào nguồn dữ liệu ra khỏi quá trình reasoning của LLM. Model sẽ chỉ cần định rõ rằng nó cần truy vấn gì, và nếu có phụ tá (MCP server) có thể hỗ trợ được thì nó có thể ủy nhiệm quá trình truy vấn sang.
MCP không phải bao giờ cũng mang lại hiệu quả cao (chẳng hạn một số phép đo cho thấy cứ để LLM chạy grep để truy vấn file nhiều khi còn tốt hơn một số file system MCP), nhưng về cơ bản nó là một patern đáng cân nhắc.
Một số ví dụ:
- Hiểu chuyện đang xảy ra tại trình duyệt, và điều khiển trình duyệt
- Truy cập knowledge base
Hooks
Hook không phải là guidance hay instruction, chúng là các scripts mà sẽ được kích hoạt – (cái hay là) tại các sự kiện vòng đời một cách chắc chắn – của Claude Code.
Ví dụ:
- Hễ sửa tệp xong thì kiểm tra xem có phải vừa sửa tệp
.jskhông, nếu đúng thì chạy pretier. - Hễ chạy shell scripts thì ghi nhật ký lại (tại đâu đó, để sau này thanh tra).
Plugin
Plugin về cơ bản là một cách để đóng gói và phân phối tất cả những thành phần kể trên (ngoại trừ CLAUDE.md).
Lời kết
Điều gì tệ hơn một ngữ cảnh tệ? Đó là việc ngữ cảnh như thế nào là đẹp không có công thức cụ thể – bởi bản thân việc mô hình phản ứng thế nào với ngữ cảnh đã là một hàm xác suất. Ta chỉ có thể cố gắng làm cho context sao cho rơi vào khu vực trông có vẻ hợp lý nhất – và về cơ bản thì việc này giống như dùng tay để “vo” một làn khói cho cuộn lại thành một quả cầu vậy.