·

Nếu toàn bộ cuộc hội thoại (session) là đơn vị tối ưu ở tầm vĩ mô, thì turn — một lượt gồm tin nhắn của người dùng và phản hồi của model — chính là đơn vị tối ưu ở tầm vi mô. Mọi token bị lãng phí ở cấp độ turn không mất đi sau lượt đó; nó bị nhân lên qua tất cả các turn còn lại của session, vì lịch sử hội thoại (conversation history) tích lũy dần và được gửi lại hoặc được model "chú ý" lại ở mỗi lượt tiếp theo.

Một agent kỹ sư phần mềm debug qua 15 turn, mỗi turn lãng phí 200 token vì cách hỏi lan man hoặc dán dư context — con số đó không phải là 200 token một lần, mà là 200 token nhân với số turn còn lại nhân với việc lịch sử đó tiếp tục được carry-forward. Đây là lý do kỷ luật ở cấp turn quan trọng không kém, thậm chí quan trọng hơn, so với chiến lược quản lý toàn cuộc hội thoại.

Chủ đề này đi sâu vào bản thân turn: cấu tạo chi phí token của nó, các nguyên tắc viết input gọn, cách ràng buộc output của model, cách sắp thứ tự các turn để tiết kiệm, và một case audit thực tế trước/sau.

Turn là đơn vị của tối ưu hóa

Một turn không chỉ là "câu hỏi của bạn". Về mặt chi phí token, một turn trong hệ thống dùng LLM (large language model) bao gồm ba thành phần cộng dồn:

  1. Input tokens của người dùng — nội dung bạn gõ hoặc agent gửi lên trong lượt này.
  2. Lịch sử hội thoại tích lũy — trong các hệ thống dùng API theo kiểu stateless (không lưu trạng thái phía server), toàn bộ lịch sử các turn trước phải được gửi lại kèm mỗi request mới, vì model không "nhớ" gì ngoài context window (cửa sổ ngữ cảnh) được truyền vào. Ngay cả trong các chat UI có trạng thái (stateful), model vẫn phải "đọc lại" và chú ý (attend) đến toàn bộ lịch sử đó để hiểu turn hiện tại — về bản chất tính toán, chi phí attention vẫn tăng theo độ dài lịch sử.
  3. Output tokens của model — phần model sinh ra để trả lời.

Điểm mấu chốt: thành phần số 2 — lịch sử tích lũy — không nằm trong tầm kiểm soát trực tiếp của turn hiện tại, nhưng nó là hậu quả dồn lại của mọi turn trước đó. Nếu turn 1 dán vào 3.000 token log không cần thiết, thì từ turn 2 đến turn N, bạn đều phải "trả tiền" lại cho 3.000 token đó, trừ khi bạn chủ động cắt gọt (đây là lý do chủ đề trước về quản lý vòng đời hội thoại và chủ đề sau về checkpointing liên quan chặt với turn-level discipline).

Vì vậy, tối ưu một turn không chỉ là tối ưu turn đó — nó là đầu tư giảm chi phí cho tất cả các turn còn lại của session. Một turn dư 500 token ở giữa một session dài 20 turn có thể gây lãng phí gấp nhiều lần một turn dư 500 token ở cuối session, vì phần dư đó còn bị "kéo theo" qua nhiều lượt sau.

Cách nhìn thực tế: hãy tưởng tượng chi phí turn là hàm của hai biến — chi phí "biên" (marginal) của riêng turn đó, và chi phí "di sản" (legacy) nó để lại cho các turn sau. Một prompt dài nhưng không để lại rác trong lịch sử (ví dụ bạn xóa nó khỏi context sau khi dùng xong) chỉ tốn chi phí biên. Một prompt ngắn nhưng để lại một đoạn context mơ hồ, khiến các turn sau phải hỏi lại để làm rõ, thực ra tốn chi phí di sản cao hơn nhiều.

Mẹo:
- Trước khi gửi một turn, tự hỏi: "Nội dung này có cần tồn tại trong lịch sử ở turn thứ 10 không, hay chỉ cần dùng một lần rồi bỏ?" Nếu chỉ dùng một lần, tìm cách tách nó ra khỏi lịch sử được giữ lại (ví dụ xử lý ngoài luồng chat, hoặc yêu cầu model tóm tắt rồi xóa bản gốc).
- Theo dõi độ dài lịch sử theo turn (nếu công cụ cho phép xem token count) để phát hiện sớm turn nào đang "phình" bất thường.

Tối ưu Input của bạn: Nguyên tắc viết Message gọn (Lean Message Principles)

Nguyên tắc 1: Một câu hỏi hoặc một nhiệm vụ cho mỗi turn

Một lỗi rất phổ biến, đặc biệt với người mới làm việc với AI agent, là dồn nhiều yêu cầu không liên quan vào một turn duy nhất để "tiết kiệm thời gian gõ". Kết quả thường ngược lại với mong đợi: model buộc phải cố gắng trả lời đầy đủ tất cả các phần, dẫn đến câu trả lời dài, lan man, và khó verify (kiểm chứng) vì bạn phải tách từng phần ra để đánh giá đúng/sai riêng biệt.

Ví dụ "bad" — một turn dồn 4 yêu cầu khác nhau:

Bạn xem giúp function calculateDiscount này có bug không, rồi viết thêm unit test cho nó, à mà cũng nhân tiện refactor luôn để dùng TypeScript strict mode, và giải thích luôn tại sao ban đầu code này lại viết theo kiểu callback thế này có ổn không.

Model sẽ phải trả lời cả bug, cả test, cả refactor, cả giải thích lịch sử thiết kế — trong một khối output dài, đan xen, khó tách bạch. Nếu bạn chỉ muốn xác nhận bug trước khi quyết định có cần refactor hay không, bạn đã lãng phí toàn bộ output tokens cho phần test và refactor có thể hóa ra không cần thiết.

Ví dụ "good" — tách thành turn riêng, chỉ hỏi một việc:

Xem function calculateDiscount dưới đây và cho biết: có bug logic nào không? Chỉ trả lời có/không kèm dòng code gây lỗi, không cần sửa hay giải thích thêm.

Turn tiếp theo (chỉ nếu cần) mới hỏi về unit test, và turn sau nữa mới hỏi về refactor — mỗi turn có phạm vi rõ, output ngắn, dễ verify, và bạn có quyền dừng sớm nếu câu trả lời của turn 1 khiến các turn sau không còn cần thiết (ví dụ: không có bug thì không cần hỏi thêm).

Nguyên tắc này đặc biệt quan trọng với QA engineer khi viết bug report qua chat với agent: đừng hỏi "kiểm tra tính năng login, tính năng logout, và cả tính năng reset password luôn" trong một turn — tách ra ba turn, mỗi turn một tính năng, để log lỗi (nếu có) rõ ràng và không bị trộn lẫn.

Nguyên tắc 2: Cung cấp context một lần, sau đó tham chiếu lại

Một nguồn lãng phí token cực lớn trong hội thoại nhiều lượt là việc dán lại toàn bộ background/context ở mỗi turn "cho chắc". Thói quen này xuất phát từ lo sợ model "quên" — nhưng nếu context đã nằm trong lịch sử hội thoại, model vẫn còn quyền truy cập nó, bạn không cần lặp lại.

Ví dụ "before" (lặp lại context mỗi turn):

Turn 3: "Dự án của chúng ta dùng Node.js 18, framework Express, database Postgres qua Prisma ORM, deploy trên AWS ECS. Bây giờ giúp tôi viết endpoint GET /users có phân trang."

Turn 4: "Dự án của chúng ta dùng Node.js 18, framework Express, database Postgres qua Prisma ORM, deploy trên AWS ECS. Giờ viết thêm endpoint POST /users."

Mỗi turn lặp lại nguyên một đoạn mô tả stack — tốn token, và nếu paste không nhất quán (ví dụ quên một chi tiết) còn gây nhiễu, dễ khiến model hiểu sai là stack đã đổi.

Ví dụ "after" (cung cấp một lần, tham chiếu lại):

Turn 3: "Dự án dùng Node.js 18 + Express + Postgres (qua Prisma) + deploy AWS ECS. [Ghi nhớ thông tin này cho các turn sau.] Viết endpoint GET /users có phân trang."

Turn 4: "Dùng đúng stack đã nêu ở turn 3, viết thêm endpoint POST /users."

