Bản dịch tiếng Việt không chính thứcXem bản gốc ↗
TỰ ĐỘNG HÓA

Ủy quyền cho tác tử con

Công cụ delegate_task tạo các phiên AIAgent con có ngữ cảnh biệt lập, được kế thừa quyền truy cập công cụ và có phiên terminal riêng. Mỗi tác tử con bắt đầu bằng một cuộc hội thoại mới, làm việc độc lập — chỉ phần tổng kết cuối cùng được đưa trở lại ngữ cảnh của tác tử cha.

Các lệnh gọi mô hình ở cấp cao nhất tự động chạy nền. Hermes trả về một mã xử lý ngay để cuộc trò chuyện có thể tiếp tục, sau đó gửi kết quả trở lại dưới dạng tin nhắn mới. Một tác tử con đóng vai trò điều phối sẽ chờ các tác tử của chính nó hoàn tất để tổng hợp kết quả trước khi trả về.

#Nhiệm vụ đơn lẻ

python
delegate_task(
    goal="Tìm nguyên nhân khiến kiểm thử thất bại",
    context="Lỗi: assertion tại test_foo.py dòng 42"
)

#Lô song song

Mặc định có thể chạy đồng thời tối đa 3 tác tử con (có thể cấu hình, không có trần cứng):

python
delegate_task(tasks=[
    {"goal": "Nghiên cứu chủ đề A", "context": "Tập trung vào nguồn sơ cấp gần đây"},
    {"goal": "Nghiên cứu chủ đề B", "context": "So sánh các cách giải thích hàng đầu"},
    {"goal": "Sửa lỗi build", "context": "Thư mục gốc: /home/user/project"}
])

#Ngữ cảnh của tác tử con hoạt động thế nào

!
Quan trọng: tác tử con không biết gì từ trước

Tác tử con bắt đầu bằng một cuộc hội thoại hoàn toàn mới. Chúng không biết lịch sử trò chuyện của tác tử cha, các lần gọi công cụ trước đó hay bất kỳ điều gì đã được thảo luận. Ngữ cảnh duy nhất của tác tử con đến từ hai trường goalcontext mà tác tử cha truyền vào khi gọi delegate_task.

Vì vậy, tác tử cha phải truyền vào lời gọi mọi thông tin mà tác tử con cần:

python
# KHÔNG TỐT — tác tử con không biết “lỗi” là lỗi nào
delegate_task(goal="Sửa lỗi")

# TỐT — tác tử con có đủ ngữ cảnh cần thiết
delegate_task(
    goal="Sửa TypeError trong api/handlers.py",
    context="""Tệp api/handlers.py gặp TypeError ở dòng 47:
    'NoneType' object has no attribute 'get'.
    Hàm process_request() nhận một dict từ parse_body(),
    nhưng parse_body() trả về None khi thiếu Content-Type.
    Dự án nằm tại /home/user/myproject và dùng Python 3.11."""
)

Tác tử con nhận một system prompt tập trung được tạo từ mục tiêu và ngữ cảnh của bạn. Prompt yêu cầu nó hoàn tất nhiệm vụ và cung cấp bản tổng kết có cấu trúc: đã làm gì, phát hiện gì, tệp nào được sửa và có vấn đề nào gặp phải.

#Ví dụ thực tế

Nghiên cứu song song

Nghiên cứu nhiều chủ đề cùng lúc và thu thập các bản tóm tắt:

python
delegate_task(tasks=[
    {
        "goal": "Nghiên cứu hiện trạng WebAssembly năm 2025",
        "context": "Tập trung vào: hỗ trợ trình duyệt, runtime ngoài trình duyệt, hỗ trợ ngôn ngữ"
    },
    {
        "goal": "Nghiên cứu mức độ ứng dụng RISC-V năm 2025",
        "context": "Tập trung vào: chip máy chủ, hệ thống nhúng, hệ sinh thái phần mềm"
    },
    {
        "goal": "Nghiên cứu tiến bộ điện toán lượng tử năm 2025",
        "context": "Tập trung vào: đột phá sửa lỗi, ứng dụng thực tế, các đơn vị chủ chốt"
    }
])

Rà soát mã và sửa lỗi

Giao một quy trình rà soát rồi sửa lỗi cho một ngữ cảnh mới:

python
delegate_task(
    goal="Rà soát mô-đun xác thực để tìm lỗ hổng bảo mật và sửa các lỗi phát hiện được",
    context="""Dự án tại /home/user/webapp.
    Các tệp mô-đun xác thực: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py.
    Dự án dùng Flask, PyJWT và bcrypt.
    Tập trung vào: SQL injection, xác thực JWT, xử lý mật khẩu, quản lý phiên.
    Sửa các lỗi tìm thấy và chạy bộ kiểm thử (pytest tests/auth/)."""
)

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

Giao một tác vụ tái cấu trúc lớn có thể làm ngữ cảnh của tác tử cha bị quá tải:

python
delegate_task(
    goal="Tái cấu trúc mọi tệp Python trong src/ để thay print() bằng logging phù hợp",
    context="""Dự án tại /home/user/myproject.
    Dùng mô-đun 'logging' với logger = logging.getLogger(__name__).
    Thay các lời gọi print() bằng cấp độ log phù hợp:
    - print(f"Error: ...") -> logger.error(...)
    - print(f"Warning: ...") -> logger.warning(...)
    - print(f"Debug: ...") -> logger.debug(...)
    - Các lệnh print khác -> logger.info(...)
    Không thay đổi print() trong tệp kiểm thử hoặc đầu ra CLI.
    Chạy pytest sau đó để xác minh không có gì bị hỏng."""
)

#Chi tiết chế độ lô

Khi tác tử cấp cao nhất cung cấp mảng tasks, Hermes trả về một mã xử lý nền, chạy các tác tử con song song và gửi một kết quả tổng hợp sau khi tất cả hoàn tất. Một tác tử điều phối sẽ chờ lô của mình trong lượt hiện tại để có thể tổng hợp kết quả.

  • Mức đồng thời tối đa: mặc định 3 tác vụ; cấu hình bằng delegation.max_concurrent_children hoặc biến môi trường DELEGATION_MAX_CONCURRENT_CHILDREN. Giá trị tối thiểu là 1, không có trần cứng.
  • Thread pool: dùng ThreadPoolExecutor với giới hạn đồng thời làm số worker tối đa.
  • Hiển thị tiến độ: chế độ CLI hiển thị cây lời gọi công cụ theo thời gian thực; chế độ gateway gom tiến độ và chuyển tới callback của tác tử cha.
  • Thứ tự kết quả: được sắp theo chỉ số tác vụ, bất kể tác vụ nào hoàn thành trước.
  • Hủy: tin nhắn tiếp theo không hủy lô nền cấp cao nhất. Dùng /stop hoặc đóng/đặt lại phiên sở hữu để hủy các tác tử con đang chạy.

Việc ủy quyền đồng bộ một tác vụ từ tác tử điều phối chạy trực tiếp, không tốn chi phí thread pool.

Kết quả nền có độ bền

Khi một lần ủy quyền nền hoàn tất, Hermes lưu sự kiện hoàn thành vào state.dbcủa hồ sơ đang hoạt động trước khi đưa vào hàng đợi lượt mới. Nếu Hermes khởi động lại sau khi tác vụ hoàn tất nhưng trước khi kết quả được giao, sự kiện chờ sẽ được khôi phục và định tuyến qua cùng các bước kiểm tra quyền sở hữu. Cơ chế claim bền vững đảm bảo chỉ consumer nhận thành công lượt tổng hợp mới xác nhận giao; lần thử thất bại sẽ nhả claim để thử lại.

Cơ chế này không tiếp tục việc thực thi của tác tử con sau sự cố. Nếu tiến trình sở hữu biến mất khi tác vụ vẫn đang chạy, trạng thái được ghi là unknown vì Hermes không thể chứng minh các tác động bên ngoài đã xảy ra hay chưa. Bản ghi chờ và đã giao được giới hạn dung lượng và tách riêng theo hồ sơ.

#Ghi đè mô hình

Bạn có thể cấu hình mô hình khác cho tác tử con trong config.yaml — hữu ích khi giao tác vụ đơn giản cho mô hình rẻ hơn hoặc nhanh hơn:

