Spotify / database-design

3 개의 포스트

spotify

Building a Natural Language Interface to the Spotify Ads API with Claude Code Plugins | Spotify Engineering (새 탭에서 열림)

Spotify Ads API의 복잡한 계층 구조와 타겟팅 설정을 해결하기 위해 자연어 인터페이스를 제공하는 Claude Code 플러그인이 개발되었습니다. 이 플러그인은 사용자의 단순한 영어 요청을 분석하여 캠페인 생성, 광고 세트 구성, 소재 업로드 등 일련의 정교한 API 호출로 자동 변환합니다. 개발자는 복잡한 SDK를 유지보수하는 대신 Markdown 기반의 에이전트 설정을 통해 AI가 광고 플랫폼의 도메인 전문가처럼 동작하도록 제어할 수 있습니다. **Markdown 기반의 경량 플러그인 아키텍처** * **컴파일 없는 개발:** 모든 기술(Skills)과 에이전트 로직이 Markdown(.md) 파일로 작성되어 빌드 단계나 패키지 매니저 없이도 인간이 읽기 쉽고 버전 관리가 용이한 구조를 가집니다. * **모듈화된 구성 요소:** 슬래시 커맨드를 정의하는 'Skills', 대화형 요청을 처리하는 'Agents', OAuth 토큰 갱신을 담당하는 'Hooks', 로컬 설정을 저장하는 'Settings'로 역할을 분리하여 관리 효율성을 높였습니다. * **유연한 유지보수:** API의 새로운 제약 사항이나 특이 동작이 발견될 경우, 코드를 수정하는 대신 Markdown 파일에 설명 문구를 한 줄 추가하는 것만으로 에이전트의 행동을 교정할 수 있습니다. **MCP 대신 CLI와 OpenAPI 명세서 활용** * **컨텍스트 윈도우 최적화:** 수많은 엔드포인트를 가진 Ads API를 MCP(Model Context Protocol) 도구로 일일이 정의하면 LLM의 컨텍스트를 과도하게 소모하지만, 이 방식은 필요한 시점에만 명세서를 참조하여 효율적입니다. * **투명한 디버깅:** 플러그인이 실행하는 모든 API 호출을 `curl` 명령어로 노출하여, 사용자가 실제 전송되는 데이터를 실시간으로 모니터링하고 필요 시 복사하여 독립적으로 실행할 수 있게 합니다. * **명세서 중심의 설계:** 8,600줄에 달하는 OpenAPI v3 명세서를 소스 오브 트루스(Source of Truth)로 직접 사용하여, API 업데이트 시 명세서 파일만 교체하면 에이전트가 즉시 변경 사항을 학습합니다. **지능형 에이전트의 도메인 전문성 구현** * **다단계 오케스트레이션:** "캠페인 생성"이라는 단일 요청을 받아 캠페인, 광고 세트, 광고 소재 생성이라는 세 가지 순차적 API 호출로 분해하고 각 단계에서 생성된 ID를 다음 단계로 자동 전달합니다. * **데이터 변환 및 검증:** 사용자 언어로 입력된 금액을 API 규격인 마이크로 단위로 변환하고, 지오타겟팅 이름을 지역 ID로 조회하며, 캠페인 실행 전 오디언스 규모가 최소 기준을 충족하는지 미리 검증합니다. * **상호작용형 가이드:** 필수 필드가 누락되었을 경우 에이전트가 사용자에게 추가 정보를 능동적으로 요청하며, 실행 전 전체 계획을 사용자에게 확인받아 의도치 않은 예산 집행을 방지합니다. 복잡한 엔터프라이즈 API를 위한 AI 인터페이스를 구축할 때, 기존의 무거운 SDK 방식보다는 Markdown과 OpenAPI 명세서를 결합한 가벼운 플러그인 방식이 개발 속도와 유지보수 면에서 더 유리합니다. 특히 광고 시스템처럼 실질적인 비용이 발생하는 도구에서는 AI의 내부 동작을 투명하게 공개하여 사용자가 제어권을 가질 수 있도록 설계하는 것이 중요합니다.

spotify

Background Coding Agents: Supercharging Downstream Consumer Dataset Migrations (Honk, Part 4) | Spotify Engineering (새 탭에서 열림)

