Chuyển tới nội dung chính

Đại lý phụ

Công cụ delegate_task tạo ra các phiên bản AIAgent con với bối cảnh biệt lập, bộ công cụ bị hạn chế và các phiên cuối của riêng chúng. Mỗi đứa trẻ có được một cuộc trò chuyện mới và làm việc độc lập - chỉ phần tóm tắt cuối cùng của nó mới phù hợp với bối cảnh của cha mẹ.

Nhiệm vụ đơn lẻ

delegate_task(
goal="Debug why tests fail",
context="Error: assertion in test_foo.py line 42",
toolsets=["terminal", "file"]
)

`

## Lô song song

Theo mặc định, tối đa 3 tác nhân phụ đồng thời (có thể định cấu hình, không có trần cứng):

`Python
delegate_task(tasks=[
\{"goal": "Research topic A", "toolsets": ["web"]},
\{"goal": "Research topic B", "toolsets": ["web"]},
\{"goal": "Fix the build", "toolsets": ["terminal", "file"]}
])

`

## Ngữ cảnh phụ hoạt động như thế nào

:::warning[Critical: Subagents Know Nothing]
Các nhóm phụ bắt đầu bằng một **cuộc trò chuyện hoàn toàn mới**. Họ không biết gì về lịch sử cuộc trò chuyện của phụ huynh, các cuộc gọi công cụ trước đó hoặc bất kỳ điều gì được thảo luận trước khi ủy quyền. Ngữ cảnh duy nhất của tác nhân phụ xuất phát từ các trường
`goal
` và
`context
` mà tác nhân mẹ điền khi gọi
`delegate_task

.

:::

Điều này có nghĩa là tác nhân mẹ phải chuyển **mọi thứ** mà tác nhân phụ cần trong cuộc gọi:

``` python

# BAD - subagent has no idea what "the error" is
delegate_task(goal="Fix the error")

# GOOD - subagent has all context it needs
delegate_task(
goal="Fix the TypeError in API/handlers.py",
context="""The file API/handlers.py has a TypeError on line 47:
'NoneType' object has no attribute 'get'.
The function process_request() receives a dict from parse_body(),
but parse_body() returns None when Content-Type is missing.
The project is at /home/user/myproject and uses Python 3.11."""
)

`
``Tác nhân phụ nhận được lời nhắc hệ thống tập trung được xây dựng từ mục tiêu và ngữ cảnh của bạn, hướng dẫn nó hoàn thành nhiệm vụ và cung cấp bản tóm tắt có cấu trúc về những gì nó đã làm, những gì nó tìm thấy, mọi tệp đã sửa đổi và mọi vấn đề gặp phải.

## Ví dụ thực tế

### Nghiên cứu song song

Nghiên cứu đồng thời nhiều chủ đề và thu thập tóm tắt:

``` python
delegate_task(tasks=[
{
"goal": "Research the current state of WebAssembly in 2025",
"context": "Focus on: browser support, non-browser runtimes, language support",
"toolsets": ["web"]
},
{
"goal": "Research the current state of RISC-V adoption in 2025",
"context": "Focus on: server chips, embedded systems, software ecosystem",
"toolsets": ["web"]
},
{
"goal": "Research quantum computing progress in 2025",
"context": "Focus on: error correction breakthroughs, practical applications, key players",
"toolsets": ["web"]
}
])

`

### Đánh giá mã + Sửa lỗi

Ủy quyền quy trình xem xét và sửa lỗi cho một bối cảnh mới:

`Python
delegate_task(
goal="Review the authentication module for security issues and fix any found",
context="""Project at /home/user/webapp.
Auth module files: src/auth/login.py, src/auth/JWT.py, src/auth/middleware.py.
The project uses Flask, PyJWT, and bcrypt.
Focus on: SQL injection, JWT validation, password handling, session management.
Fix any issues found and run the test suite (pytest tests/auth/).""",
toolsets=["terminal", "file"]
)

`

### Tái cấu trúc nhiều tệp

Ủy quyền một nhiệm vụ tái cấu trúc lớn có thể làm ngập bối cảnh của cấp độ gốc:

`Python
delegate_task(
goal="Refactor all Python files in src/ to replace print() with proper logging",
context="""Project at /home/user/myproject.
Use the 'logging' module with logger = logging.getLogger(__name__).
Replace print() calls with appropriate log levels:

- print(f"Error: ...") -> logger.error(...)
- print(f"Warning: ...") -> logger.warning(...)
- print(f"Debug: ...") -> logger.debug(...)
- Other prints -> logger.info(...)
Don't change print() in test files or CLI output.
Run pytest after to verify nothing broke.""",
toolsets=["terminal", "file"]
)

`

## Chi tiết chế độ hàng loạt

Khi bạn cung cấp mảng
`tasks

, các tác nhân phụ sẽ chạy **song song** bằng cách sử dụng nhóm luồng:
- **Đồng thời tối đa:** 3 tác vụ theo mặc định (có thể định cấu hình thông qua
`delegation.max_concurrent_children
` hoặc
`DELEGATION_MAX_CONCURRENT_CHILDREN
` env var; tầng 1, không có trần cứng). Các lô lớn hơn giới hạn sẽ trả về lỗi công cụ thay vì bị cắt bớt một cách âm thầm.
- **Nhóm luồng:** Sử dụng
`ThreadPoolExecutor
` với giới hạn đồng thời được định cấu hình là số lượng công nhân tối đa
- **Hiển thị tiến trình:** Ở chế độ CLI, chế độ xem dạng cây hiển thị các lệnh gọi công cụ từ mỗi tác nhân phụ trong thời gian thực với các dòng hoàn thành cho mỗi nhiệm vụ. Ở chế độ cổng, tiến trình được phân nhóm và chuyển tiếp đến lệnh gọi lại tiến trình của cấp độ gốc
- **Sắp xếp kết quả:** Kết quả được sắp xếp theo chỉ mục nhiệm vụ để khớp với thứ tự đầu vào bất kể thứ tự hoàn thành
- **Truyền bá gián đoạn:** Làm gián đoạn cấp độ gốc (ví dụ: gửi tin nhắn mới) sẽ làm gián đoạn tất cả các cấp độ con đang hoạt động

Ủy quyền một nhiệm vụ chạy trực tiếp mà không cần chi phí nhóm luồng.

## Ghi đè mô hình

Bạn có thể định cấu hình một mô hình khác cho các tác nhân phụ thông qua
`config.yaml
` — hữu ích khi ủy thác các tác vụ đơn giản cho các mô hình rẻ hơn/nhanh hơn:

``` yaml

# In ~/.Hermes/config.yaml
delegation:
model: "Google/Gemini-flash-2.0" # Cheaper model for subagents
provider: "OpenRouter" # Optional: route subagents to a different provider

`
``Nếu bị bỏ qua, các tác nhân phụ sẽ sử dụng mô hình giống như tác nhân gốc.

## Mẹo lựa chọn bộ công cụ

Tham số
`toolsets
` kiểm soát những công cụ mà tác nhân phụ có quyền truy cập. Chọn dựa trên nhiệm vụ:

| Mẫu bộ công cụ | Trường hợp sử dụng |
|-------|----------|
|

["terminal", "file"]
` | Công việc viết mã, gỡ lỗi, chỉnh sửa tệp, xây dựng |
|

["web"]
` | Nghiên cứu, kiểm tra thực tế, tra cứu tài liệu |
|

["terminal", "file", "web"]
` | Nhiệm vụ toàn ngăn xếp (mặc định) |
|

["file"]
` | Phân tích chỉ đọc, xem xét mã mà không thực thi |
|

["terminal"]
` | Quản trị hệ thống, quản lý quy trình |

Một số bộ công cụ nhất định bị chặn đối với các tác nhân phụ bất kể bạn chỉ định điều gì:
-
`delegation
` — bị chặn đối với các tác nhân phụ lá (mặc định). Được giữ lại cho trẻ em
`role="orchestrator"

, được giới hạn bởi
`max_spawn_depth

- xem [Depth Limit and Nested Orchestration](#depth-limit-and-nested-orchestration) bên dưới.
-
`clarify

- tác nhân phụ không thể tương tác với người dùng
-
`memory

- không ghi vào bộ nhớ liên tục được chia sẻ
-
`code_execution
` — trẻ nên suy luận từng bước
-
`send_message

- không có tác dụng phụ đa nền tảng (ví dụ: gửi tin nhắn Telegram)

## Số lần lặp tối đa

Mỗi tác nhân phụ có một giới hạn lặp lại (mặc định: 50) để kiểm soát số lượt gọi công cụ có thể thực hiện:

``` python
delegate_task(
goal="Quick file check",
context="Check if /etc/nginx/nginx.conf exists and print its first 10 lines",
max_iterations=10 # Simple task, don't need many turns
)

`

## Thời gian chờ của trẻ

Các tác nhân phụ sẽ bị hủy do bị kẹt nếu chúng im lặng trong hơn
`delegation.child_timeout_seconds
` giây đồng hồ treo tường. Giá trị mặc định là **600** (10 phút) — tăng từ mức 300 trong các bản phát hành trước đó vì các mô hình có tính suy luận cao về các nhiệm vụ nghiên cứu không tầm thường đã bị loại bỏ giữa chừng. Điều chỉnh nó mỗi lần cài đặt:

`YAML
delegation:
child_timeout_seconds: 600 # default

`
``Hạ thấp nó cho các mô hình cục bộ nhanh; nâng cao nó cho các mô hình suy luận chậm về các vấn đề khó khăn. Bộ hẹn giờ sẽ đặt lại mỗi khi trẻ thực hiện lệnh gọi API hoặc lệnh gọi công cụ - chỉ những nhân viên thực sự nhàn rỗi mới kích hoạt lệnh hủy.:::tip Diagnostic dump on zero-call timeout
Nếu tác nhân phụ hết thời gian thực hiện lệnh gọi API **không** (thường là: không thể truy cập nhà cung cấp, lỗi xác thực hoặc từ chối lược đồ công cụ),
`delegate_task
` sẽ ghi chẩn đoán có cấu trúc vào

~/.Hermes/logs/subagent-timeout-<session-<timestamp.log
` chứa ảnh chụp nhanh cấu hình của tác nhân phụ, dấu vết phân giải thông tin xác thực và bất kỳ thông báo lỗi sớm nào. Nguyên nhân gốc rễ dễ dàng hơn nhiều so với hành vi hết thời gian chờ im lặng trước đó.

:::

## Giám sát các tác nhân phụ đang chạy (

/agents

)

TUI cung cấp lớp phủ

