Khi các tác nhân đảm nhận những nhiệm vụ tham vọng hơn, chúng gặp khó khăn trong việc:
- Hoàn thành công việc một cách đáng tin cậy ở quy mô lớn
- Quản lý ngữ cảnh của chính chúng
Chúng tôi đã thử nghiệm cách giải quyết những thách thức này dưới hình thức mà chúng tôi gọi là dynamic subagents: thay vì đưa ra các tác vụ cho subagent thông qua lệnh gọi công cụ chung chung, tác nhân sẽ viết một tập lệnh ngắn để điều khiển việc thực thi subagent. Điều này có nghĩa là các mô hình có thể dựa vào các mẫu mã mà chúng giỏi viết (như vòng lặp, rẽ nhánh hoặc đồng thời) để viết logic điều phối phù hợp với nhiệm vụ.
Tại sao lại là dynamic subagents?
Deep Agents đã hỗ trợ subagents. Chúng cô lập ngữ cảnh, cho phép tác nhân chính ủy thác các đơn vị công việc riêng lẻ và giữ các kết quả trung gian ra khỏi cửa sổ ngữ cảnh chính. Vậy tại sao chúng ta cần dynamic subagents?
Với subagents thông thường, chúng được gọi từng cái một, bằng cách tác nhân chính gọi trực tiếp chúng. Điều đó hoạt động ở quy mô nhỏ. Nó sẽ bị phá vỡ khi bạn cần tạo ra hàng trăm subagents, hoặc khi logic điều phối có điều kiện hoặc nhiều giai đoạn.
Dynamic subagents giải quyết vấn đề này bằng sự điều phối theo chương trình (programmatic orchestration). Thay vì thực hiện các lệnh gọi công cụ từng bước một, tác nhân viết một tập lệnh ngắn để điều phối và gọi các subagents, và chạy nó trong một trình thông dịch nhẹ.
Ví dụ kinh điển: một subagent cho mỗi trang của một tài liệu 300 trang. Thay vì gọi công cụ subagent 300 lần, tác nhân viết một vòng lặp:
1const results = await Promise.all(pages.map(page =>2 task({ description: `Tóm tắt trang ${page.number}`, subagentType: "summarizer" })3));
Điều này mở khóa hai thứ mà sự điều phối dựa trên lệnh gọi công cụ không thể cung cấp một cách đáng tin cậy:
Phạm vi bao phủ xác định (Deterministic coverage) ở quy mô lớn. Nếu không có cấu trúc, các tác nhân sẽ đưa ra các phán đoán về phạm vi, sàng lọc 75 trên 500 mục và coi như đã hoàn thành. Một vòng lặp phân phối thì không. Phạm vi bao phủ trở thành một sự đảm bảo về mặt cấu trúc, không phải là một vấn đề về kỹ thuật prompt.
Sự điều phối phức tạp đáng tin cậy. Viết sự điều phối dưới dạng mã đáng tin cậy hơn là để mô hình tái tạo nó như một chuỗi các lệnh gọi công cụ, đặc biệt là đối với các pipeline fan-out + tổng hợp, nhiều giai đoạn hoặc rẽ nhánh có điều kiện.
Đây là ý tưởng tương tự đằng sau workflows trong Claude Code và Recursive Language Models (RLMs): một mô hình viết mã, và mã đó phân phối nhiều tác nhân hơn.
Bắt đầu nhanh
Dynamic subagents yêu cầu hai thứ: subagents để phân phối công việc và một code interpreter: một môi trường chạy an toàn, nhẹ, nơi mô hình viết và thực thi mã điều phối. Deep Agents bao gồm một code interpreter tùy chọn dựa trên QuickJS. Để sử dụng nó, hãy cài đặt gói middleware QuickJS, sau đó truyền CodeInterpreterMiddleware qua đối số middleware trên create_deep_agent.
1pip install -U "deepagents[quickjs]"
1from deepagents import create_deep_agent2from langchain_quickjs import CodeInterpreterMiddleware34agent = create_deep_agent(5 model="openai:gpt-5.5",6 middleware=[CodeInterpreterMiddleware()],7)
Deep Agents đi kèm với một subagent đa năng được tích hợp sẵn, vì vậy đã có sẵn một hồ sơ subagent chung có thể được sử dụng trong các workflow. Đối với các workflow chuyên biệt, hãy cấu hình custom subagents với tên, mô tả và system prompt riêng của chúng: tên và mô tả là cách tác nhân biết nên sử dụng vai trò nào.
Để kích hoạt dynamic subagents, hãy nhắc tác nhân của bạn bằng từ "workflow", như sau:
1result = await agent.ainvoke({2 "messages": [{"role": "user", "content": "Chạy một workflow để xem xét mọi tệp trong src/routes/ và tóm tắt các rủi ro hàng đầu."}]3})
Sử dụng với một coding agent
Cách nhanh nhất để dùng thử dynamic subagents là với dcode, coding agent trên terminal của chúng tôi được xây dựng bằng Deep Agent. Nó đi kèm với code interpreter được bật sẵn, vì vậy không có gì phải kết nối — dynamic subagents hoạt động ngay lập tức.
Cài đặt
1curl -LsSf https://langch.in/dcode | bash
Chạy
1dcode
Để kích hoạt dynamic subagents, chỉ cần yêu cầu một “workflow”. Thay vì tự mình làm việc vất vả, hoặc cố gắng quản lý việc phân nhánh subagent bằng công cụ tác vụ gốc của nó, tác nhân sẽ viết một tập lệnh điều phối gọi hàm task() toàn cục được tích hợp sẵn và thực thi nó trong code interpreter. Ví dụ: “chạy một workflow để xem xét mọi tệp trong src/ để tìm SQL injection.”
Khi các subagent được sinh ra, dcode hiển thị chúng trực tiếp trong bảng dynamic subagents được nhóm thành các giai đoạn theo lần phân phối.

