KRIT.JUNSREE PERSONAL WEBSITE
MEDIUM

สร้าง Autonomous AI Agent ด้วย Claude Agent SDK — คู่มือครบ

Tutorial Abhinav Dobhal — จาก install SDK + CLI → first streaming agent → file/bash op → custom MCP tool (@tool decorator) → advanced config → real-world example (FastAPI web server gen). เทียบ query() vs ClaudeSDKClient + troubleshooting (CLINotFoundError, permission error, unexpected tool call)

By krit.junsree@gmail.com ◆ Jul 10, 2026 ◆ 16 MIN READ Beginner

☰ ON THIS PAGE

Abhinav Dobhal สอน tutorial สร้าง autonomous AI agent ด้วย Claude Agent SDK — setup, first streaming agent, file/bash ops, custom tool ผ่าน MCP, advanced config, real-world example (FastAPI web server gen), troubleshooting

ทำไม Claude Agent SDK ถึงสำคัญ

LLM integration ส่วนใหญ่หยุดที่ text generation. Claude Agent SDK ไปไกลกว่านั้น:

  • File system operation — agent read/write/edit ไฟล์ตรง
  • Bash execution — รัน shell command + script
  • MCP integration — เชื่อม custom tool + data source
  • Session management — คง context ข้าม interaction
  • Built-in guardrail — คุม permission, allowed tool, cwd
  • Cost tracking — monitor token + cost realtime

ต่างจาก basic API wrapper — SDK เปิด production-grade primitive สำหรับ agent ที่ plan/execute/report

Setup ที่จำเป็น

1. ติดตั้ง Python SDK

bash
pip install claude-agent-sdk

2. ติดตั้ง Claude Code CLI

bash
npm install -g @anthropic-ai/claude-code

หรือ native installer (macOS/Linux/WSL):

bash
curl -fsSL https://claude.ai/install.sh | bash

Verify: claude doctor

3. Set API Key

bash
export ANTHROPIC_API_KEY=your_key_here

Agent แรก: Streaming Response

python
# app.py
import asyncio
from claude_agent_sdk import query, AssistantMessage, TextBlock, ResultMessage

async def main():
    async for message in query(prompt="Hello, how are you?"):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)
        if isinstance(message, ResultMessage):
            print(f"Cost: ${message.total_cost_usd}")
            print(f"Usage: {message.usage}")

asyncio.run(main())

ResultMessage มี cost + usage stat — สำคัญสำหรับ production monitoring

ให้ Agent มี Capability จริง

File Op + Bash

python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Write", "Bash"],
        permission_mode="acceptEdits",
        cwd="/path/to/your/project"
    )
    async for message in query(
        prompt="Create a file called greeting.txt with 'Hello, World!' and verify its contents",
        options=options
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)

asyncio.run(main())

Key config:

  • allowed_tools — whitelist (Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch)
  • permission_mode"acceptEdits" = auto-approve file mod
  • cwd — จำกัดขอบเขต directory เพื่อ safety

Custom Tool ผ่าน MCP

python
import asyncio
from typing import Any
from claude_agent_sdk import query, ClaudeAgentOptions, tool, create_sdk_mcp_server

@tool("greet", "Greet a user by name", {"name": str})
async def greet(args: dict[str, Any]) -> dict[str, Any]:
    name = args["name"]
    return {"content": [{"type": "text", "text": f"Hello {name}! Welcome to the system."}]}

@tool("calculate", "Perform basic arithmetic", {"operation": str, "a": float, "b": float})
async def calculate(args: dict[str, Any]) -> dict[str, Any]:
    operation = args["operation"]
    a, b = args["a"], args["b"]
    operations = {
        "add": a + b, "subtract": a - b, "multiply": a * b,
        "divide": a / b if b != 0 else "Error: Division by zero"
    }
    result = operations.get(operation, "Unknown operation")
    return {"content": [{"type": "text", "text": f"Result: {result}"}]}

server = create_sdk_mcp_server(name="my_tools", version="1.0.0", tools=[greet, calculate])

async def main():
    options = ClaudeAgentOptions(
        mcp_servers={"my": server},
        allowed_tools=["mcp__my__greet", "mcp__my__calculate"],
    )
    async for message in query(
        prompt="Greet Mason, then calculate 15 multiplied by 4",
        options=options
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)

asyncio.run(main())

MCP pattern สำคัญ:

  • Tool name ต้อง qualified เต็ม: mcp____
  • @tool decorator ให้ type safety + documentation
  • In-process server ประหยัด IPC overhead มากกว่า external MCP

Advanced Config

text
options = ClaudeAgentOptions(
    system_prompt={
        "type": "preset",
        "preset": "claude_code",
        "append": "You are an expert Python developer specializing in FastAPI."
    },
    setting_sources=["project"],  # Load CLAUDE.md and project configs
    allowed_tools=["Read", "Write", "Edit", "Bash"],
    permission_mode="acceptEdits",
    cwd="/path/to/repo",
    model="claude-sonnet-4-5-20250929"
)

Real-World: Web Server Generation

python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    options = ClaudeAgentOptions(
        system_prompt="You are an expert Python web developer.",
        allowed_tools=["Read", "Write", "Bash"],
        permission_mode="acceptEdits",
        cwd="./projects/web-server"
    )
    prompt = """
    Create a production-ready FastAPI web server with:
    - Health check endpoint at /health
    - User registration endpoint at /users
    - Proper error handling
    - Environment variable configuration
    - Basic logging setup
    Also create a requirements.txt file.
    """
    async for message in query(prompt=prompt, options=options):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)

asyncio.run(main())

One-Off vs Continuous Session

Feature query() ClaudeSDKClient
Session ใหม่ทุกครั้ง Persistent ข้าม turn
Use case One-shot automation Multi-turn conversation
Custom tool ไม่รองรับ MCP integration เต็ม
Interrupt/hook ไม่มี มี
Complexity ต่ำ กลาง

Troubleshooting

  • CLINotFoundError — CLI ไม่ install หรือไม่อยู่ใน PATH → รัน claude doctor
  • Auth fail — เช็ค ANTHROPIC_API_KEY
  • Permission error — เช็ค allowed_tools + permission_mode + cwd
  • Unexpected tool call — ใช้ disallowed_tools, tool hook, system prompt ชัดขึ้น

ทำไมวิธีนี้ชนะ

  1. Foundation แน่น — build บน harness เดียวกับ Claude Code
  2. Tool ecosystem — file op + Bash + web + MCP
  3. Safety control — granular permission + cwd isolation + tool whitelist
  4. Observability — cost tracking + usage metric + structured log
  5. Standard-based — MCP = tool reuse ข้าม project

สร้างอะไรต่อไป

  • Coding Agent — scaffold project, รัน test, gen PR
  • Domain Agent — เชื่อม CRM/billing/doc ผ่าน MCP, automate workflow
  • Research Agent — WebFetch + WebSearch + document processing + cited report

เริ่มวันนี้

  1. ติดตั้ง SDK + CLI
  2. เริ่มจาก query() ทดลอง
  3. เพิ่ม file op + allowed_tools + acceptEdits
  4. สร้าง custom MCP tool 1 ตัวสำหรับ domain
  5. อ่าน official doc เพิ่มเติม

Claude Agent SDK bridge gap ระหว่าง chat กับ autonomous system — agent จริงจัดการงานได้ ไม่ใช่แค่คุย


แหล่งที่มา: “Building Autonomous AI Agents with the Claude Agent SDK: A Complete Guide” โดย Abhinav Dobhal ตีพิมพ์ 5 ต.ค. 2025 บน Medium · อ่านต้นฉบับ

Leave a Reply

Your email address will not be published. Required fields are marked *