Bạn đang debug một bug phức tạp trong main session, đang tailing log production, đang giữ một đống context về state hiện tại. Bây giờ muốn nhờ ai đó review một đoạn code. Bạn không thể bỏ main session, bạn cũng không muốn nhồi thêm task vào context đang có.

Đây là lúc subagent ra đời.

Subagent không phải là tính năng chat mới của Claude Code. Nó là một session riêng biệt, có tool whitelist riêng, có system prompt riêng, chạy độc lập hoàn toàn. Main session spawn nó ra, giao task, và nhận kết quả về. Bài này đi vào chi tiết: agent definition file trông như thế nào, spawn ra sao, khác skill ở điểm nào.

Subagent là gì

Về mặt kỹ thuật, subagent là một Claude Code session mới được khởi tạo bằng cách gọi công cụ Agent từ main session. Session đó:

  • Nhận một system prompt riêng (persona của agent, quy tắc của agent)
  • Chỉ thấy tool subset mà main session cho phép
  • Chạy hoàn toàn độc lập, không chia sẻ context với main session
  • Kết thúc khi task hoàn thành, trả kết quả về cho main session
Main session (full tool access)
    |
    | Agent({subagent_type: "fullstack-engineer", prompt: "..."})
    |
    v
Subagent session (tool subset: All, nhưng system prompt riêng)
    - Đọc code, hiểu context
    - Thực hiện thay đổi
    - Báo cáo kết quả
    |
    v
Main session nhận kết quả về

Khác biệt then chốt so với cách dùng thông thường: main session không bị gián đoạn. Bạn có thể spawn subagent chạy ngầm (run_in_background: true) trong khi main session tiếp tục làm việc khác.

Cấu trúc agent definition file

Agent definition sống trong ~/.claude/agents/<name>.md. Đây là ví dụ rút gọn từ agent fullstack-engineer:

---
name: fullstack-engineer
description: "Use this agent when the user needs to implement, modify,
  or extend fullstack features across the codebase. This includes
  frontend components, backend APIs, database changes, and integration
  work.

  Examples:

  - User: \"Add a new status field to the order model and display it in the UI\"
    Assistant: \"I'll use the fullstack-engineer agent to implement this
    across the stack safely.\"
    (Use the Agent tool to launch the fullstack-engineer agent to
    implement the feature with backward compatibility considerations.)

  - User: \"Refactor the authentication flow to support OAuth\"
    Assistant: \"Let me use the fullstack-engineer agent to handle this
    refactor carefully.\"
    (Use the Agent tool to launch the fullstack-engineer agent since
    this touches both frontend and backend with breaking change risks.)"
model: opus
color: red
memory: user
---

Phần sau dấu --- cuối là body: system prompt cho agent này. Nó define persona, nguyên tắc làm việc, checklist chất lượng. Khi agent session được spawn, body này trở thành instruction layer của session đó.

Các field frontmatter

FieldÝ nghĩa
nameTên agent. Dùng để gọi qua subagent_type khi spawn. Cũng là tên CC dùng để hiểu khi nào nên tự gợi ý spawn.
descriptionMô tả dài khi nào dùng agent này. Bắt buộc có examples block (xem dưới). Model dùng description để quyết định tự spawn hay không khi user request match.
modelopus, sonnet, haiku, hoặc inherit (kế thừa từ main session). Opus cho task phức tạp cần reasoning sâu. Haiku cho task đơn giản cần tốc độ.
colorMàu hiển thị trong terminal UI. Thuần cosmetic.
memoryScope của persistent memory: user (global, áp dụng mọi project) hoặc project (per-project).

Không có field tools trong frontmatter này vì fullstack-engineer dùng All tools. Bài 16 về spawning patterns sẽ nói rõ cách truyền tool subset khi spawn.

Examples block trong description

Đây là phần quan trọng nhất của description. Format chuẩn:

- User: "<user request>"
  Assistant: "<assistant response>"
  (Use the Agent tool to launch <agent-name> because <reason>.)

Examples block dạy CC khi nào nên tự gợi ý spawn agent này, và cách giải thích cho user lý do. Không có examples block thì CC phải đoán, đoán sai thường xuyên.

Body: system prompt

Phần body (sau frontmatter) là nội dung dài nhất. Với fullstack-engineer, body bao gồm:

  • Core Principles: Safety First, Backward Compatibility, Read Before Write, Incremental Changes, No Assumptions.
  • Backward Compatibility Checklist: danh sách cụ thể cho API changes, database changes, component changes, function signatures, data format changes.
  • Development Workflow: quy trình 5 bước từ understand requirement đến clean up.
  • Safety Rules: giống rules trong global CLAUDE.md nhưng scoped cho agent này.
  • Quality Self-Check: checklist checkbox trước khi present work.

Body dài và chi tiết là bình thường. Agent chỉ nhận body này một lần khi spawn, nên chi tiết không làm tốn token của main session.

Khác skill ở điểm nào

Câu hỏi này hay xuất hiện vì cả hai đều nằm trong ~/.claude/. Nhưng chúng hoạt động ở tầng hoàn toàn khác:

Điểm so sánhSkillSubagent
Chạy ở đâuCùng main sessionSession riêng biệt
Inject vào đâuL2 (user instructions) của main sessionSystem prompt của session mới
Tool accessDùng tool của main sessionTool subset được chỉ định
ContextCó đầy đủ context của main sessionChỉ nhận prompt task được truyền vào
StateChia sẻ state với main sessionKhông chia sẻ
Dùng khi nàoWrap workflow phức tạp thành 1 lệnhCần isolation, persona riêng, hoặc tool subset

Skill là instruction markdown. Khi user gọi /skill-name, CC inject nội dung skill vào conversation và đi theo hướng dẫn. Tool vẫn là tool của main session, context vẫn là context đang có.

Subagent là session mới. Nó không biết gì về session cha ngoài cái prompt task được truyền vào. Nó cũng không tự truy cập context cha, không đọc memory của cha, không thấy lịch sử conversation của cha.

Tóm lại: skill là “dạy main session làm thêm việc”, subagent là “spawn một worker riêng làm việc thay”.

Cách spawn subagent

Từ main session, CC gọi công cụ Agent:

Agent({
  subagent_type: "fullstack-engineer",
  prompt: "Implement a pagination component for the orders list. ...",
  // Tùy chọn:
  // run_in_background: true   <- spawn ngầm, main session không chờ
  // isolation: "worktree"     <- tạo git worktree riêng cho agent
})

subagent_type khớp với name trong frontmatter của agent definition file. Nếu subagent_type là một agent name không tồn tại trong ~/.claude/agents/, CC fallback về một generic agent.

Hai chiều spawn:

Foreground (mặc định): main session block, chờ subagent xong rồi mới tiếp tục. Dùng khi task ngắn và main session cần kết quả trước khi làm bước tiếp theo.

Background (run_in_background: true): main session không chờ. Subagent chạy song song, báo cáo khi xong. Dùng khi task dài hoặc main session cần tiếp tục công việc khác ngay.

Thêm isolation: "worktree" thì CC tạo một git worktree riêng cho agent. Agent commit vào branch riêng, không động đến branch đang mở ở main session. Bài 17 về worktree isolation sẽ đi sâu vào pattern này.

Tools whitelist: least privilege

Đây là best practice quan trọng nhất khi dùng subagent.

Mặc định, nếu không chỉ định tool subset, agent nhận All tools. Nhưng agent cụ thể không cần dùng hết. Ví dụ:

Agent review code: chỉ cần đọc và tìm kiếm, không cần sửa.

tools: Read, Grep, Glob

Agent explore codebase: đọc, tìm kiếm, list file.

tools: Read, Grep, Glob, LS

