들어가며: "캠페인 만들어줘" 한마디에 3번의 API 호출이 일어난다
광고 API는 강력하지만, 사용하기는 까다롭습니다. Spotify Ads API v3는 30개 이상의 리소스 타입, 중첩된 타겟팅 구조, 그리고 캠페인 > 광고세트 > 광고로 이어지는 다단계 엔티티 계층을 가지고 있습니다.
예를 들어 "코네티컷 주 리스너를 대상으로 오디오 캠페인을 시작하고 싶어"라는 의도를 실행으로 옮기려면, 개발자는 지오 타겟 ID 조회, 금액 단위 변환, Audience 사전 검증, 3개의 POST 요청을 순서대로 수동 오케스트레이션해야 합니다. 의도(Intent)와 실행(Execution) 사이의 인지적 거리가 상당합니다.
Spotify 엔지니어링 팀은 이 간극을 자연어 인터페이스로 메우기로 결정했습니다. 사용자가 평범한 영어로 원하는 바를 말하면, 시스템이 나머지를 알아서 처리하는 구조입니다. 그 결과물이 바로 Claude Code 플러그인 형태로 공개된 spotify-ads-api 플러그인입니다.
이 글에서는 해당 플러그인의 아키텍처, 핵심 기술 결정 사항, 그리고 LLM 기반 에이전트 위에 개발자 도구를 구축하면서 얻은 교훈을 깊이 있게 다룹니다.
참고: 이 플러그인은 GitHub과 Anthropic Claude Plugins 마켓플레이스에서 오픈소스(Apache 2.0)로 공개되어 있습니다. 직접 다운로드하여 Claude에게 말만 걸면 광고 캠페인을 생성할 수 있습니다.

핵심 아키텍처: 마크다운이 전부다
이 플러그인의 가장 놀라운 점은 컴파일된 코드가 단 한 줄도 없다는 것입니다. 빌드 단계, 패키지 매니저, 번들러, 트랜스파일러가 전혀 없습니다. 모든 컴포넌트는 .md 파일로 작성되었습니다.
Claude Code의 플러그인 시스템은 네 가지 컴포넌트 타입을 제공합니다:
| 컴포넌트 | 역할 | 구현 방식 |
|---|---|---|
| Skills (스킬) | 슬래시 명령어 정의 | 자기 완결적 Markdown 파일. 명령어 동작, API 엔드포인트, 요청 형식, 출력 처리 포함 |
| Agents (에이전트) | 자유형 자연어 처리 | request-builder 에이전트가 사용자의 대화형 요청을 감지하여 API 호출 시퀀스로 분해 |
| Hooks (훅) | 도구 호출 전 가로채기 | PreToolUse 훅으로 OAuth 토큰 자동 갱신 및 HTTP 헤더 주입 |
| Settings (설정) | 사용자별 구성 | gitignored 로컬 파일에 자격 증명, 광고 계정, 환경 설정 저장 |
이 설계의 장점은 모든 컴포넌트가 사람이 읽을 수 있고, diff 가능하며, 버전 관리가 가능하다는 점입니다. 테스트 중 새로운 API 특성이 발견되면, 수정은 대개 Markdown 파일에 문장 하나 추가하는 것으로 끝납니다.
왜 MCP가 아니라 CLI + OpenAPI 스펙인가?
Model Context Protocol (MCP)은 LLM과 외부 도구를 연결하는 사실상의 표준이 되어가고 있습니다. 하지만 Spotify 팀은 여러 이유로 MCP 대신 CLI-first + 원시 OpenAPI 스펙 접근법을 선택했습니다.
- API 표면이 너무 넓다: Spotify Ads API는 수십 개의 엔드포인트와 중첩된 요청 스키마를 가집니다. 각각을 MCP 도구로 정의하면 거대한 도구 레지스트리가 생성되어, 사용자가 해당 엔드포인트가 필요하지 않더라도 모든 상호작용에서 상당한 컨텍스트 윈도우를 소모합니다. Claude Code 플러그인 방식에서는 에이전트가 필요할 때만 관련 참조 문서를 로드합니다.
- curl 명령어는 투명하고 디버깅 가능하다: 플러그인이 만드는 모든 API 호출은 curl 명령어로 사용자에게 표시됩니다. 사용자는 정확히 무엇이 전송되는지 확인하고, 복사하고, 수정하고, 독립적으로 실행할 수 있습니다. 이 투명성은 모든 요청이 실제 예산에 영향을 미칠 수 있는 광고 시스템에서 감사 가능성(Auditability)과 사용자 제어를 제공합니다.
- OpenAPI 스펙이 진리의 원천(Source of Truth)이다: Spotify Ads API는 약 8,600줄의 포괄적인 OpenAPI v3 스펙을 제공합니다. 이 스펙을 MCP 도구 스키마로 변환하고 API 진화에 맞춰 유지보수하는 대신, 플러그인에 원시 스펙을 그대로 탑재합니다. 에이전트는 엔드포인트의 파라미터나 응답 형식을 이해해야 할 때 이 스펙을 직접 읽습니다. API가 변경되면 파일 하나만 업데이트하면 됩니다.
# 예시: 플러그인이 생성하는 실제 curl 명령어 (사용자에게 표시됨)
# 사용자는 이 명령어를 복사하여 독립적으로 실행/검증 가능
curl -X POST "https://api.spotify.com/v1/ads-api/v3/campaigns" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"ad_account_id": "ACC123",
"name": "Back to School Promo",
"objective": "AUDIO",
"status": "ACTIVE"
}'
OpenAPI Links: 내비게이션 그래프로 활용하기
이 프로젝트에서 특히 빛을 발한 기능은 OpenAPI Links입니다. OpenAPI 3.x 스펙의 상대적으로 덜 사용되는 기능으로, 한 연산의 응답을 다른 연산의 입력으로 사용하는 방법을 정의합니다.
Spotify Ads API 스펙은 엔티티 계층 전체를 Links로 인코딩합니다:
- 캠페인 생성 응답(201) → 광고세트 생성 링크
- 광고세트 생성 응답 → 광고 생성 링크 + 부모 캠페인으로 역링크
- 광고 응답 → 참조하는 크리에이티브, 이미지, 로고로 측면 링크
인간 개발자에게는 이러한 관계가 대개 암묵적이지만, LLM 에이전트에게는 명시적으로 선언된 Links가 큰 이점을 제공합니다. $response.body#/id, $request.path.ad_account_id 같은 런타임 표현식은 에이전트에게 어떤 필드를 추출하여 다음 요청에 주입해야 하는지 정확히 알려줍니다.
에이전트가 "전체 캠페인 생성"을 세 개의 순차적 API 호출로 분해할 때, 이는 OpenAPI Links가 정의한 동일한 탐색 경로(campaign → ad set → ad)를 따르는 것입니다. 광고세트 응답은 또한 타겟팅 조회 엔드포인트로 링크되며, 에이전트는 지오 타겟 페이로드를 구성하기 전에 /targets/geos를 호출해야 한다는 것을 알게 됩니다.

에이전트 설계: 도메인 전문가로 변신시키기
자연어 에이전트(agents/spotify-ads-request-builder.md)는 LLM을 Spotify Ads API 전문가로 만드는 마크다운 파일입니다. 시스템 프롬프트는 다음과 같은 도메인 지식을 포함합니다:
- 값 변환: 달러 → 마이크로 단위, 날짜 설명 → ISO 8601, 플랫폼 이름 → API Enum 값
- 다단계 오케스트레이션: "전체 캠페인 생성"을 3개의 순차적 API 호출(캠페인→광고세트→광고)로 분해하고, 단계 간 ID 전달
- 지오 타겟팅 조회: 사용자가 "코네티컷 타겟"이라고 말하면 에이전트가 지오 타겟팅 검색 엔드포인트를 호출하여 지역 ID를 찾고 올바른 구조로
geo_targets객체 구성 - 사전 비행 검증(Pre-flight Validation): 광고세트 생성 전에 Audience Estimate 엔드포인트를 호출하여 타겟팅이 최소 임계값을 충족하는지 확인
- 실행 제어: 사용자의
auto_execute설정을 존중하여 curl 명령어를 보여주고 확인을 받거나 직접 실행
한국 개발 생태계에서의 적용 맥락
이 접근법은 한국의 SI(시스템 통합) 환경이나 대기업 내부 API 연동 프로젝트에서 특히 유용할 수 있습니다. 전통적인 SI 프로젝트에서는:
- 복잡한 레거시 API를 문서화하고 유지보수하는 데 많은 비용이 소모됩니다.
- API 변경 시 SDK나 클라이언트 라이브러리를 함께 업데이트해야 하는 부담이 있습니다.
- 비즈니스 사용자가 직접 API를 호출하기 어려워, 항상 개발자 중개가 필요합니다.
마크다운 기반 플러그인 접근법은 이러한 문제에 대한 실용적인 대안을 제시합니다. OpenAPI 스펙을 진리의 원천으로 삼고, LLM 에이전트가 이를 직접 읽도록 함으로써:
- API 문서와 구현이 분리되지 않습니다.
- API 변경 시 스펙 파일 하나만 업데이트하면 에이전트가 자동으로 적응합니다.
- 비즈니스 사용자는 자연어로 질의하고, 에이전트가 내부 API 호출을 처리합니다.
물론 국내 환경에서는 API 게이트웨이, 보안 정책, 레거시 시스템과의 통합 등 추가 고려 사항이 있을 수 있습니다. 하지만 이 아키텍처의 핵심 가치인 "투명성"과 "문서 기반 실행"은 한국 기업의 API 거버넌스에도 긍정적인 시사점을 줍니다.

결론: 이 접근법의 한계와 다음 단계
이 기술의 한계 또는 주의사항
이 플러그인은 특정한 명제에 베팅하고 있습니다: "복잡한 API를 위한 최고의 인터페이스는 자연어이며, 상세한 문서로 기반을 다지고 투명하게 실행하는 것이다." 하지만 이 접근법이 모든 API 통합에 확장 가능한지는 아직 열린 질문입니다.
- 매우 복잡한 워크플로: 수십 개의 엔드포인트가 얽힌 초대형 API에서는 마크다운 프롬프트만으로 모든 엣지 케이스를 처리하기 어려울 수 있습니다.
- 지연 시간: 에이전트가 OpenAPI 스펙(8,600줄)을 필요할 때마다 참조하면 토큰 소비와 지연 시간이 증가할 수 있습니다.
- 멀티턴 컨텍스트: 여러 번의 API 호출이 필요한 긴 워크플로에서 에이전트가 컨텍스트를 잃을 위험이 있습니다.
다음 단계 학습 방향
- Idempotency Key 지원: 네트워크 재시도나 에이전트 재실행 시 중복 캠페인 생성을 방지하기 위한 멱등성 키 도입이 계획되어 있습니다.
- 다른 플랫폼으로 확장: Claude 외에도 Codex, Gemini CLI 등 다른 LLM 플랫폼을 탐색 중입니다. 특히 GPT-5.5와 Images 2.0의 이미지 생성 기능을 크리에이티브 제작에 활용하는 것에 관심을 가지고 있습니다.
- 사용자 흐름 관찰 및 최적화: 현재 에이전트 로직은 비교적 단순한 광고 흐름을 기준으로 작성되었습니다. 실제 사용 패턴을 관찰하여 에이전트가 가장 많은 설명을 요구하는 지점(Decomposition Bottleneck)을 식별하고, 시스템 프롬프트를 사전 최적화할 계획입니다.
함께 보면 좋은 글
이 플러그인은 프레임워크도, 런타임도, curl, jq, python3 외의 의존성도 없습니다. 진리의 원천은 OpenAPI 스펙이고, 비즈니스 로직은 산문(Prose)입니다. 복잡한 API를 자연어로 조종하는 이 실험이 앞으로의 개발자 도구에 어떤 영향을 미칠지 지켜보는 것도 흥미로울 것입니다.
본 글은 Spotify Engineering 블로그의 게시물을 기반으로 재구성하였습니다.