Bạn có thể dùng thử cách này nhanh nhất với dcode nhưng bạn cũng có thể sử dụng nó trong công cụ bạn chọn thông qua ACP (ví dụ: Zed)
Cách thức hoạt động
Tác nhân được cung cấp một eval tool. Nó viết JavaScript thực thi một cách an toàn bên trong trình thông dịch. Khi subagents được cấu hình, trình thông dịch sẽ hiển thị một hàm task() toàn cục được tích hợp sẵn để phân phối chúng từ mã. Dựa trên nhiệm vụ hiện tại, mô hình viết các mã khác nhau — một vòng lặp, một nhánh, một Promise.all — và trình thông dịch chạy nó một cách xác định.

task() nhận một mô tả, một subagentType và một responseSchema tùy chọn — khi được cung cấp, kết quả đã là một đối tượng được gõ, sẵn sàng để lọc hoặc chuyển sang bước tiếp theo.
1const result = await task({2 description: "Xem xét src/auth/login.ts để tìm các vấn đề bảo mật.",3 subagentType: "reviewer",4 responseSchema: {5 type: "object",6 properties: {7 severity: { type: "string", enum: ["high", "medium", "low"] },8 issues: { type: "array", items: { type: "string" } },9 },10 },11});1213const critical = result.severity === "high" ? result.issues : [];14critical; // model sees the last line
Để biết thêm, hãy xem Programmatic subagents và Interpreters trong tài liệu.
Các Mẫu Điều Phối Phổ Biến
Anthropic's dynamic workflows đã phổ biến một tập hợp các mẫu điều phối cho công việc tác nhân song song. Chúng không phải là các tính năng bạn bật lên. Chúng là những hình dạng tự nhiên xuất hiện từ công việc và tác nhân sẽ chuyển sang một hình dạng khác khi nhiệm vụ thay đổi. Bảng dưới đây ánh xạ mỗi hình dạng với loại công việc mà nó phù hợp.

