18. Kiến trúc Supervisor & Subagents

Nam

Nam Hoang / Feb 17, 2026

8 min read

Trong các bài học trước, chúng ta đã xây dựng những Agent đơn lẻ có khả năng xử lý nhiều công cụ. Tuy nhiên, khi nhiệm vụ trở nên quá phức tạp, việc nhồi nhét mọi thứ vào một Agent sẽ dẫn đến vấn đề "Ngộp ngữ cảnh" (Context Bloat), làm giảm độ chính xác và tốn Token. Bài học này sẽ hướng dẫn bạn kiến trúc Supervisor & Subagents để chia nhỏ gánh nặng, tích hợp vào hệ thống chuyên nghiệp từ Bài 1.

I. Tại sao cần chia nhỏ Agent?

Hãy tưởng tượng một quy trình: Tìm tin tức -> Viết báo cáo chuyên sâu -> Dịch thuật.

  • Nếu dùng 1 Agent: Nó phải giữ hàng chục kết quả tìm kiếm thô trong đầu khi đang cố gắng dịch thuật. Điều này dễ làm AI bị "loạn" và đưa ra kết quả kém chất lượng.
  • Kiến trúc Đa Agent:
    • Researcher chỉ lo tìm kiếm và trả về bản tóm tắt gọn gàng.
    • Writer nhận bản tóm tắt đó để viết bài.
    • Supervisor (Quản lý) đứng ở giữa để điều phối luồng công việc.

Kết quả là mỗi Agent chỉ nhận được thông tin vừa đủ và chính xác nhất cho nhiệm vụ của mình.

II. Cơ chế hoạt động của Subagents

Chúng ta sử dụng thư viện deepagents (một phần mở rộng của hệ sinh thái LangChain) để cấp cho Supervisor một công cụ đặc biệt gọi là task. Công cụ này cho phép Supervisor "thuê" một Agent chuyên gia chạy trong một không gian (Thread) riêng biệt, hoàn thành việc và chỉ gửi lại kết quả cuối cùng.

III. Mã nguồn: 18-supervisor-subagent-orchestration.ts

Chúng ta sẽ xây dựng một đội ngũ nội dung chuyên nghiệp sử dụng Gemini 2.5 Flash và hệ thống quản lý môi trường env.ts.

// apps/langchain/scripts/18-supervisor-subagent-orchestration.ts
// pnpm --filter=ai-notes-langchain run tsx scripts/18-supervisor-subagent-orchestration.ts

import './env';
import { createGeminiModel, generateImage } from '@workspace/util-langchain';
import { createAgent, tool } from 'langchain';
import { createSubAgentMiddleware, type SubAgent } from 'deepagents';
import { z } from 'zod';

// 1. Define a specialist tool for the Researcher
const searchTool = tool(
  async ({ query }) => {
    // Simulate real-time web search results
    return `[Web Search Result for "${query}"]: LangChain 1.0 has been released with native Multi-agent orchestration and improved streaming.`;
  },
  {
    name: 'internet_search',
    description: 'Search for raw data on the internet.',
    schema: z.object({ query: z.string() }),
  },
);

// 2. Define Sub-agents (The Specialists)
const researcher: SubAgent = {
  name: 'researcher_specialist',
  description: 'Gathers raw data from the web. Returns facts, not formatting.',
  systemPrompt:
    'Your only job is to use the search tool to get accurate raw data.',
  tools: [searchTool],
  model: createGeminiModel({ model: 'gemini-1.5-flash' }), // Efficient model for searching
};

const writer: SubAgent = {
  name: 'content_writer',
  description:
    'Professional editor. Transforms raw facts into engaging articles.',
  systemPrompt:
    'You rewrite raw data into professional blog posts. No tools needed.',
  tools: [],
  model: createGeminiModel({ model: 'gemini-1.5-flash' }),
};

async function main() {
  // 3. Initialize the Supervisor (The Manager)
  const supervisorModel = createGeminiModel({ model: 'gemini-2.0-flash' }); // Powerful model for planning

  const supervisorAgent = createAgent({
    model: supervisorModel,
    systemPrompt: `You are a Project Manager. 
    1. Assign 'researcher_specialist' to find raw data.
    2. Assign 'content_writer' to write a post based on that data.
    3. Return the final post to the user.`,
    middleware: [
      createSubAgentMiddleware({
        subagents: [researcher, writer],
        defaultModel: supervisorModel,
      }),
    ],
  });

  // 4. Generate visual diagram
  await generateImage(
    supervisorAgent,
    'images/courses/langchain-course/scripts-18-multi-agent.jpg',
  );

  console.log('--- Starting Multi-Agent Team Workflow ---');

  // 5. Execute a complex request
  const result = await supervisorAgent.invoke({
    messages: [
      {
        role: 'user',
        content:
          'Research about LangChain 1.0 and write a short introduction for me.',
      },
    ],
  });

  console.log('\n--- FINAL DELIVERABLE ---');
  console.log(result.messages.at(-1).content);
}

main().catch(console.error);

IV. Phân tích quy trình điều phối

Khi bạn chạy mã nguồn này, hệ thống thực hiện quy trình Context Isolation cực kỳ hiệu quả:

  1. Phân tích (Supervisor): Supervisor nhận yêu cầu và tự động gọi công cụ task(agentName="researcher_specialist", ... ).
  2. Cô lập (Researcher): Agent Researcher được khởi tạo. Nó chỉ thấy nhiệm vụ tìm kiếm. Toàn bộ lịch sử gọi tool và dữ liệu thô của nó nằm trong một "vùng an toàn" riêng.
  3. Bàn giao (Result Handoff): Researcher trả về một đoạn text kết quả. Các tin nhắn rác (tool messages) bị loại bỏ hoàn toàn khỏi ngữ cảnh của Supervisor.
  4. Tổng hợp (Writer): Supervisor nhận kết quả sạch, sau đó bàn giao tiếp cho Writer để biên tập lại.
  5. Hoàn tất: Người dùng nhận được bài viết cuối cùng mà không hề biết về quá trình tra cứu phức tạp bên dưới.

Sơ đồ hoạt động:

Bạn có thể thấy Supervisor đóng vai trò là "nút thắt" trung tâm điều phối các nhánh chuyên gia:

Sơ đồ Multi-agent Team

V. Tổng kết

  • Kiến trúc Supervisor giúp giải quyết bài toán phức tạp bằng cách chia nhỏ để trị.
  • Context Isolation bảo vệ Agent khỏi việc bị quá tải dữ liệu, giúp tăng độ chính xác của suy luận.
  • Sử dụng các model khác nhau cho Supervisor (Mạnh/Đắt) và Subagents (Nhanh/Rẻ) là chiến lược tối ưu chi phí trong production.
  • Hệ thống env.tsutil-langchain giúp bạn quản lý một đội ngũ nhiều Agent một cách nhất quán và dễ dàng theo dõi qua sơ đồ.

Trong bài học tiếp theo, chúng ta sẽ học về Agent Handoffs — cách để các Agent có thể chủ động "nhường sân" cho nhau một cách trực tiếp mà không cần sự can thiệp liên tục của Supervisor!

👉 Bài tiếp theo: 19. Bàn giao quyền điều khiển (Handoffs)