Menu

Token và context window: AI đọc văn bản thế nào

Mô hình AI đọc văn bản dưới dạng token, những mẩu nhỏ của từ, và chỉ chứa được một số lượng token giới hạn cùng lúc: đó là context window. Tìm hiểu cách cả hai hoạt động và nên làm gì khi cuộc chat trở nên dài.

Mọi prompt bên dưới đều có thể chỉnh sửa: thay đổi nó, rồi mở trong ChatGPT, Claude hoặc ứng dụng AI khác.

Mô hình ngôn ngữ AI không đọc từng chữ cái hay từng từ. Chúng đọc token: những mẩu văn bản nhỏ, thường là cả một từ, đôi khi chỉ là một phần của từ. Và chúng chỉ nhận được một số lượng token giới hạn mỗi lần, giới hạn này gọi là context window (cửa sổ ngữ cảnh). Hai khái niệm này giải thích vì sao các công cụ AI được tính giá như hiện nay, vì sao các cuộc chat dài bắt đầu quên chỉ dẫn ban đầu, và vì sao một mô hình có thể gặp khó khi đếm chữ cái trong một từ mà nó vừa đánh vần đúng.

Token trong AI là gì?

Trước khi mô hình thấy prompt của bạn, một chương trình gọi là tokenizer chia văn bản thành các mảnh lấy từ một bộ từ vựng cố định và chuyển mỗi mảnh thành một con số. Mô hình làm việc hoàn toàn với các con số đó, và nó viết câu trả lời theo cùng cách, từng token một, rồi ứng dụng chuyển chúng ngược lại thành văn bản.

Bộ từ vựng được học từ một lượng lớn văn bản, nên các từ phổ biến thường là một token duy nhất, còn các từ hiếm hơn bị chia thành vài mảnh quen thuộc. Khoảng trắng thường được gắn vào đầu từ đứng sau nó. Một câu tiếng Anh có thể được chia gần như sau:

Token ization isn 't magic .

Cách chia này chỉ mang tính minh họa. Mỗi dòng mô hình có tokenizer riêng, và cùng một câu có thể ra số mảnh khác nhau ở mỗi mô hình. Nhiều nhà cung cấp công bố công cụ tokenizer hoặc API đếm token để bạn kiểm tra số lượng thực tế.

Hình ảnh, âm thanh và tệp cũng được chuyển thành token khi mô hình nhận chúng, đó là lý do một ảnh chụp màn hình đính kèm cũng dùng hết một phần ngân sách token giống như văn bản của bạn.

Một từ bằng bao nhiêu token?

Với văn bản tiếng Anh, một quy tắc ước lượng được dùng rộng rãi là khoảng bốn ký tự cho mỗi token, tức khoảng ba phần tư một từ. Theo ước tính đó, 1.000 token tương đương khoảng 750 từ tiếng Anh, và một bài viết 3.000 từ là khoảng 4.000 token.

Tỷ lệ này thay đổi theo nội dung:

  • Các ngôn ngữ khác thường tốn nhiều token hơn cho cùng một ý nghĩa. Tokenizer được huấn luyện trên dữ liệu mà tiếng Anh chiếm tỷ lệ lớn, nên từ tiếng Anh có token gọn, còn văn bản tiếng Nhật, tiếng Hàn, tiếng Ả Rập, tiếng Hindi và nhiều ngôn ngữ khác bị chia thành nhiều mảnh hơn. Khoảng cách này phụ thuộc vào tokenizer và đã được thu hẹp ở các tokenizer mới hơn, nhưng chưa biến mất.
  • Code tốn token cho thụt lề, dấu ngoặc, toán tử và tên định danh dài, nên một tệp thường tốn nhiều token hơn so với số từ của nó.
  • Số, URL và các chuỗi khác thường như ID và mã hash thường bị chia thành nhiều token nhỏ.

Vì sao token quan trọng

Chi phí. API tính tiền theo token, với giá riêng cho token bạn gửi đi và token mô hình viết ra. Trong một cuộc chat, toàn bộ cuộc trò chuyện được gửi lại với mỗi tin nhắn mới, nên một cuộc trò chuyện dài tốn nhiều chi phí hơn cho mỗi tin nhắn so với một cuộc trò chuyện ngắn.

Giới hạn. Mô hình có một context window cho mọi thứ nó đọc và viết trong một request, và thường có thêm một giới hạn riêng cho độ dài của một câu trả lời. Trong API bạn có thể tự đặt giới hạn đó, và với API của Anthropic thì bắt buộc phải đặt: max_tokens là tham số bắt buộc.

Tốc độ. Câu trả lời được tạo ra lần lượt từng token, nên câu trả lời càng dài thì càng mất nhiều thời gian để hoàn thành.

Các việc liên quan đến chính tả. Vì mô hình nhìn một từ như magic thành một hoặc hai đơn vị chứ không phải năm chữ cái, những việc phụ thuộc vào từng ký tự, như đếm chữ cái, đảo ngược một từ hay tìm từ có độ dài chính xác, khó với nó hơn vẻ bề ngoài. Các mô hình mới xử lý nhiều việc trong số này tốt hơn, nhưng khi từng ký tự là quan trọng, hãy kiểm tra câu trả lời hoặc yêu cầu mô hình viết từ đó ra từng chữ cái một trước.

