Thiết kế AI trả JSON đúng cấu trúc để workflow không vỡ ở bước sau
Đừng để một câu trả lời tự do của AI làm hỏng bước Sheets, CRM hay email. Playbook này hướng dẫn thiết kế schema, kiểm tra dữ liệu theo nghiệp vụ, xử lý refusal và phân nhánh an toàn cho workflow AI.
Một workflow nhận form khách hàng, nhờ AI phân loại rồi tạo lead trong CRM có thể hỏng chỉ vì AI trả thêm một câu như: “Dưới đây là JSON của bạn”.
Node kế tiếp không đọc được. Lead chưa được tạo, nhưng đội vận hành có thể tưởng rằng quy trình đã xong.
Nguy hiểm hơn: JSON vẫn hợp lệ về mặt kỹ thuật nhưng sai về nghiệp vụ. Trường email có thể trống, mức ưu tiên có thể bị suy diễn, hoặc AI có thể điền thông tin không có trong dữ liệu đầu vào.
Với workflow gửi email, cập nhật CRM hoặc xử lý dữ liệu, parse được JSON chỉ là điểm bắt đầu.
OpenAI Structured Outputs và Anthropic tool use là hai cơ chế giúp đưa đầu ra của mô hình về dạng có cấu trúc, để bước sau xử lý ổn định hơn. Đây là nền tảng hữu ích cho người dùng n8n, Make, Zapier, Power Automate, Apps Script và backend nội bộ.
Tách việc hiểu ngôn ngữ khỏi việc hành động
Hãy hình dung một luồng xử lý ticket:
Trigger: Có phản hồi mới từ form hoặc email.
AI step: Trích xuất loại yêu cầu, mức ưu tiên, thông tin liên hệ và đề xuất xử lý.
Action: Tạo ticket, gán người phụ trách hoặc chuẩn bị email phản hồi.
Nếu AI trả văn bản tự do, bạn phải dùng biểu thức, regex hoặc node Parse JSON để đoán lại ý của mô hình. Cách này dễ vỡ khi câu trả lời đổi cách diễn đạt.
Nếu đầu ra có schema rõ ràng, node sau chỉ cần đọc các trường như category, priority hoặc customeremail.
Theo tài liệu OpenAI, Structured Outputs giúp phản hồi tuân thủ JSON Schema được cung cấp. JSON Schema là hợp đồng dữ liệu, mô tả:
Có những trường nào.
Mỗi trường có kiểu dữ liệu gì.
Trường nào là bắt buộc.
Có chấp nhận trường ngoài schema hay không.
Tuy nhiên, schema chỉ kiểm soát cấu trúc. Workflow vẫn cần kiểm tra ngữ nghĩa nghiệp vụ trước khi hành động.
Ví dụ:
Một chuỗi có kiểu string chưa chắc là email có thể dùng.
Giá trị priority: "high" có thể đúng enum nhưng chưa chắc phù hợp với nội dung ticket.
Dữ liệu thiếu vẫn có thể cần chuyển sang người xử lý thay vì tự động tiếp tục.
Thiết kế schema từ node hành động ngược về node AI
Đừng bắt đầu bằng prompt: “Hãy phân loại ticket.”
Hãy bắt đầu ở node cuối: CRM, Sheet hoặc email thực sự cần trường nào?
Ví dụ, node tạo ticket có thể cần:
category: nhóm yêu cầu để định tuyến.
priority: mức ưu tiên hợp lệ.
customeremail: địa chỉ để phản hồi.
summary: tóm tắt ngắn cho nhân viên.
needshumanreview: cờ chặn các hành động cần người kiểm tra.
Một số nguyên tắc thiết kế schema:
Chỉ giữ field mà bước sau thực sự dùng. Schema càng lớn, việc đánh giá và xử lý dữ liệu càng khó.
Dùng enum cho tập giá trị hữu hạn. Không để mô hình tự tạo nhãn trạng thái mới ngoài workflow của bạn.
Khai báo trường bắt buộc rõ ràng. Structured Outputs giúp tránh bỏ sót required key.
Chặn thuộc tính ngoài ý muốn bằng additionalProperties: false khi hệ thống không cần nhận field lạ.
Có đường thoát khi bất định. Dùng cờ như needshumanreview thay vì buộc mô hình phải đoán.
Prompt vẫn quan trọng, dù Structured Outputs giúp giảm nhu cầu phải liên tục nhắc mô hình “chỉ trả JSON”.
text
Bạn là bước phân loại cho workflow hỗ trợ khách hàng.
Đọc nội dung: <tickettext>
Thông tin khách hàng đã có: <customercontext>
Chỉ trích xuất thông tin có căn cứ trong dữ liệu đầu vào.
Không tự suy diễn email, mức ưu tiên hoặc cam kết xử lý.
Nếu thiếu thông tin cần thiết, đặt needshumanreview là true.
Tóm tắt để nhân viên có thể đọc và xử lý tiếp.
Trong n8n hoặc Make, <tickettext> có thể là biến từ node trigger. Trong Apps Script hay backend, đó là nội dung ghép từ form, email hoặc CRM.
Chỉ gửi vào mô hình lượng dữ liệu cần thiết cho tác vụ. Nếu chỉ phân loại ticket, không cần đưa toàn bộ hồ sơ khách hàng vào prompt.
Dùng Structured Outputs để lấy object đã parse
OpenAI hỗ trợ khai báo schema bằng z.object trong JavaScript và nhận kết quả đã parse khi yêu cầu thành công.
Ví dụ dưới đây trích xuất thông tin sự kiện từ văn bản:
javascript
import OpenAI from "openai";
import { zodResponseFormat } from "openai/helpers/zod";
import { z } from "zod";
const openai = new OpenAI();
const CalendarEvent = z.object({
name: z.string(),
date: z.string(),
participants: z.array(z.string()),
});
const completion = await openai.chat.completions.parse({
model: "gpt-6-astra",
messages: [
{ role: "system", content: "Extract the event information." },
{
role: "user",
content: "Alice and Bob are going to a science fair on Friday.",
},
],
responseformat: zodResponseFormat(CalendarEvent, "event"),
});
const event = completion.choices[0].message.parsed;
Khi yêu cầu thành công và không có refusal, event là object với ba trường:
name
date
participants
Bạn có thể map từng trường sang cột Sheet, field CRM hoặc payload của node tiếp theo, thay vì cắt chuỗi từ một đoạn văn AI trả về.
Với đầu vào “Alice and Bob are going to a science fair on Friday”, workflow cần nhận được tên sự kiện, thông tin ngày được nhắc đến và danh sách người tham gia theo đúng schema.
Nếu hệ thống yêu cầu định dạng ngày riêng, chẳng hạn một chuẩn ngày nội bộ, vẫn nên đặt bước kiểm tra hoặc chuẩn hóa trước khi ghi vào lịch.
Tài liệu OpenAI cũng nêu:
Python có thể khai báo schema bằng pydantic.BaseModel.
Ruby SDK hỗ trợ schema qua T::Struct của Sorbet.
REST API hỗ trợ JSON Schema.
Với nền tảng no-code, hãy kiểm tra node hoặc connector OpenAI mà bạn đang dùng có hỗ trợ responseformat hoặc JSON Schema hay không.
Validate, retry và nhánh lỗi: không retry mọi thứ
Structured Outputs giảm nhu cầu validate hoặc retry vì lỗi định dạng. Nhưng một workflow vận hành thực tế vẫn nên có bước kiểm tra sau AI.
Điểm quan trọng là phân loại lỗi trước khi retry.
Nhánh A — Đúng cấu trúc, đạt quy tắc nghiệp vụ
Ví dụ: đủ field bắt buộc, giá trị thuộc tập workflow chấp nhận và dữ liệu cần thiết cho bước tiếp theo đã có.
Bạn có thể tiếp tục tạo ticket, ghi Sheet hoặc cập nhật CRM.
Nhánh B — Đúng cấu trúc nhưng chưa đủ nghĩa
Ví dụ:
AI đánh dấu needshumanreview: true.
Thiếu dữ liệu cần cho một hành động quan trọng.
Có field hợp lệ về kiểu dữ liệu nhưng không đủ căn cứ để thực hiện.
Không nên retry mù quáng. Thay vào đó, có thể tạo ticket cần bổ sung thông tin, thông báo cho nhân viên hoặc gửi mẫu hỏi lại khách hàng.
Nhánh C — Refusal
OpenAI cho biết refusal vì lý do an toàn có thể được phát hiện bằng lập trình.
Đây không phải lỗi JSON để ép chạy lại. Workflow nên ghi nhận trạng thái, dừng hành động tự động và chuyển sang hàng chờ người xử lý khi phù hợp.
Nhánh D — Lỗi gọi API hoặc lỗi node tạm thời
Đây là nhóm lỗi phù hợp hơn cho retry có kiểm soát.
Mỗi lần retry nên ghi lại:
ID workflow hoặc ID lần chạy.
Node gặp lỗi.
Trạng thái retry.
Mã lỗi trả về từ nhà cung cấp, nếu có.
Khi hết số lần retry mà đội ngũ đã đặt ra, chuyển dữ liệu sang một bảng hoặc hàng chờ cần xử lý lại. Đừng để workflow treo hoặc tự lặp vô hạn.
Với hành động có tác động lớn như gửi email, thanh toán, xóa dữ liệu hoặc sửa CRM, hãy cân nhắc đặt bước duyệt của con người trước action. AI có thể chuẩn bị JSON và bản nháp; người phụ trách là người duyệt hành động cuối cùng.
Để hạn chế gửi trùng hoặc tạo lead trùng khi retry, workflow cũng nên có cơ chế nhận diện lần chạy dựa trên ID của trigger.
Khi nào dùng workflow cố định, khi nào cần agent?
Nếu luồng đã rõ — form vào, AI phân loại, tạo ticket — workflow cố định thường là lựa chọn dễ quan sát và dễ kiểm tra hơn.
Agent phù hợp hơn khi mô hình cần chọn công cụ theo ngữ cảnh, chẳng hạn:
Tra CRM.
Tìm tài liệu liên quan.
Xác định có cần hỏi lại hay tạo yêu cầu mới.
Theo tài liệu Anthropic, tool use cho phép bạn định nghĩa tool kèm inputschema. Khi Claude quyết định gọi tool, ứng dụng nhận tooluse block, thực thi thao tác rồi gửi kết quả lại bằng toolresult.
Với chế độ mặc định, mô hình tự quyết định có gọi tool hay trả lời trực tiếp. Nếu một thao tác là bắt buộc, đừng chỉ dựa vào prompt. Hãy cấu hình lựa chọn tool phù hợp và kiểm soát quyền thực hiện hành động ở phía ứng dụng.
Tài liệu Anthropic cũng lưu ý: khi thiếu tham số bắt buộc, mô hình có thể hỏi lại, nhưng trong một số trường hợp cũng có thể suy diễn giá trị. Vì vậy, schema không thay thế quy tắc nghiệp vụ: thiếu dữ liệu quan trọng thì không tự hành động.
Vận hành an toàn: log đủ, gửi dữ liệu tối thiểu
Để truy vết lỗi, hãy cân nhắc lưu:
Input đã che dữ liệu nhạy cảm khi cần.
Phiên bản schema.
Output đã parse.
Nhánh workflow được chọn.
ID lần chạy.
Khi một field sai, bạn sẽ dễ xác định vấn đề nằm ở prompt, schema, mapping hay node action.
Không đặt API key trong prompt, Sheet công khai hoặc JSON gửi qua chat. Dùng biến môi trường hoặc cơ chế quản lý credential của nền tảng automation.
Chỉ gửi dữ liệu khách hàng tối thiểu cần cho tác vụ. Với email, số điện thoại và nội dung nhạy cảm, cần xác định rõ ai được xem log và thời gian lưu giữ.
Tài liệu tham chiếu không nêu giá, quota hay giới hạn riêng cho workflow của bạn. Trước khi chạy diện rộng, hãy theo dõi số lần gọi, lỗi retry và mức sử dụng trong dashboard của nhà cung cấp để đặt ngưỡng vận hành nội bộ.
Checklist trước khi bật workflow
[ ] Schema chỉ chứa field mà node sau thực sự cần.
[ ] Required, enum và additionalProperties đã được xác định.
[ ] Có nhánh riêng cho refusal, lỗi tạm thời và dữ liệu thiếu ý nghĩa.
[ ] Retry không thể gây gửi trùng hoặc ghi trùng.
[ ] Hành động có tác động lớn có bước duyệt phù hợp.
[ ] Log không làm lộ API key hoặc dữ liệu khách hàng không cần thiết.