Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 5 — Xây hệ phân cấp (hierarchical) từng bước

Đã đọc 0/9 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Khi tác vụ đủ lớn, một supervisor với chục worker cũng bị quá tải quyết định. Giải pháp: phân cấp — supervisor cấp cao điều phối các supervisor cấp dưới, mỗi cái quản một nhóm worker theo lĩnh vực. Giống công ty: CEO → trưởng phòng → nhân viên.

Khi nào cần phân cấp

Khi số worker vượt ~6–8, hoặc khi các worker gom được thành cụm lĩnh vực rõ ràng (nghiên cứu, viết, kiểm thử). Dưới ngưỡng đó, một supervisor phẳng thường tốt hơn — phân cấp thêm tầng độ trễ và điểm lỗi.

Kiến trúc ví dụ: nhà máy nội dung

Top Supervisor (điều phối toàn bộ báo cáo)
 +-- Research Team Lead
 |     +-- Web Researcher
 |     +-- Data Analyst
 +-- Writing Team Lead
 |     +-- Draft Writer
 |     +-- Editor
 +-- QA Lead
       +-- Fact Checker
       +-- Style Critic

Top Supervisor giao "chuẩn bị dữ liệu" cho Research Lead; Research Lead tự điều phối Web Researcher + Data Analyst rồi trả một gói kết quả gọn lên trên. Top Supervisor không cần biết chi tiết bên trong team — đúng nguyên tắc đóng gói.

Xây từng bước

  • Vẽ cây trách nhiệm. Mỗi nút một câu mô tả. Không code trước khi cây rõ.
  • Định nghĩa hợp đồng lên/xuống mỗi tầng. Team lead nhận task tóm tắt từ trên, trả kết quả tóm tắt lên — không rò rỉ chi tiết nội bộ.
  • Xây từ dưới lên. Làm worker lá chạy được trước, test độc lập.
  • Ghép mỗi team lead + worker của nó, test như một khối kín.
  • Ghép top supervisor cuối cùng.
  • Thêm giới hạn ngân sách bước cho từng tầng để lỗi ở nhánh không lan.

Đoạn cấu trúc

class TeamLead:
    def __init__(self, name, workers, max_steps=6):
        self.name = name
        self.workers = workers        # dict[name -> agent]
        self.max_steps = max_steps
    def run(self, task):
        state = {"task": task, "history": []}
        for _ in range(self.max_steps):
            d = self.decide(state)
            if d.get("done"):
                return self.summarize(state)   # gói gọn trả lên trên
            r = self.workers[d["worker"]].run(d["task"])
            state["history"].append(r)
        return self.summarize(state)

top = Supervisor(teams={
    "research": TeamLead("research", {...}),
    "writing":  TeamLead("writing",  {...}),
    "qa":       TeamLead("qa",       {...}),
})

summarize() là chìa khóa: nó nén trạng thái nội bộ thành gói gọn cho tầng trên. Không có nó, ngữ cảnh sẽ leo dốc theo mỗi tầng.

Khung tư duy: mỗi tầng là một hộp đen

Tầng trên chỉ nên thấy giao diện (task vào, kết quả ra) của tầng dưới, không thấy ruột. Đây là đóng gói (encapsulation) áp cho agent. Nó giữ ngữ cảnh mỗi tầng nhỏ và cho phép thay ruột team mà không ảnh hưởng tầng trên.

Checklist

  • [ ] Cây trách nhiệm mỗi nút mô tả được trong một câu.
  • [ ] Mỗi tầng có hợp đồng vào/ra rõ và có summarize.
  • [ ] Ngân sách bước riêng cho từng tầng.
  • [ ] Worker lá test được độc lập trước khi ghép.

Sai lầm thường gặp

  • Phân cấp quá sớm/quá sâu. 3 tầng cho tác vụ 5 bước là over-engineering; độ trễ và lỗi tăng vô ích.
  • Không nén kết quả giữa tầng. Chi tiết nội bộ rò lên trên, ngữ cảnh phình, mất lợi ích phân cấp.
  • Ngân sách bước dùng chung toàn hệ. Một nhánh lỗi ngốn hết budget, các nhánh khác chết đói.
  • Ghép từ trên xuống. Không test được nút lá độc lập, khi lỗi không biết tầng nào gây ra.

Ví dụ thất bại điển hình và cách chữa

Một team dựng hệ 3 tầng cho tác vụ soạn hợp đồng. Ban đầu chạy tốt, nhưng khi Fact Checker (nút lá) trả kết quả dài dòng, Team Lead truyền nguyên văn lên Top Supervisor. Sau vài lượt, ngữ cảnh của Top Supervisor phình tới mức nó bắt đầu 'quên' mục tiêu gốc. Chẩn đoán: thiếu bước summarize nén kết quả giữa tầng. Cách chữa là ép mỗi Team Lead trả về một gói cố định — ví dụ tối đa 5 bullet + trạng thái done/blocked — thay vì transcript nội bộ.

def summarize(self, state):
    return {
        "team": self.name,
        "status": "done" if state.get("complete") else "blocked",
        "key_findings": top_n(state["history"], n=5),  # nén, không đổ thô
        "open_issues": state.get("blockers", []),
    }

Bài học: trong hệ phân cấp, kỷ luật nén ngữ cảnh giữa tầng quan trọng ngang việc chia tầng cho đúng. Một cây đẹp mà rò chi tiết giữa các tầng sẽ mất sạch lợi ích đóng gói và biến thành một agent khổng lồ ngụy trang.

Bài 6 chuyển sang một tô-pô khác: các agent ngang hàng cộng tác (không có sếp) và khi nào nó hợp lý hơn supervisor.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi