API Key 없이 Claude Agent 서버 만들기! #2 - Claude Agent SDK의 모든 옵션 파헤치기

조현상·2026년 4월 2일

ClaudeCode

목록 보기
10/17
post-thumbnail

들어가며

이전 글에서 API Key 없이 Claude Agent 서버를 만드는 방법을 다뤘습니다. 그 서버의 핵심에는 ClaudeAgentOptions라는 클래스가 있었죠.

options = ClaudeAgentOptions(
    permission_mode="bypassPermissions",
    allowed_tools=["Read", "Write", "Edit", "Bash"],
)

이전 글에서는 딱 이 두 줄만 썼지만, 실제로 ClaudeAgentOptions에는 30개가 넘는 옵션이 있습니다. 이 글에서는 하나하나 뜯어보면서, 어떤 상황에서 어떤 옵션을 쓰면 되는지 정리합니다.


기본 구조

ClaudeAgentOptions는 Python dataclass로 정의되어 있고, query() 함수에 넘겨서 Claude Agent의 동작을 제어합니다.

from claude_agent_sdk import query, ClaudeAgentOptions

options = ClaudeAgentOptions(
    # 여기에 옵션들을 넣는다
)

async for message in query(prompt="할 일", options=options):
    ...

모든 필드에는 기본값이 있으므로, 필요한 것만 골라서 쓰면 됩니다.


옵션 분류

30개가 넘는 옵션을 용도별로 7개 그룹으로 나눠서 설명합니다.


1. 권한 제어 — "에이전트가 뭘 할 수 있게 할 것인가"

이 그룹이 가장 중요합니다. Claude Agent는 파일을 읽고, 쓰고, 코드를 실행할 수 있는데, 이걸 어디까지 허용할지 결정합니다.

permission_mode

permission_mode: Literal["default", "acceptEdits", "plan", "bypassPermissions", "dontAsk"] | None

에이전트의 전반적인 권한 수준을 설정합니다.

모드설명언제 쓰나
"default"위험한 동작마다 사용자에게 확인 요청대화형 CLI에서 기본값
"acceptEdits"파일 편집은 자동 허용, 나머지는 확인코드 수정 자동화
"plan"읽기만 허용, 수정 불가코드 분석/리뷰
"bypassPermissions"모든 동작 자동 허용서버/자동화 환경 필수
"dontAsk"확인 안 하고, 허용 안 된 건 건너뜀CI/CD 파이프라인

서버 환경에서는 사용자에게 "이거 실행해도 될까요?"라고 물어볼 수 없으므로, "bypassPermissions"가 사실상 필수입니다.

# 서버 환경에서의 기본 설정
options = ClaudeAgentOptions(
    permission_mode="bypassPermissions"
)

allowed_tools / disallowed_tools

allowed_tools: list[str]      # 기본값: []
disallowed_tools: list[str]   # 기본값: []

에이전트가 사용할 수 있는 도구를 화이트리스트/블랙리스트로 제어합니다.

# 파일 읽기/쓰기만 허용하고, 명령어 실행은 금지
options = ClaudeAgentOptions(
    permission_mode="bypassPermissions",
    allowed_tools=["Read", "Write", "Edit", "Glob", "Grep"],
    disallowed_tools=["Bash"],  # 셸 명령 차단
)

주요 도구 목록:

  • Read — 파일 읽기
  • Write — 파일 생성
  • Edit — 파일 수정
  • Bash — 셸 명령 실행
  • Glob — 파일 패턴 검색
  • Grep — 파일 내용 검색
  • WebFetch — 웹 요청
  • WebSearch — 웹 검색

can_use_tool

can_use_tool: Callable | None  # 기본값: None

도구 사용 요청이 올 때마다 호출되는 콜백 함수입니다. 단순 허용/차단보다 세밀한 제어가 필요할 때 씁니다.

async def my_permission_check(tool_name, tool_input, context):
    # rm -rf 같은 위험한 명령은 차단
    if tool_name == "Bash" and "rm -rf" in tool_input.get("command", ""):
        return PermissionResultDeny(message="위험한 명령입니다")
    return PermissionResultAllow()

options = ClaudeAgentOptions(
    can_use_tool=my_permission_check
)

2. 모델 설정 — "어떤 Claude를 쓸 것인가"

model / fallback_model

model: str | None             # 기본값: None (CLI 기본 모델)
fallback_model: str | None    # 기본값: None