/agents
` (bí danh

/tasks

) để biến phân tán
`delegate_task
` đệ quy thành bề mặt kiểm tra hạng nhất:
- Chế độ xem dạng cây trực tiếp của các tác nhân phụ đang chạy và đã hoàn thành gần đây, được nhóm theo cấp độ gốc
- Chi phí mỗi nhánh, mã thông báo và tổng số lần chạm vào tệp
- Điều khiển tắt và tạm dừng - hủy một tác nhân phụ cụ thể đang bay mà không làm gián đoạn tác nhân anh chị em của nó
- Đánh giá hậu kỳ: xem qua lịch sử từng lượt của từng đại lý phụ ngay cả sau khi họ đã quay lại cấp độ gốc

CLI cổ điển chỉ in

/agents
` dưới dạng tóm tắt văn bản; TUI là nơi lớp phủ tỏa sáng. Xem [TUI — Slash commands](/docs/user-guide/TUI#slash-commands).

## Giới hạn độ sâu và phối hợp lồng nhau

Theo mặc định, việc ủy quyền là **phẳng**: cha mẹ (độ sâu 0) sinh ra con (độ sâu 1) và những con đó không thể ủy quyền thêm. Điều này ngăn chặn việc ủy ​​quyền đệ quy chạy trốn.

Đối với quy trình làm việc nhiều giai đoạn (nghiên cứu → tổng hợp hoặc điều phối song song các vấn đề phụ), cha/mẹ có thể sinh ra **người điều phối** con *có thể* ủy quyền cho nhân viên của mình:

``` python
delegate_task(
goal="Survey three code review approaches and recommend one",
role="orchestrator", # Allows this child to spawn its own workers
context="...",
)

`

-
`role="leaf"
` (mặc định): trẻ không thể ủy quyền thêm - giống với hành vi ủy quyền phẳng.

-
`role="orchestrator"

: con giữ lại bộ công cụ
`delegation

. Được kiểm soát bởi
`delegation.max_spawn_depth
` (mặc định **1** = phẳng, vì vậy
`role="orchestrator"
` theo mặc định là không hoạt động). Tăng
`max_spawn_depth
` lên 2 để cho phép các con của người điều phối sinh ra các cháu lá; 3 cho ba cấp độ (giới hạn).
-
`delegation.orchestrator_enabled: false

: kill switch toàn cầu buộc mọi trẻ em phải sử dụng
`leaf
` bất kể tham số
`role

.

**Cảnh báo chi phí:** Với
`max_spawn_depth: 3
` và
`max_concurrent_children: 3

, cây có thể đạt 3×3×3 = 27 tác nhân lá đồng thời. Mỗi cấp độ bổ sung sẽ nhân lên số tiền chi tiêu — cố ý tăng
`max_spawn_depth

.

## Tuổi thọ và độ bền

:::warning[delegate_task is synchronous — not durable]
`delegate_task
` chạy **trong lượt hiện tại của phụ huynh**. Nó chặn cha mẹ cho đến khi mọi đứa trẻ hoàn thành (hoặc bị hủy bỏ). Đây **không phải** là hàng đợi công việc nền:
- Nếu cha mẹ bị gián đoạn (người dùng gửi tin nhắn mới,

/stop

,

/new

), tất cả trẻ em đang hoạt động sẽ bị hủy và trả về
`status="interrupted"

. Công việc đang thực hiện của họ bị loại bỏ.
- Trẻ **không** tiếp tục chạy sau khi lượt của phụ huynh kết thúc.
- Phần tử con bị hủy trả về kết quả có cấu trúc (
`status="interrupted"

,
`exit_reason="interrupted"

), nhưng do phần tử gốc cũng bị gián đoạn nên kết quả đó thường không bao giờ trở thành câu trả lời hiển thị cho người dùng.

Đối với **công việc lâu dài** phải tồn tại khi bị gián đoạn hoặc tồn tại lâu hơn lượt hiện tại, hãy sử dụng:
-
`cronjob
` (action=
`create

) — lên lịch chạy tác nhân riêng biệt; miễn nhiễm với sự gián đoạn của cha mẹ.
-
`terminal(background=True, notify_on_complete=True)
` — các lệnh shell chạy dài tiếp tục chạy trong khi tác nhân thực hiện những việc khác.
:::

## Thuộc tính chính
- Mỗi tác nhân phụ có **phiên cuối cùng** riêng (tách biệt với tác nhân gốc)
- **Ủy quyền lồng nhau được chọn tham gia** — chỉ trẻ em
`role="orchestrator"
` mới có thể ủy quyền thêm và chỉ khi
`max_spawn_depth
` được nâng lên từ giá trị mặc định là 1 (phẳng). Vô hiệu hóa toàn cầu với
`orchestrator_enabled: false

.
- Tác nhân lá **không được** gọi:
`delegate_task

,
`clarify

,
`memory

,
`send_message

,
`execute_code