yaml
# Trong ~/.hermes/config.yaml
delegation:
  model: "google/gemini-flash-2.0"  # Mô hình rẻ hơn cho tác tử con
  provider: "openrouter"            # Tùy chọn: định tuyến qua nhà cung cấp khác

Nếu bỏ qua, tác tử con sử dụng cùng mô hình với tác tử cha.

#Quyền truy cập công cụ được kế thừa

delegate_task không nhận tham số toolsets do mô hình truyền vào. Mỗi tác tử con kế thừa các bộ công cụ đang bật của tác tử cha, vì vậy mô hình không thể tự cấp cho tác tử con năng lực mà tác tử cha không có. Hãy cấu hình công cụ của tác tử cha trước khi bắt đầu hội thoại nếu công việc được giao cần thêm năng lực.

Một số công cụ bị chặn với tác tử con ngay cả khi tác tử cha có quyền:

  • delegate_task — bị chặn với tác tử lá (mặc định); được giữ lại cho tác tử role="orchestrator" và bị giới hạn bởi max_spawn_depth.
  • clarify — tác tử con không thể tương tác với người dùng.
  • memory — không được ghi vào bộ nhớ bền vững dùng chung.
  • send_message — không có tác động phụ đa nền tảng.
  • cronjob — không được lên lịch công việc mới dưới danh nghĩa tác tử cha.

Cả hai vai trò vẫn giữ execute_code để gom các thao tác máy móc bằng chương trình.

#Số vòng lặp tối đa

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

python
delegate_task(
    goal="Kiểm tra tệp nhanh",
    context="Kiểm tra /etc/nginx/nginx.conf có tồn tại và in 10 dòng đầu",
    max_iterations=10  # Tác vụ đơn giản, không cần nhiều lượt
)

#Thời gian chờ cho tác tử con

Mặc định tác tử con không có giới hạn thời gian thực. Tác tử chỉ thất bại do điều nó đang thực hiện — lỗi API, lỗi công cụ hoặc hết ngân sách vòng lặp — không phải vì một đồng hồ đếm ngược ở tầng ủy quyền. Các bản phát hành trước từng có giới hạn cứng 300 giây, sau là 600 giây, khiến các tác tử đang làm việc bình thường bị dừng giữa chừng.

Tác tử thực sự bị kẹt vẫn được phát hiện: bộ giám sát độ cũ heartbeat ngừng làm mới hoạt động của tác tử cha khi tác tử con không có tiến triển, cho phép thời gian chờ bất hoạt của gateway kích hoạt với worker thực sự treo.

Nếu vẫn muốn giới hạn cứng, chẳng hạn để kiểm soát chi phí cho tác vụ cron không giám sát, hãy bật theo từng bản cài đặt:

yaml
delegation:
  child_timeout_seconds: 0       # mặc định: 0 = không giới hạn
  # child_timeout_seconds: 1800  # tùy chọn giới hạn cứng (tối thiểu 30 giây)

Giá trị dương áp dụng giới hạn thời gian thực; 0 hoặc số âm sẽ tắt giới hạn. Khi hết giờ, kết quả chứa metadata có cấu trúc gồm timeout_seconds,timed_out_after_secondstimeout_phase để phân biệt nguyên nhân mà không cần phân tích chuỗi lỗi.

i
Bản chẩn đoán khi hết giờ trước lần gọi mô hình đầu tiên

Nếu tác tử con hết giờ khi chưa gọi API lần nào, delegate_task ghi bản chẩn đoán vào ~/.hermes/logs/subagent-timeout-<session>-<timestamp>.log, gồm ảnh chụp cấu hình, dấu vết tìm thông tin xác thực, lỗi sớm và stack trace của mọi luồng đang chạy.

#Phát hiện tác tử nền bị đình trệ

Các lần ủy quyền nền (delegate_task(background=true)) được bộ giám sát tiến độ theo dõi mặc định, không cần cấu hình. Khác với thời gian chờ cứng, nó không can thiệp vào tác tử đang có tiến triển, bất kể tác tử đó chạy bao lâu.

