Chuyển đến nội dung chính
  1. Bài viết/

Bài 01: Ảo tưởng kiểm soát — tư duy hệ thống trong kỷ nguyên AI

Cắm LLM vào một hệ thống quen với logic if-else thì lời hứa ‘cùng đầu vào, cùng đầu ra’ vỡ ngay. Bài này chỉ ra chỗ vỡ nằm ở đâu, và ba lớp hàng rào dựng lại quyền kiểm soát: chặn định dạng sai từ lúc sinh chữ, cam kết tỉ lệ lỗi bằng số, và đặt cầu dao ngay bên trong mô hình.

I. Vấn đề của lập trình truyền thống #

Phần mềm truyền thống chạy trên một lời hứa: cùng đầu vào, cùng đầu ra, mọi lúc. Cắm một LLM vào giữa luồng nghiệp vụ, lời hứa đó vỡ — và nó vỡ theo một kiểu có thể mô tả bằng toán, chứ không phải vỡ ngẫu nhiên. Bài này bóc chỗ vỡ đó ra: vì sao ảo giác và vòng lặp vô tận là hệ quả cấu trúc của cách mô hình sinh chữ, chứ không phải bug vá được bằng thêm một câu if. Sau đó là ba lớp hàng rào dựng lại quyền kiểm soát mà không cần mô hình phải hoàn hảo: chặn token sai định dạng ngay lúc sinh, biến câu “chắc là ổn” thành một tỉ lệ lỗi cam kết được bằng số, và đặt cầu dao đọc tín hiệu ngay bên trong mạng nơ-ron.

Suốt hàng thập kỷ, kỹ thuật phần mềm vận hành trên một lời hứa đơn giản: viết logic, nhận kết quả. Cùng đầu vào, cùng đầu ra, mọi lúc. Test chạy xanh hôm nay thì mai vẫn xanh, trừ khi có người sửa code.

Rồi chúng ta cắm Large Language Model (LLM) vào các tính năng cốt lõi, và lời hứa vỡ. Cùng một câu hỏi gửi hai lần có thể ra hai câu trả lời khác nhau. Công việc thôi xoay quanh quản lý các câu if-else và bắt đầu xoay quanh điều phối những thứ chỉ đúng theo xác suất.

Giữ nguyên lối tư duy “kiểm soát tuyệt đối” cũ, những vết nứt sẽ thành lỗi diện rộng ngay khoảnh khắc hệ thống gặp một dữ kiện chưa từng thấy trong lúc test.

Abstract isometric representation of an FSM transitioning into a chaotic probabilistic system, clean line art, modern anime style, flat color, cel shading, minimalist, high contrast, pure titanium silver and dark graphite color palette, subtle academic cinnabar fire accents highlighting the chaotic nodes, professional technical aesthetic, pure off-white background, 4k, vector style.

II. Khác biệt nằm ở đâu: FSM và Absorbing Markov Chain #

Sự dịch chuyển này có gốc toán học, và nó đơn giản hơn cái tên của nó.

Software 1.0 chạy như một Finite State Machine (FSM). Một FSM là cỗ máy chỉ có hữu hạn trạng thái, kèm một bảng quy định: đang ở trạng thái nào, gặp sự kiện gì, thì nhảy sang trạng thái nào. Cái máy bán nước tự động là một FSM: đang chờ tiền, nhận đủ 10 nghìn, nhảy sang trạng thái nhả hàng. Không có trạng thái thứ ba nào chen ngang. Viết bằng xác suất thì mỗi bước chuyển hoặc $P = 1$ (chắc chắn xảy ra) hoặc $P = 0$ (không bao giờ xảy ra). Không có gì ở giữa — và chính vì thế mà ta debug được.

Hệ thống LLM chạy như một Absorbing Markov Chain1. Markov chain là chuỗi bước đi mà bước kế tiếp chỉ phụ thuộc chỗ đang đứng, không phụ thuộc đường đã đi qua. “Absorbing” nghĩa là trong chuỗi đó có ít nhất một ô không có đường ra: bước vào rồi thì ở lại vĩnh viễn. Với mô hình sinh văn bản, ô không có đường ra chính là token kết thúc <EOS>. Mỗi bước sinh chữ là một lần rút thăm có trọng số trên toàn bộ từ điển, và quá trình chỉ dừng khi rút trúng <EOS>.

Khác biệt then chốt: FSM đảm bảo bằng cấu trúc rằng nó sẽ tới đích. Markov chain chỉ đảm bảo rằng nó có xu hướng tới đích.

