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

Host Agent 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 spawn và giám sát một subprocess claude CLI, subprocess này sở hữu một shell, một working directory, và các session file trên đĩa. Host nó không giống host một stateless API wrapper. Mỗi agent đang chạy là một process sống lâu gắn với local state, điều này định hình cách bạn cấp phát tài nguyên, lưu trữ session, và scale trên nhiều tenant.

Trang này bao quát việc self-host trên hạ tầng của riêng bạn: hiểu mô hình subprocess, chọn session pattern, chuẩn bị container, và xử lý các mối quan tâm production như persistence, observability, auth, và multi-tenant isolation. Để lấy Dockerfile và Kubernetes manifest có thể deploy ngay, xem hosting cookbook.

Nếu bạn không cần kiểm soát hạ tầng, isolation tùy biến, hay data plane riêng, cân nhắc dùng Managed Agents thay thế: một REST API được host sẵn nơi Anthropic vận hành agent và sandbox, ứng dụng của bạn chỉ gửi event và nhận stream kết quả, không cần hạ tầng hosting nào.

Mọi quyết định hosting trên trang này đều xuất phát từ cách SDK chạy agent. Khi code của bạn gọi query(), SDK spawn một process claude CLI riêng biệt và giao tiếp qua stdio. Subprocess đó sở hữu shell, working directory, và các JSONL session transcript trên đĩa cục bộ.

Một agent session ứng với một subprocess. Chạy N session đồng thời nghĩa là có N subprocess, mỗi cái có process tree và transcript file riêng. Theo mặc định, tất cả kế thừa working directory của ứng dụng bạn, nên hãy truyền cwd cho mỗi lời gọi query() khi các session cần filesystem riêng biệt:

```typescript TypeScript theme={null} query({ prompt, options: { cwd: "/work/session-a" } }) ```
query(prompt=prompt, options=ClaudeAgentOptions(cwd="/work/session-a"))

Ba loại agent state sống trên filesystem của container theo mặc định. Không loại nào sống sót qua việc container restart, scale-down, hay chuyển sang node khác.

StateVị trí mặc định
Session transcript~/.claude/projects/, hoặc thư mục projects/ bên dưới CLAUDE_CONFIG_DIR nếu được set
File memory CLAUDE.md~/.claude/CLAUDE.md cho tier user, và working directory của session cho tier project
Artifact trong working directoryWorking directory của session

Để lưu trữ transcript qua nhiều host, cấu hình một SessionStore adapter. File memory và các artifact khác trong working directory cần chiến lược lưu trữ riêng, ví dụ một mounted volume hoặc sync với object-store.

Để biết cách session, resumption, và forking hoạt động ở tầng API, xem Sessions.

Bốn pattern dưới đây bao quát vòng đời session: container sống lâu bao lâu so với các session nó phục vụ. Về việc container chạy ở đâu, hosting cookbookcode có thể deploy cho Docker local, Modal, và Kubernetes. Chọn session pattern ở đây và một deployment target trong cookbook.

Tạo một container cho mỗi tác vụ người dùng và hủy nó khi tác vụ hoàn thành. Phù hợp nhất cho tác vụ một lần. Người dùng vẫn có thể tương tác với AI trong lúc tác vụ đang chạy, nhưng khi hoàn thành thì container bị hủy.

Các workload ví dụ gồm điều tra và sửa bug, trích xuất hóa đơn và biên lai, dịch tài liệu, và chuyển đổi media.

Container chạy một entrypoint one-shot gọi SDK rồi thoát. Với TypeScript, lưu file dưới dạng entrypoint.mts hoặc set "type": "module" trong package.json để top-level await khả dụng.

```typescript TypeScript theme={null} import { query } from "@anthropic-ai/claude-agent-sdk";

const prompt = process.env.TASK_PROMPT!; for await (const message of query({ prompt, options: { maxTurns: 20 } })) { console.log(message); }

```python Python theme={null}
import asyncio
import os
from claude_agent_sdk import ClaudeAgentOptions, query
async def main():
async for message in query(
prompt=os.environ["TASK_PROMPT"],
options=ClaudeAgentOptions(max_turns=20),
):
print(message)
asyncio.run(main())

Chạy các instance container sống lâu, thường host nhiều SDK process trên mỗi container, để phục vụ công việc liên tục. Phù hợp nhất cho agent hành động tự chủ, phục vụ nội dung, hoặc xử lý luồng message khối lượng lớn.

Các workload ví dụ gồm một email agent phân loại và trả lời mail đến, một site builder host một site có thể chỉnh sửa theo từng user qua container port, và một chat bot xử lý traffic liên tục từ nền tảng như Slack.

Container expose một endpoint HTTP hoặc WebSocket và map mỗi session đang hoạt động tới một query sống lâu cùng subprocess đứng sau nó. Trong TypeScript, dùng streamInput() để thêm lượt vào một session đang hoạt động và startup() để pre-warm subprocess trước khi có traffic đến. Trong Python, dùng ClaudeSDKClient để giữ một session mở qua nhiều lượt. Chọn kích thước container sao cho chứa được số session đồng thời tối đa trong bộ nhớ.

Container tạm thời hydrate từ SessionStore khi khởi động và ghi cập nhật ngược lại. Phù hợp nhất cho các session trải dài qua nhiều lần tương tác nhưng nằm idle giữa các lần đó. Container thu nhỏ trong lúc idle và bật lại khi người dùng quay lại.

Các workload ví dụ gồm một personal project manager với check-in không liên tục, deep research tạm dừng và tiếp tục qua nhiều giờ, và một customer support agent load lịch sử ticket qua các lần tương tác.

Tinh chỉnh idle timeout của provider theo tần suất bạn kỳ vọng người dùng quay lại. Tắt container mà không cấu hình SessionStore sẽ mất transcript theo, nên store là bắt buộc cho pattern này, không phải tùy chọn.

Pattern này xoay quanh việc resume một session theo ID với một store dùng chung được gắn kèm:

```typescript TypeScript theme={null} import { query, type SessionStore } from "@anthropic-ai/claude-agent-sdk";

declare const userInput: string; declare const sessionId: string; // tra từ database của bạn theo user declare const sessionStore: SessionStore; // S3, Redis, Postgres, hoặc adapter của riêng bạn

for await (const message of query({ prompt: userInput, options: { resume: sessionId, sessionStore }, })) { // … }

```python Python theme={null}
from claude_agent_sdk import query, ClaudeAgentOptions, SessionStore
import asyncio
user_input: str = ...
session_id: str = ... # tra từ database của bạn theo user
session_store: SessionStore = ... # S3, Redis, Postgres, hoặc adapter của riêng bạn
async def main():
async for message in query(
prompt=user_input,
options=ClaudeAgentOptions(
resume=session_id,
session_store=session_store,
),
):
...
asyncio.run(main())

Xem Session storage để biết đầy đủ interface SessionStore và các adapter tham khảo.

Chạy nhiều SDK subprocess trong một container. Phù hợp nhất cho các agent cần cộng tác chặt chẽ, ví dụ mô phỏng multi-agent nơi các agent tương tác với nhau trong một môi trường dùng chung.

Cho mỗi agent một working directory riêng để chúng không ghi đè file của nhau, và cô lập việc load settings để file CLAUDE.md của từng agent không rò rỉ sang agent khác. Xem Multi-tenant isolation để biết các tùy chọn cụ thể.

Chạy SDK bên trong một container sandbox để có process isolation, giới hạn tài nguyên, kiểm soát network, và filesystem tạm thời. Nhiều provider chuyên về môi trường container sandbox phù hợp với mô hình của Agent SDK.

Các câu hỏi cần trả lời khi chọn provider:

  • Ai vận hành sandbox: một sandbox-as-a-service provider vận hành hạ tầng cho bạn, còn tùy chọn self-hosted cho bạn phần mềm để tự chạy.
  • Độ trễ cold-start: từ “tạo sandbox” đến “sẵn sàng nhận request đầu tiên” mất bao lâu. Pattern ephemeral cần khởi động dưới một giây. Pattern long-running chịu được nhiều hơn.
  • Persistent storage: provider có cung cấp durable volume hay chỉ có disk tạm thời. Pattern hybrid cần durable storage ở đâu đó, dù trong sandbox hay bên cạnh nó.
  • Mô hình pricing: tính theo giây, theo request, hay theo giờ cố định. Pricing theo giây phù hợp workload ephemeral có tính bùng nổ. Theo giờ phù hợp session dài hạn.
  • Networking: có hỗ trợ egress rule tùy biến, outbound proxy, và private VPC peering cho môi trường regulated hay không.

Các provider để đánh giá:

Với các tùy chọn self-hosted như Docker, gVisor, và Firecracker, cùng cấu hình isolation chi tiết, xem Isolation Technologies.

Container chỉ cần runtime ngôn ngữ của SDK bạn dùng:

  • Python 3.10+ cho Python SDK, hoặc Node.js 18+ cho TypeScript SDK
  • Cả hai package SDK đều đóng gói sẵn binary Claude Code native cho nền tảng host, nên không cần cài Claude Code hay Node.js riêng cho CLI được spawn

Binary đóng gói sẵn được ghim theo phiên bản package SDK, nên cập nhật SDK chính là cách cập nhật CLI. SDK tuân theo semver: nhận patch release liên tục và xem lại changelog TypeScript hoặc Python trước khi nhận minor.

1 GiB RAM, 5 GiB disk, và 1 CPU cho mỗi agent là điểm khởi đầu hợp lý cho một instance vừa mới chạy. Mức dùng bộ nhớ tăng theo độ dài session và hoạt động tool, nên hãy chọn kích thước theo độ dài session và mức đồng thời bạn thực sự cần, thay vì theo baseline lúc idle. Xem Scaling và concurrency để biết cách tính số agent trên mỗi host.

SDK cần outbound HTTPS tới api.anthropic.com, hoặc tới regional endpoint của provider khi chạy trên Amazon Bedrock hay Google Cloud’s Agent Platform. Nếu agent của bạn dùng MCP server hoặc tool bên ngoài, chúng cũng cần outbound access tới các endpoint đó. Với production, route outbound traffic qua một egress proxy để enforce domain allowlist, inject credential, và log request. Xem Secure Deployment để biết pattern đầy đủ.

Với inbound traffic, expose một port HTTP hoặc WebSocket trên container. Ứng dụng của bạn xử lý request từ client trên port đó và gọi SDK nội bộ; bản thân subprocess không lắng nghe trên network.

Cân nhắc các quyết định dưới đây trước khi ship một agent self-hosted.

Disk cục bộ mặc định sẽ mất khi restart, scale-down, hay chuyển sang node khác. Với bất kỳ session nào người dùng mong muốn resume, mirror transcript sang durable storage bằng SessionStore adapter. Xem Reference implementations để biết adapter cho S3, Redis, Postgres, và conformance suite cho adapter riêng của bạn.

Ba điều cần biết về cách SessionStore hoạt động:

  • Chỉ transcript: SessionStore mirror transcript, không mirror file memory CLAUDE.md hay các artifact khác trong working directory. Mount một shared volume hoặc sync riêng.
  • Mirror, không phải thay thế: subprocess ghi vào đĩa cục bộ trước, và store nhận một bản sao của mỗi batch. Local write vẫn là bản gốc chính thức (authoritative).
  • Message mirror_error: một batch bị store từ chối sẽ được gửi lại tối đa ba lần tổng cộng, với một khoảng backoff ngắn trước mỗi lần retry; một lời gọi bị timeout thì không được retry. Nếu batch vẫn thất bại, SDK bỏ nó, phát ra message { type: "system", subtype: "mirror_error" }, và tiếp tục query. Cảnh báo (alert) trên các message này nếu độ bền của store là quan trọng.

Agent SDK agent là các process sống lâu, spawn tool call qua nhiều vòng round-trip API. Không có telemetry bạn sẽ không thấy tool nào đã chạy, chạy mất bao lâu, hay session bị nghẽn ở đâu.

SDK kế thừa cấu hình OpenTelemetry từ môi trường. Set các biến môi trường OTEL ở tầng container hoặc orchestrator để mỗi lời gọi query() export span, metric, và log event tới collector của bạn. Ví dụ dưới đây bật OTLP export cho cả ba loại signal. CLAUDE_CODE_ENHANCED_TELEMETRY_BETA chỉ cần thiết cho trace; bỏ qua nếu bạn chỉ export metric và log.

.env
CLAUDE_CODE_ENABLE_TELEMETRY=1
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.example.com:4318

Nội dung prompt và tool input không được đưa vào export theo mặc định. Xem Control sensitive data in exports để biết các flag opt-in, và Observability để biết đầy đủ catalog signal.

Ba mối quan tâm về auth quan trọng ở thời điểm hosting:

  • Anthropic API: subprocess đọc ANTHROPIC_API_KEY từ môi trường của nó. Cung cấp key này từ secret manager của bạn, hoặc set ANTHROPIC_BASE_URL để route model call qua một proxy inject key bên ngoài container. Xem Credential management để biết pattern proxy và Setup trong quickstart SDK để biết các phương thức xác thực được hỗ trợ.
  • Inbound: đặt authentication tại một gateway đứng trước agent container. Agent nên nhận request đã được xác thực sẵn và không nên là thành phần validate token người dùng.
  • Outbound tool: giữ credential của tool ngoài môi trường agent. Route outbound call qua một proxy inject API key sau khi request rời khỏi container. Agent thực hiện lời gọi; proxy thêm credential.

Mỗi session chạy trong subprocess riêng, nên mức đồng thời trên một host bị giới hạn bởi RAM host chứa được bao nhiêu subprocess.

Tính kích thước mỗi host theo công thức này:

agent trên mỗi host = (RAM host - overhead) / (trần RAM mỗi session)

Đo trần per-session bằng cách chạy một session tiêu biểu đến độ dài mục tiêu dưới tải tool kỳ vọng và ghi lại peak RSS. Điểm khởi đầu 1 GiB trong Tài nguyên là sàn (floor), không phải trần (ceiling).

Việc routing scale ngang phụ thuộc vào pattern bạn dùng. Với session dài hạn, nơi container chứa nhiều session, chạy một pool container sau load balancer và pin mỗi session vào một container bằng consistent hashing trên sessionId. Một session đã pin sẽ tiếp tục hit cùng container, và do đó cùng subprocess đang chạy, cho tới khi bị evict hoặc container restart.

Fanout lớn các subagent đồng thời từ một session có thể chạm rate limit của API. Chia công việc thành các batch nhỏ hơn thay vì dispatch một lượt rộng duy nhất.

Chi phí token Anthropic thường vượt trội chi phí hạ tầng container theo bậc độ lớn hoặc hơn. Một container cấu hình tối thiểu chạy khoảng $0.05 mỗi giờ, trong khi một session agent dài có thể tốn hàng đô la tiền token. Xem Cost tracking để biết cách hạch toán token theo từng session.

Hành vi SDK mặc định đọc settings và file memory CLAUDE.md từ filesystem. Trong một container dùng chung phục vụ nhiều tenant, các file đó có thể rò rỉ context của tenant này sang session của tenant khác.

Để cô lập tenant trong một container dùng chung:

  • Truyền settingSources: [] trong TypeScript hoặc setting_sources=[] trong Python để không load settings từ filesystem.
  • Set CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 trong env. Auto memory tại ~/.claude/projects/<project>/memory/ load vào system prompt bất kể settingSources. Xem What settingSources does not control để biết các input khác load vô điều kiện.
  • Trỏ CLAUDE_CONFIG_DIR tới một thư mục riêng cho từng tenant để các tenant không dùng chung config toàn cục ~/.claude.json.
  • Dùng một working directory riêng cho mỗi tenant. Truyền cwd tường minh trên mỗi lời gọi query().
  • Áp dụng egress rule riêng cho từng tenant tại proxy của bạn, ví dụ IP outbound riêng, credential riêng, hoặc domain allowlist riêng, để một tenant bị xâm nhập không thể exfiltrate dữ liệu qua egress policy của tenant khác.

Ví dụ dưới đây áp dụng cả bốn tùy chọn cấp SDK cùng nhau. Xây tenantDirconfigDir sao cho mỗi tenant nhận một path không tenant nào khác đọc được. Trong TypeScript, env thay thế toàn bộ environment của subprocess, nên spread ...process.env để giữ các biến kế thừa như PATHANTHROPIC_API_KEY. Trong Python, env được merge lên trên environment kế thừa.

```typescript TypeScript theme={null} import { query } from "@anthropic-ai/claude-agent-sdk";

declare const prompt: string; declare const tenantDir: string; declare const configDir: string;

for await (const message of query({ prompt, options: { cwd: tenantDir, settingSources: [], env: { …process.env, CLAUDE_CONFIG_DIR: configDir, CLAUDE_CODE_DISABLE_AUTO_MEMORY: “1”, }, }, })) { // … }

```python Python theme={null}
from claude_agent_sdk import query, ClaudeAgentOptions
import asyncio
prompt: str = ...
tenant_dir: str = ...
config_dir: str = ...
async def main():
async for message in query(
prompt=prompt,
options=ClaudeAgentOptions(
cwd=tenant_dir,
setting_sources=[],
env={
"CLAUDE_CONFIG_DIR": config_dir,
"CLAUDE_CODE_DISABLE_AUTO_MEMORY": "1",
},
),
):
...
asyncio.run(main())

Để biết network control cho từng tenant, xem Secure Deployment.

Lên kế hoạch cho những điều dưới đây trong thiết kế deployment của bạn.

Giới hạnNên làm gì
Không có timeout ở cấp sessionMột session không tự timeout. Set maxTurns trong Options để giới hạn số vòng round trip tool-use trước khi agent dừng.
Bộ nhớ tăng dần qua session dàiGiới hạn độ dài session hoặc recycle subprocess định kỳ. Xem Scaling và concurrency.
Fanout subagent song song lớn có thể chạm rate limitChia công việc thành batch nhỏ hơn thay vì dispatch một lượt rộng duy nhất.
Không có deadline wall-clock cho từng subagentGiới hạn mỗi subagent bằng maxTurns trong AgentDefinition của nó. Chỉ với subagent chạy nền, CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS set một stall watchdog kích hoạt khi một subagent run_in_background ngừng tạo output; nó không phải deadline tổng thời gian chạy.