Context window là gì?

Context window là số token tối đa mà mô hình có thể xem xét trong một request. Hãy coi nó là bộ nhớ làm việc của mô hình: mọi thứ mô hình có thể dùng để viết câu trả lời đều phải nằm gọn trong đó cùng lúc, bao gồm:

  • system prompt, gồm chỉ dẫn riêng của ứng dụng và của bạn
  • cuộc trò chuyện tính đến lúc đó, mọi tin nhắn của người dùng và mọi câu trả lời
  • tệp đính kèm, tài liệu được dán vào và kết quả tìm kiếm hay kết quả từ công cụ
  • câu trả lời đang được viết

Bất cứ thứ gì nằm ngoài cửa sổ đều không tồn tại đối với mô hình. Không có bộ nhớ nền nào để nó tra cứu. Kích thước context window rất khác nhau giữa các mô hình và liên tục tăng lên, nên hãy xem tài liệu của nhà cung cấp cho mô hình bạn dùng thay vì dựa vào một con số trong bài viết nào đó.

Mô hình cũng không giữ lại gì giữa các request. Thứ trông như trí nhớ trong một cuộc chat thực ra là ứng dụng gửi lại toàn bộ cuộc trò chuyện mỗi lần. Tính năng bộ nhớ trong các ứng dụng chat cũng hoạt động như vậy: ứng dụng lưu ghi chú về bạn, hoặc tìm trong các cuộc chat trước, rồi chèn những gì tìm được vào ngữ cảnh của cuộc chat mới.

Điều gì xảy ra khi cuộc chat trở nên dài

Khi một cuộc trò chuyện vượt quá context window, phải có thứ gì đó bị hy sinh. Tùy ứng dụng, các tin nhắn cũ nhất bị bỏ đi, các phần cũ được thay bằng bản tóm tắt, hoặc bạn được báo rằng cuộc chat đã chạm giới hạn và nên mở cuộc chat mới. Trong mọi trường hợp, các chi tiết từ đầu, kể cả chỉ dẫn bạn đưa ra trong tin nhắn đầu tiên, có thể không còn ảnh hưởng đến câu trả lời.

Cửa sổ bị đầy không phải là vấn đề duy nhất. Mô hình có càng nhiều tài liệu trước mặt thì càng có nhiều thứ để bỏ sót, và trong một cuộc chat dài, các quyết định ban đầu phải cạnh tranh với mọi thứ được nói sau đó. Dấu hiệu thường gặp là câu trả lời bỏ qua một ràng buộc bạn đặt ra từ trước, code quay lại phiên bản bạn đã sửa, hoặc mô hình lặp lại một ý tưởng bạn đã bác bỏ.

Làm việc trong giới hạn của context window

Mở cuộc chat mới cho mỗi việc. Một cuộc chat mới với tin nhắn đầu tiên rõ ràng thường tốt hơn một cuộc chat dài đã trôi qua nhiều chủ đề.

Mang theo một bản tóm tắt. Khi một cuộc chat đã tích lũy được những quyết định hữu ích, hãy yêu cầu một bản tóm tắt để dán vào cuộc chat mới, rồi tiếp tục ở đó. Điền vào các chỗ trống bên dưới cho phù hợp với công việc của bạn.

Tiếp tục trong cuộc chat mới
Fill in
Cuộc chat này đang dài ra. Hãy viết một bản tóm tắt mình có thể dán vào cuộc chat mới để tiếp tục công việc. Bao gồm: mục tiêu, các quyết định chúng ta đã đưa ra và lý do, phiên bản hiện tại của database schema, và các câu hỏi còn bỏ ngỏ. Giữ bản tóm tắt dưới 200 từ, không tính database schema.
Try it
Example replyReplies vary between models and runs.

Mục tiêu: cơ sở dữ liệu cho một ứng dụng thư viện nhỏ, lưu trong SQLite.

Quyết định:

  • Lượt mượn có bảng riêng, để giữ lại toàn bộ lịch sử cho mượn.
  • Một cuốn sách được tính là còn sẵn khi không có lượt mượn nào có returned_at trống.

Schema hiện tại:

CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT NOT NULL, author TEXT NOT NULL);
CREATE TABLE members (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE);
CREATE TABLE loans (
  id INTEGER PRIMARY KEY,
  book_id INTEGER NOT NULL REFERENCES books(id),
  member_id INTEGER NOT NULL REFERENCES members(id),
  loaned_at TEXT NOT NULL,
  returned_at TEXT
);

Câu hỏi còn bỏ ngỏ:

  • Có cần phí trả sách muộn không?
  • Thư viện có nên theo dõi nhiều bản của cùng một cuốn sách không?