Bộ giám sát lấy mẫu số lần gọi API, công cụ hiện tại và thời điểm hoạt động gần nhất:

  1. Tác tử đang tiến triển không bao giờ bị chạm tới. Bất kỳ tín hiệu nào thay đổi cũng đặt lại đồng hồ.
  2. Tác tử đứng yên quá ngưỡng (450 giây khi rảnh, 1.200 giây khi đang trong công cụ) sẽ bị ngắt và có 120 giây để thoát gọn.
  3. Tác tử vẫn không quay lại sẽ được kết thúc cưỡng bức với sự kiện stalled, giúp phiên sở hữu nhận được kết quả và giải phóng slot bất đồng bộ.

Sự kiện stalled mang metadata stalled_after_quiet_seconds,stall_threshold_seconds, stall_phasestall_grace_seconds.

#Giám sát tác tử đang chạy (/agents)

Giao diện TUI có bảng /agents (bí danh /tasks) để biến cây ủy quyền đệ quy thành bề mặt kiểm tra trực tiếp:

  • Cây các tác tử đang chạy và vừa hoàn tất, nhóm theo tác tử cha.
  • Tổng hợp chi phí, token và tệp bị tác động theo từng nhánh.
  • Điều khiển dừng và tạm dừng một tác tử mà không ảnh hưởng các tác tử cùng cấp.
  • Xem lại lịch sử từng lượt của tác tử con ngay cả sau khi nó đã trả kết quả.

CLI cổ điển in /agents dưới dạng văn bản. Trên CLI và mọi nền tảng gateway, lệnh này cũng liệt kê hoạt động trực tiếp của từng tác tử con nền:

text
Các lần ủy quyền nền: 1 đang chạy
- deleg_ab12cd34 · đang chạy · nghiên cứu bộ giám sát đình trệ
  - tác tử con 1: 4 lần gọi API · trong web_search · hoạt động 12 giây trước
  - tác tử con 2: 7 lần gọi API · giữa các lượt · hoạt động 3 giây trước

#Nhật ký trực tiếp

Mỗi lần gọi delegate_task tạo một tệp nhật ký chỉ-ghi-thêm, con người có thể đọc cho từng tác vụ:

text
<hermes_home>/cache/delegation/live/<delegation_id>/task-<n>.log

Phản hồi điều phối chứa đường dẫn live_transcripts và các tệp được tạo sẵn ngay khi điều phối:

bash
tail -f ~/.hermes/cache/delegation/live/deleg_ab12cd34/task-0.log

Mỗi dòng có dấu thời gian, văn bản của tác tử con, đoạn suy nghĩ, lời gọi công cụ, kết quả công cụ và trạng thái cuối. manifest.json mô tả lô. Nhật ký được giữ sau khi hoàn tất và các thư mục quá 7 ngày tự động bị dọn khi có lần điều phối mới.

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

Mặc định việc ủy quyền là phẳng: tác tử cha ở độ sâu 0 tạo tác tử con ở độ sâu 1, và tác tử con không thể ủy quyền tiếp. Điều này ngăn cây đệ quy tăng không kiểm soát.

Với quy trình nhiều giai đoạn, tác tử cha có thể tạo tác tử con kiểu điều phối để tác tử này tiếp tục giao việc:

python
delegate_task(
    goal="Khảo sát ba cách rà soát mã và đề xuất một cách",
    role="orchestrator",  # Cho phép tác tử con tạo worker riêng
    context="...",
)
  • role="leaf" (mặc định): không thể ủy quyền tiếp.
  • role="orchestrator": giữ bộ công cụ delegation, nhưng bị ràng buộc bởi delegation.max_spawn_depth. Mặc định 1 nghĩa là cây phẳng.
  • delegation.orchestrator_enabled: false: công tắc toàn cục buộc mọi tác tử con thành tác tử lá.
!
Cảnh báo chi phí

Với max_spawn_depth: 3max_concurrent_children: 3, cây có thể đạt 3×3×3 = 27 tác tử lá đồng thời. Hãy tăng độ sâu một cách có chủ đích.

#Vòng đời và độ bền

!
Kết quả nền bền vững không đồng nghĩa với thực thi bền vững

