GBT
한국외국어대학교Global Business & Technology
GenAI 특강 · Claude Code CLI vs SDK
목차 강의 홈 ↗
부록 · 심화 비교 실습

Claude Code CLI vs SDK
— 에이전트 워크플로우 비교

이 실습이 끝나면 같은 작업(논문 작성 워크플로우)을 CLI 대화, subprocess 자동화, API 직접 호출의 세 가지 방식으로 구현하고, 상황에 맞는 방식을 스스로 고를 수 있게 된다. 순서는 CLI → SDK(CLI 호출) → SDK(API)다.

부록 · 심화3가지 구현 방식Python 코드 실습실습 과제 4개
1
CLI · SDK+CLI · SDK API

세 가지 방식, 한눈 비교

핵심 차이는 "누가 에이전트인가"다. ①은 Claude가, ②는 CLI가 에이전트이고 코드는 오케스트레이터, ③은 내가 에이전트 루프를 설계한다.

OVERVIEW

비교표: 본질 · 도구 · 비용 · 제어

Claude Code CLI와 Anthropic SDK로 에이전트를 구성하는 방식은 크게 세 가지다. 아래 표가 이 페이지 전체의 지도다.

구분① CLI 직접② SDK에서 CLI 호출③ SDK API 직접 호출
본질터미널 대화형 지시Python이 CLI를 서브프로세스 실행Python이 Claude API 직접 호출
에이전트Claude 자체가 에이전트CLI가 에이전트, 코드가 오케스트레이터내가 에이전트 루프를 설계
도구(파일/실행)내장 자동CLI 내장 도구 자동직접 정의·구현
코드량없음적음(subprocess)많음(tool 정의 등)
자동화셸 스크립트 수준Python 완전 자동화Python 완전 자동화
비용Claude Code 구독Claude Code 구독API 토큰 종량 과금
제어프롬프트 간접프롬프트+코드 분기완전한 코드 제어
적합탐색·일회성CLI 장점+자동화프로덕션·고도 커스텀
① CLI 직접터미널에서 자연어로 지시하면 Claude가 알아서 파일을 읽고 고치고 실행한다. 코드가 한 줄도 필요 없다.
② SDK에서 CLI 호출Python의 subprocess로 CLI를 실행한다. CLI의 내장 도구를 그대로 쓰면서 반복·분기·파이프라인을 코드로 얹는다.
③ SDK API 직접Anthropic SDK로 API를 직접 호출한다. 도구 정의부터 에이전트 루프까지 전부 내가 설계하는 대신, 완전한 제어를 얻는다.
실습 시나리오

이 페이지의 실습은 하나의 시나리오를 세 방식으로 반복한다. LaTeX 논문 작성 워크플로우 — 문헌 분석, Related Work 수정, Figure 생성, 전체 리뷰, 커밋. 같은 작업이 방식에 따라 어떻게 달라지는지 비교하며 따라가면 된다.

2
PART 1 · CLI 직접

CLI로 논문 작업 — Claude 자체가 에이전트

사람은 '무엇을'만 말하고, Claude가 '어떻게'(도구 선택·실행 순서)를 결정한다. 자연어 한마디가 곧 오케스트레이션이다.

SETUP

설치와 CLAUDE.md

설치는 npm 한 줄, 실행은 프로젝트 폴더에서 claude 한 단어다. 프로젝트 루트에 CLAUDE.md를 두면 Claude가 자동으로 읽고 규칙을 따른다.

npm install -g @anthropic-ai/claude-code
cd my-paper        # 프로젝트 폴더로 이동
claude             # 대화 시작

CLAUDE.md 예시 — 프로젝트 개요 · 구조 · 작업 규칙

# CLAUDE.md

## 프로젝트 개요
LaTeX로 작성하는 학술 논문 프로젝트다.

## 구조
- paper/main.tex   : 논문 본문
- paper/refs.bib   : 참고문헌
- scripts/plot.py  : Figure 생성 스크립트
- results/         : 실험 결과 데이터