Cách tốt hơn nữa trong các hệ thống hỗ trợ system prompt hoặc pinned message (tin nhắn được "ghim" — luôn nằm ở đầu context bất kể lịch sử dài bao nhiêu): đặt toàn bộ thông tin stack/dự án vào system prompt một lần, và mọi turn sau chỉ tập trung vào yêu cầu cụ thể, không cần nhắc lại gì cả. Nhiều framework agent (ví dụ khi bạn tự dựng orchestration qua API) cho phép tách riêng "system context" khỏi "user turns" — hãy dùng đúng cơ chế này thay vì nhúng lặp lại context vào từng user message.

Với các agent code như Claude Code, cơ chế tương đương là file cấu hình dự án (như CLAUDE.md trong repo này) — thông tin về stack, convention, quy tắc commit chỉ cần khai báo một lần trong file, agent tự đọc lại mỗi khi cần, bạn không phải gõ lại trong mỗi turn chat.

Nguyên tắc 3: Dùng input có cấu trúc cho nhiệm vụ có cấu trúc

Khi bản chất nhiệm vụ đã có cấu trúc — danh sách yêu cầu, tập test case, bảng so sánh — hãy trình bày bằng cấu trúc tương ứng (bullet list, table, khối JSON/YAML, danh sách đánh số) thay vì viết thành đoạn văn xuôi dài dòng. Điều này vừa giảm số token (văn xuôi thường dùng nhiều từ nối, từ đệm hơn cấu trúc liệt kê), vừa giảm sự mơ hồ khiến model phải "đoán" ranh giới giữa các ý.

Ví dụ "before" — đoạn văn liệt kê yêu cầu dưới dạng prose:

"Chúng tôi cần một API cho phép người dùng đăng ký tài khoản, trong đó email phải là duy nhất trong hệ thống và phải đúng định dạng email, mật khẩu phải tối thiểu 8 ký tự và có ít nhất một chữ số, ngoài ra tên người dùng không được để trống và không được vượt quá 50 ký tự, và cuối cùng sau khi đăng ký thành công thì phải gửi email xác nhận."

Đoạn này chứa 4 yêu cầu riêng biệt, bị nén vào một câu dài, model phải tự tách ra và có rủi ro bỏ sót một điều kiện.

Ví dụ "after" — cấu trúc lại thành danh sách:

Yêu cầu cho API đăng ký tài khoản:
- email: duy nhất trong hệ thống, đúng format email
- password: tối thiểu 8 ký tự, chứa ít nhất 1 chữ số
- username: không rỗng, tối đa 50 ký tự
- sau khi đăng ký thành công: gửi email xác nhận

Cùng lượng thông tin, nhưng ngắn hơn về token, và mỗi điều kiện là một dòng độc lập — model (và cả người review sau này) dễ dàng đối chiếu từng điều kiện với code sinh ra, không lo bị bỏ sót.

Với product manager viết acceptance criteria hay QA viết test case, nguyên tắc này áp dụng trực tiếp: viết theo dạng Given/When/Then hoặc bảng test case (input – expected output) thay vì kể chuyện bằng văn xuôi.

Mẹo (áp dụng cho cả 3 nguyên tắc):
- Trước khi gửi turn, đọc lại một lượt: turn này có đang gánh nhiều hơn một việc không? Có đang lặp lại thông tin đã nói không? Có đang mô tả thứ vốn có cấu trúc bằng văn xuôi không?
- Nếu dùng agent code có file cấu hình dự án (CLAUDE.md, AGENTS.md...), hãy chuyển toàn bộ context lặp đi lặp lại vào đó — coi nó như "system prompt bền vững" của bạn.
- Khi liệt kê yêu cầu/test case, luôn ưu tiên bảng hoặc danh sách có nhãn rõ (label) hơn là câu văn ghép nhiều mệnh đề bằng "và", "ngoài ra", "cũng như".

Tối ưu Output của Model: Ràng buộc phản hồi rõ ràng

Một prompt không ràng buộc gì về hình thức trả lời thường khiến model có xu hướng viết dài, rào trước đón sau (hedging), và giải thích lại những phần không cần giải thích — vì mặc định model được huấn luyện để "hữu ích và đầy đủ" khi không có chỉ dẫn ngược lại. Vấn đề là output tokens trong hầu hết các hệ thống định giá theo token đều được tính (hoặc có trọng số) cao hơn input tokens, nên phần lãng phí ở output thường đắt hơn phần lãng phí ở input tương ứng.