사용할 모델을 지정합니다. model이 실패하면 fallback_model로 자동 전환됩니다.

options = ClaudeAgentOptions(
    model="claude-sonnet-4-6",
    fallback_model="claude-haiku-4-5-20251001",
)

thinking / effort

thinking: ThinkingConfig | None
effort: Literal["low", "medium", "high", "max"] | None

Claude의 사고 깊이를 조절합니다.

# 복잡한 문제: 깊게 생각하게 하기
options = ClaudeAgentOptions(
    thinking={"type": "enabled", "budget_tokens": 10000},
    effort="max",
)

# 단순한 작업: 빠르게 처리
options = ClaudeAgentOptions(
    thinking={"type": "disabled"},
    effort="low",
)

thinking에는 3가지 모드가 있습니다:

  • {"type": "adaptive"} — Claude가 알아서 판단
  • {"type": "enabled", "budget_tokens": N} — 최대 N 토큰까지 사고
  • {"type": "disabled"} — 사고 과정 비활성화

3. 실행 제한 — "얼마나 오래, 얼마나 많이"

max_turns

max_turns: int | None  # 기본값: None (제한 없음)

에이전트의 최대 턴 수를 제한합니다. 한 턴은 "Claude 응답 → 도구 실행 → 결과 반환"의 한 사이클입니다.

# 간단한 질문에는 3턴이면 충분
options = ClaudeAgentOptions(max_turns=3)

무한 루프 방지에 유용합니다. 서버 환경에서는 반드시 설정하는 것을 권장합니다.

max_budget_usd

max_budget_usd: float | None  # 기본값: None

API 비용 상한선을 달러 단위로 설정합니다.

options = ClaudeAgentOptions(max_budget_usd=1.0)  # 1달러 초과 시 중단

task_budget

task_budget: TaskBudget | None  # 기본값: None

토큰 단위로 예산을 설정합니다. 모델이 남은 예산을 인식하고, 예산 내에서 작업을 마무리하려고 시도합니다.

options = ClaudeAgentOptions(
    task_budget={"total": 50000}  # 5만 토큰 예산
)

4. 시스템 프롬프트 — "에이전트에게 역할 부여하기"

system_prompt

system_prompt: str | SystemPromptPreset | SystemPromptFile | None

3가지 방식으로 시스템 프롬프트를 설정할 수 있습니다.

# 방법 1: 직접 문자열로
options = ClaudeAgentOptions(
    system_prompt="너는 Python 전문가야. 항상 타입 힌트를 포함해서 코드를 작성해."
)

# 방법 2: Claude Code 기본 프롬프트 + 추가 지시
options = ClaudeAgentOptions(
    system_prompt={
        "type": "preset",
        "preset": "claude_code",
        "append": "한국어로 답변해줘."
    }
)

# 방법 3: 파일에서 읽기
options = ClaudeAgentOptions(
    system_prompt={
        "type": "file",
        "path": "/path/to/system-prompt.md"
    }
)

5. 세션 관리 — "대화를 이어가기"

session_id / continue_conversation / resume / fork_session

session_id: str | None              # 기본값: None
continue_conversation: bool         # 기본값: False
resume: str | None                  # 기본값: None
fork_session: bool                  # 기본값: False

Claude Agent는 대화 내역을 세션 단위로 관리합니다.

# 새 대화 시작 (기본)
options = ClaudeAgentOptions()

# 기존 세션 이어서 대화
options = ClaudeAgentOptions(
    session_id="abc-123",
    continue_conversation=True,
)

# 가장 최근 세션 재개
options = ClaudeAgentOptions(resume="most-recent")

# 기존 세션을 복제해서 새 세션으로 분기
options = ClaudeAgentOptions(
    session_id="abc-123",
    continue_conversation=True,
    fork_session=True,  # 원본 세션은 건드리지 않음
)

6. 환경 설정 — "어디서 어떻게 실행할 것인가"

cwd

cwd: str | Path | None  # 기본값: None (현재 디렉토리)

에이전트의 작업 디렉토리를 설정합니다. 에이전트가 파일을 읽고 쓸 때 이 디렉토리를 기준으로 동작합니다.

options = ClaudeAgentOptions(
    cwd="/app/workspace"  # 에이전트를 이 디렉토리에 가둔다
)

Docker 환경에서는 볼륨 마운트된 디렉토리를 지정하면, 에이전트의 파일 작업을 호스트와 공유할 수 있습니다.

env

env: dict[str, str]  # 기본값: {}

에이전트 프로세스에 전달할 환경변수입니다.

options = ClaudeAgentOptions(
    env={
        "NODE_ENV": "production",
        "DATABASE_URL": "postgresql://localhost:5432/mydb",
    }
)

cli_path

cli_path: str | Path | None  # 기본값: None (자동 탐색)

Claude Code CLI의 경로를 직접 지정합니다. 여러 버전의 CLI가 설치되어 있을 때 유용합니다.

add_dirs

add_dirs: list[str | Path]  # 기본값: []

추가 작업 디렉토리를 지정합니다. 여러 프로젝트에 걸쳐 작업할 때 씁니다.

options = ClaudeAgentOptions(
    cwd="/app/frontend",
    add_dirs=["/app/backend", "/app/shared"],  # 이 디렉토리들도 접근 가능
)

7. 고급 기능

tools

tools: list[str] | ToolsPreset | None  # 기본값: None

allowed_tools가 "이 도구들을 자동 승인"이라면, tools는 "이 도구들만 로드"입니다. Claude Code의 기본 도구셋을 쓰려면 프리셋을 사용합니다.

# Claude Code 기본 도구셋 사용
options = ClaudeAgentOptions(
    tools={"type": "preset", "preset": "claude_code"}
)

mcp_servers

mcp_servers: dict[str, McpServerConfig] | str | Path

MCP(Model Context Protocol) 서버를 연결합니다. 외부 도구를 Claude에 붙일 수 있는 확장 포인트입니다.

options = ClaudeAgentOptions(
    mcp_servers={
        "my-db-server": {
            "type": "stdio",
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
        }
    }
)

hooks

hooks: dict[HookEvent, list[HookMatcher]] | None

에이전트의 동작에 훅을 걸 수 있습니다. 도구 실행 전/후, 중지 시점 등에 콜백을 등록합니다.

async def log_tool_use(input_data, tool_use_id, context):
    print(f"도구 사용: {input_data['tool_name']}")
    return {}

options = ClaudeAgentOptions(
    hooks={
        "PreToolUse": [
            HookMatcher(matcher=None, hooks=[log_tool_use])
        ]
    }
)

지원되는 훅 이벤트:

  • PreToolUse — 도구 실행 전
  • PostToolUse — 도구 실행 후
  • PostToolUseFailure — 도구 실행 실패 시
  • UserPromptSubmit — 사용자 프롬프트 제출 시
  • Stop — 에이전트 종료 시
  • SubagentStart / SubagentStop — 서브 에이전트 시작/종료 시

output_format

output_format: dict[str, Any] | None  # 기본값: None

Claude의 응답을 정해진 JSON 스키마로 받을 수 있습니다.

options = ClaudeAgentOptions(
    output_format={
        "type": "json_schema",
        "schema": {
            "type": "object",
            "properties": {
                "summary": {"type": "string"},
                "severity": {"type": "string", "enum": ["low", "medium", "high"]},
                "suggestions": {"type": "array", "items": {"type": "string"}},
            },
            "required": ["summary", "severity", "suggestions"],
        }
    }
)

코드 리뷰 자동화 같은 상황에서, 항상 같은 구조의 결과를 받고 싶을 때 유용합니다.

agents

agents: dict[str, AgentDefinition] | None

커스텀 서브 에이전트를 정의합니다. 복잡한 작업을 여러 에이전트로 분업시킬 수 있습니다.

options = ClaudeAgentOptions(
    agents={
        "code-reviewer": AgentDefinition(
            description="코드 리뷰 전문가",
            prompt="코드를 분석하고 개선점을 제안해줘.",
            tools=["Read", "Glob", "Grep"],
            model="claude-sonnet-4-6",
        ),
        "test-writer": AgentDefinition(
            description="테스트 코드 작성가",
            prompt="주어진 코드에 대한 테스트를 작성해줘.",
            tools=["Read", "Write", "Bash"],
        ),
    }
)

sandbox

sandbox: SandboxSettings | None

Bash 명령을 샌드박스 안에서 격리 실행합니다.

options = ClaudeAgentOptions(
    sandbox={
        "enabled": True,
        "autoAllowBashIfSandboxed": True,
        "excludedCommands": ["docker", "git"],  # 이 명령은 샌드박스 밖에서 실행
        "network": {
            "allowLocalBinding": True,
        },
    }
)

include_partial_messages

include_partial_messages: bool  # 기본값: False

True로 설정하면 Claude가 응답을 생성하는 도중의 부분 메시지도 스트림으로 받을 수 있습니다. 실시간 타이핑 효과를 구현할 때 쓰입니다.

enable_file_checkpointing

enable_file_checkpointing: bool  # 기본값: False

파일 변경 이력을 추적합니다. 나중에 특정 시점으로 파일을 되돌릴 수 있습니다.


실전 조합 예시

안전한 코드 리뷰 봇

options = ClaudeAgentOptions(
    permission_mode="plan",                # 읽기만 허용
    system_prompt="코드를 리뷰하고 개선점을 JSON으로 반환해.",
    model="claude-sonnet-4-6",
    max_turns=5,
    effort="high",
    output_format={
        "type": "json_schema",
        "schema": {
            "type": "object",
            "properties": {
                "issues": {"type": "array", "items": {"type": "string"}},
                "score": {"type": "integer"},
            },
            "required": ["issues", "score"],
        }
    },
)

파일 생성 자동화 서버

options = ClaudeAgentOptions(
    permission_mode="bypassPermissions",
    allowed_tools=["Read", "Write", "Edit", "Glob", "Grep"],
    disallowed_tools=["Bash"],             # 명령 실행은 차단
    cwd="/app/workspace",
    max_turns=20,
    max_budget_usd=0.5,
    thinking={"type": "adaptive"},
)

세션을 이어가는 대화형 에이전트

# 첫 번째 요청
options = ClaudeAgentOptions(
    permission_mode="bypassPermissions",
    cwd="/app/workspace",
)
# session_id를 저장해둔다

# 두 번째 요청 — 이전 대화 이어서
options = ClaudeAgentOptions(
    permission_mode="bypassPermissions",
    session_id=saved_session_id,
    continue_conversation=True,
    cwd="/app/workspace",
)

옵션 전체 요약표

옵션타입기본값한 줄 설명
permission_modestrNone권한 모드 (default/acceptEdits/plan/bypassPermissions/dontAsk)
allowed_toolslist[str][]자동 승인할 도구 목록
disallowed_toolslist[str][]사용 금지할 도구 목록
can_use_toolCallableNone도구 승인 콜백 함수
toolslist[str]None로드할 도구 목록 / 프리셋
modelstrNone사용할 모델
fallback_modelstrNone폴백 모델
thinkingdictNone사고 모드 설정 (adaptive/enabled/disabled)
effortstrNone사고 깊이 (low/medium/high/max)
max_turnsintNone최대 턴 수
max_budget_usdfloatNone비용 상한 (달러)
task_budgetdictNone토큰 예산
system_promptstr/dictNone시스템 프롬프트
session_idstrNone세션 ID
continue_conversationboolFalse기존 세션 이어서 대화
resumestrNone세션 재개
fork_sessionboolFalse세션 분기
cwdstr/PathNone작업 디렉토리
add_dirslist[]추가 작업 디렉토리
envdict{}환경변수
cli_pathstr/PathNoneCLI 경로
settingsstrNone설정 파일 경로
mcp_serversdict{}MCP 서버 설정
hooksdictNone훅 콜백 설정
agentsdictNone커스텀 서브 에이전트
output_formatdictNone구조화된 출력 스키마
sandboxdictNoneBash 샌드박스 설정
include_partial_messagesboolFalse부분 메시지 스트리밍
enable_file_checkpointingboolFalse파일 변경 추적
betaslist[]베타 기능 활성화
pluginslist[]플러그인 설정

마치며

ClaudeAgentOptions는 단순한 설정 클래스가 아니라, Claude Agent의 동작 범위를 결정하는 제어판입니다.

처음 시작한다면 이 3가지만 기억하세요:
1. permission_mode — 서버에서는 "bypassPermissions"
2. allowed_tools / disallowed_tools — 도구 범위 제한
3. max_turns — 무한 루프 방지

나머지는 필요할 때 하나씩 추가하면 됩니다.

전체 소스 코드는 GitHub에서 확인할 수 있습니다:
👉 GitHub 레포지토리 링크

profile
꿈꾸는 개발자

0개의 댓글