Đẩy AI vào hệ thống mà không tính đến chuyện này, bạn gặp Degenerate Loop2 — mô hình kẹt trong một chu trình kín và không bao giờ rút trúng <EOS>. Trên thực tế nó trông như thế này: model bắt đầu lặp “Xin lỗi vì sự bất tiện. Xin lỗi vì sự bất tiện.” cho tới khi chạm trần max_tokens. Với trần 4096 token, một request hỏng kiểu này tiêu hết ngân sách token của nó và giữ luôn một slot xử lý trong vài chục giây.

Trong khung nhìn đó, ảo giác không còn là lỗi nội dung. Nó là một quá trình không có cơ chế tự dừng.

Và không, bạn không vá được đường ra bằng code truyền thống. Cứ mỗi edge case lại thêm một vòng kiểm tra, codebase phình tới mức không ai dám sửa — trong khi tập edge case của một mô hình xác suất thì không đóng lại được.

III. Chỗ này ai từng vận hành hệ phân tán đều thấy quen #

Điều phối LLM giống lạ lùng với việc vận hành microservice: cả hai buộc bạn ra quyết định khi không bao giờ có đủ thông tin chắc chắn.

Trong hệ phân tán, định lý CAP phát biểu ràng buộc đó. Nội dung của nó, bỏ hết ký hiệu: khi đường mạng giữa hai nửa hệ thống đứt, bạn chỉ được chọn một trong hai — hoặc mọi người đọc ra cùng một dữ liệu (nhất quán), hoặc hệ thống vẫn trả lời được (sẵn sàng). Không có cấu hình nào cho bạn cả hai, vì nửa bên kia đang không nói chuyện được.

Hệ thống AI đứng trước ràng buộc cùng dạng. Khi mô hình không có đủ dữ kiện, nó chỉ được chọn một trong hai: từ chối trả lời (giữ tính đúng, mất tính sẵn sàng) hoặc bịa ra một câu trôi chảy (giữ sẵn sàng, mất tính đúng). Mặc định của mọi LLM thương mại hiện nay là vế thứ hai. Kiến trúc sư phải là người đổi mặc định đó.

Hai kỹ thuật quen thuộc của hệ phân tán chuyển thẳng sang được:

  • RAG như một phép neo dữ liệu. RAG (Retrieval-Augmented Generation) là việc tra cứu tài liệu thật trước, rồi nhét đoạn tài liệu đó vào prompt để mô hình trả lời dựa trên nó. Vai trò của nó giống hệt việc đọc dữ liệu từ nguồn chuẩn thay vì đọc từ cache: câu trả lời được ghim vào một thứ kiểm chứng được, và ta có đường dẫn để truy lại.
  • Byzantine Fault Tolerance cho hệ multi-agent. BFT là bài toán kinh điển: một nhóm phải thống nhất quyết định trong khi vài thành viên có thể trả lời bậy hoặc nói dối. Trong hệ nhiều agent, agent bịa số liệu chính là một Byzantine node. Cách xử lý cũng y hệt: hỏi ba agent độc lập cùng một câu, lấy đáp án được ít nhất hai bên đồng thuận, và ghi lại trường hợp cả ba trả lời khác nhau như một tín hiệu cần người xem lại. Đổi lại là chi phí: ba lần token và ba lần độ trễ cho mỗi câu hỏi, nên chỉ áp cho những quyết định đắt tiền.

A clear, side-by-side technical illustration of two mechanical input-output systems on a pristine minimalist white table. Left side “Deterministic”: A titanium silver funnel perfectly dropping solid silver cubes into a neat, straight line. Right side “Probabilistic”: A titanium silver funnel dropping solid silver cubes, but they transform into a glowing, swirling cloud of cinnabar red data particles before landing in a scattered, unpredictable pattern. Modern anime vector art style, clean line art, flat colors, cel shading, bright and relaxing atmosphere, purely informative conceptual diagram, pure off-white background.

IV. Chặn đầu ra sai định dạng bằng Constrained Decoding #

Lớp hàng rào đầu tiên quấn một cỗ máy trạng thái chặt chẽ quanh chuỗi xác suất, nhốt sự bất định lại trước khi nó kịp rò ra ngoài.

Muốn hiểu cơ chế, cần biết mô hình sinh chữ thế nào. Ở mỗi bước, nó chấm điểm cho toàn bộ từ điển — cỡ 100.000 đến 200.000 token tùy mô hình — rồi rút thăm một token theo điểm số đó. Không có gì trong quy trình này bắt nó phải tôn trọng cú pháp JSON.

Constrained Decoding chen vào đúng giữa hai bước: sau khi mô hình chấm điểm, trước khi rút thăm, nó ép điểm của mọi token không hợp lệ về 0.