Giải pháp là đưa ràng buộc phản hồi (response constraints) ngay trong prompt, thuộc ba nhóm chính sau.

Ràng buộc về độ dài

Chỉ định rõ giới hạn độ dài mong muốn, tránh để model tự quyết định "bao nhiêu là đủ".

Ví dụ cụ thể:

"Trả lời trong tối đa 5 câu."

"Chỉ đưa ra diff code (định dạng unified diff), không giải thích lại các đoạn code không thay đổi."

"Tóm tắt trong đúng 3 bullet point, mỗi bullet không quá 15 từ."

Với agent code, ràng buộc "chỉ đưa diff, không lặp lại phần không đổi" đặc biệt quan trọng — nếu không có ràng buộc này, nhiều model có xu hướng in lại toàn bộ file dù chỉ sửa một dòng, gây lãng phí output token nghiêm trọng khi file dài.

Ràng buộc về định dạng

Chỉ định cấu trúc đầu ra cụ thể, loại bỏ phần mở đầu/kết luận dư thừa mà model thường tự thêm ("Chắc chắn! Đây là...", "Hy vọng điều này giúp được bạn!").

Ví dụ cụ thể:

"Chỉ trả về JSON đúng theo schema sau, không kèm text nào khác: { \"bug_found\": boolean, \"line\": number, \"description\": string }"

"Dùng bullet list. Không viết đoạn mở đầu giới thiệu, không viết đoạn kết luận tổng kết."

"Trả lời theo đúng 2 cột: Vấn đề | Đề xuất sửa. Không thêm phần nào khác."

Ràng buộc định dạng còn có lợi ích phụ: output có cấu trúc cố định (như JSON) dễ được xử lý tự động bởi bước tiếp theo trong pipeline (ví dụ agent tự parse JSON để quyết định hành động kế tiếp), giảm luôn cả nhu cầu có một turn riêng để "diễn giải" câu trả lời văn xuôi thành dữ liệu có thể dùng được.

Ràng buộc về độ tin cậy và sự không chắc chắn

Khi không được yêu cầu rõ, nhiều model có xu hướng viết những đoạn hedging dài — liệt kê nhiều khả năng, nhiều "có thể", nhiều disclaimer — để tránh nói sai. Điều này có thể chấp nhận được với câu hỏi rủi ro cao, nhưng lại gây lãng phí lớn với các câu hỏi kỹ thuật đơn giản mà thực ra model có đủ cơ sở để trả lời chắc chắn.

Ví dụ cách ràng buộc:

"Nếu bạn không chắc, chỉ cần trả lời 'Không chắc' và nêu giả định cần kiểm tra thêm — không viết đoạn giải thích dài về các khả năng."

"Bỏ mọi disclaimer dạng 'lưu ý là...', 'tuy nhiên cần cân nhắc...'. Nếu có rủi ro thật sự cần cảnh báo, chỉ nêu đúng 1 dòng rủi ro quan trọng nhất."

"Giả định môi trường là production trừ khi tôi nói khác. Không hỏi lại để xác nhận môi trường."

Ràng buộc loại này đặc biệt hữu ích trong các turn thuộc quy trình lặp đi lặp lại (ví dụ agent QA chạy hàng trăm lần kiểm tra tương tự) — nơi disclaimer lặp đi lặp lại ở mỗi lần chạy chỉ tạo ra nhiễu và tốn token mà không tăng thêm giá trị thông tin.

Mẹo:
- Viết ràng buộc output ngay trong system prompt hoặc đầu turn, đừng chờ model trả lời dài rồi mới sửa — sửa sau vẫn tốn token của lượt trả lời dài đó.
- Với các tác vụ lặp lại nhiều lần (batch, loop qua nhiều file/ticket), định nghĩa format ràng buộc một lần và tái sử dụng cho mọi turn cùng loại — coi nó như một "template phản hồi".
- Cẩn trọng không ràng buộc quá mức khiến model bỏ sót thông tin quan trọng (ví dụ ép "tối đa 1 câu" cho một câu hỏi vốn cần giải thích nhiều bước) — ràng buộc nên khớp với độ phức tạp thật của câu hỏi.

Sắp thứ tự Turn: Trình tự ảnh hưởng đến hiệu quả

