Chạy agent song song theo DAG: tiết kiệm 4 phút, đổi gì?
Số đo thật từ một issue chia thành DAG cho agent chạy song song: 14m40s xuống 10m22s, vì sao chọn barrier thay vì eager, và các chi phí đi kèm.
Bạn mở ba tab agent cho cùng một issue, mỗi tab sửa một phần, rồi mất cả buổi chiều gỡ conflict ở lần merge cuối. Phần code chạy nhanh; phần đau nằm ở chỗ ghép lại. Bài này lấy số đo thật từ một workflow chia issue thành DAG rồi cho agent chạy song song — kèm chỗ mà khoản tiết kiệm biến thành chi phí.
Node là đơn vị code, edge là phụ thuộc thật
Tác giả công cụ vincent (bản 0.8.0) mô tả cấu trúc gọn: "nodes are implementation units, needs edges describe real dependencies, independent nodes can run in parallel". Mỗi unit lấy branch và worktree riêng, unit phụ thuộc bắt đầu từ branch đã chứa dependency của nó, và cuối cùng "an integration step validates the combined result".
Chi tiết đáng copy về repo của bạn: giới hạn phạm vi file của từng lane — theo tác giả, công cụ này "constrains lanes to avoid agents modifying overlapping files". Conflict biến mất vì hai lane không chạm cùng file, không phải vì bạn chạy song song.
Số đo thật: ba unit, hai wave, tiết kiệm ~4 phút
Trên một issue thật (issue #324), việc được chia thành ba unit qua hai wave: wave 1 tạo dependency, wave 2 chạy hai lane độc lập song song. Thời gian code của các lane khoảng 4m18s và 10m22s. Tuần tự là "~14m40s", chạy như một wave song song là "~10m22s" — tiết kiệm khoảng bốn phút. Tác giả nói thẳng về con số đó: "That number isn't spectacular, and I don't want to pretend it is."
Giá trị thật không nằm ở bốn phút mà ở tính chất scale: "the floor becomes the longest dependency chain through the graph rather than the sum of all independent work". Đọc ngược lại sẽ ra tiêu chí quyết định: nếu DAG của issue gần như một chuỗi thẳng, song song hoá không trả lại gì.
Barrier hay eager: số liệu chọn barrier
Phần phản trực giác nhất: eager scheduling cho phép việc phụ thuộc chạy ngay khi dependency của nó xong, nghe hiển nhiên là tốt hơn. Nhưng theo tác giả, trên các workflow thực đã chạy, nó "saved zero additional time compared with barrier", và đánh đổi tính tái lập: "an eagerly scheduled lane can start from a different branch state depending on timing". Với code do agent sinh ra, mất tái lập là mất khả năng debug. Kết luận của tác giả: "Get the graph right first. The scheduler is the last thing to optimize."
Chi phí đi kèm được liệt kê rõ: "More parallel lanes mean more agent sessions, more worktrees, more merges, and more opportunities for integration problems." Phân tích thêm: mỗi lane là một session riêng nên chi phí token tăng theo số lane, còn thời gian chỉ giảm tới chuỗi phụ thuộc dài nhất — đổi tiền lấy wall-clock, không phải tối ưu miễn phí.
Cổng chặn nằm ở bước integration
Bước integration cần bắt thứ mà snapshot test bỏ qua. Một test plan cho patch do agent sinh mô tả lỗi đặc trưng: "They match a snapshot you already had, then break a relation you never wrote down. Golden files do not catch that class of defect." Bẫy thứ hai là test vòng tròn: "Those tests pass because they were generated from the same patch."
Cách chặn được đề xuất là metamorphic check — "a relation that must hold across transformations: round-trip, permutation, idempotence, monotonicity, or error preservation" — và giữ danh sách quan hệ đó ngoài tầm ghi của agent: "Keep relations in a file the patch job cannot write." Tác giả nói rõ đây là "a proposed workflow", chưa phải số đo production — hãy tự đo lại.
Thử theo thứ tự này
- Vẽ DAG cho issue kế tiếp, đếm chuỗi phụ thuộc dài nhất; nếu nó chiếm gần hết tổng thời gian, đừng mở lane thứ hai.
- Chạy barrier trước, đo lại, chỉ thử eager khi barrier đã hết chỗ cải thiện.
- Viết 3-4 quan hệ bất biến cho module agent được sửa, để file đó ngoài quyền ghi của job.
Không spam, hủy đăng ký bất kỳ lúc nào.
Bài viết liên quan

MCP hay agent loop? Chọn kiến trúc và chỗ chặn an toàn
04 thg 9, 2026