. Các tác nhân phụ của bộ điều phối giữ lại
`delegate_task
` nhưng vẫn không thể sử dụng bốn tác nhân còn lại.
- **Tuyên truyền gián đoạn** — làm gián đoạn cấp độ gốc sẽ làm gián đoạn tất cả các thành phần con đang hoạt động (bao gồm cả các cháu dưới sự điều phối)
- Chỉ bản tóm tắt cuối cùng mới được đưa vào ngữ cảnh của cấp độ gốc, giúp việc sử dụng mã thông báo luôn hiệu quả
- Các tác nhân phụ kế thừa **khóa API, cấu hình nhà cung cấp và nhóm thông tin xác thực** của cha mẹ (cho phép xoay vòng khóa theo giới hạn tốc độ)

## Ủy quyền và exec_code| Yếu tố | đại biểu_task | thực thi_code |
|--------|--------------|-------------|
| **Lý luận** | Vòng lý luận LLM đầy đủ | Chỉ thực thi mã Python |
| **Bối cảnh** | Cuộc trò chuyện mới mẻ | Không có cuộc trò chuyện, chỉ có kịch bản |
| **Quyền truy cập công cụ** | Tất cả các công cụ không bị chặn với lý luận | 7 công cụ thông qua RPC, không cần lý luận |
| **Song song** | 3 tác nhân con đồng thời theo mặc định (có thể định cấu hình) | Kịch bản đơn |
| **Tốt nhất cho** | Nhiệm vụ phức tạp cần phán đoán | Đường ống cơ khí nhiều bước |
| **Chi phí mã thông báo** | Cao hơn (vòng LLM đầy đủ) | Thấp hơn (chỉ trả về thiết bị xuất chuẩn) |
| **Tương tác người dùng** | Không có (đại diện phụ không thể làm rõ) | Không có |

**Quy tắc chung:** Sử dụng
`delegate_task
` khi nhiệm vụ phụ yêu cầu lý luận, phán đoán hoặc giải quyết vấn đề gồm nhiều bước. Sử dụng
`execute_code
` khi bạn cần xử lý dữ liệu cơ học hoặc quy trình làm việc theo kịch bản.

## Cấu hình

``` yaml

# In ~/.Hermes/config.yaml
delegation:
max_iterations: 50 # Max turns per child (default: 50)
# max_concurrent_children: 3 # Parallel children per batch (default: 3)
# max_spawn_depth: 1 # Tree depth (1-3, default 1 = flat). Raise to 2 to allow orchestrator children to spawn leaves; 3 for three levels.
# orchestrator_enabled: true # Disable to force all children to leaf role.
model: "Google/Gemini-3-flash-preview" # Optional provider/model override
provider: "OpenRouter" # Optional built-in provider
API_mode: Anthropic_messages # optional; auto-detected from base_url for Anthropic_messages endpoints

# Or use a direct custom endpoint instead of provider:
delegation:
model: "qwen2.5-coder"
base_url: "http://localhost:1234/v1"
API_key: "local-key"
# API_mode: "Anthropic_messages" # Optional. Wire protocol override for base_url ("chat_completions", "Codex_responses", or "Anthropic_messages"). Empty = auto-detect from URL (e.g. /Anthropic suffix). Set explicitly for endpoints the heuristic can't classify (Azure AI Foundry, MiniMax, Zhipu GLM, LiteLLM proxies, …).

`
``Khi
`base_url
` trỏ đến điểm cuối tương thích với Anthropic — ví dụ: đường dẫn kết thúc bằng

/Anthropic

, tuyến Claude của Azure Foundry hoặc proxy MiniMax

/Anthropic
` —
`API_mode
` được tự động phát hiện là
`Anthropic_messages
` nên tác nhân phụ sử dụng định dạng dây phù hợp mà bạn không cần cài đặt bất cứ điều gì. Đặt
`API_mode
` một cách rõ ràng khi dự đoán tự động phát hiện sai (hiếm).

:::tip
Tác nhân tự động xử lý việc ủy quyền dựa trên mức độ phức tạp của nhiệm vụ. Bạn không cần phải yêu cầu nó ủy quyền một cách rõ ràng — nó sẽ làm như vậy khi thấy hợp lý.
:::