Không chỉ nội dung từng turn, mà thứ tự giữa các turn cũng ảnh hưởng lớn đến tổng chi phí token của cả session — vì thứ tự sai có thể khiến bạn phải chi trả cho những turn "đắt" mà lẽ ra không cần thiết.

Sắp thứ tự từ rộng đến hẹp (broad-to-narrow)

Một lỗi phổ biến là viết ngay một prompt đầu tiên siêu chi tiết, siêu dài, cố gắng đặc tả toàn bộ yêu cầu ngay từ turn 1 — với hy vọng nhận được kết quả hoàn chỉnh ngay lần đầu. Rủi ro là nếu định hướng ban đầu sai (ví dụ bạn hiểu nhầm một phần yêu cầu, hoặc model hiểu sai ý), toàn bộ output đắt đỏ đó (và cả phần input dài dòng) coi như lãng phí, và bạn còn phải tốn thêm turn để sửa.

Chiến lược hiệu quả hơn: bắt đầu bằng một câu hỏi rộng, ở mức khung sườn, rồi dựa vào phản hồi để thu hẹp dần ở các turn sau.

Ví dụ trình tự broad-to-narrow cho việc thiết kế một tính năng:

Turn 1 (rộng): "Tôi cần thiết kế cơ chế rate limiting cho API. Gợi ý 2-3 hướng tiếp cận khả thi, mỗi hướng 1-2 câu, không cần chi tiết implement."

Turn 2 (thu hẹp): "Chọn hướng sliding window ở option 2. Giờ mô tả kiến trúc chi tiết hơn: dùng Redis hay in-memory, và tại sao."

Turn 3 (chi tiết): "Viết implementation cụ thể bằng Node.js dùng Redis, kèm test case cho trường hợp burst traffic."

So với việc viết ngay một prompt turn 1 yêu cầu "viết toàn bộ implementation rate limiting sliding window bằng Redis kèm test case" — nếu hóa ra bạn muốn dùng in-memory thay vì Redis vì lý do hạ tầng, toàn bộ output turn 1 (code + test, có thể vài trăm đến vài nghìn token) bị bỏ, và bạn phải làm lại từ đầu.

Turn xác nhận (confirmation turns)

Confirmation turn là một turn ngắn, rẻ, dùng để xác nhận hướng đi hoặc mức độ hiểu đúng của model trước khi cam kết vào một turn tốn kém (ví dụ sinh code dài, viết draft tài liệu dài, chạy một quy trình nhiều bước).

Ví dụ:

"Trước khi viết full implementation, tóm tắt lại trong 3 dòng: bạn hiểu yêu cầu của tôi là gì, và bạn định làm theo hướng nào?"

Nếu tóm tắt đó đúng, bạn tiếp tục turn sinh code tốn kém với độ tin cậy cao hơn. Nếu tóm tắt sai, bạn chỉ mới mất một turn rẻ để phát hiện và sửa hướng, thay vì mất một turn đắt.

Tuy nhiên, confirmation turn không phải luôn "lãi". Nó trả giá bằng: (1) thêm một round-trip, tốn thời gian chờ, và (2) thêm chi phí input/output của chính turn xác nhận đó. Với các nhiệm vụ đơn giản, rõ ràng, rủi ro hiểu sai thấp (ví dụ "sửa lỗi chính tả trong đoạn văn này"), thêm confirmation turn là overhead thuần túy, không mang lại lợi ích.

Quy tắc thực dụng để quyết định có cần confirmation turn hay không:

  • Nên dùng khi: turn kế tiếp tốn kém (output dài, nhiều bước), yêu cầu có thể hiểu theo nhiều hướng, hoặc chi phí làm sai cao (ví dụ code sẽ được merge trực tiếp, tài liệu sẽ gửi khách hàng).
  • Không cần khi: nhiệm vụ đơn giản, rõ ràng, chi phí sửa lại thấp, hoặc bạn đã có confirmation tương đương từ context trước đó trong cùng session.

Mẹo:
- Với các nhiệm vụ mới, phức tạp, hoặc có rủi ro cao (deploy production, sinh code lớn, viết tài liệu chính thức), mặc định đi theo trình tự broad-to-narrow kèm ít nhất một confirmation turn trước bước tốn kém nhất.
- Với các nhiệm vụ lặp lại quen thuộc (bạn đã làm nhiều lần, biết chắc model hiểu đúng ý), có thể bỏ qua confirmation turn để tiết kiệm round-trip.
- Đặt confirmation turn ngay trước bước đắt nhất, không phải ở đầu session — xác nhận sớm quá khi thông tin còn thiếu cũng dễ sai.

Audit Turn thực tế: Trước và Sau

Hãy xem một tình huống thực tế: một kỹ sư backend đang nhờ agent hỗ trợ điều tra một lỗi production, và trao đổi diễn ra qua 2 turn như sau.

Trước khi tối ưu:

Turn 1 (người dùng): "Chào, bên mình đang gặp vấn đề, hệ thống order service của mình dùng Node.js với Express, có kết nối tới Postgres qua Prisma, và cũng có gọi tới một service thanh toán bên thứ 3 nữa, gần đây thấy có một số order bị stuck ở trạng thái pending không chuyển sang completed được, mình có paste log ở đây nè [dán nguyên 400 dòng log server trong 3 ngày], bạn xem giúp coi lỗi ở đâu, mà cũng xem giúp luôn có cần thêm retry logic không, và nếu được thì viết giúp luôn function xử lý retry, à với lại giải thích thêm cho mình về cơ chế idempotency luôn nha vì mình cũng không rành lắm."

→ Model phải xử lý 400 dòng log (phần lớn không liên quan), đồng thời cố trả lời 4 yêu cầu khác nhau (chẩn đoán lỗi, đánh giá nhu cầu retry, viết code retry, giải thích idempotency) trong một khối output dài, các phần đan xen nhau, khó xác định phần nào là chẩn đoán thật, phần nào là suy đoán do thiếu thông tin.

Ước tính thô: 400 dòng log ~ 4.000-6.000 input token (tùy độ dài dòng log), phần lớn không liên quan đến order bị stuck. Output cố gắng trả lời 4 việc có thể lên tới 800-1.200 output token, nhiều đoạn hedging vì chưa đủ thông tin để chẩn đoán chắc chắn.

Sau khi tối ưu (áp dụng các nguyên tắc đã học):

Turn 1 (người dùng, đã lọc log và tách yêu cầu):
```
Bug: order bị stuck ở trạng thái pending, không chuyển completed.
Stack: Node.js + Express + Postgres (Prisma) + payment service bên thứ 3.
Log liên quan (đã lọc, chỉ giữ order_id=8841 trong khung 10 phút trước khi stuck):
[dán 25 dòng log đã lọc, chỉ liên quan trực tiếp đến order 8841]

Câu hỏi duy nhất: dựa vào log này, nguyên nhân khả năng cao nhất khiến order stuck ở pending là gì? Trả lời tối đa 3 câu, chỉ nêu 1 nguyên nhân khả năng cao nhất kèm dòng log làm chứng cứ.
```

Turn này chỉ ~600-900 input token (log đã lọc còn 25 dòng liên quan) và ràng buộc output "tối đa 3 câu" khiến model buộc phải đưa ra chẩn đoán cụ thể, không lan man.

Turn 2 (chỉ nếu chẩn đoán ở turn 1 chỉ ra vấn đề là do thiếu retry khi payment service timeout): "Xác nhận đúng hướng. Viết function retry với exponential backoff cho lần gọi payment service, dùng idempotency key theo order_id. Chỉ đưa code, không giải thích lý thuyết idempotency."

Nếu người kỹ sư thực sự cần hiểu về idempotency, đó là một turn hoàn toàn riêng, hỏi sau, không trộn vào turn debug.

So sánh: phiên bản trước tốn khoảng 5.000-7.000 input token cho log dư thừa (ước tính, tùy độ dài log thực tế) và một output dài, khó verify, chứa cả nội dung có thể không cần thiết ngay lúc đó. Phiên bản sau giảm input xuống dưới 1.000 token cho turn chẩn đoán, output ngắn, đúng trọng tâm, và turn tiếp theo (viết retry code) chỉ được thực hiện khi đã xác nhận đúng hướng — tránh nguy cơ viết nhầm code retry cho một nguyên nhân sai. Tổng thể, việc tách turn và lọc log không chỉ tiết kiệm token mà còn tăng chất lượng chẩn đoán, vì model không bị "loãng sự chú ý" bởi 375 dòng log không liên quan.