## 작업 규칙
- .tex 수정 후에는 pdflatex 컴파일이 되는지 확인한다
- Figure는 scripts/plot.py를 실행해 생성한다
- 커밋 메시지는 한국어로 쓴다
  • 프로젝트 폴더에서 claude 실행 시 CLAUDE.md를 읽었다는 표시가 나오는가
  • 이후 모든 대화에서 CLAUDE.md의 작업 규칙이 자동으로 적용되는가
WORKFLOW

대화형 워크플로우 5단계

코드 없이 자연어 다섯 마디로 논문 작업 전체가 돌아간다. 각 단계에서 Claude는 스스로 파일을 읽고, 수정하고, 스크립트를 실행하고, 커밋한다.

  1. 문헌 분석 — refs.bib를 읽고 연구 흐름을 정리시킨다.
    refs.bib에서 주요 논문을 읽고 연구 흐름을 시간순으로 분류해줘
  2. 섹션 업데이트 — 방금의 분석을 이어받아 Related Work를 고친다.
    방금 분석한 내용을 바탕으로 Related Work 섹션을 업데이트해줘. 기존 내용은 유지하고 빠진 분류만 추가해줘
  3. Figure 생성 — 결과 폴더를 분석해 시각화 코드를 추가하고 실행까지 시킨다.
    results/ 폴더를 분석해서 plot.py에 시각화 함수를 추가하고 실행해줘
  4. 전체 리뷰 — 문법·논리·인용을 한 번에 점검한다.
    main.tex 전체를 리뷰해줘. 문법 오류, 논리 전개, 인용 누락을 확인해줘
  5. 커밋 — 변경사항을 의미 단위로 나눠 커밋시킨다.
    변경사항을 의미 단위로 나눠서 커밋해줘
PART 1 요약

사람은 '무엇을'만 말한다. '어떻게'(어떤 파일을 읽을지, 어떤 도구를 쓸지, 어떤 순서로 실행할지)는 Claude가 결정한다. 자연어 한마디가 곧 오케스트레이션이다.

생각해보기

이 5단계를 매주 반복해야 한다면 어떨까. 매번 터미널을 열고 같은 다섯 마디를 입력하는 것은 곧 지겨워진다. 이 반복을 코드로 옮기는 것이 다음 파트다.

3
PART 2 · SDK에서 CLI 호출

subprocess로 CLI를 코드에 넣기

CLI가 에이전트 역할을 그대로 하고, Python 코드는 오케스트레이터가 된다. API 키 없이 구독만으로 완전 자동화가 가능하다.

STEP 1 · 기본 호출

claude -p 를 subprocess로 실행한다

claude -p "프롬프트"는 대화 없이 한 번 실행하고 결과를 출력하는 비대화 모드다. 이것을 subprocess로 감싸면 CLI가 곧 함수가 된다.

import subprocess

def claude_cli(prompt: str, cwd: str = ".") -> str:
    result = subprocess.run(["claude", "-p", prompt], cwd=cwd,
        capture_output=True, text=True, timeout=300)
    return result.stdout

review = claude_cli("main.tex를 읽고 문법·논리 오류를 찾아줘", cwd="paper")
API 키 불필요Claude Code 구독만 있으면 된다. 별도 토큰 과금이 없다.
도구 정의 불필요파일 읽기·쓰기·명령 실행은 CLI 내장 도구가 알아서 한다.
코드량 최소subprocess 몇 줄이면 끝. 에이전트 루프를 직접 짤 필요가 없다.
CLI 기능 전부 사용CLAUDE.md 자동 적용, Git 통합 등 CLI의 기능을 그대로 누린다.
STEP 2 · JSON 구조화

출력을 구조화해서 받기

--output-format json 옵션을 주면 결과가 JSON으로 나와, 코드에서 파싱해 다음 단계에 넘기기 좋다.

import subprocess, json

def claude_cli_json(prompt: str, cwd: str = ".") -> str:
    r = subprocess.run(
        ["claude", "-p", prompt, "--output-format", "json"],
        cwd=cwd, capture_output=True, text=True, timeout=300)
    return json.loads(r.stdout)["result"]
