5. Đầu ra có cấu trúc (Structured Output)

Nam

Nam Hoang / Feb 05, 2026

6 min read

Điểm tập trung của bài này là giúp bạn điều khiển định dạng đầu ra của AI. Thay vì trả về một đoạn hội thoại tự do, Agent sẽ trả về một đối tượng Javascript (JSON) sạch sẽ để ứng dụng của bạn có thể xử lý logic ngay lập tức.

I. Tại sao cần Structured Output?

Văn bản tự nhiên rất tốt cho con người, nhưng máy tính cần dữ liệu có cấu trúc. Structured Output cực kỳ hữu ích khi bạn cần:

  1. Trích xuất thông tin: Lấy tên khách hàng, mã đơn hàng từ một đoạn chat.
  2. Phân loại: Gán nhãn cho nội dung (ví dụ: "Tích cực", "Tiêu cực").
  3. Tích hợp hệ thống: Biến AI thành một API trả về dữ liệu cho ứng dụng Web hoặc Mobile.

II. Tham số responseFormat và Zod

Trong hàm createAgent, LangChain cung cấp tham số responseFormat. Bạn chỉ cần truyền vào một Zod Schema, LangChain sẽ tự động yêu cầu AI tuân thủ cấu trúc đó. Model Gemini 2.5 Flash (được khởi tạo qua tiện ích nội bộ) có khả năng xử lý JSON rất tốt và chính xác.

III. Mã nguồn: 05-understanding-structured-output.ts

Chúng ta sẽ xây dựng một Agent chuyên phân tích đánh giá sản phẩm. Lưu ý cách nạp môi trường và sử dụng model tập trung đã thiết lập ở các bài trước.

// apps/langchain/scripts/05-understanding-structured-output.ts
// pnpm --filter=ai-notes-langchain run tsx scripts/05-understanding-structured-output.ts

import './env'; // Load API keys
import { createGeminiModel, generateImage } from '@workspace/util-langchain';
import { createAgent } from 'langchain';
import { z } from 'zod';

// 1. Define the data structure using Zod
const ReviewAnalysisSchema = z.object({
  sentiment: z
    .enum(['Positive', 'Negative', 'Neutral'])
    .describe('The overall sentiment of the customer'),
  rating: z.number().min(1).max(5).describe('Star rating from 1 to 5'),
  summary: z.string().describe('A one-sentence summary of the review'),
  features: z.array(z.string()).describe('List of product features mentioned'),
});

async function main() {
  const model = createGeminiModel();

  // 2. Initialize Agent with responseFormat
  const agent = createAgent({
    model: model,
    // This forces the output to match the ReviewAnalysisSchema
    responseFormat: ReviewAnalysisSchema,
    systemPrompt:
      'You are a customer data analyst. Extract key information from reviews accurately.',
  });

  // 3. Generate visual diagram
  await generateImage(
    agent.graph,
    'graph-ignore/scripts-05-structured-output.jpg',
  );

  console.log('--- Analyzing customer review... ---');

  // 4. Execute the Agent
  const result = await agent.invoke({
    messages: [
      {
        role: 'user',
        content:
          'The product is amazing, the design is sleek and battery life is great. However, price is a bit high, I give it 4 stars.',
      },
    ],
  });

  // 5. Access the JSON data via 'structuredResponse'
  console.log('\nStructured JSON Result:');
  console.log(JSON.stringify(result.structuredResponse, null, 2));

  if (result.structuredResponse) {
    console.log(
      `\nConclusion: Customer sentiment is ${result.structuredResponse.sentiment}`,
    );
  }
}

main().catch(console.error);

IV. Phân tích kỹ thuật

  • structuredResponse: Đây là thuộc tính quan trọng nhất. Sau khi thực thi, Agent trả về một đối tượng đã được giải mã (parsed) sẵn, bạn có thể truy cập result.structuredResponse.sentiment như code Javascript thông thường.
  • Tự động sửa lỗi: Nếu AI trả về JSON sai định dạng, LangChain sẽ tự động gửi thông báo lỗi ngược lại cho AI và yêu cầu nó sửa lại cho đến khi đạt chuẩn Zod.
  • Mô tả trường (.describe): Các dòng mô tả trong Zod schema giúp AI hiểu rõ ngữ cảnh và ý nghĩa của từng thuộc tính cần điền.

Sơ đồ hoạt động:

Sơ đồ Structured Output Agent

V. Cách chạy code

Sử dụng lệnh sau để thực thi:

pnpm --filter=ai-notes-langchain run tsx scripts/05-understanding-structured-output.ts

Điểm mấu chốt cần nhớ

  • Sử dụng Zod để định nghĩa "khuôn mẫu" dữ liệu mong muốn.
  • Truyền schema vào tham số responseFormat của createAgent.
  • Kết quả được trả về trực tiếp trong thuộc tính structuredResponse.
  • Kết hợp với hệ thống env.tsutil-langchain giúp quy trình phát triển chuyên nghiệp và bảo mật hơn.

Trong bài học tiếp theo, chúng ta sẽ học kỹ hơn về cách Xác thực dữ liệu phức tạp để đảm bảo Agent luôn trả về dữ liệu hoàn hảo, không có lỗi logic!

👉 Bài tiếp theo: 6. Xác thực dữ liệu với Zod Schema