- Giao việc lặp cho Claude nằm trên một DẢI: đầu ít-phải-build nhất là routine (chạy trên hạ tầng Anthropic), đầu kia là headless mode + Agent SDK (chạy từ code của bạn). Routine = một prompt được lưu, gói 3 thứ (prompt + repository + connectors) rồi chạy trên cloud khi được kích hoạt — không script, không server, không máy nào của bạn phải thức, không workflow file phải maintain. Ba trigger: cron schedule (VD 9am mỗi sáng), HTTP POST tới API endpoint của nó, và GitHub event (VD có PR mới). Tạo bằng web claude.ai/code/routines hoặc lệnh /schedule ngay trong Claude Code (VD "/schedule daily dependency audit at 9am").
- ⚠️ Ba giới hạn của routine: (1) đang là research preview — hành vi/limit còn đổi; (2) recurring schedule chạy nhiều nhất MỖI GIỜ một lần, cần dày hơn thì routine không phải công cụ; (3) mỗi run bắt đầu từ fresh clone của default branch và chỉ push được lên branch prefix claude/ trừ khi nới theo từng repo — guardrail giữ cho lần chạy tự chủ không viết đè main.
- Headless mode dùng khi việc cần môi trường của bạn hoặc cần logic bọc quanh: cờ -p (--print) chạy Claude Code như lệnh one-shot không UI, đọc stdin ghi stdout nên pipe được như mọi tool shell. Theo khoá, -p bỏ auto-discovery của hook/skill/ plugin/MCP server/CLAUDE.md nên khởi động nhanh hơn (⚠️ docs hiện hành gán việc này cho --bare, còn -p trơn vẫn nạp context như session tương tác). Muốn dữ liệu có cấu trúc: --output-format json + --json-schema → object khớp schema nằm ở field structured_output, móc ra bằng jq. Nhiều bước thì bắt session_id từ JSON rồi claude --resume "$(jq -r .session_id /tmp/plan.json)" — script này khởi động, script kia resume với đầy đủ context. CI cần kết quả lặp lại được thì dùng --bare (deterministic mode). Thứ tự chọn: routine mặc định → -p khi cần pipeline của bạn → --bare cho CI → Agent SDK khi việc thuộc về sản phẩm của bạn.
- Agent SDK: chạy Claude Code programmatically từ app/script của bạn (TypeScript + Python), trao đúng agent loop CLI dùng (đọc/sửa file, tool use) dưới quyền bạn. Package = @anthropic-ai/claude-agent-sdk (KHÔNG phải @anthropic-ai/claude-code — đó là CLI, không import được). Dùng query({ prompt }) như async iterator, stream ra JSON message (tool call, tool result, text). Giới hạn tool bằng options.allowedTools (VD ["Read","Glob"]) = bản SDK của --allowedTools. SDK hỗ trợ đủ như CLI: custom system prompt, MCP, hooks, subagents, session resumption. Đây là thứ query_hook.js dùng để một Claude review một Claude khác.
TL;DR — Giao việc lặp nằm trên một dải, không phải một lựa chọn: routine ít phải build nhất (nhưng còn research preview, 3 giới hạn phải biết) → headless
-pkhi cần môi trường của bạn hoặc logic bọc quanh → Agent SDK khi cần chạy Claude Code từ chính app của bạn. Chọn sai đầu dải là tự dựng thứ đã có sẵn.
Phần 4/7 của ghi chú khoá Claude Code in Action — đề thi thử 219 câu (chấm điểm + giải thích) nằm ở tab "Đề thi thử" trên trang tổng quan.
Routine & headless — giao hẳn việc lặp cho Claude
Khi đã tin Claude làm được một task, nước đi kế tiếp là thôi tự tay làm nó. Cùng một prompt chạy trên một trigger lặp lại thì không việc gì phải ngồi bấm mỗi lần. Có hai đường giao việc, và chúng nằm trên một dải (spectrum):
- Đầu này: routine — chạy trên hạ tầng của Anthropic, bạn không build gì cả.
- Đầu kia: headless mode + Agent SDK — chạy Claude Code từ code của chính bạn, toàn quyền kiểm soát.
Bắt đầu từ đầu ít-phải-build nhất.
Routine — một prompt được lưu, chạy trên cloud
Routine là cách trực tiếp nhất để tự động hoá một task: không script, không server. Nó gói ba thứ: một prompt, repository nó làm việc trên đó, và các connector nó cần — rồi chạy cái gói đó trên cloud mỗi khi được kích hoạt.
Điểm mấu chốt: hạ tầng là của Anthropic. Không có máy nào của bạn phải bật suốt đêm, không có workflow file nào phải maintain. Mô tả công việc một lần, rồi nó cứ chạy.
Ba loại trigger:
| Trigger | Ví dụ |
|---|---|
| Cron schedule | mỗi sáng 9am |
| HTTP POST tới API endpoint của nó | code của bạn tự kích hoạt |
| GitHub event | có pull request mới |
Cái gì cùng một prompt trên một trigger lặp lại đều hợp: morning dependency audit, PR triager (fire khi có PR mới), quét Sentry ticket hằng ngày để biết cái nào gấp nhất.
Hai cách tạo routine
- Từ web tại
claude.ai/code/routines: đặt tên → viết instruction mô tả Claude phải làm gì trong mỗi session → chọn repository → chọn trigger. - Từ trong Claude Code, khỏi rời terminal — lệnh
/schedule+ mô tả bằng lời thường:
/schedule daily dependency audit at 9am
Cùng một thứ, hai cửa vào — chọn cửa nào hợp nếp làm việc của bạn.
🆕 Cửa thứ ba (khoá chưa nhắc, tự quan sát 25/07/2026): bản app Claude Code đã có mục Routines ngay trên sidebar (More → Routines, cạnh Artifacts) — mở ra xem/sửa routine khỏi cần vào web. Cùng một thứ với hai cách trên, chỉ khác lối vào. Đi thi thì nhớ web +
/scheduletheo lời khoá.
⚠️ Ba giới hạn phải biết TRƯỚC khi dựa vào routine
- Routine đang là research preview — hành vi và giới hạn còn đổi, đừng ngạc nhiên.
- Recurring schedule chạy nhiều nhất là MỖI GIỜ một lần. Cần dày hơn → routine không phải công cụ cho việc đó.
- Mỗi run bắt đầu từ một fresh clone của default branch, và chỉ push được lên branch có prefix
claude/trừ khi bạn nới ra theo từng repo. Đây chính là guardrail giữ cho một lần chạy tự chủ không viết đè lênmain.
Headless mode — khi công việc cần môi trường của bạn
Routine hợp khi việc vừa vặn với cloud. Nhưng có lúc việc cần môi trường của bạn, hoặc cần logic bọc quanh lần chạy — đó là lúc tụt xuống headless mode.
Cốt lõi là cờ -p (viết tắt của --print): chạy Claude Code như một lệnh one-shot, không UI tương tác. Nó đọc stdin, ghi stdout → pipe được như mọi tool shell khác:
claude -p "summarize the changes in this diff"
Theo khoá: -p bỏ qua auto-discovery của hook, skill, plugin, MCP server và CLAUDE.md → bạn có Claude + đúng bộ tool bạn cho phép tường minh, không dính thứ môi trường local tình cờ nạp vào; đổi lại khởi động nhanh hơn nhiều.
⚠️ Freshness — chỗ này docs nói khác: theo docs hiện hành, chính
--baremới là cờ bỏ auto-discovery (hook, skill, plugin, MCP server, auto memory,CLAUDE.md); cònclaude -ptrơn vẫn nạp đúng lượng context như một session tương tác, gồm mọi thứ cấu hình trong thư mục làm việc hoặc~/.claude. Docs cũng ghi--baresẽ thành mặc định của-pở bản sau — nhiều khả năng khoá đang mô tả trạng thái tương lai đó. Đi thi thì theo lời khoá; đi làm thì nhớ gõ--barecho chắc.
Lấy output có cấu trúc
Vì headless pipe như tool shell, bạn thường muốn nhận lại dữ liệu có cấu trúc thay vì văn xuôi. Ghép một JSON schema với JSON output format → Claude ràng buộc output khớp schema của bạn.
Object khớp schema nằm ở field structured_output trong JSON response → móc ra bằng jq rồi đẩy vào database hay script khác:
claude -p "Extract the exported function names from src/core/style.js" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output.functions'
→ Được một mảng sạch để đưa cho bước tiếp theo.
Tự động hoá nhiều bước bằng session
Việc trải qua nhiều bước thì khỏi nhồi hết vào một lệnh. Bắt lấy session ID từ JSON output rồi resume sau:
claude --resume "$(jq -r .session_id /tmp/plan.json)"
Một script khởi động công việc; một script khác resume nó sau, giữ nguyên context. Rất hợp khi lượt đầu ra một plan còn lượt sau thi hành plan đó.
--bare — chạy tất định cho CI
Khi CI cần đúng một kết quả ở mọi lần chạy, có một mode làm sẵn cho việc đó: cờ --bare = deterministic mode. Đây là lựa chọn đúng khi chạy Claude Code bên trong pipeline và bạn muốn output lặp lại được, đoán trước được, thay vì thứ đổi theo từng lần chạy.
Chọn cái nào?
| Dùng | Khi nào |
|---|---|
| Routine | Mặc định cho việc lặp — chạy trên hạ tầng Anthropic, không phải host gì |
Headless -p |
Việc cần pipeline của bạn, muốn đẩy dữ liệu qua một script |
--bare |
CI cần đúng một kết quả mỗi lần chạy |
| Agent SDK | Việc thuộc về sản phẩm của bạn (nhúng hẳn vào app — mục ngay dưới) |
Nguyên tắc: bắt đầu bằng routine; chỉ tụt xuống dải dưới khi công việc thật sự cần thêm quyền kiểm soát.
Áp dụng thực tế: đọc mục này tôi thấy đúng một trục quen: ai chịu trách nhiệm vận hành. Routine = thuê ngoài trọn gói — không máy phải thức, không workflow phải nuôi; đổi lại chấp nhận research preview và trần 1 lần/giờ, nên tôi sẽ không đặt vào đó thứ mà delivery phụ thuộc theo phút. Ba giới hạn đó không phải chi tiết vụn: "fresh clone + chỉ push branch
claude/" chính là least-privilege cho bot, cùng tinh thầnallowed_toolsbên GitHub Actions — bot không có đường chạmmain, con người vẫn giữ cửa merge. Với repo này thì routine hợp mấy việc định kỳ mà không gấp: quét link chết, soátupdatedcủa note /learn đã cũ, rà dependency. Còn headless-plà thứ tôi thấy dùng được ngay và không cần cloud: nó biến Claude thành một mắt xích trong pipeline —git diff | claude -p ... | jq— nghĩa là AI trở thành một bước có input/output rõ ràng, kiểm được, thay vì một cuộc trò chuyện. Và--json-schema+structured_outputmới là chỗ đáng giá nhất với dân delivery: văn xuôi thì không tự động hoá được, JSON thì được — có schema là có hợp đồng dữ liệu, có hợp đồng thì mới ghép được vào hệ khác.--barecho CI khớp với bài học "đừng để môi trường mỗi máy mỗi khác": cùng input, cùng cấu hình → cùng kết quả, không phụ thuộc hook trong~/.claudecủa một ông đồng đội nào đó.
Agent SDK — chạy Claude Code bằng code
Agent SDK cho phép chạy Claude Code programmatically từ app/script của bạn — có cho TypeScript và Python. Nó trao đúng agent loop mà CLI dùng (đọc file, sửa file, tool use) nhưng dưới quyền điều khiển của bạn. Đây chính là thứ query_hook.js (bài "hai hook thực chiến") dùng để một Claude review một Claude khác.
⚠️ Freshness — tên package đã đổi: video khoá dùng tên cũ không còn chạy. Package hiện hành là
@anthropic-ai/claude-agent-sdk. Đừng nhầm với@anthropic-ai/claude-code— đó là CLI, không import được.
Cài đặt
mkdir sdk-demo && cd sdk-demo
npm init -y
npm install @anthropic-ai/claude-agent-sdk
Ví dụ tối giản
Tạo index.mjs:
import { query } from "@anthropic-ai/claude-agent-sdk";
const prompt = "List the files in the current directory";
for await (const message of query({ prompt })) {
console.log(JSON.stringify(message, null, 2));
}
Chạy node index.mjs → thấy một stream JSON messages — đúng các conversation event như trong CLI: tool call, tool result, và text của Claude. (query() trả về một async iterator, for await để duyệt.)
Giới hạn tool — allowedTools
Mặc định SDK có full tool set. Thu hẹp bằng allowedTools:
for await (const message of query({
prompt,
options: { allowedTools: ["Read", "Glob"] },
})) {
// ...
}
Đây là bản SDK của flag --allowedTools trên CLI (và cùng tinh thần allowed_tools trong GitHub Actions).
Còn gì nữa
SDK làm được mọi thứ CLI làm: custom system prompts, MCP servers, hooks, subagents, và session resumption. Xem Agent SDK documentation cho reference đầy đủ.
Đặt vào dải tự động hoá ở mục trên, SDK là nấc cuối — dùng khi công việc thuộc về sản phẩm của bạn. Cả TypeScript và Python đều phơi ra cùng một hàm query và cùng bộ primitive như CLI: truyền vào prompt + options (allowedTools để kiểm soát Claude được làm gì, một system prompt, và một permission mode), rồi lặp qua các message Claude stream về và xử lý theo cách app của bạn cần. Cùng một engine với CLI, chỉ khác là gọi được từ bên trong sản phẩm.
Áp dụng thực tế: SDK là cái seam biến Claude Code từ công cụ tương tác thành building block nhúng được vào hệ thống của mình. Ba góc tôi ghim: (1) vòng khép kín với bài hooks —
query_hook.jsnhúng thẳng SDK bên trong một hook, tức Claude Code gọi Claude Code; "AI reviews AI" chỉ là API này, không có gì huyền bí; (2)allowedTools= một cần gạt least-privilege dùng khắp nơi — CLI--allowedTools, GitHub Actionsallowed_tools, SDKoptions.allowedTools; học một lần, và luôn thu hẹp tool cho tác vụ tự động (một script chỉ cần đọc thì cho đúng["Read","Glob"], đừng để full set); (3) kỷ luật chi phí — mỗiquery()là một lượt model tính tiền; một hook gọiquery()mỗi lần edit (như query_hook) nhân chi phí âm thầm, nên production phải bọc rate/spend guard. Và cái bẫy tên packageclaude-code(CLI) vsclaude-agent-sdk(thư viện) đúng bằng comment cảnh báo trongsdk.tscủa sandbox — import nhầm là fail ngay.
Phần tiếp theo: Claude Code: custom command & skill
Nguồn: Claude Code in Action (Anthropic Academy) — Copyright Anthropic. Phần đề thi thử cho khoá này nằm ở tab "Đề thi thử" trên trang tổng quan khoá.