STEP 3 · 파이프라인

멀티 단계 파이프라인: CLI 호출을 코드로 연결

Part 1의 대화 5단계가 그대로 함수 호출의 연쇄가 된다. 앞 단계의 결과를 다음 단계 프롬프트에 주입하는 것이 핵심이다.

# paper_pipeline.py — 문헌 분석 → 섹션 업데이트 → Figure → 리뷰

# 1) 문헌 분석
analysis = claude_cli(
    "refs.bib에서 주요 논문을 읽고 연구 흐름을 시간순으로 분류해줘",
    cwd="paper")

# 2) 섹션 업데이트 — 분석 결과를 프롬프트에 주입
claude_cli(
    "다음 문헌 분석을 바탕으로 Related Work 섹션을 업데이트해줘. "
    "기존 내용은 유지하고 빠진 분류만 추가해줘.\n\n" + analysis,
    cwd="paper")

# 3) Figure 생성
claude_cli(
    "results/ 폴더를 분석해서 plot.py에 시각화 함수를 추가하고 실행해줘",
    cwd="paper")

# 4) 전체 리뷰
review = claude_cli(
    "main.tex 전체를 리뷰해줘. 문법 오류, 논리 전개, 인용 누락을 확인해줘",
    cwd="paper")
print(review)
  • python paper_pipeline.py 한 번으로 4단계가 사람 개입 없이 순서대로 실행되는가
  • 2단계 프롬프트에 1단계의 분석 결과가 실제로 포함되어 전달되는가
생각해보기

이 방식으로 대부분의 자동화가 가능하다. 그런데 각 단계에서 도구 자체를 내 마음대로 정의하고 싶다면, 혹은 대화 맥락 없이 역할별로 완전히 독립된 에이전트를 여럿 돌리고 싶다면? 그것이 다음 파트다.

4
PART 3 · SDK API 직접 호출

내가 에이전트 루프를 설계한다

도구 정의, 실행, 루프, 역할 분리까지 전부 내 코드다. 코드량은 가장 많지만 제어는 완전하다. 과금은 API 토큰 종량제다.

STEP 1 · 설정과 단일 호출

anthropic SDK 설치와 첫 호출

SDK를 설치하고 API 키를 환경변수로 등록하면, Claude 호출은 client.messages.create 한 번이다.

pip install anthropic
export ANTHROPIC_API_KEY=sk-ant-...   # 발급받은 API 키
from anthropic import Anthropic

client = Anthropic()   # ANTHROPIC_API_KEY 환경변수를 자동으로 읽는다

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=4096,
    system="당신은 LaTeX 논문 작성을 돕는 조교다.",
    messages=[{"role": "user",
               "content": "main.tex의 다음 문단에서 문법 오류를 찾아줘:\n" + paragraph}],
)
print(response.content[0].text)

여기까지는 단순한 질의응답이다. 파일을 읽거나 명령을 실행하는 능력은 아직 없다. 그 능력을 주는 것이 Tool Use다.

STEP 2 · Tool Use

도구를 직접 정의한다 — read_file / write_file / run_command

CLI에서는 내장이던 도구를 여기서는 input_schema로 직접 정의한다. Claude가 도구를 호출하면 실제 실행은 내 코드가 한다.

import subprocess

tools = [
    {
        "name": "read_file",
        "description": "지정한 경로의 텍스트 파일을 읽어 내용을 돌려준다",
        "input_schema": {
            "type": "object",
            "properties": {"path": {"type": "string", "description": "파일 경로"}},
            "required": ["path"],
        },
    },
    {
        "name": "write_file",
        "description": "지정한 경로에 내용을 저장한다",
        "input_schema": {
            "type": "object",
            "properties": {"path": {"type": "string"},
                           "content": {"type": "string"}},
            "required": ["path", "content"],
        },
    },
    {
        "name": "run_command",
        "description": "셸 명령을 실행하고 출력을 돌려준다 (예: pdflatex, python)",
        "input_schema": {
            "type": "object",
            "properties": {"command": {"type": "string"}},
            "required": ["command"],
        },
    },
]

