Bỏ qua để đến nội dung

Dùng tính năng Claude Code trong SDK

Bài viết được dịch tự động từ bài viết gốc, chưa được kiểm tra lại bởi con người. Chỉ những bài viết có dấu tick xanh cạnh tiêu đề là đã được kiểm tra.

Agent SDK được xây trên cùng nền tảng với Claude Code, nghĩa là agent SDK của bạn có quyền truy cập vào cùng các tính năng dựa-trên-filesystem: project instructions (CLAUDE.md và rules), skill, hook, và nhiều hơn nữa.

Khi bạn bỏ qua settingSources, query() đọc cùng filesystem settings như Claude Code CLI: user, project, và local settings, file CLAUDE.md, và skill, agent, command trong .claude/. Để chạy mà không có các thứ này, truyền settingSources: [], giới hạn agent chỉ còn những gì bạn cấu hình bằng code. Managed policy settings và config toàn cục ~/.claude.json vẫn được đọc bất kể option này. Xem Những gì settingSources không kiểm soát.

Kiểm soát filesystem settings với settingSources

Phần tiêu đề “Kiểm soát filesystem settings với settingSources”

Option setting sources (setting_sources trong Python, settingSources trong TypeScript) kiểm soát SDK load những filesystem-based settings nào. Truyền một danh sách tường minh để chọn nguồn cụ thể, hoặc truyền mảng rỗng để tắt user, project, và local settings.

Ví dụ này load cả user-level và project-level settings bằng cách đặt settingSources thành ["user", "project"]:

from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessage
import asyncio
async def main():
async for message in query(
prompt="Help me refactor the auth module",
options=ClaudeAgentOptions(
# "user" load từ ~/.claude/, "project" load từ ./.claude/ trong cwd.
# Kết hợp cả hai cho agent quyền truy cập CLAUDE.md, skill, hook, và
# permission từ cả hai vị trí.
setting_sources=["user", "project"],
allowed_tools=["Read", "Edit", "Bash"],
),
):
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, "text"):
print(block.text)
if isinstance(message, ResultMessage) and message.subtype == "success":
print(f"\nResult: {message.result}")
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Help me refactor the auth module",
options: {
// "user" load từ ~/.claude/, "project" load từ ./.claude/ trong cwd.
// Kết hợp cả hai cho agent quyền truy cập CLAUDE.md, skill, hook, và
// permission từ cả hai vị trí.
settingSources: ["user", "project"],
allowedTools: ["Read", "Edit", "Bash"]
}
})) {
if (message.type === "assistant") {
for (const block of message.message.content) {
if (block.type === "text") console.log(block.text);
}
}
if (message.type === "result" && message.subtype === "success") {
console.log(`\nResult: ${message.result}`);
}
}

Khi chạy, phản hồi của assistant được in ra stdout, theo sau bởi một dòng kết quả cuối khi lần chạy hoàn tất.

Mỗi nguồn load setting từ một vị trí cụ thể, với <cwd> là thư mục làm việc bạn truyền qua option cwd, hoặc thư mục hiện tại của process nếu không đặt.

NguồnNó load gìVị trí
"project"CLAUDE.md project, .claude/rules/*.md, skill project, hook project, settings.json project<cwd>/.claude/ cho settings.json và hook; <cwd> và mọi thư mục cha cho CLAUDE.md và rules; <cwd> và mọi thư mục cha tới repository root cho skill
"user"CLAUDE.md user, ~/.claude/rules/*.md, skill user, user settings~/.claude/
"local"CLAUDE.local.md, .claude/settings.local.json<cwd>/.claude/ cho settings.local.json; <cwd> và mọi thư mục cha cho CLAUDE.local.md

Bỏ qua settingSources tương đương với ["user", "project", "local"].

Option cwd quyết định SDK tìm input cấp project ở đâu. CLAUDE.md và rules load từ <cwd> và từ mọi thư mục cha. Skill load từ <cwd> và từ mọi thư mục cha tới repository root. settings.json project và hook chỉ load từ <cwd>/.claude/, không fallback lên thư mục cha.

settingSources bao phủ user, project, và local settings. Một vài input vẫn được đọc bất kể giá trị của nó:

InputHành viCách tắt
Managed policy settingsPolicy được quản lý bởi endpoint, như một MDM plist, registry policy, hay managed settings file, load từ host. Server-managed settings được fetch trên cấu hình đủ điều kiện khi session xác thực bằng organization OAuth login hoặc API key cấu hình trực tiếpEndpoint policy: xoá managed settings file, plist, hoặc registry policy khỏi host. Server-managed settings: do admin tổ chức của bạn kiểm soát; không thể tắt từ SDK
Config toàn cục ~/.claude.jsonLuôn được đọcĐổi vị trí bằng CLAUDE_CONFIG_DIR trong env
Auto memory tại ~/.claude/projects/<project>/memory/Load vào system prompt khi bắt đầu session. Agent ghi memory mới ở đó bằng tool WriteEdit chuẩn thay vì một tool memory riêng, nên các tool này phải được bật để agent lưu được memoryĐặt autoMemoryEnabled: false trong settings, hoặc CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 trong env
claude.ai MCP connectorsLoad khi session xác thực bằng login claude.ai của bạn. Không load khi CLAUDE_CODE_OAUTH_TOKEN chứa token từ claude setup-token, thứ chỉ có thể gọi model request. Truyền mcpServers: {} không tắt được connector nàyĐặt strictMcpConfig: true, disableClaudeAiConnectors: true trong settings, hoặc ENABLE_CLAUDEAI_MCP_SERVERS=false trong env

File CLAUDE.md.claude/rules/*.md cho agent của bạn context lâu dài về project: quy ước code, lệnh build, quyết định kiến trúc, và chỉ dẫn. Khi settingSources bao gồm "project" (như trong ví dụ trên), SDK load các file này vào context khi bắt đầu session. Agent sau đó theo quy ước project của bạn mà không cần bạn lặp lại trong mỗi prompt.

CấpVị tríKhi load
Project (root)<cwd>/CLAUDE.md hoặc <cwd>/.claude/CLAUDE.mdsettingSources bao gồm "project"
Project rules<cwd>/.claude/rules/*.md.claude/rules/*.md trong mọi thư mục chasettingSources bao gồm "project"
Project (thư mục cha)File CLAUDE.md trong các thư mục trên cwdsettingSources bao gồm "project", load khi bắt đầu session
Project (thư mục con)File CLAUDE.md trong các thư mục con của cwdsettingSources bao gồm "project", load theo yêu cầu khi agent đọc một file trong subtree đó
Local<cwd>/CLAUDE.local.mdCLAUDE.local.md trong mọi thư mục chasettingSources bao gồm "local"
User~/.claude/CLAUDE.mdsettingSources bao gồm "user"
User rules~/.claude/rules/*.mdsettingSources bao gồm "user"

Mọi cấp đều cộng dồn: nếu cả CLAUDE.md project và user đều tồn tại, agent thấy cả hai. Không có quy tắc ưu tiên cứng giữa các cấp; nếu chỉ dẫn xung đột, kết quả tuỳ vào cách Claude diễn giải. Viết quy tắc không xung đột, hoặc nêu rõ độ ưu tiên trong file cụ thể hơn (“Các chỉ dẫn cấp project này ghi đè lên mặc định cấp user nếu xung đột”).

Skill là file markdown cho agent của bạn kiến thức chuyên biệt và workflow có thể gọi được. Khác với CLAUDE.md (load mỗi session), skill load theo yêu cầu. Agent nhận mô tả skill khi khởi động và load nội dung đầy đủ khi liên quan.

Skill được phát hiện từ filesystem qua settingSources. Khi option skills trên query() bị bỏ qua, skill user và project được phát hiện sẽ được bật và tool Skill khả dụng, khớp hành vi CLI. Để kiểm soát skill nào được bật, truyền skills"all", một danh sách tên skill, hoặc [] để tắt hết. Khi skills được đặt, SDK tự động thêm tool Skill vào allowedTools. Nếu bạn cũng truyền danh sách tools tường minh, hãy bao gồm "Skill" trong danh sách đó để Claude gọi được skill.

from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
import asyncio
# Skill trong .claude/skills/ được phát hiện tự động
# khi settingSources bao gồm "project"
async def main():
async for message in query(
prompt="Review this PR using our code review checklist",
options=ClaudeAgentOptions(
setting_sources=["user", "project"],
skills="all",
allowed_tools=["Read", "Grep", "Glob"],
),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
// Skill trong .claude/skills/ được phát hiện tự động
// khi settingSources bao gồm "project"
for await (const message of query({
prompt: "Review this PR using our code review checklist",
options: {
settingSources: ["user", "project"],
skills: "all",
allowedTools: ["Read", "Grep", "Glob"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}

SDK hỗ trợ hai cách định nghĩa hook, và chúng chạy song song với nhau:

  • Filesystem hooks: lệnh shell định nghĩa trong settings.json, load khi settingSources bao gồm nguồn liên quan. Đây là cùng hook bạn cấu hình cho phiên Claude Code tương tác.
  • Programmatic hooks: hàm callback truyền trực tiếp vào query(). Chúng chạy trong process ứng dụng của bạn và có thể trả về quyết định có cấu trúc.

Cả hai loại thực thi trong cùng vòng đời hook. Nếu bạn đã có hook trong .claude/settings.json của project và đặt settingSources: ["project"], các hook đó tự động chạy trong SDK mà không cần cấu hình thêm.

Hook callback nhận input của tool và trả về một dict quyết định. Trả về {} nghĩa là cho phép tool tiếp tục. Để chặn thực thi, trả về một object hookSpecificOutput với permissionDecision: "deny"permissionDecisionReason. Lý do được gửi cho Claude làm kết quả tool. Các trường decisionreason cấp top-level đã deprecated cho PreToolUse.

from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, ResultMessage
import asyncio
# PreToolUse hook callback. Các tham số vị trí:
# input_data: dict HookInput với tool_name, tool_input, hook_event_name
# tool_use_id: str | None, ID của lời gọi tool đang bị chặn
# context: HookContext, dành cho hỗ trợ abort-signal trong tương lai
async def audit_bash(input_data, tool_use_id, context):
command = input_data.get("tool_input", {}).get("command", "")
if "rm -rf" in command:
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked",
}
}
return {} # Dict rỗng: cho phép tool tiếp tục
# Filesystem hook từ .claude/settings.json chạy tự động
# khi settingSources load chúng. Bạn cũng có thể thêm programmatic hook:
async def main():
async for message in query(
prompt="Refactor the auth module",
options=ClaudeAgentOptions(
setting_sources=["project"], # Load hook từ .claude/settings.json
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[audit_bash]),
]
},
),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())
import { query, type HookInput, type HookJSONOutput } from "@anthropic-ai/claude-agent-sdk";
// PreToolUse hook callback. HookInput là một discriminated union theo
// hook_event_name, nên narrow theo nó cho TypeScript biết đúng shape
// tool_input cho sự kiện này.
const auditBash = async (input: HookInput): Promise<HookJSONOutput> => {
if (input.hook_event_name !== "PreToolUse") return {};
const toolInput = input.tool_input as { command?: string };
if (toolInput.command?.includes("rm -rf")) {
return {
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructive command blocked",
},
};
}
return {}; // Object rỗng: cho phép tool tiếp tục
};
// Filesystem hook từ .claude/settings.json chạy tự động
// khi settingSources load chúng. Bạn cũng có thể thêm programmatic hook:
for await (const message of query({
prompt: "Refactor the auth module",
options: {
settingSources: ["project"], // Load hook từ .claude/settings.json
hooks: {
PreToolUse: [{ matcher: "Bash", hooks: [auditBash] }]
}
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
Loại hookPhù hợp nhất cho
Filesystem (settings.json)Chia sẻ hook giữa phiên CLI và SDK. Hỗ trợ "command" (shell script), "http" (POST tới một endpoint), "mcp_tool" (gọi tool của một MCP server đã kết nối), "prompt" (LLM đánh giá một prompt), và "agent" (sinh một agent verifier). Các hook này chạy trong agent chính và mọi subagent nó sinh ra.
Programmatic (callback trong query())Logic đặc thù ứng dụng, quyết định có cấu trúc, và tích hợp in-process. Các hook này cũng chạy bên trong subagent. Hook input, tham số đầu tiên của callback, mang trường agent_idagent_type xác định agent nào trigger hook.

Agent SDK cho bạn nhiều cách để mở rộng hành vi agent của bạn. Nếu chưa chắc dùng cái nào, bảng này ánh xạ mục tiêu thường gặp tới cách tiếp cận đúng.

Bạn muốn…DùngMôi trường SDK
Đặt quy ước project agent của bạn luôn theoCLAUDE.mdsettingSources: ["project"] tự động load nó
Cho agent tài liệu tham khảo nó load khi liên quanSkillssettingSources + option skills
Chạy một workflow tái sử dụng (deploy, review, release)User-invocable skillssettingSources + option skills
Giao một subtask độc lập cho context mới (nghiên cứu, review)Subagentstham số agents + allowedTools: ["Agent"]
Điều phối nhiều instance Claude Code với task list chia sẻ và nhắn tin trực tiếp giữa các agentAgent teamsKhông cấu hình trực tiếp qua option SDK. Agent teams là tính năng CLI nơi một session đóng vai trò team lead, điều phối công việc giữa các teammate độc lập
Chạy logic tất định trên lời gọi tool (audit, block, transform)Hookstham số hooks với callback, hoặc shell script load qua settingSources
Cho Claude quyền truy cập tool có cấu trúc tới một dịch vụ bên ngoàiMCPtham số mcpServers

Mỗi tính năng bạn bật đều thêm vào context window của agent.

  • Extend Claude Code: Tổng quan khái niệm về mọi tính năng mở rộng, kèm bảng so sánh và phân tích chi phí context
  • Skills trong SDK: Hướng dẫn đầy đủ về dùng skill bằng code
  • Subagents: Định nghĩa và gọi subagent cho subtask độc lập
  • Hooks: Chặn và kiểm soát hành vi agent tại các điểm thực thi quan trọng
  • Permissions: Kiểm soát quyền truy cập tool bằng mode, rule, và callback
  • System prompts: Chèn context mà không cần file CLAUDE.md