Dưới đây chúng ta sẽ đi sâu vào cách hoạt động của từng mẫu trong Deep Agents, với các dấu vết trực tiếp. Chúng tôi cũng đã tổng hợp một video giải thích sáu mẫu này, bạn có thể xem tại đây.
Phân loại và hành động
Các mục được phân loại trước, sau đó mỗi mục được xử lý bởi một subagent chuyên biệt dựa trên phân loại của nó. Điều này cho phép bạn xử lý các đầu vào hỗn hợp, nơi các mục khác nhau cần chuyên môn khác nhau.

Các trường hợp sử dụng: Phân loại vé hỗ trợ, nhật ký lỗi, phản hồi của người dùng hoặc bất kỳ lô mục nào cần xử lý khác nhau tùy thuộc vào loại của chúng.
Ví dụ: phân loại tồn đọng vé hỗ trợ. Tác nhân đọc các vé và phân loại từng cái là lỗi, yêu cầu tính năng hoặc câu hỏi. Lỗi cho một điều tra viên lỗi, yêu cầu tính năng cho một nhà phân tích tính năng và câu hỏi cho một người trả lời hỗ trợ. Kết quả là một bản tóm tắt được nhóm theo danh mục.
Xem dấu vết tại đây.
Phân nhánh và tổng hợp
Tác nhân phân phối cùng một loại công việc trên nhiều mục một cách song song, sau đó kết hợp các kết quả.

Các trường hợp sử dụng: Xem xét mã trên một thư mục, phân tích một lô tài liệu, xử lý tệp nhật ký, chạy cùng một kiểm tra trên nhiều dịch vụ.
Ví dụ: xem xét bảo mật theo từng tệp trên toàn bộ cây mã nguồn. Tác nhân khám phá mọi tệp TypeScript trong src/ và phân phối một subagent kiểm tra bảo mật cho mỗi tệp một cách song song. Sau đó, nó hợp nhất các kết quả thành một báo cáo ưu tiên duy nhất với xếp hạng mức độ nghiêm trọng và các dòng cần thay đổi.
Xem dấu vết tại đây.
Xác minh đối kháng
Một mẫu hai lượt. Lượt đầu tiên tạo ra các phát hiện. Lượt thứ hai gửi từng phát hiện đến các bộ xác minh độc lập và chỉ những phát hiện vượt qua được sự đồng thuận mới được giữ lại. Điều này làm giảm các kết quả dương tính giả khi độ tin cậy quan trọng hơn tốc độ.

Các trường hợp sử dụng: Kiểm toán bảo mật nơi các kết quả dương tính giả gây tốn kém, kiểm tra tuân thủ, bất kỳ đánh giá nào bạn cần độ tin cậy cao trong các phát hiện.
Ví dụ: một cuộc kiểm toán bảo mật nơi các kết quả dương tính giả là không thể chấp nhận được. Một kiểm toán viên tung một lưới rộng để tìm các lỗ hổng tiềm ẩn, sau đó mỗi phát hiện được chuyển cho một bộ xác minh độc lập, người đọc lại mã từ đầu và đưa ra phán quyết CONFIRMED hoặc REFUTED. Chỉ những phát hiện được xác nhận mới tồn tại trong báo cáo cuối cùng.
Xem dấu vết tại đây.
Tạo và lọc
Nhiều subagent tạo ra các giải pháp độc lập cho cùng một vấn đề. Tác nhân so sánh, chấm điểm và lọc các kết quả trong mã, chỉ giữ lại những kết quả tốt nhất.