def execute_tool(name: str, args: dict) -> str:
    if name == "read_file":
        return open(args["path"], encoding="utf-8").read()
    if name == "write_file":
        with open(args["path"], "w", encoding="utf-8") as f:
            f.write(args["content"])
        return "saved"
    if name == "run_command":
        r = subprocess.run(args["command"], shell=True,
                           capture_output=True, text=True, timeout=120)
        return r.stdout + r.stderr
STEP 3 · 에이전트 루프

while True — 에이전트의 심장

Claude가 도구를 요청하면 실행해서 결과를 돌려주고, 다시 호출한다. stop_reasonend_turn이 될 때까지 반복하는 이 루프가 에이전트의 전부다.

def agent_loop(task: str) -> str:
    messages = [{"role": "user", "content": task}]
    while True:
        response = client.messages.create(
            model="claude-opus-5", max_tokens=4096,
            tools=tools, messages=messages)

        if response.stop_reason == "end_turn":      # 작업 완료
            return response.content[0].text

        if response.stop_reason == "tool_use":      # 도구 호출 요청
            messages.append({"role": "assistant", "content": response.content})
            results = []
            for block in response.content:
                if block.type == "tool_use":
                    output = execute_tool(block.name, block.input)
                    results.append({"type": "tool_result",
                                    "tool_use_id": block.id,
                                    "content": str(output)})
            messages.append({"role": "user", "content": results})
  • 도구 호출 → 실행 → 결과 전달 → 재호출의 순환이 코드에서 보이는가
  • CLI가 내부에서 해 주던 일이 정확히 이 루프였다는 것이 납득되는가
STEP 4 · 멀티에이전트

역할별 에이전트 4개로 파이프라인 구성

각 에이전트에 전용 시스템 프롬프트와 깨끗한 컨텍스트를 준다. 문헌 분석 → 작성 → Figure → 리뷰가 서로 독립된 전문가로 이어진다.

def run_agent(system: str, task: str, use_tools: bool = False) -> str:
    """전용 시스템 프롬프트 + 독립 컨텍스트로 에이전트 1개 실행"""
    messages = [{"role": "user", "content": task}]
    while True:
        response = client.messages.create(
            model="claude-opus-5", max_tokens=4096, system=system,
            tools=tools if use_tools else [], messages=messages)
        if response.stop_reason != "tool_use":
            return response.content[0].text
        messages.append({"role": "assistant", "content": response.content})
        results = [{"type": "tool_result", "tool_use_id": b.id,
                    "content": str(execute_tool(b.name, b.input))}
                   for b in response.content if b.type == "tool_use"]
        messages.append({"role": "user", "content": results})

# 파이프라인: 문헌 분석 → 작성 → Figure → 리뷰
literature = run_agent(
    "당신은 문헌 분석 전문가다.",
    "refs.bib의 논문들을 읽고 연구 흐름을 시간순으로 분류하라",
    use_tools=True)                       # read_file

draft = run_agent(
    "당신은 LaTeX 논문 작성 전문가다.",
    "다음 문헌 분석을 반영해 Related Work 섹션을 수정하라:\n" + literature,
    use_tools=True)                       # read_file / write_file

figures = run_agent(
    "당신은 matplotlib 시각화 전문가다.",
    "results/를 분석해 plot.py에 시각화 함수를 추가하고 실행하라",
    use_tools=True)                       # run_command

review = run_agent(
    "당신은 엄격한 논문 리뷰어다.",
    "main.tex를 리뷰하고 심각한 문제를 우선순위 순으로 지적하라",
    use_tools=True)
print(review)
생각해보기