Lệnh gọi delegate_task ở cấp cao nhất chạy nền khi phiên hỗ trợ giao kết quả sau. Hermes trả mã xử lý ngay và đưa kết quả trở lại cuộc trò chuyện khi hoàn tất. Endpoint request/response không trạng thái sẽ quay về thực thi đồng bộ nếu không thể giao kết quả tách rời.

  • Tin nhắn tiếp theo không hủy tác tử con nền; /stop hoặc đóng/đặt lại phiên sở hữu mới hủy.
  • Khởi động lại tiến trình Hermes không tiếp tục tác tử đang chạy; lần thử trở thành unknown.
  • Tác tử hoàn tất trước khi khởi động lại nhưng chưa giao kết quả sẽ được khôi phục và định tuyến lại.
  • Tác tử bị hủy trả về kết quả có cấu trúc, dù tác tử cha thường đã bị ngắt nên kết quả có thể không hiển thị.

Để thực thi bền vững qua việc đóng phiên hoặc khởi động lại tiến trình, hãy dùng:

  • cronjob với action="create" để lên lịch một lượt chạy tác tử độc lập.
  • terminal(background=True, notify_on_complete=True) cho lệnh chạy dài.

#Đặc tính chính

  • Mỗi tác tử con có phiên terminal riêng, tách biệt với tác tử cha.
  • Tác tử con kế thừa bộ công cụ đã bật của tác tử cha và không thể tự mở rộng quyền.
  • Ủy quyền lồng nhau là tùy chọn, chỉ dành cho vai trò điều phối khi tăng max_spawn_depth.
  • Tác tử lá không thể gọi delegate_task, clarify, memory, send_message hay cronjob.
  • Hủy tuân theo quyền sở hữu của phiên và nhánh điều phối.
  • Chỉ bản tổng kết cuối cùng đi vào ngữ cảnh cha, giúp tiết kiệm token.
  • Tác tử con kế thừa API key, cấu hình nhà cung cấp và nhóm thông tin xác thực của tác tử cha.

#Ủy quyền so với execute_code

Yếu tốdelegate_taskexecute_code
Lập luậnVòng lặp suy luận LLM đầy đủChỉ thực thi mã Python
Ngữ cảnhCuộc hội thoại mới, biệt lậpKhông hội thoại, chỉ có script
Quyền công cụMọi công cụ không bị chặn, có suy luận7 công cụ qua RPC, không suy luận
Song songMặc định 3 tác tử con đồng thờiMột script duy nhất
Phù hợp nhấtTác vụ phức tạp cần phán đoánQuy trình máy móc nhiều bước
Chi phí tokenCao hơnThấp hơn
Tương tác người dùngKhôngKhông

Quy tắc nhanh: dùng delegate_task khi tác vụ cần suy luận, phán đoán hoặc giải quyết vấn đề nhiều bước. Dùng execute_code khi cần xử lý dữ liệu máy móc hoặc quy trình có thể viết script.

#Cấu hình

yaml
# Trong ~/.hermes/config.yaml
delegation:
  max_iterations: 50
  # max_concurrent_children: 3  # Số tác tử song song (mặc định: 3)
  # max_spawn_depth: 1         # Độ sâu cây (mặc định: 1 = phẳng)
  # orchestrator_enabled: true # Tắt để buộc mọi tác tử con thành tác tử lá
  model: "google/gemini-3-flash-preview"
  provider: "openrouter"
  api_mode: anthropic_messages

# Hoặc dùng endpoint tùy chỉnh trực tiếp thay cho nhà cung cấp:
delegation:
  model: "qwen2.5-coder"
  base_url: "http://localhost:1234/v1"
  api_key: "local-key"
  # api_mode: "anthropic_messages"

Khi base_url trỏ tới endpoint tương thích Anthropic, chẳng hạn đường dẫn kết thúc bằng /anthropic, Azure Foundry Claude hoặc proxy MiniMax, Hermes tự phát hiện api_mode: anthropic_messages. Chỉ đặt thủ công khi việc tự phát hiện sai.

i
Mẹo

Tác tử tự xử lý việc ủy quyền dựa trên độ phức tạp của nhiệm vụ. Bạn không cần yêu cầu rõ ràng — nó sẽ tự giao việc khi phù hợp.