Mẹo:
- Trước khi dán log/dữ liệu lớn vào một turn, luôn tự lọc trước theo phạm vi liên quan trực tiếp (theo ID, theo khung thời gian, theo mã lỗi) — đừng để model tự "mò" trong biển dữ liệu.
- Khi một turn vừa muốn chẩn đoán vừa muốn sửa, luôn tách chẩn đoán ra làm turn riêng và rẻ trước, chỉ đầu tư vào turn sửa (đắt) sau khi chẩn đoán đã được xác nhận.

Khoảng cách kỷ luật: Vì sao đa số người dùng đang chi tiêu quá tay ở cấp turn

Dù các nguyên tắc trên khá đơn giản để hiểu, quan sát thực tế cho thấy phần lớn người dùng — kể cả kỹ sư có kinh nghiệm — vẫn thường xuyên vi phạm chúng. Một số thói quen xấu phổ biến và lý do chúng tồn tại:

  • Dán nguyên file/log không cắt gọt. Lý do: cắt gọt tốn thời gian và công sức suy nghĩ xem phần nào liên quan; dán nguyên khối "cho chắc" cảm giác nhanh hơn và an toàn hơn (sợ bỏ sót thông tin quan trọng). Thực tế, việc này thường phản tác dụng vì làm model bị nhiễu.
  • Lặp lại context dư thừa ở mỗi turn. Lý do: lo sợ model "quên" nếu không nhắc lại, hoặc do quy trình làm việc rời rạc (copy-paste từ mẫu có sẵn) khiến việc lặp trở thành thao tác mặc định thay vì được cân nhắc lại mỗi lần.
  • Hỏi mơ hồ, không rõ phạm vi (open-ended). Lý do: đôi khi người dùng chính họ cũng chưa suy nghĩ rõ mình cần gì, nên đặt câu hỏi rộng "cho model tự lo" — nhưng câu hỏi rộng thường kéo theo output dài và ít tập trung.
  • Không chỉ định format, để model "tự quyết". Lý do: nghĩ rằng việc thêm ràng buộc format là "phức tạp hóa" một yêu cầu vốn đơn giản, hoặc đơn giản là quên — trong khi việc thêm 1-2 dòng ràng buộc format thường tốn ít token hơn nhiều so với phần output dư thừa nó ngăn chặn được.

Những thói quen này bền vững vì chúng đều là con đường có lực cản thấp nhất trong ngắn hạn — dán nguyên log nhanh hơn lọc log, lặp context nhanh hơn nhớ đã nói gì, hỏi mơ hồ nhanh hơn suy nghĩ kỹ phạm vi câu hỏi. Nhưng "nhanh" ở từng turn riêng lẻ lại tích lũy thành chi phí token và chi phí chất lượng đáng kể trên toàn session, đặc biệt trong các agent tự động hóa chạy hàng trăm, hàng nghìn turn mỗi ngày — nơi thói quen xấu của một người được nhân lên ở quy mô hệ thống.

Xây dựng kỷ luật ở cấp turn không đòi hỏi công cụ đặc biệt, chỉ đòi hỏi một quy trình kiểm tra nhỏ trước khi gửi mỗi turn: lọc dữ liệu đầu vào, tách một nhiệm vụ mỗi turn, tránh lặp context, và luôn ràng buộc rõ hình thức phản hồi mong muốn. Đây là một kỹ năng có thể rèn thành phản xạ, giống như việc lập trình viên rèn phản xạ viết commit message rõ ràng hay đặt tên biến có ý nghĩa — ban đầu cần chủ ý, nhưng dần trở thành bản năng nghề nghiệp.

Mẹo:
- Tạo cho mình một checklist ngắn 4 dòng (lọc dữ liệu — một việc mỗi turn — không lặp context — ràng buộc format) và dán ở nơi dễ thấy trong vài tuần đầu luyện thói quen, đến khi nó trở thành phản xạ.
- Với team, đưa các nguyên tắc turn-level này vào tài liệu hướng dẫn nội bộ (playbook) về cách làm việc với AI agent, để cả kỹ sư, QA, và PM đều áp dụng nhất quán — vì lợi ích tiết kiệm token chỉ thực sự lớn khi được áp dụng ở quy mô toàn team, không phải chỉ vài cá nhân.