Agent fullstack-engineer: cần làm việc thực sự, cần đủ tool.

tools: All

Hai lý do giảm tool:

  1. Giảm risk: agent review với chỉ Read, Grep không thể tình cờ sửa file. Tool whitelist là guardrail cứng, không phụ thuộc vào việc agent có tuân thủ instruction hay không.

  2. Giảm token: mỗi tool trong whitelist đều có schema được inject vào context của agent. Whitelist hẹp hơn thì schema ngắn hơn, tiết kiệm token input của agent session.

+----------------------------------+
| Agent session context            |
|                                  |
| System prompt (body)             |  <- persona + rules
| Tools available (schemas)        |  <- càng hẹp càng tốt
| Task prompt từ main session      |
+----------------------------------+

Anti-pattern hay gặp: spawn agent review với tools: All. Agent đó có thể sửa file bất cứ lúc nào nó “nghĩ” nên sửa, dù task chỉ là review. Tốn thêm token để load schema của Bash, Edit, Write trong khi chúng không được dùng.

Agents có sẵn trong một setup thực tế

Trong ~/.claude/agents/ của một setup thực, bạn thường thấy:

fullstack-engineer: agent đa năng cho mọi feature development. Dùng model opus, có persona về backward compatibility và safety. Tool: All.

ui-ux-designer: agent chuyên về visual refinements, layout, typography, accessibility. Model inherit (kế thừa từ main session). Có body chi tiết về color theory, spacing system, animation guidelines. Tool: thường All nhưng scope hẹp về file type.

svg-diagram-specialist: agent chuyên vẽ SVG diagram. Tool whitelist hẹp vì chỉ cần tạo file SVG, không cần đọc codebase rộng.

Đây là những agent generic, không mang persona của một project cụ thể. Best practice: giữ agent definition ở ~/.claude/agents/ (global) và chỉ viết persona về kỹ năng, không hardcode context project vào đó. Context project thì truyền qua prompt khi spawn.

Khi nào dùng subagent thay vì làm trực tiếp

Ba tình huống điển hình:

Main session đang bận: đang monitor deployment, đang tailing log, đang giữ nhiều file mở. Spawn agent background để nó làm task khác song song thay vì nhồi vào context đang có.

Task cần persona chuyên biệt: muốn ai đó chỉ nghĩ về UI/UX mà không bị distracted bởi business logic, hoặc muốn ai đó chỉ review backward compatibility mà không bị tác động bởi pressure của feature delivery. Agent với system prompt riêng giữ focus tốt hơn.

Task cần isolation git: feature mới muốn để trên branch riêng, review qua PR trước khi merge. Kết hợp isolation: "worktree" với agent, task chạy trên worktree riêng, PR mở về main branch. Xem bài 17.

Tóm tắt và bài tiếp theo

  • Subagent là session riêng biệt, có system prompt riêng (body của agent file), tool subset riêng, chạy độc lập. Không chia sẻ context với main session ngoài task prompt được truyền vào khi spawn.
  • Agent definition file: frontmatter có name, description (kèm examples block), model, memory. Body là system prompt cho persona.
  • Khác skill: skill inject vào main session, subagent là session mới. Skill dùng tool của main session, subagent dùng tool subset riêng.
  • Best practice tools whitelist: hẹp nhất có thể. Review agent không cần Edit, Write. Giảm risk, giảm token.
  • Spawn: Agent({subagent_type: ..., prompt: ...}). Foreground hoặc background. Có hoặc không có worktree isolation.

Bài 16 sẽ đi sâu vào các spawning pattern: parallel foreground, background, sequential, và team mode. Mỗi pattern phù hợp với tình huống khác nhau và có trade-off khác nhau về risk và complexity. Bài 17 mổ xẻ worktree isolation: cơ chế, hook liên quan, và cách integrate kết quả về main branch mà không cần checkout.


Bài thuộc series Claude Code từ zero. Series plan tại bài giới thiệu.