Các trường hợp sử dụng: Đề xuất kiến trúc, chiến lược tái cấu trúc, các biến thể nội dung, bất kỳ nhiệm vụ nào mà việc khám phá nhiều tùy chọn trước khi cam kết tạo ra kết quả tốt hơn.
Ví dụ: các thiết kế lại bộ giới hạn tốc độ cạnh tranh, được xếp hạng. Tác nhân có một kiến trúc sư để tạo ra một số thiết kế lại độc lập của rate-limiter.ts, mỗi thiết kế được ghi vào tệp riêng của nó để chúng không ghi đè lên nhau. Sau đó, nó chấm điểm chúng dựa trên tính đúng đắn khi chịu tải đột biến, hỗ trợ nhiều phiên bản và độ phức tạp. Cái mạnh nhất sẽ thắng, kèm theo lý do tại sao.
Xem dấu vết tại đây.
Giải đấu
Các biến thể được so sánh trực tiếp với nhau bởi một subagent giám khảo, với những người thắng cuộc tiến lên qua các vòng loại trực tiếp.

Các trường hợp sử dụng: Tối ưu hóa theo các tiêu chí chủ quan, lựa chọn phong cách, lựa chọn giữa các triển khai cạnh tranh.
Ví dụ: một bảng đấu cặp đôi trên các bản viết lại của một trình xử lý createOrder lộn xộn. Một số người viết, mỗi người tạo ra một bản viết lại ứng cử viên với các ưu tiên khác nhau, sau đó một giám khảo so sánh chúng trực tiếp, đưa những người thắng cuộc tiến lên từng vòng cho đến khi một nhà vô địch nổi bật. Nó trả về cùng với lý do của giám khảo.
Xem dấu vết tại đây.
Lặp lại cho đến khi hoàn thành
Tác nhân chạy một vòng lặp khám phá, loại bỏ trùng lặp với những gì nó đã tìm thấy, cho đến khi không có kết quả mới nào xuất hiện. Hữu ích khi phạm vi công việc không được biết trước.

Các trường hợp sử dụng: Tìm kiếm toàn diện, phát hiện mã chết, kiểm toán phụ thuộc, bất kỳ cuộc quét nào bạn muốn có sự đầy đủ hơn là một số lượng kết quả cố định.
Ví dụ: một cuộc quét bảo mật dựa trên lượt. Tác nhân chạy một lượt quét, kiểm tra những gì nó tìm thấy trong mã và chỉ bắt đầu một lượt khác nếu lượt trước đó phát hiện ra các vấn đề mới. Nó dừng lại khi một lượt không tìm thấy gì mới. Nó báo cáo các phát hiện tổng hợp và số lượt nó đã thực hiện.
Xem dấu vết tại đây.
Kết luận
Dynamic subagents là cách bạn cung cấp cho các tác nhân nhiều quyền tự chủ hơn và tăng độ tin cậy. Mã xử lý phạm vi bao phủ và ngữ cảnh trung gian, và mô hình vẫn thực hiện công việc nặng nhọc về phán đoán. Các mẫu trên đây là một điểm khởi đầu. Trong thực tế, các tác nhân kết hợp và pha trộn chúng dựa trên những gì nhiệm vụ yêu cầu.
Đây là ý tưởng Recursive Language Model ở dạng đơn giản nhất. Một tác nhân viết mã và mã đó phân phối nhiều tác nhân hơn. Đó là một tác nhân tự gọi chính nó một cách đệ quy và nó không bị giới hạn bởi một cửa sổ ngữ cảnh hay bị đóng khung trong một workflow cố định. Một tác nhân có thể chia nhỏ vấn đề đến mức cần thiết và tập hợp lại các mảnh ghép theo bất kỳ hình dạng nào phù hợp. Các mẫu điều phối được nêu bật ở trên là những cái nhìn đầu tiên về những gì có thể, nhưng trần nhà sẽ chỉ tiếp tục tăng lên khi các mô hình trở nên tốt hơn trong việc viết mã.
Dynamic subagents là cách Deep Agents đặt điều này vào tay bạn ngay hôm nay. Hãy bắt đầu bằng cách thêm một code interpreter vào tác nhân của bạn hoặc sử dụng dcode nơi dynamic subagents hoạt động ngay lập tức.
Lời cảm ơn
Đồng tác giả bởi @colifran_ và @huntlovell. Cảm ơn @hwchase17, @masondrxy, và @chester_curme vì đã xem xét kỹ lưỡng.