Spotify는 배경 코딩 에이전트 'Honk'와 내부 플랫폼인 Backstage를 결합하여 약 1,800개의 데이터셋 소비자를 새로운 버전으로 마이그레이션하는 복잡한 과정을 자동화했습니다. 이 프로젝트를 통해 수동 작업 시 약 10주가 소요될 것으로 예상되었던 엔지니어링 공수를 획기적으로 절감하며 대규모 소프트웨어 유지보수의 새로운 가능성을 확인했습니다. 결과적으로 에이전트 기반의 자동화가 성공하려면 데이터 환경의 표준화와 명확한 컨텍스트 제공이 핵심적이라는 교훈을 얻었습니다. **데이터셋 마이그레이션의 도전 과제** * Spotify는 새로운 기능을 지원하기 위해 널리 사용되던 기존 데이터셋 2개를 폐기하고 새 버전으로 교체해야 하는 상황에 직면했습니다. * 마이그레이션 대상은 약 1,800개의 직접적인 파이프라인이었으며, SQL 기반(BigQuery Runner, dbt)과 Scala 기반(Scio)이라는 서로 다른 세 가지 프레임워크가 혼재되어 있었습니다. * 6개월이라는 짧은 기간 내에 수천 개의 저장소를 수정해야 했기에, 단순 수동 작업으로는 감당하기 어려운 규모였습니다. **Backstage와 Fleet Management를 통한 대상 식별** * 마이그레이션 전, Backstage의 'Endpoint Lineage'와 'Codesearch' 플러그인을 활용하여 폐기될 데이터셋을 사용하는 모든 저장소와 팀을 정확히 파악했습니다. * 식별된 대상 저장소들은 Spotify의 대규모 변경 관리 도구인 'Fleetshift'를 통해 관리 범주로 지정되었습니다. * 이를 통해 수천 개의 저장소에 걸친 변경 사항을 한곳에서 모니터링하고 조율할 수 있는 기반을 마련했습니다. **에이전트를 위한 컨텍스트 엔지니어링과 제약 사항** * Honk 에이전트가 정확한 수정을 수행할 수 있도록 인간용 마이그레이션 가이드를 재구성하여 상세한 컨텍스트 파일을 제공했습니다. * 초기에 에이전트가 잘못된 필드 매핑을 추측하는 문제를 해결하기 위해, 모든 필드 변경 사항을 명확한 테이블 형태로 프롬프트에 포함했습니다. * 프레임워크의 유연성이 너무 높아 표준화가 어려운 Scio 파이프라인은 자동화 대상에서 제외하고, 비교적 구조가 일관된 SQL 기반 프레임워크(dbt, BigQuery Runner)에 집중했습니다. * 에이전트가 스스로 판단하기 어려운 모호한 케이스의 경우, 코드를 직접 수정하는 대신 해당 위치에 인간 엔지니어가 참고할 수 있는 가이드 링크와 주석을 남기도록 설정했습니다. **자동화된 마이그레이션의 성과와 기술적 교훈** * Fleetshift를 통해 총 240개의 자동 마이그레이션 Pull Request(PR)를 성공적으로 배포했습니다. * 하지만 많은 SQL 저장소에 유닛 테스트가 부족하여, 에이전트가 수정한 내용을 스스로 검증하고 보완하는 '자가 수정 루프'를 완전히 활용하지 못한 점은 한계로 남았습니다. * 이번 프로젝트를 통해 데이터 환경의 전략적 표준화와 테스트 코드의 의무화가 배경 코딩 에이전트의 효율을 극대화하는 필수 조건임을 확인했습니다. 성공적인 에이전트 도입을 위해서는 코드의 표준화와 테스트 자동화가 선행되어야 합니다. 향후 Spotify는 Honk가 스스로 Jira 티켓이나 문서를 읽고 컨텍스트를 수집하는 기능을 추가하여, 인간이 사전 컨텍스트를 작성하는 수고를 더욱 줄이고 복잡한 작업의 성공률을 높일 계획입니다.

spotify

Inside the Archive: The Tech Behind Your 2025 Wrapped Highlights | Spotify Engineering (새 탭에서 열림)

