Kế 22: Bày trận địa lợi — Structured output ép format
Kế 22 Binh pháp AI: Dùng grammar-constrained decoding ép AI trả về JSON, bảng biểu, XML chuẩn xác 100%. Giảm 90% lỗi parsing và post-processing.
Gia Cát Lượng và Bát Quái Trận Đồ
Truyền kỳ kể rằng, khi Gia Cát Lượng lần đầu ra quân ở Nam An, quân sĩ đều kinh hãi trước địa hình hiểm trở. Ông không bắt quân sĩ xông pha loạn đả, mà sai họ dựng đá, cắm cờ theo hình Bát Quái. Khi địch quân lao vào, họ không còn đường thoát — mỗi bước đều bị ép vào một ngõ cụt do địa thế và cờ trận định sẵn. Địch không bị giết bởi gươm giáo, mà bị vây bởi chính sự kết hợp giữa địa lợi (terrain) và trận pháp (formation).
Kế 22: Bày trận địa lợi trong Binh pháp AI chính là nghệ thuật này — không "nhờ" AI trả về JSON rồi cầu nguyện nó đúng format, mà bày trận địa hình (grammar constraint) để ép buộc AI chỉ có thể đi theo đúng lối thoát duy nhất: output hợp lệ.
Vấn đề: Cỗ xe tăng trong đầm lầy
Bạn ra lệnh: "Trả về JSON có trường name và age". AI đáp:
Sure! Here is the JSON you requested:
```json
{
"name": "Nguyễn Văn A",
"age": 28,
}Chúc bạn một ngày tốt lành!
Hoặc: thiếu dấu phẩy cuối, thêm dấu nháy đơn thay vì nháy kép, hoặc tự động sinh thêm trường `"explanation"` không có trong schema. Với 100 request, bạn nhận 85 JSON hợp lệ và 15 cái lỗi — đủ để pipeline ETL của bạn crash giữa đêm.
Cách "thông thường" để xử lý là viết regex để cắt bỏ "Sure! Here is...", rồi dùng `json.loads()` kèm try-except, rồi retry... Đây là đánh giặc bằng cách đuổi theo từng tên lính chạy trốn (post-processing) thay vì bày trận từ đầu để chúng không thể chạy.
## Kế sách: Vây thành ép hàng bằng Grammar-Constrained Decoding
**Định nghĩa đơn giản:** Thay vì để AI tự do dự đoán token tiếp theo, ta dùng **Finite State Machine (FSM)** — một bản đồ địa hình (grammar) — để vật lý xóa xác suất của mọi token "bước sai hướng" về 0. AI không còn "lựa chọn" viết prose hay JSON; nó bị ép buộc phải đi theo con đường duy nhất còn lại: cú pháp chuẩn xác.
### ### Via Negativa: Cấm đường sai thay vì chỉ đường đúng
Tương tự như kỹ thuật "Via Negativa" trong lý thuyết đầu tư — loại bỏ cái sai dễ hơn chọn đúng cái đúng — ta không nói *"Hãy viết JSON đúng"*, mà dùng constraint để cấm mọi token không hợp lệ ngay tại bước sampling.
**Cơ chế vật lý:**
1. **Grammar Parsing:** Chuyển JSON Schema hoặc regex thành cây trạng thái (state machine).
2. **Logit Masking:** Tại mỗi bước sinh token, engine kiểm tra: *"Nếu thêm token này, có còn valid theo schema không?"*
3. **Zero Probability:** Nếu không, set probability của token đó về 0 trong softmax distribution trước khi sampling.
4. **Forced Compliance:** AI chỉ có thể chọn từ những token "còn sống sót" — tức là những token giữ cú pháp đúng.
**Prompt mẫu (kết hợp với tool):**
```python
# Sử dụng Outlines hoặc Instructor để ép buộc
from pydantic import BaseModel
import instructor
from openai import OpenAI
class Invoice(BaseModel):
amount: float
currency: str
due_date: str
client = instructor.patch(OpenAI())
# FSM tự động ép AI chỉ sinh token hợp lệ cho schema này
invoice = client.chat.completions.create(
model="gpt-4o",
response_model=Invoice, # Constraint vật lý
messages=[{"role": "user", "content": "Trích xuất hóa đơn từ: 'Thanh toán 500 USD trước 2024-12-25'"}]
)
# Luôn trả về object Python hợp lệ, không cần parse, không có "Sure!"Output mẫu:
- Trước (thông thường):
{"amount": 500, "currency": "USD", "due_date": "25/12/2024"} + [trailing comma lỗi] - Sau (ép format):
Invoice(amount=500.0, currency='USD', due_date='2024-12-25')— 100% valid, không cần regex.
### Các công cụ trận địa
| Công cụ | Cơ chế | Ưu điểm |
|---|---|---|
| Outlines | FSM-based GCD | Mã nguồn mở, hỗ trợ regex, CFG, JSON Schema |
| Instructor | Pydantic + GCD | Tích hợp sẵn với OpenAI, Anthropic, tự retry |
| SGLang | Đa mô hình + constrained decoding | Tốc độ cao cho inference song song |
| OpenAI JSON Mode | API-level constraint | Dễ dùng nhưng ít linh hoạt hơn custom FSM |
Tại sao kế này hiệu quả: Vật lý của sự ép buộc
Bản chất LLM là "path walker" không có rào chắn. Khi bạn prompt "give me JSON", bạn hy vọng model tự nguyện đi đúng đường trong khu rừng token rộng lớn. Nhưng model đang "say rượu" trên distribution — nó có thể rẽ lầm vào Certainly! Here is hay dấu phẩy thừa bất cứ lúc nào.
Grammar-Constrained Decoding xây tường thành quanh những con đường sai. Tại mỗi ngã ba, nó vật lý chặn lối rẽ bằng cách set probability của invalid tokens về 0. Model không "cố gắng tuân thủ hơn"; thay vào đó, kết quả đúng format là sự đầu hàng duy nhất có thể (ép hàng) khi mọi lối thoát khác bị cắt đứt.
Hiệu suất thực tế:
- Độ chính xác cú pháp: Tăng từ
`<95%`(prompt-based) lên 100% (constrained decoding). - Thời gian xử lý: Giảm 80% thời gian post-processing (không cần retry, validate, sửa lỗi thủ công).
- Tốc độ inference: Chậm hơn ~10-30% do overhead FSM checker tại mỗi step, nhưng bù lại bằng việc loại bỏ bước validate/retry.
Trade-off cần biết: Constraint đảm bảo syntactic correctness (cú pháp đúng), không đảm bảo semantic correctness (nội dung đúng). AI vẫn có thể sinh {"amount": -999} (sai logic) dù JSON valid.
Ứng dụng thực chiến: Ai nên bày trận?
### Nếu bạn là Developer (API Integration)
Xây dựng endpoint trả về JSON cho mobile app. Dùng Instructor hoặc Outlines để đảm bảo mobile không bao giờ nhận được response crash app. Kết hợp với Pydantic để validation 2 lớp: constraint ép cú pháp, Pydantic ép kiểu dữ liệu.
### Nếu bạn là Data Analyst (Extraction)
Trích xuất dữ liệu từ 10.000 hóa đơn scan. Thay vì nhờ AI "viết CSV rồi tôi copy vào Excel", dùng constraint ép AI trả về chuẩn CSV với header cố định, không thêm dòng giải thích, không thiếu cột. Pipeline chạy lights-out mà không cần người kiểm tra từng dòng.
### Nếu bạn là AI Engineer (Multi-Agent Systems)
Thiết kế hệ thống multi-agent (Kế 29). Agent A truyền message cho Agent B qua API. Dùng strict JSON Schema với additionalProperties: false để ngăn Agent A tự ý thêm field "helpful_comment" làm Agent B parse lỗi. Giao tiếp liên quân cần địa lợi (protocol) chặt chẽ.
So sánh: Prompt "lịch sự" vs Bày trận ép buộc
| Chiến thuật | Tỷ lệ lỗi cú pháp | Cần post-process | Độ trễ | Chi phí token |
|---|---|---|---|---|
| Prompt thông thường ("Hãy trả JSON") | ~15-20% | Cao (regex, retry) | Thấp (1 pass) | Lãng phí do retry |
| Few-shot examples | ~5-10% | Trung bình | Thấp | Tăng input tokens |
| JSON Mode (OpenAI) | ~2-5% | Thấp | Thấp | Giống base |
| Grammar-Constrained (Outlines/Instructor) | 0% | Không | Cao hơn 10-30% | Tối ưu (no retry) |
Kết luận: Nếu bạn đang viết script một lần dùng, prompt thông thường đủ dùng. Nếu bạn xây hệ thống production, "Bày trận địa lợi" là kế sách bắt buộc — giống như bạn không bao giờ viết API trả về "gần đúng JSON".
Đọc thêm: Các kế liên quan
Kế 21: Đường tiếp vận RAG
Nối kho kiến thức vào AI để có dữ liệu đúng trước khi ép format
Kế 23: Căn cứ ký ức
Dùng memory files để AI nhớ cấu trúc output xuyên suốt nhiều session
Kế 24: Vây hãm tài liệu
Chiến thuật xử lý tài liệu 100+ trang trước khi ép vào structured output
Đọc tiếp Level 1: Kế 23: Căn cứ ký ức — Khi đã có format chuẩn, làm sao để AI không "quên" cấu hình này giữa các phiên làm việc?
Kế 21: Đường tiếp vận RAG — Nối knowledge base vào AI
Kế 21 Binh pháp AI: Mở kho kiến thức nội bộ cho AI bằng RAG. Giải quyết triệt để lỗi thời thông tin và ảo giác, biến AI thành chuyên gia domain cụ thể.
Kế 23: Căn cứ ký ức — Memory để AI nhớ xuyên sessions
Kế 23 Binh pháp AI: Xây dựng hệ thống memory file hai tầng (session + permanent) để AI không bị 'não cá vàng' giữa các phiên làm việc, tăng hiệu quả dự án dà...