Cái quyết định “hợp lệ” là một cỗ máy trạng thái biên dịch sẵn từ JSON Schema hoặc regex của bạn, lưu dưới dạng cây tiền tố (radix tree) để tra cứu trong thời gian gần như không đáng kể. Ví dụ với schema chỉ cho phép {"status": "ok"} hoặc {"status": "error"}: ngay sau khi mô hình sinh xong {"status": ", cây chỉ còn hai nhánh sống, okerror. Toàn bộ 200.000 token còn lại bị dập về xác suất 0. Mô hình không thể sinh sai định dạng, kể cả khi nó rất muốn.

Điểm đáng giá: hàng rào này không phụ thuộc vào việc mô hình có “hiểu” schema hay không. Nó là ràng buộc cứng ở tầng decode, nên tỉ lệ đầu ra sai cú pháp về đúng 0%, và bạn bỏ được toàn bộ đống code retry-khi-parse-lỗi. Cái nó không làm được: bảo đảm nội dung bên trong đúng. {"status": "ok"} vẫn có thể là một lời nói dối đúng cú pháp — và đó là việc của lớp hàng rào thứ hai.

V. Cam kết tỉ lệ lỗi bằng số với Conformal Risk Control #

Vấn đề tiếp theo là mô hình tự tin hơn nhiều so với mức nó xứng đáng.

Nguyên nhân nằm ở cách huấn luyện. RLHF — kỹ thuật tinh chỉnh mô hình theo điểm chấm của con người — thưởng cho những câu trả lời nghe dứt khoát, mạch lạc, dễ chịu. Người chấm hiếm khi thưởng cho câu “tôi không chắc”. Sau vài triệu vòng như vậy, mô hình học được rằng giọng chắc chắn luôn có lợi, kể cả khi nội dung sai.

Cách đo độ vênh này là Expected Calibration Error (ECE). Cách đọc nó rất đời thường: gom mọi câu trả lời vào 10 cái rổ theo độ tự tin mà mô hình khai báo, rồi so trong từng rổ. Rổ “tự tin 90%” mà đúng đúng 90% số lần thì mô hình hiệu chỉnh tốt, ECE gần 0. Rổ “tự tin 90%” mà chỉ đúng 30% thì mô hình đang nói dối về chính nó.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np

def calculate_sequence_ece(confidences: np.ndarray, accuracies: np.ndarray, M: int = 10) -> float:
    """
    Đo độ vênh giữa mức tự tin mô hình khai báo và tỉ lệ nó thực sự trả lời đúng.
    Gom các câu trả lời vào M rổ theo độ tự tin, rồi lấy chênh lệch bình quân
    giữa "tự tin trung bình" và "đúng trung bình" của từng rổ.
    """
    bin_boundaries = np.linspace(0, 1, M + 1)
    ece = 0.0

    for i in range(M):
        mask = (confidences > bin_boundaries[i]) & (confidences <= bin_boundaries[i+1])
        if np.any(mask):
            acc_bin = np.mean(accuracies[mask])
            conf_bin = np.mean(confidences[mask])
            ece += np.abs(conf_bin - acc_bin) * np.mean(mask)

    return ece

# Mô phỏng một mô hình bị ép trả lời trôi chảy nhưng rỗng
sim_conf = np.array([0.99, 0.98, 0.99, 0.97]) # Khai báo: gần như chắc chắn
sim_acc = np.array([1, 0, 0, 0])              # Thực tế: đúng 1 trên 4

print(f"Sequence-Level ECE: {calculate_sequence_ece(sim_conf, sim_acc):.4f}")
# Output: 0.7325

Đọc con số 0,7325 bằng lời: mô hình khai báo mức chắc chắn bình quân 98,25%, thực tế đúng 25%. Vênh 73 điểm phần trăm. Mọi cảnh báo, mọi ngưỡng tự động dựa trên “độ tự tin” của mô hình đều đang đứng trên con số đó.

Conformal Risk Control đổi cách đặt vấn đề. Thay vì cố làm mô hình bớt tự tin, nó lấy một tập dữ liệu hiệu chuẩn có đáp án đúng, chạy mô hình lên đó, rồi dò ra một ngưỡng: dưới ngưỡng này thì hệ thống từ chối trả lời và chuyển cho người. Ngưỡng được chọn sao cho tỉ lệ lỗi trên dữ liệu mới không vượt mức bạn đặt — ví dụ 5% — và đó là một cam kết thống kê chứng minh được, không phải cảm giác.

Cái giá phải trả: mọi câu bị từ chối đều thành việc của con người. Đặt trần lỗi 5% thay vì 10% thường làm tỉ lệ chuyển tay người tăng đáng kể. Đây là một núm vặn đánh đổi giữa rủi ro và chi phí vận hành, không phải một nút “làm cho đúng”.

VI. Đặt cầu dao bên trong mô hình với Mechanistic Interpretability #

Đo rủi ro sau khi câu trả lời đã sinh xong vẫn là đo muộn. Lớp hàng rào thứ ba đi vào bên trong.

Bên trong mạng nơ-ron, mỗi bước xử lý là một vector vài nghìn chiều, và không chiều nào ứng với một khái niệm đọc được — mỗi khái niệm bị trộn lẫn trên rất nhiều chiều cùng lúc. Sparse Autoencoder là một mạng phụ được huấn luyện để bóc vector dày đặc đó thành vài chục nghìn “công tắc”, với ràng buộc gần như toàn bộ công tắc phải tắt tại mỗi thời điểm. Ràng buộc đó ép mỗi công tắc còn sáng phải mang một nghĩa cụ thể, và người ta đọc được nghĩa đó bằng cách xem nó sáng lên trước những đầu vào nào.

Có được các công tắc đọc được, ta dựng được cầu dao thời gian thực: khi nhóm công tắc đặc trưng cho hành vi bịa đặt sáng lên, hệ thống cắt luồng sinh chữ ngay tại token đó — trước khi câu trả lời hỏng kịp ra tới người dùng. Cùng một logic với circuit breaker mà bạn đã đặt trước các service hay lỗi, chỉ khác là nó nằm bên trong mô hình.

Cần nói thẳng mức trưởng thành của kỹ thuật này: nó mới, tốn kém, và hiện chủ yếu chạy được ở nơi có toàn quyền truy cập trọng số mô hình.3 Với đội dùng API đóng, hai lớp hàng rào phía trên mới là thứ triển khai được ngay.

VII. Tổng kết kiến trúc #

Vai trò người thiết kế hệ thống tĩnh của Software 1.0 đang nhường chỗ cho kỹ sư giám sát một luồng xác suất. Ba lớp hàng rào, xếp theo thứ tự nên triển khai:

  1. Constrained Decoding — chặn mọi token sai định dạng bằng JSON Schema hoặc regex, ngay tại tầng decode.
  2. Conformal Risk Control — đổi đánh giá cảm tính lấy một trần lỗi cam kết được bằng số, kèm cơ chế từ chối trả lời khi dưới ngưỡng.
  3. Internal Circuit Breaker — bẫy tín hiệu rủi ro ngay bên trong mạng bằng Sparse Autoencoder, trước khi đầu ra hỏng xuất hiện.
Lớp hàng ràoChặn đượcKhông chặn đượcCái giá phải trả
Constrained DecodingSai cú pháp, sai schemaNội dung sai nhưng đúng formatVài phần trăm độ trễ khi sinh chữ
Conformal Risk ControlTỉ lệ lỗi vượt trần đã cam kếtTừng lỗi đơn lẻTỉ lệ chuyển tay người tăng; cần tập hiệu chuẩn
Internal Circuit BreakerBịa đặt, ngay lúc đang sinhLỗi không để lại dấu bên trongCần quyền truy cập trọng số; chi phí hạ tầng

A clear technical illustration of a futuristic containment architecture. A highly structured, geometric cage made of thick, perfectly straight titanium silver bars. Securely contained inside the transparent cage is a vibrant, shifting, glowing sphere of interconnected cinnabar red data nodes (representing unpredictable AI weights). The silver cage is stable, orderly, and unyielding, effectively controlling the chaotic red energy inside. Modern anime background art style, highly detailed vector aesthetic, clean line art, flat colors, cel shading, bright, informative and easy to understand, pure off-white background.

VIII. Nguồn tham khảo #



  1. Absorbing Markov Chain: chuỗi chuyển trạng thái có ít nhất một trạng thái hấp thụ — bước vào rồi thì không chuyển đi đâu được nữa. Với mô hình sinh văn bản, trạng thái đó là token kết thúc <EOS>, và chạm tới nó là lúc quá trình sinh dừng lại. ↩︎

  2. Degenerate Loop: luồng sinh văn bản kẹt trong vòng lặp, lặp lại mãi một chuỗi token và không bao giờ chạm tới <EOS>. Trên production nó biểu hiện thành request treo tới trần max_tokens↩︎

  3. Sparse Autoencoder ở quy mô mô hình lớn còn là hướng nghiên cứu đang mở: chi phí huấn luyện lớp bóc tách không nhỏ, số lượng công tắc đọc được vẫn chỉ phủ một phần hành vi mô hình, và toàn bộ cách làm đòi hỏi truy cập trạng thái kích hoạt bên trong — thứ mà các API thương mại không mở ra. ↩︎