같은 파이프라인을 Part 2에서는 CLI 호출 네 줄로 만들었다. 여기서는 코드가 훨씬 길다. 그런데도 이 방식을 쓰는 이유가 뭘까. 다음 섹션이 그 답이다 — 핵심 하나만 미리 말하면, 위 코드의 리뷰어는 앞 단계의 대화를 전혀 모른다. 그래서 더 엄격하다.

5
DEEP DIVE

"대화로 하면 되는데 왜 코드로?" — SDK 장점 8가지

결론부터: 일회성 작업이면 대화가 낫다. 반복·병렬·무인 실행·시스템 통합이 필요한 순간부터 코드가 이긴다.

장점 1–4 · 실행 구조

격리 · 분기 · 병렬 · 재현성

1 · 컨텍스트 격리CLI 대화는 맥락이 쌓여 역할 전환이 어렵다. SDK는 각 에이전트가 독립 컨텍스트(깨끗한 상태 + 전용 시스템 프롬프트)를 가져 역할 품질이 올라간다.
2 · 조건 분기·루프CLI는 사람이 매번 판단해야 한다. SDK는 for i in range(3): 리뷰 → 심각 이슈 없으면 break, 있으면 수정 — 사람이 없어도 리뷰→수정→재리뷰가 자동으로 돈다.
3 · 병렬 실행CLI는 대화 1개씩. SDK는 asyncio.gather로 챕터 5개를 동시에 리뷰 — 시간이 1/5로 준다.
4 · 재현성·버전 관리대화는 매번 다르고 기록이 사라진다. 코드는 고정되고, Git으로 관리되고, 팀과 공유되고, 변경이 추적된다.
장점 5–8 · 운영과 통합

로깅 · 스케줄링 · 에러 처리 · 시스템 통합

5 · 로깅·모니터링매 단계의 입력·출력·소요시간을 기록하고 결과를 파일로 저장한다. 디버깅과 실행 간 비교가 가능해진다.
6 · 스케줄링·트리거cron(매주 월요일 09시), Git hook, CI/CD, 파일 변경 감지 — 사람이 터미널을 열지 않아도 실행된다.
7 · 에러 처리·복구retry 루프, 타임아웃 시 프롬프트 단축, 3회 실패 시 Slack 알림 — 실패 시나리오를 명시적으로 제어한다.
8 · 출력 후처리·통합리뷰 결과를 Notion에 업로드하고, GitHub Issue를 자동 생성하고, S3에 올린 뒤 경로를 문서에 삽입한다.
한 문장 비교

CLI = "나 대신 해줘" (일회성 위임) / SDK = "이 프로세스를 시스템으로" (자동화 구축).

6
SELECTION GUIDE

언제 무엇을 쓰나 — 선택 가이드

대부분의 자동화 니즈는 ② SDK+CLI로 충분하다. ③은 프로덕션·고도 커스텀이 필요할 때만 전환한다.

상황별 판단

이 상황이면 CLI로 충분, 저 상황이면 SDK

상황판단이유
논문 한 번 리뷰CLI 충분일회성 작업은 대화가 가장 빠르다
1개 작업 · 혼자 · 단순 수정CLI 충분자동화 비용이 이득보다 크다
매주 반복 실행SDK스케줄링(cron) — 사람 없이 돌아야 한다
10개 문서 배치 처리SDK병렬 실행으로 시간 단축
팀과 공유SDK대화는 공유가 안 되고 코드는 된다
리뷰→수정→재리뷰 자동 루프SDK조건 분기를 코드가 판단
Notion·GitHub·DB 등 시스템 연결SDK출력 후처리·통합은 코드의 영역

세 방식 각각의 적합 영역

방식적합한 상황
① CLI탐색적 작업, 일회성 복잡 작업, 빠른 반복
② SDK+CLI반복 자동화, CLI 기능+자동화, API 키 없이 — 대부분의 자동화 니즈는 이걸로 충분
③ SDK API프로덕션 서비스, 커스텀 도구, 토큰·비용·형식 세밀 제어, DB·외부 API 통합
실무 추천 경로