Chỉ dán những gì nhiệm vụ cần. Hàm có bug và đoạn code gọi nó, không phải cả repository. Phần hợp đồng đang được hỏi, không phải cả bốn mươi trang. Ít tài liệu hơn thì ít thứ bị bỏ sót hơn.

Đặt câu hỏi sau tài liệu dài, và nhắc lại điều quan trọng. Khi dán một tài liệu dài, hãy đặt câu hỏi ở cuối, sau tài liệu, và nhắc lại các ràng buộc chính ở đó. Khi đó chỉ dẫn nằm ngay cạnh chỗ mô hình bắt đầu viết.

Chia nhỏ tài liệu quá dài cho một tin nhắn. Một số ứng dụng giới hạn lượng văn bản bạn dán vào một tin nhắn, ngay cả khi context window của mô hình chứa được nhiều hơn. Gửi tài liệu thành nhiều phần giúp vượt qua giới hạn tin nhắn, nhưng không vượt qua được context window: mỗi phần vẫn được tính vào đó. Hãy dặn mô hình từ đầu là đừng trả lời cho đến khi bạn gửi xong mọi phần.

Fill in
Mình sẽ gửi cho bạn một tài liệu dài, chia làm 3 phần. Sau mỗi phần, chỉ trả lời "Đã nhận phần N trên 3" và không gì khác. Đừng tóm tắt hay trả lời gì cho đến khi mình đặt câu hỏi. Phần 1 trên 3: """ [dán phần 1] """
Try it
Example replyReplies vary between models and runs.

Đã nhận phần 1 trên 3

Đếm token khi cần thiết. Nếu bạn đang xây dựng với API, hãy đếm trước khi gửi. Thư viện mã nguồn mở tiktoken của OpenAI tách token bằng các tokenizer của OpenAI, còn API của Anthropic có endpoint đếm token. Số đếm từ tokenizer của một nhà cung cấp chỉ là ước tính đối với nhà cung cấp khác.

import tiktoken

enc = tiktoken.get_encoding("o200k_base")  # one of OpenAI's tokenizers
tokens = enc.encode("Tokenization isn't magic.")
print(len(tokens))
print([enc.decode([t]) for t in tokens])

Khi bạn xây ứng dụng quanh một mô hình, việc quyết định đưa gì vào cửa sổ và theo thứ tự nào trở thành một bài toán thiết kế riêng. Context engineering đề cập vấn đề đó, còn prompt chaining cho thấy cách chia một công việc lớn thành các bước vừa vặn. Để xem một tin nhắn đơn lẻ nằm ở đâu trong toàn bộ đầu vào, hãy đọc prompt là gì.

Câu hỏi thường gặp

Token trong AI là gì?

Token là đơn vị văn bản mà mô hình ngôn ngữ đọc và viết. Nó có thể là cả một từ phổ biến, một phần của từ dài hơn, một dấu câu hoặc một khoảng trắng. Trước khi mô hình thấy prompt của bạn, một bộ tách token (tokenizer) chia nó thành các token và chuyển mỗi token thành một con số, và mô hình tạo câu trả lời từng token một.

1.000 token bằng bao nhiêu từ?

Với tiếng Anh, một quy tắc ước lượng phổ biến là khoảng bốn ký tự cho mỗi token, tức khoảng 750 từ cho mỗi 1.000 token. Con số thực tế phụ thuộc vào tokenizer của mô hình và vào nội dung văn bản. Code, số và nhiều ngôn ngữ khác tiếng Anh, trong đó có tiếng Việt, tốn nhiều token hơn cho cùng một lượng nội dung.

Context window là gì?

Context window (cửa sổ ngữ cảnh) là số token tối đa mà mô hình có thể xem xét trong một request. Nó phải chứa system prompt, cuộc trò chuyện tính đến lúc đó, mọi tệp đính kèm hoặc kết quả từ công cụ, và câu trả lời mô hình đang viết. Bất cứ thứ gì nằm ngoài nó đều không tồn tại đối với mô hình.

Điều gì xảy ra khi cuộc chat vượt quá context window?

Ứng dụng phải tạo chỗ trống. Tùy ứng dụng, nó sẽ bỏ các tin nhắn cũ nhất, thay chúng bằng một bản tóm tắt, hoặc báo cho bạn biết cuộc trò chuyện đã chạm giới hạn. Dù theo cách nào, các chỉ dẫn và chi tiết từ đầu cuộc chat cũng có thể không còn ảnh hưởng đến câu trả lời, đó là lý do các cuộc chat dài đôi khi có vẻ quên mất mọi thứ.

ChatGPT hay Claude có nhớ các cuộc chat trước của mình không?

Bản thân mô hình thì không. Mỗi câu trả lời được tạo ra từ những gì có trong context window của request đó. Một số ứng dụng có tính năng bộ nhớ, lưu ghi chú về bạn hoặc tìm trong các cuộc chat cũ rồi thêm những gì tìm được vào cuộc chat mới, và các dự án có thể chứa tệp và chỉ dẫn dùng chung, nhưng đó là ứng dụng đưa văn bản vào ngữ cảnh, không phải mô hình tự nhớ.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu