Structured Output với Tool Use
Những điều bạn cần biết
Khi bạn cần structured output được đảm bảo tuân thủ schema từ Claude, có một thứ bậc độ tin cậy rất rõ ràng:
tool_usevới JSON schema — loại bỏ hoàn toàn lỗi cú pháp JSON- JSON dựa trên prompt — model có thể tạo ra JSON sai định dạng
Thứ bậc này là một khái niệm nền tảng trong đề thi. tool_use buộc Claude phải trả về dữ liệu tuân theo một JSON schema đã định nghĩa, loại bỏ các vấn đề cú pháp như thiếu dấu ngoặc, dấu phẩy thừa ở cuối, hoặc key không có dấu ngoặc kép. Trích xuất dựa trên prompt (yêu cầu model xuất ra JSON trong một câu trả lời dạng văn bản) không đưa ra bất kỳ đảm bảo cấu trúc nào và định kỳ sẽ tạo ra output không thể parse được khi chạy trong production.
tool_choice: Ba chế độ
Tham số tool_choice kiểm soát việc model có gọi tool hay không và gọi như thế nào. Hiểu rõ ba chế độ này là điều then chốt cho đề thi:
"auto" (mặc định): Model tự quyết định có gọi tool hay trả về văn bản. Model có thể chọn phản hồi bằng một tin nhắn văn bản thay vì gọi tool trích xuất. Dùng chế độ này khi model thực sự cần có tùy chọn phản hồi theo kiểu hội thoại.
"any": Model BẮT BUỘC phải gọi một tool nhưng được tự chọn tool nào. Dùng chế độ này khi bạn có nhiều schema trích xuất khác nhau (ví dụ extract_invoice, extract_receipt, extract_contract) và loại tài liệu chưa được biết trước. Model sẽ chọn tool phù hợp và trả về structured output. Đảm bảo có structured output, đồng thời linh hoạt trong việc chọn tool.
{"type": "tool", "name": "extract_metadata"}: Model BẮT BUỘC phải gọi đúng tool được nêu tên. Dùng cách này để ép buộc một bước bắt buộc đầu tiên — ví dụ, đảm bảo bước trích xuất metadata chạy trước các bước làm giàu dữ liệu (enrichment). Không có sự linh hoạt, kiểm soát tối đa.
typescriptCopy
// Force guaranteed structured output with unknown document type
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tool_choice: { type: "any" },
tools: [extractInvoiceTool, extractReceiptTool, extractContractTool],
messages: [{ role: "user", content: documentText }]
});
// Force a specific extraction step
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tool_choice: { type: "tool", name: "extract_metadata" },
tools: [extractMetadataTool],
messages: [{ role: "user", content: documentText }]
});Những điều tool_use KHÔNG ngăn chặn được
Đây chính là chỗ đề thi hay đánh lừa. tool_use với JSON schema chỉ loại bỏ lỗi cú pháp, nhưng KHÔNG ngăn chặn lỗi ngữ nghĩa:
- Sai lệch về tổng số: Các dòng chi tiết không cộng lại đúng bằng tổng đã nêu
- Lỗi đặt sai trường: Giá trị bị đặt nhầm trường (ví dụ, một ngày tháng nằm trong trường số tiền khi cả hai đều là kiểu string)
- Bịa đặt dữ liệu (fabrication): Model tự bịa ra giá trị cho các trường bắt buộc khi tài liệu gốc không có thông tin đó
Schema đảm bảo cấu trúc. Nó không đảm bảo tính chính xác. Việc xác thực ngữ nghĩa cần thêm logic riêng (được trình bày ở Task Statement 4.4).
Thiết kế schema cho production
Thiết kế schema hiệu quả ngăn chặn cả một nhóm lỗi ngay từ tầng cấu trúc:
Trường tùy chọn/nullable — Khi tài liệu gốc có thể không chứa một số thông tin nhất định, hãy đặt các trường đó là tùy chọn hoặc nullable. Đây là biện pháp phòng vệ chính chống lại việc bịa đặt dữ liệu. Nếu một trường là bắt buộc, model sẽ bị áp lực phải tạo ra một giá trị dù nguồn không có thông tin đó. Nếu trường đó là nullable, model có thể trung thực trả về null.
jsonCopy
{
"type": "object",
"properties": {
"invoice_number": { "type": "string" },
"vendor_name": { "type": "string" },
"payment_terms": { "type": ["string", "null"] },
"purchase_order": { "type": ["string", "null"] }
},
"required": ["invoice_number", "vendor_name"]
}Giá trị enum "unclear" — Với những trường hợp mơ hồ mà nguồn dữ liệu thực sự không rõ ràng, hãy thêm một tùy chọn "unclear" rõ ràng vào các trường enum. Điều này ngăn model bị ép phải đưa ra một phân loại khi bằng chứng còn mập mờ.
"other" + trường chi tiết dạng chuỗi — Để phân loại có thể mở rộng, hãy thêm một giá trị enum "other" đi kèm một trường chuỗi chi tiết tự do. Điều này giúp bắt được các trường hợp biên mà các hạng mục định trước của bạn chưa bao quát tới.
jsonCopy
{
"category": {
"type": "string",
"enum": ["invoice", "receipt", "contract", "unclear", "other"]
},
"category_detail": {
"type": ["string", "null"],
"description": "Freeform detail when category is 'other'"
}
}Quy tắc chuẩn hóa định dạng — Hãy đưa các chỉ dẫn chuẩn hóa định dạng vào trong prompt bên cạnh schema. Schema thực thi cấu trúc; prompt thực thi tính nhất quán về định dạng (ví dụ "Tất cả ngày tháng theo định dạng ISO 8601", "Tất cả số tiền là số thập phân, không kèm ký hiệu tiền tệ").
Khái niệm chính
tool_use với JSON schema loại bỏ lỗi cú pháp nhưng không loại bỏ lỗi ngữ nghĩa. Hãy đặt các trường là tùy chọn/nullable khi tài liệu gốc có thể thiếu thông tin — điều này ngăn model bịa đặt giá trị. Dùng tool_choice "any" để đảm bảo có structured output khi chưa biết trước loại tài liệu.
Bẫy thi
Bẫy thi: Tin rằng tool_use với JSON schema ngăn chặn được mọi lỗi trích xuất
tool_use chỉ loại bỏ lỗi cú pháp JSON. Lỗi ngữ nghĩa — các giá trị cộng không đúng, dữ liệu bị đặt sai trường, giá trị bịa đặt cho thông tin bị thiếu — vẫn xảy ra và cần được xác thực riêng.
Bẫy thi: Nhầm lẫn tool_choice 'auto' với 'any'
'auto' cho phép model trả về văn bản thay vì gọi tool — không đảm bảo có structured output. 'any' đảm bảo có lời gọi tool nhưng để model tự chọn tool nào. Để đảm bảo có structured output khi loại tài liệu chưa được biết trước, hãy dùng 'any'.
Bẫy thi: Đặt tất cả các trường trong schema là bắt buộc để đảm bảo dữ liệu đầy đủ
Các trường bắt buộc gây áp lực khiến model bịa ra giá trị khi thông tin không có trong nguồn dữ liệu. Các trường tùy chọn/nullable cho phép trả về null một cách trung thực, điều này luôn tốt hơn là dữ liệu bịa đặt trông có vẻ hợp lý.
Tình huống luyện tập
Không tìm thấy câu hỏi luyện tập "q-4-3-001".
Bài tập thực hành
Xây dựng một tool trích xuất dữ liệu có cấu trúc với JSON Schema
Bạn sẽ học được gì
- Thiết kế JSON schema với các trường tùy chọn/nullable để ngăn việc bịa đặt dữ liệu thiếu
- Hiểu ba chế độ tool_choice (auto, any, forced) và khi nào dùng chế độ nào
- Nhận diện rằng tool_use loại bỏ lỗi cú pháp nhưng không loại bỏ lỗi ngữ nghĩa
- Áp dụng các mẫu thiết kế schema: giá trị enum unclear, other + chuỗi chi tiết, chuẩn hóa định dạng
Các bước
Vì sao: Thiết kế schema trực tiếp ngăn chặn việc bịa đặt dữ liệu. Các trường bắt buộc gây áp lực khiến model bịa ra giá trị khi thông tin không có sẵn. Các trường tùy chọn/nullable cho phép trả về null một cách trung thực. Đây là cách khắc phục tận gốc dữ liệu trích xuất bị ảo giác.
Bạn sẽ thấy: Một JSON schema hợp lệ với mảng required chỉ chứa 3 trường luôn có mặt, các định nghĩa kiểu nullable cho các trường tùy chọn, và một mảng enum bao gồm unclear và other bên cạnh các hạng mục tiêu chuẩn.
Vì sao: Đề thi kiểm tra sự phân biệt giữa auto, any, và forced tool_choice. Auto cho phép model phản hồi theo kiểu hội thoại thay vì gọi tool, nghĩa là không có gì đảm bảo về structured output. Bạn cần tận mắt thấy chế độ thất bại này.
Bạn sẽ thấy: Ít nhất một phản hồi trong đó model trả về một tin nhắn văn bản mô tả nội dung tài liệu thay vì gọi tool trích xuất. Điều này minh họa tại sao auto không phù hợp khi bạn cần đảm bảo có structured output.
Vì sao: tool_choice any đảm bảo có lời gọi tool trong khi vẫn để model tự chọn tool nào. Đây là thiết lập đúng để đảm bảo có structured output khi loại tài liệu chưa được biết trước, một điểm phân biệt then chốt trong đề thi so với auto.
Bạn sẽ thấy: Mọi phản hồi đều có stop_reason là tool_use và chứa một lời gọi tool hợp lệ với structured output tuân theo schema của bạn. Không có phản hồi nào chỉ là văn bản.
Vì sao: Việc ép buộc chọn tool đảm bảo một bước bắt buộc đầu tiên luôn được thực thi bất kể quyết định của model. Đề thi kiểm tra điều này cho các tình huống như trích xuất metadata phải chạy trước các bước làm giàu dữ liệu.
Bạn sẽ thấy: Phản hồi luôn gọi đúng tool bạn đã chỉ định, ngay cả khi nội dung tài liệu có thể gợi ý một tool khác phù hợp hơn. Model không có sự linh hoạt nào trong việc chọn tool.
Vì sao: Bước này xác thực nguyên tắc thiết kế schema quan trọng nhất: các trường tùy chọn/nullable ngăn chặn việc bịa đặt dữ liệu. Đề thi kiểm tra cụ thể tình huống các trường bắt buộc gây áp lực khiến model bịa ra dữ liệu trông có vẻ hợp lý cho thông tin bị thiếu.
Bạn sẽ thấy: Với 3 tài liệu đầy đủ, tất cả các trường được điền giá trị đúng. Với 2 tài liệu thiếu thông tin, các trường nullable trả về null thay vì giá trị bịa đặt. Không có ngày tháng, số tiền, hay mã định danh nào bị bịa ra.
Nguồn tham khảo
- Claude Certified Architect Foundations Exam Guide — Task Statement 4.3 — Anthropic
- Tool Use (Function Calling) — Anthropic
- Building with Claude API (Skilljar) — Anthropic