①에서 시작해 필요할 때만 ③으로

  1. CLI로 "이게 되네!" 확인 — 먼저 대화로 작업이 가능한지, 품질이 나오는지 탐색한다.
  2. subprocess로 자동화 — 반복이 확인되면 그 대화를 claude -p 파이프라인으로 옮긴다.
  3. 필요할 때만 API 전환 — 프로덕션 서비스화, 커스텀 도구, 세밀한 비용·형식 제어가 필요해진 시점에 ③으로 간다.
7
EXERCISES

실습 과제 4개

15분짜리 CLI 실습에서 45분짜리 멀티에이전트 구현까지, 이 페이지의 세 방식을 순서대로 직접 만들어 본다.

과제 1–4

CLI → 자동 리뷰 → 파이프라인 → 멀티에이전트

과제 1 · CLI — 대화형 논문 교정 (15분)CLAUDE.md를 작성하고, 대화로 main.tex를 교정한 뒤, Git 커밋까지 시켜 본다.
과제 2 · SDK+CLI — 자동 리뷰 스크립트 (20분)auto_review.py를 작성한다. 리뷰 결과를 review_output.md로 저장하고, 여러 .tex 파일을 반복 리뷰하도록 확장한다.
과제 3 · SDK+CLI — 파이프라인 (30분)paper_pipeline.py를 완성한다. 문헌분석 → 섹션수정 → Figure → 리뷰가 한 번의 실행으로 이어지게 한다.
과제 4 · SDK API — 멀티에이전트 (45분)paper_agents.py를 작성한다. Tool Use를 구현하고 4개 에이전트 파이프라인을 완성한다. (도전) 리뷰 결과를 writer에게 되먹이는 피드백 루프를 추가한다.
  • 과제 1: CLAUDE.md의 규칙이 교정·커밋에 실제로 반영되었는가
  • 과제 2: review_output.md가 생성되고, .tex 여러 개에 대해 루프가 도는가
  • 과제 3: 사람 개입 없이 4단계가 끝까지 실행되는가
  • 과제 4: 에이전트 4개가 각자 독립 컨텍스트로 실행되는가 / (도전) 피드백 루프가 도는가
8
WRAP-UP

핵심 정리

세 방식의 본질과 실무 경로를 한 번 더 눌러 둔다.

SUMMARY

세 문장으로 남기는 결론

핵심 정리

하나. ① CLI = Claude가 에이전트. 자연어로 위임하는 방식이며, 탐색과 일회성 작업에서 가장 빠르다.

둘. ② SDK+CLI = CLI를 코드로 자동화. API 키 없이 구독만으로 반복·파이프라인이 돌아가는, 가장 실용적인 방식이다.

셋. ③ SDK API = 내가 에이전트를 설계. 도구 정의부터 루프까지 완전한 제어가 필요할 때 쓴다. 대부분은 ①→②로 충분하고, ③은 프로덕션으로 갈 때 전환한다.

핵심 용어의미
CLAUDE.md프로젝트 루트에 두는 지침 파일. CLI가 자동으로 읽고 작업 규칙으로 따른다
claude -pCLI의 비대화 모드. 프롬프트 한 번 실행 후 결과를 출력해 subprocess 자동화에 쓴다
Tool Use도구를 input_schema로 정의해 Claude가 호출하게 하는 API 기능. 실행은 내 코드가 담당
에이전트 루프stop_reason이 tool_use인 동안 도구 실행→결과 전달을 반복하는 while 루프
컨텍스트 격리에이전트마다 깨끗한 대화 상태와 전용 시스템 프롬프트를 주어 역할 품질을 높이는 것

출처 원본 노션 페이지: Claude Code CLI vs SDK — 에이전트 워크플로우 비교, indecisive-pyramid-af1.notion.site

한국외국어대학교 Global Business & Technology · GenAI 특강 · 부록: Claude Code CLI vs SDK.
이 자료는 단일 HTML 파일로 배포되는 실습 가이드다. 코드 블록은 원문 그대로이며, 프롬프트 블록은 우측 상단 버튼으로 복사할 수 있다.