스포티파이는 2025년 'Wrapped(연말 결산)'를 통해 사용자의 1년 감상 기록 중 가장 의미 있는 순간들을 발굴하고, 이를 LLM(대규모 언어 모델)을 활용해 개인화된 서사로 풀어내는 'Wrapped Archive' 기능을 선보였습니다. 이 시스템은 약 3억 5천만 명의 사용자에게 최대 5개씩, 총 14억 개의 리포트를 생성하기 위해 고도화된 데이터 추출 휴리스틱과 모델 증류(Distillation) 기술, 그리고 대규모 병렬 처리가 가능한 분산 아키텍처를 활용했습니다. 단순한 통계 나열을 넘어 데이터에 기반한 창의적인 스토리텔링을 대규모로 구현하면서도 비용 효율성과 시스템 안정성을 동시에 확보한 것이 핵심입니다. ### 데이터 기반의 '특별한 날' 선정 알고리즘 스포티파이는 수억 개의 감상 이벤트 중에서 사용자에게 가장 의미 있을 법한 날들을 선별하기 위해 우선순위가 지정된 휴리스틱 세트를 설계했습니다. * **다양한 지표 활용**: 단순히 청취 시간이 긴 날뿐만 아니라, 처음 듣는 아티스트가 가장 많았던 '발견의 날', 특정 장르가 지배적이었던 날, 평소 취향에서 크게 벗어난 '이색적인 날' 등을 정의했습니다. * **서사적 가치 부여**: 생일이나 새해 첫날 같은 맥락적 데이터와 결합하여 통계적 강점과 이야기로서의 잠재력이 높은 날을 최대 5개까지 압축했습니다. * **분산 데이터 파이프라인**: 대규모 데이터를 처리하기 위해 분산 파이프라인을 구축하여 사용자별 후보일을 계산하고, 이를 오브젝트 스토리지에 저장한 뒤 메시지 큐(PubSub)를 통해 비동기적으로 리포트 생성 단계에 전달했습니다. ### 14억 개 리포트 생성을 위한 LLM 최적화 모든 사용자에게 고품질의 리포트를 제공하기 위해서는 거대 모델의 성능과 소형 모델의 경제성 사이에서 균형을 잡아야 했습니다. * **정교한 프롬프트 엔지니어링**: 시스템 프롬프트를 통해 데이터 기반의 스토리텔링, 재치 있는 톤앤매너, 안전 가이드라인을 정의하고, 사용자 프롬프트에는 구체적인 청취 로그와 수학적 통계 블록을 포함해 할루시네이션(환각)을 방지했습니다. * **모델 증류 및 미세 조정(Fine-tuning)**: 비용 절감을 위해 고성능 프런티어 모델로 생성한 고품질 데이터를 학습 데이터(Gold Dataset)로 사용하여 더 작고 빠른 모델을 미세 조정했습니다. * **DPO(Direct Preference Optimization) 적용**: 인간의 피드백을 반영한 A/B 테스트 데이터를 바탕으로 DPO를 실시하여, 소형 모델임에도 불구하고 베이스라인 모델에 필적하는 성능을 확보했습니다. ### 대규모 병렬 처리와 데이터 정합성 유지 나흘 동안 멈춤 없이 14억 개의 리포트를 생성하고 저장하기 위해 높은 처리량과 안정성을 보장하는 인프라를 구축했습니다. * **배치 처리 엔진**: 초당 수천 건의 요청을 처리할 수 있도록 시스템을 설계했으며, 한 사용자의 리포트가 생성될 때 이전 리포트의 내용을 참고하게 하여 내용 중복을 방지했습니다. * **경합 없는 스토리지 설계**: 열 지향(Column-oriented) 키-값 데이터베이스를 사용하여 각 리포트를 고유한 컬럼 식별자(YYYYMMDD)로 저장했습니다. 이를 통해 락(Lock)이나 복잡한 읽기-수정-쓰기 과정 없이 병렬 쓰기가 가능하게 했습니다. * **쓰기 순서 제어**: 리포트 본문을 먼저 저장한 후 메타데이터를 작성하는 방식을 채택하여, 생성 중인 리포트가 사용자에게 노출되는 현상을 방지하고 데이터 일관성을 유지했습니다. 대규모 사용자 데이터를 바탕으로 LLM 서비스를 기획한다면, 처음부터 거대 모델을 직접 호출하기보다 고성능 모델로 생성한 고품질 데이터를 활용해 소형 모델을 증류(Distillation)하고 특정 목적에 최적화하는 전략이 비용과 성능 면에서 훨씬 유리합니다. 또한, 수억 건의 동시 쓰기가 발생하는 환경에서는 데이터베이스의 물리적 구조를 활용해 경합을 최소화하는 스키마 설계가 필수적입니다.