AI가 그린 슬라이드를 ‘진짜 PowerPoint’로: PPT Master(hugohe3/ppt-master)의 SVG 중간 언어·DrawingML 컴파일러·품질 게이트 심층 해부

한 줄 요약: AI에게 슬라이드를 만들게 하면 대개 ‘예쁜 그림’이나 ‘텍스트 상자만 얹은 껍데기’가 나온다. hugohe3/ppt-master는 AI가 제한된 SVG로 페이지를 그리게 하고, 결정론적 컴파일러가 그것을 PowerPoint의 네이티브 DrawingML 도형으로 옮긴다. 오늘 GitHub Trending Python 일간 1위에 오른 이 프로젝트의 설계와 검사 게이트를 박스에서 직접 돌려 보며 뜯어봤다.

PPT Master는 PDF·DOCX 같은 원자료를 AI 에이전트가 제한된 SVG로 그리게 한 뒤, 결정론적 컴파일러가 PowerPoint 네이티브 도형으로 옮긴다. 결과물은 슬라이드 그림이 아니라 하나하나 고칠 수 있는 도형과 텍스트다
PPT Master는 PDF·DOCX 같은 원자료를 AI 에이전트가 제한된 SVG로 그리게 한 뒤, 결정론적 컴파일러가 PowerPoint 네이티브 도형으로 옮긴다. 결과물은 슬라이드 그림이 아니라 하나하나 고칠 수 있는 도형과 텍스트다

왜 지금 이 저장소인가

‘AI로 PPT 만들기’ 도구는 이미 많다. 문제는 결과물의 편집 깊이다. 실무에서 덱은 한 번 만들고 끝나지 않는다. 숫자가 바뀌고, 상사가 순서를 바꾸고, 회사 템플릿에 맞춰야 한다. 슬라이드가 통째로 이미지이거나 위치만 맞춘 텍스트 상자 묶음이면 그때마다 다시 만들어야 한다. PPT Master는 이 지점을 정면으로 노린다. README의 첫 문장이 “편집 가능은 이제 기본, 차이는 네이티브 깊이”다.

항목 확인한 값 (10/11 KST 기준) 해석
저장소 hugohe3/ppt-master (Python, MIT) 2025년 12월 10일 공개. 금융 실무자(CPA)인 Hugo He가 사실상 혼자 만든다. 전체 커밋 2,132개 중 2,044개가 본인 계정
별 / 포크 59,565 / 4,697 (11:57 KST, GitHub API) 오늘 GitHub Trending Python 일간 1위(오늘 +461), 전체 일간 9위. 열린 이슈+PR은 8건뿐이다
최신 릴리스 v6.7.0 (10/8 11:01 KST) 9/10 v6.3.2 → 9/13 v6.4.0 → 9/16 v6.5.0 → 9/19 v6.6.0 → 10/8 v6.7.0. 최근 한 달 커밋 166개. 주 단위로 마이너 버전이 오른다
형태 앱이 아니라 에이전트 스킬(skills/ppt-master/SKILL.md) + 결정론적 Python 스크립트 Claude Code·Codex·Cursor 같은 에이전트가 워크플로 문서를 읽고 스크립트를 부른다. 모델은 사용자가 고른다
코드 규모 (직접 집계) scripts/ Python 약 19만 7천 줄, 워크플로·레퍼런스 Markdown 약 1만 2천 줄, 템플릿 SVG 12,167개(대부분 아이콘) ‘프롬프트 몇 장’짜리 스킬이 아니다. 실제 무게는 SVG 검사기와 PPTX 컴파일러에 있다
배포 git clone, 릴리스 zip ppt-master-skill-v6.7.0.zip(22.5MB), npx skills add, Claude Code 플러그인 마켓플레이스 README는 스킬 zip을 ‘약 56MB’라고 적었지만 v6.7.0 첨부 파일은 22.5MB였다
런타임 요구 Python 3.10+, pip install -r requirements.txt python-pptx, skia-pathops, uharfbuzz, PyMuPDF, mammoth, edge-tts 등. pandoc은 .doc·.odt 같은 드문 형식에만 필요

이 글은 README와 docs/technical-design.md(964줄), why-ppt-master.md, SKILL.md, 공유 SVG 표준(shared-standards-core.md), SECURITY.md, v6.7.0 릴리스 노트, 그리고 박스에서 직접 설치·변환·라운드트립·테스트한 결과를 바탕으로 썼다. 실제 LLM으로 덱을 생성하지는 않았다. 생성 품질에 관한 문장은 모두 프로젝트의 설명이다.

구조: 앱이 아니라 ‘스킬 + 컴파일러’

PPT Master에는 실행 파일도, 웹 서버도, 자체 모델 호출 코드도 중심에 없다. 사용자는 Claude Code나 Codex 같은 에이전트에게 “이 PDF로 덱 만들어 줘”라고 말하고, 에이전트가 SKILL.md를 읽은 뒤 정해진 순서대로 문서를 읽고 스크립트를 부른다. 작성자의 표현으로는 harness + model = agent다. 프로젝트는 하네스(워크플로와 도구)만 책임지고, 품질의 천장은 모델이 정한다.

경로 역할 눈여겨볼 점
skills/ppt-master/SKILL.md 진입점. 로드 순서, 라우팅, 전역 실행 규율 142줄로 짧다. ‘경로 먼저’, ‘라우트 하나만 로드’, ‘BLOCKING 게이트에선 멈춤’ 같은 규칙만 두고 세부는 라우트 문서로 넘긴다
workflows/ routing.md, generate-pptx.md, edit-native-pptx.md, create-template.md, profiles/(quick·beautify·image-to-pptx) ‘선택된 라우트의 문서만 읽는다’는 규칙으로 컨텍스트를 아낀다
references/ 역할별 지침: strategist·executor-*·image-*·shared-standards·svg-effects·native-* 역할(Strategist/Executor/Image) 전환 때마다 해당 파일만 읽게 한다. 하나의 거대한 프롬프트를 쪼갠 구조
scripts/svg_quality* SVG 계약 검사기 (svg_quality_checker.py + svg_quality/) 오류는 막고 경고는 통과. 자동 수정은 의도적으로 없다
scripts/svg_to_pptx* SVG → DrawingML 컴파일러와 패키지 검증 요소 단위 디스패치. 내보내기 전에 품질 보고서 지문을 확인한다
scripts/pptx_to_svg* 기존 PPTX를 편집용 SVG 작업 공간으로 가져오기 Edit Native PPTX(원본 보존 편집)와 템플릿 추출의 기반
scripts/source_to_md/ PDF·DOCX·XLSX·PPTX·EPUB·웹 → Markdown 순수 Python 우선, pandoc은 폴백. 웹 수집은 사설망 차단이 기본
scripts/image_backends/·tts_backends/ 이미지 생성 백엔드 15종, 음성 합성 5종 공급자별 키(OPENAI_API_KEY 등)와 IMAGE_BACKEND로 명시 선택. 통합 키 하나로 뭉치지 않는다
templates/ 레이아웃·브랜드·덱·차트·표·아이콘(64MB) 템플릿은 선택 사항. 기본은 ‘자유 디자인’
scripts/tests/ 56개 테스트 파일, 700개 테스트 ‘dogfood_*’ 이름의 실사용 회귀 테스트가 많다. 태국어·힌디어 같은 다국어 조판 회귀도 있다

흥미로운 점은 무게 중심이다. 워크플로·레퍼런스 문서는 1만 2천 줄 정도인데 스크립트는 약 19만 7천 줄이다. 모델에게 ‘잘 그려라’라고 길게 부탁하는 대신, 모델이 쓴 결과를 기계가 검사하고 번역하는 쪽에 투자했다. 이게 이 프로젝트를 다른 ‘프롬프트 모음형’ 스킬과 가르는 첫 번째 차이다.

라우트: 요청 모양에 따라 정확히 하나만

SKILL.md의 규칙 중 가장 강한 것은 ‘라우트는 하나만 로드’다. 새 덱 생성, 기존 덱 보존 편집, 템플릿 추출은 서로 다른 계약을 갖고, 에이전트는 라우팅 문서가 고른 하나의 절차 문서만 읽는다. 기술 설계 문서는 “실패한 실행 대부분은 명령이 아니라 라우트 선택에서 시작한다”고 적는다.

라우트 / 프로필 언제 쓰나 핵심 계약
Generate — Default 문서·주제에서 새 덱을 만들 때 Strategist가 design_spec.md·spec_lock.md를 만들고 사용자 확인(BLOCKING)을 받은 뒤 Executor가 페이지별 SVG 작성. 5쪽 조기 점검 + 최종 점검
Generate — Quick “확인 없이 빨리”라고 명시했을 때 계획 문서·확인 단계·svg_final/을 건너뛴다. 대신 재개 불가. 컨텍스트를 잃으면 처음부터
Generate — Beautify 기존 PPTX의 쪽수·순서·문구는 그대로, 레이아웃만 개선 보이는 페이지는 전부 재생성. ‘제자리 편집’이 아니다
Generate — Image to PPTX 슬라이드 스크린샷을 편집 가능한 슬라이드로 현재 Codex 전용, 항상 Quick. 차트·표는 생성형 복원 금지(실제 값 또는 manual_required)
Edit Native PPTX 회사 템플릿 PPTX에 새 내용을 채우거나 노트·내레이션만 얹을 때 pptx_to_svg.py --roundtrip → 고른 페이지만 편집 → svg_to_pptx.py --roundtrip. 손대지 않은 페이지는 원본 그대로
Create Template 기존 자료(PPTX·이미지·문서)에서 재사용 가능한 Brand/Style/Layout/Deck 추출 결과는 Generate 1단계의 템플릿 후보가 된다

기본(Default) 흐름은 사람의 확인을 두 번 받는다. 먼저 전달 방식(누구에게, 무엇을)과 템플릿 사용 여부를 정하고, 그다음 Strategist가 완성한 설계 명세를 확인받는다. ⛔ BLOCKING 표시가 붙은 단계에서는 사용자가 답할 때까지 멈추라는 규칙이 있다. 서사 방식(mode)도 고른다. 결론부터 쌓는 pyramid, 이야기형 narrative, 교육용 instructional, 보여 주기용 showcase, 중립 정보형 briefing의 다섯 가지이고, 시각 스타일 18종과 자유롭게 조합된다.

Strategist가 설계 명세를 쓰고 Executor가 페이지별 SVG를 작성하면, 검사기가 오류 0을 확인하고 svg_to_pptx가 DrawingML로 컴파일한다. 검사 뒤에 SVG를 고치면 보고서 지문이 어긋나 내보내기가 거부된다
Strategist가 설계 명세를 쓰고 Executor가 페이지별 SVG를 작성하면, 검사기가 오류 0을 확인하고 svg_to_pptx가 DrawingML로 컴파일한다. 검사 뒤에 SVG를 고치면 보고서 지문이 어긋나 내보내기가 거부된다

왜 서브 에이전트로 쪼개지 않았나

요즘 에이전트 도구는 병렬 서브 에이전트를 즐겨 쓴다. PPT Master는 일부러 반대로 간다. 기술 설계 문서는 이유를 이렇게 든다. 페이지 디자인은 앞 단계의 색 선택, 실제로 확보된(또는 실패해 대체된) 이미지, 앞 페이지의 시각적 리듬에 의존한다. 서브 에이전트는 오래된 부분 스냅숏으로 시작해 덱이 시각적으로 흔들린다. 같은 이유로 ‘한 번에 다섯 쪽씩’ 같은 묶음 생성도 금지한다. 묶으면 컨텍스트 압축이 빨라져 일관성이 더 빨리 무너진다는 것이다. 그 대가가 ‘10쪽에 10~20분’이라는, 프로젝트 스스로 밝힌 느린 속도다.

핵심 설계: SVG를 ‘프로젝트 전용 중간 언어’로

왜 하필 SVG인가. 설계 문서는 소거법으로 설명한다.

  • DrawingML 직접 생성: 둥근 사각형 하나에 중첩 XML 수십 줄이 필요하다. 모델의 학습 데이터도 적고, 사람이 눈으로 디버깅하기 어렵다.
  • HTML/CSS: 모델이 가장 잘 아는 형식이지만 세계관이 다르다. HTML은 내용 흐름으로 위치가 정해지는 ‘문서’, PowerPoint는 모든 요소가 절대 좌표에 놓인 ‘캔버스’다.
  • EMF/WMF: DrawingML과 가장 가깝지만 모델이 거의 모른다.
  • 슬라이드를 이미지로 넣기: 가장 쉽지만 편집성이 사라진다.

SVG는 DrawingML과 같은 ‘절대 좌표 2D 벡터’ 세계관을 공유하고, 모델이 잘 쓰며, 사람이 브라우저로 바로 볼 수 있다. 다만 여기서 SVG는 브라우저가 그릴 수 있는 아무 SVG가 아니다. 문서의 표현대로 “SVG가 PPT Master에 맞추지, PPT Master가 SVG 표준 전체를 따라가지 않는다.” 허용 요소·속성·단위·메타데이터를 닫아 둔 닫힌 문법이다.

SVG 쪽 DrawingML 쪽 정확도 등급 / 규칙
<rect rx> prstGeom prst="roundRect" Native-stable. 실험에서 카드 3장이 모두 roundRect 자동 도형이 됐다
<path d>, <line> custGeom (자유형) Native-normalized. 실험의 축선(line)은 FREEFORM으로 들어왔다
<text> + 비위치 <tspan> 한 텍스트 프레임 안의 여러 런 줄바꿈은 같은 x에 양수 dy. 형제 <text>로 쪼개면 경고
최상위 <g id> + data-pptx-bounds 그룹 도형 (이름 = id) 필수. 애니메이션 단위이자 편집 단위. 그룹끼리 1px 넘게 겹치면 오류
캔버스 전체 단색 <rect> 슬라이드 배경 p:bg 첫 레이어일 때만 승격. 실험 3쪽 모두 승격
linearGradient, 그림자·글로 필터 gradFill, outerShdw/glow 지원 목록 안에서만. 나머지 필터는 Bake-required
mask, <style>, class, foreignObject, textPath, 스크립트 없음 금지. 검사기가 오류로 막는다
HTML 엔티티 &nbsp;, 맨 & — XML이 깨져 내보내기 중단. 문자는 유니코드 그대로, 예약 문자만 XML 엔티티
SVG는 DrawingML로 가는 프로젝트 전용 중간 언어다. 둥근 사각형은 roundRect, path는 자유형, text와 tspan은 한 텍스트 프레임의 런, 그라데이션은 gradFill로 옮겨지고 목록 밖 기능은 검사기가 막는다
SVG는 DrawingML로 가는 프로젝트 전용 중간 언어다. 둥근 사각형은 roundRect, path는 자유형, text와 tspan은 한 텍스트 프레임의 런, 그라데이션은 gradFill로 옮겨지고 목록 밖 기능은 검사기가 막는다

실제로 써 보면 계약이 꽤 구체적이다. 아래는 박스에서 직접 쓴 페이지의 일부다. 최상위 그룹마다 고유 id와 모듈 영역 data-pptx-bounds를 달고, 색은 대문자 6자리 HEX, 길이는 단위 없는 숫자다.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720"
     font-family="Malgun Gothic, Arial" lang="ko-KR" data-pptx-page-role="content">
  <rect id="bg" x="0" y="0" width="1280" height="720" fill="#FFFFFF"/>
  <g id="title" data-pptx-bounds="80 50 1120 80">
    <text x="80" y="110" font-size="44" font-weight="bold" fill="#1C3056">세 단계 파이프라인</text>
  </g>
  <g id="card-1" data-pptx-bounds="80 180 340 400">
    <rect x="80" y="180" width="340" height="400" rx="24" fill="#E8EEF6"/>
    <text x="110" y="250" font-size="30" font-weight="bold" fill="#1C3056">1. Strategist</text>
  </g>
</svg>

설계상 중요한 선택이 하나 더 있다. 입력을 세 상태로 나눈다. 권장 표기(canonical)는 경고 없이 통과, 문서화된 옛 표기(compatible)는 경고만 내고 변환기가 정규화, 매핑이 없거나 뜻이 모호한 표기(invalid)는 오류로 막는다. 호환 표기를 다시 프롬프트에 되먹이지 않아 생성 문법이 점점 넓어지는 것을 막는다는 설명이다. ‘읽기는 너그럽게, 쓰기는 좁게’를 명시적인 계약으로 만든 셈이다.

품질 게이트: 자동 수정 없는 검사기

LLM이 쓴 SVG는 결정론적이지 않다. 긴 덱에서는 계약 위반이 조금씩 섞이고, 그것은 보통 14쪽째 변환이 중단되거나 PowerPoint가 요소를 조용히 버리는 식으로 드러난다. 검사기는 이것을 ‘14쪽이 계약을 어겼다’로 바꿔 준다. 설계 문서가 강조하는 세 가지 원칙은 이렇다.

  • 후처리 전에 검사: 아이콘 삽입·이미지 인라인 같은 후처리는 원본 위반을 가릴 수 있어서, 에이전트가 쓴 svg_output/을 직접 본다.
  • 오류는 막고, 경고는 통과, 자동 수정은 없음: 검사기가 디자인 의도를 추측해 고치지 않는다. 대신 위치와 대안을 구체적으로 알려 준다.
  • 보고서와 원본의 지문을 맞춘다: 정식 내보내기와 --quick-generate는 현재 SVG 원본의 지문으로 최종 보고서를 확인하고, 없거나 오래됐거나 실패한 보고서면 PPTX를 만들지 않는다.
게이트 무엇을 막나 실험 결과
attribution_guard.py LICENSE 해시, SPONSORS*.md, SKILL.md 메타데이터, 9개 진입 스크립트의 가드 호출 중 하나라도 빠지면 실패 원본: 종료 코드 0. SPONSORS.md를 지운 사본: guard·svg_to_pptx.py --help 모두 종료 코드 78
조기 점검 (--stage early) 1~5쪽을 ‘방법 표본’으로 보고 반복될 실수를 먼저 고친다 6쪽 이하 덱은 건너뛴다. 3쪽 데모라 해당 없음
최종 점검 (--stage final) SVG 계약 위반(오류)은 막고, 권고(경고)는 통과 정상 3쪽: 오류 0, 경고 5(문단 분할 1건·라벨 0.4% 경계 초과 4건). 금지 기능 SVG: 오류 5건, 종료 코드 1
보고서 지문 확인 검사 뒤에 SVG를 고치면 그 보고서로는 내보낼 수 없다 검사 후 라벨 한 글자를 고치자 found stale로 거부(종료 1). 실패 보고서는 found failed로 거부
postflight 패키지·리소스 감사와 품질 보고서 연결 passed-with-warnings. 결과는 validation/<출력명>.report.json

무결성 가드는 따로 짚을 만하다. SKILL.md 로드 순서의 2단계가 attribution_guard.py 실행이고, 0이 아니면 “즉시 멈추고, 검사하거나 고치거나 우회하지 말라”고 적혀 있다. 프로젝트 관리자·검사기·내보내기 등 진입 스크립트 9개도 시작하자마자 같은 검사를 부른다. 실험에서 스폰서 문서 하나를 지운 사본은 --help조차 종료 코드 78로 멈췄다. 저작자 표기를 지키려는 장치지만, 사내 포크를 만들려는 조직에는 운영상 제약이 된다(아래 ‘주의점’에서 다시 다룬다).

설치와 실행: LLM 없이 파이프라인 끝까지

에이전트가 하는 일은 결국 ‘계약에 맞는 SVG 파일을 쓰는 것’이다. 그래서 사람이 그 역할을 대신하면 모델 호출 없이 검사·컴파일·라운드트립 전 과정을 확인할 수 있다. 박스에서 그렇게 했다.

git clone https://github.com/hugohe3/ppt-master.git
cd ppt-master
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt

# 무결성 게이트 (SKILL.md 로드 순서 2단계와 같다)
python3 skills/ppt-master/scripts/attribution_guard.py; echo $?   # 0이어야 진행
S=skills/ppt-master/scripts
python3 $S/project_manager.py init mwdemo --format ppt169
P=projects/mwdemo_ppt169_20261011

# (에이전트가 하는 일) svg_output/01_cover.svg ... 를 계약에 맞게 작성
python3 $S/svg_quality_checker.py $P --quick-generate --stage final --json
python3 $S/svg_to_pptx.py $P --quick-generate          # 기본은 Fade 전환. 끄려면 -t none
#  -> exports/mwdemo_20261011_115703.pptx
#  -> validation/mwdemo_20261011_115703.report.json

3쪽짜리 덱(표지, 카드 3장, 막대 4개)을 직접 쓰고 Quick 경로로 내보냈다. 내보내기 자체는 1초 남짓이었다. python-pptx로 결과를 열어 보니 SVG의 <g id="card-1">가 이름까지 그대로 PowerPoint 그룹이 됐고, rx가 있는 사각형은 roundRect 자동 도형, 텍스트는 편집 가능한 텍스트 상자가 됐다. 미디어 파일은 0개, 즉 전부 벡터 도형이다. 옵션을 아무것도 주지 않았는데 모든 슬라이드에 Fade 전환이 들어간 점은 기억해 둘 만하다.

점검 항목 (박스: Linux x86_64, venv Python 3.12.15, 10/11 KST) 결과 메모
uv pip install -r requirements.txt 성공, 패키지 88개 설치 PyMuPDF·nbconvert까지 끌려와 가볍지는 않다. python-docx는 테스트에만 필요해 따로 넣었다
project_manager.py init mwdemo --format ppt169 1280×720 프로젝트 생성 현재 디렉터리와 무관하게 저장소의 projects/ 아래에 만든다
직접 쓴 3쪽 SVG → 최종 점검 오류 0 / 경고 5 에이전트 역할을 사람이 대신했다. LLM 호출은 한 번도 없었다
svg_to_pptx.py --quick-generate 약 1초, 16.7KB PPTX, 슬라이드 3장 flat 구조: 프로젝트 전용 마스터 1개 + Blank 레이아웃. 미디어 파일 0개(전부 벡터)
python-pptx로 결과 열어 보기 그룹 8개, 텍스트 상자 18개, roundRect 4개, 사각형 4개, 자유형 1개 그룹 이름이 SVG id(title, card-1…) 그대로. 텍스트는 모두 편집 가능한 상자
기본 전환 효과 3장 모두 Fade 전환이 들어감 아무 옵션도 안 줬는데 붙었다. 원치 않으면 -t none
검사 후 SVG 수정 → 내보내기 거부 (found stale) CI에서 ‘검사 따로, 내보내기 따로’ 꼼수를 막는다
금지 기능 SVG (<style>·class·mask) 검사 오류 5건 → 내보내기 거부 자동 수정 없이 위치와 대안을 알려 준다
pptx_to_svg.py --roundtrip → 2쪽만 수정 → svg_to_pptx.py --roundtrip passthrough 2, rebuilt 1 slide1.xml·slide3.xml이 원본과 바이트 단위로 동일, slide2만 바뀜
라운드트립에서 긴 제목으로 수정 검사기: 가로 39.7% 넘침 오류 그런데 svg_to_pptx.py --roundtrip은 종료 코드 0으로 파일을 썼고 postflight만 status=failed. 자동화는 종료 코드가 아니라 보고서를 봐야 한다
web_to_md.py로 127.0.0.1·169.254.169.254 둘 다 거부 (Refusing non-public URL target) 클라우드 메타데이터 SSRF 방어가 기본값
같은 도구로 example.com 거부 → --allow-private-hosts를 줘야 성공 박스 DNS가 198.18.0.1(가짜 IP 대역)로 답하는 환경이라 공개 사이트도 막혔다. 이 옵션은 보호 전체를 끈다

Edit Native PPTX: 회사 템플릿을 망가뜨리지 않는 법

실무자에게 가장 쓸모 있는 라우트는 오히려 이쪽일 수 있다. 이미 디자인팀이 만든 PPTX가 있을 때, 새 덱을 처음부터 생성하면 마스터·레이아웃·세부 서식이 미묘하게 달라진다. Edit Native PPTX는 기존 PPTX를 편집용 SVG 작업 공간으로 가져오고, 원본 패키지는 sources/source.pptx로 따로 보존한다. 고른 페이지만 고치고 다시 내보내면 손대지 않은 페이지는 원본 그대로 복원된다는 것이 계약이다.

# 기존 PPTX → 편집용 작업 공간
python3 $S/pptx_to_svg.py deck.pptx -o rt-out --roundtrip
#   rt-out/authoring-svg-flat/slide_0N.svg  (편집 대상)
#   rt-out/sources/source.pptx              (원본 보존)

# 2쪽만 고친 뒤
python3 $S/svg_quality_checker.py rt-out --roundtrip --json
python3 $S/svg_to_pptx.py rt-out --roundtrip
#   Round-trip export summary: output_pages=3 passthrough=2 ... rebuilt=1
Edit Native PPTX 라운드트립에서는 고친 슬라이드만 다시 빌드하고 나머지는 원본을 그대로 통과시킨다. 박스 실험에서 손대지 않은 slide1·slide3의 XML은 원본과 바이트 단위로 같았다
Edit Native PPTX 라운드트립에서는 고친 슬라이드만 다시 빌드하고 나머지는 원본을 그대로 통과시킨다. 박스 실험에서 손대지 않은 slide1·slide3의 XML은 원본과 바이트 단위로 같았다

실험에서는 앞서 만든 3쪽 PPTX를 가져와 2쪽 제목만 바꿨다. 결과 PPTX의 slide1.xml과 slide3.xml은 원본과 바이트 단위로 같았고, slide2.xml만 바뀌었다. 내보내기 요약도 passthrough=2, rebuilt=1로 정확히 그 사실을 보고했다.

반대로 걸리는 점도 하나 찾았다. 제목을 원래 텍스트 상자보다 훨씬 길게 바꾸자 검사기는 ‘가로 39.7% 넘침’ 오류를 냈다. 그런데 이 상태에서 svg_to_pptx.py --roundtrip을 돌리면 종료 코드 0으로 PPTX를 썼고, postflight 보고서에만 status=failed가 남았다. Quick 경로는 실패한 보고서로는 내보내기 자체를 거부했으니(위 표), 라운드트립 경로만 다르게 동작한 것이다. 자동화에 넣는다면 종료 코드만 믿지 말고 보고서를 확인해야 한다.

# 라운드트립은 품질 게이트가 실패해도 종료 코드 0으로 파일을 쓸 수 있다 (v6.7.0 실험).
# 자동화에서는 postflight 보고서의 status를 직접 확인한다.
python3 - <<'EOF'
import json, glob, sys
r = json.load(open(sorted(glob.glob("rt-out/validation/*.report.json"))[-1]))
s = json.dumps(r)
sys.exit(0 if '"status": "passed' in s and '"failed"' not in s else 1)
EOF

테스트와 재현 범위

테스트 실행 결과 해석
pytest scripts/tests (v6.7.0, 56개 파일) 699 통과 / 1 실패, 하위 테스트 1,214 통과, 56초 LLM·API 키 없이 전부 로컬에서 돈다
실패 1건 test_web_to_md_security.py의 HTTPS 연결 바인딩 테스트 urllib3 2.8.0에서 목(mock) 반환형이 맞지 않아 TypeError
같은 파일을 urllib3 2.5.0으로 재실행 27 통과, 하위 97 통과 버전 조합 문제로 보인다. requirements.txt는 urllib3을 고정하지 않는다
돌리지 않은 것 실제 LLM으로 덱 생성, AI 이미지 생성, TTS 내레이션, --native-charts-and-tables 생성 품질과 ‘10쪽 10~20분’은 프로젝트가 밝힌 값이다

테스트 스위트는 LLM이나 API 키 없이 1분 안에 끝난다. 이름에 dogfood가 붙은 파일이 많은데, 실제 사용 중 나온 결함(태국어·힌디어 조판, 템플릿 경로, 편집 라운드트립 등)을 회귀 테스트로 굳힌 것이다. 실패 1건은 urllib3 2.8.0과 테스트의 목(mock) 반환형이 맞지 않아 생겼고, urllib3 2.5.0에서는 같은 파일이 전부 통과했다. 의존성 상한이 없는 requirements.txt로 설치하면 이런 일이 생길 수 있으니, 운영에서는 잠금 파일을 따로 만드는 편이 안전하다.

위험·라이선스·운영 주의점

주제 내용 실무 판단
라이선스 코드 MIT. 단 PDF 변환에 쓰는 PyMuPDF는 AGPL-3.0 PDF 변환을 포함해 사내 배포 번들을 만들면 AGPL 조건을 따로 검토해야 한다. PDF가 필요 없으면 해당 줄을 빼도 된다고 명시
무결성 가드 LICENSE·스폰서 파일·메타데이터가 바뀌면 주요 스크립트가 종료 코드 78로 멈춘다 MIT라 법적으로는 수정이 자유지만, 코드가 ‘공식 배포본 그대로’를 강제한다. 사내 포크에서 스폰서 문서를 지우면 도구가 멈춘다. SKILL.md는 에이전트에게 이 게이트를 우회하지 말라고 지시한다
스폰서 노출 README 상단에 API 중계 서비스 제휴 링크 SKILL.md는 사용자가 묻지 않으면 스폰서·모델 추천을 꺼내지 말라고 규정. 조직 도입 땐 공급자 선택을 따로 정하는 게 맞다
‘데이터는 로컬’의 범위 변환·SVG·PPTX는 로컬 단 에이전트의 모델 호출, 이미지 생성 API, 웹 이미지 검색(Openverse·Pexels 등), edge-tts(Microsoft 온라인 음성) 내레이션은 외부로 나간다
API 키 .env에 공급자별 키 약 18종 현재 디렉터리 → 스킬 디렉터리 → 저장소 루트 → ~/.ppt-master/.env 순서로 첫 파일을 읽는다. 어떤 파일이 읽혔는지 확인 습관이 필요하다
로컬 서버 라이브 미리보기·확인 UI·스펙 리뷰 페이지 PUBLIC_HOST = '127.0.0.1'로 고정. v6.3.1에서 미리보기 SVG 새니타이저 우회와 아이콘 속성 주입 취약점이 비공개 제보로 고쳐졌다
텔레메트리 코드 검색 기준 외부 전송 코드는 찾지 못했다 ‘telemetry’라는 이름은 analysis/page-context/에 쓰는 로컬 토큰 집계다
프롬프트 인젝션 원문 PDF·웹 페이지가 에이전트 컨텍스트로 들어간다 도구가 막아 주는 영역이 아니다. 에이전트의 명령 실행 권한을 프로젝트 폴더로 좁혀 두는 게 안전하다
  • 1인 프로젝트의 속도: 커밋의 96%가 한 사람이고 주 단위로 마이너 버전이 오른다. v6.7.0만 봐도 Google 이미지 기본 모델 교체, 설계 명세 브라우저 리뷰 페이지 신설, 문서 변환기 손실 수정이 한꺼번에 들어갔다. 기능이 빨리 느는 장점과 동작이 자주 바뀌는 위험이 같이 온다. 태그 고정을 권한다.
  • 모델 의존성: README는 Kimi K3나 Claude 같은 큰 컨텍스트(약 100만 토큰) 모델과 이미지 생성 모델 조합을 권장하고, 다른 모델은 “품질 차이가 있다”고 적는다. 싼 모델일수록 사람이 손볼 게 많아진다는 경고도 있다.
  • Quick의 재개 불가: Quick은 계획 문서를 남기지 않는다. 긴 덱을 Quick으로 돌리다 에이전트 컨텍스트가 끊기면 처음부터 다시 해야 한다.
  • 의도적 비지원: SmartArt(닫힌 객체 모델이라 일반 도형으로 재구성), WordArt·변형 텍스트, 반사·부드러운 가장자리, OLE·비디오·매크로는 범위 밖이다. 기능별 경계는 docs/powerpoint-svg-mapping.md에 공개돼 있다.
  • 차트의 선택: 기본 차트·표는 앱 간 표시가 일정한 ‘편집 가능한 도형’이다. 데이터 편집 창이 붙는 진짜 차트 객체가 필요하면 --native-charts-and-tables로 별도 파일을 만든다. 이 옵션은 이번에 돌려 보지 않았다.

대안과 비교

접근 출력 강점 약점·주의
PPT Master (MIT) 네이티브 DrawingML PPTX (도형·텍스트·마스터·선택적 네이티브 차트·표·수식) 로컬 실행, 모델 선택 자유, 품질 게이트, 원본 보존 편집 라우트 설치·에이전트 필요, 10쪽에 10~20분(프로젝트 설명), 1인 유지보수, 모델 품질에 크게 좌우
호스티드 AI 슬라이드 SaaS 웹 덱 + PPTX/PDF 내보내기 브라우저에서 몇 초, 공동 편집·공유 링크 자료가 외부 서버로 간다. 내보낸 PPTX의 편집 깊이는 제품마다 다르고 구독료가 붙는다
PowerPoint 안의 AI 비서 PowerPoint 문서 자체 앱 안에서 바로, 조직 계정·권한과 결합 라이선스 비용, 디자인 자유도와 문서 변환 범위는 제품 정책에 묶인다
Markdown 슬라이드 (Marp·Slidev 등) HTML/PDF, PPTX는 주로 이미지 기반 개발자 친화, 버전 관리 쉬움 PowerPoint 안에서 도형 단위로 고치는 게 목적이라면 맞지 않는다
python-pptx 스크립트 직접 작성 PPTX 완전한 통제, 결정론적 디자인·서사 판단이 없다. DrawingML이 장황해 모델이 직접 쓰기 어렵다는 게 PPT Master가 SVG를 택한 이유
에이전트 기본 문서 스킬 PPTX (대개 python-pptx 계열) 추가 설치가 거의 없다 검사기·라운드트립·템플릿 추출 같은 운영 장치는 보통 없다

정리하면 PPT Master의 차별점은 ‘AI가 슬라이드를 만든다’가 아니라 AI의 출력을 좁은 중간 언어로 묶고, 그 언어를 검사·컴파일하는 결정론적 계층을 크게 만든 것이다. 모델은 잘하는 일(SVG 쓰기, 서사 구성)만 하고, PowerPoint의 장황한 XML은 기계가 맡는다. 이 분업은 PPTX가 아닌 다른 문서 생성 에이전트에도 그대로 옮길 만한 패턴이다.

누가 도입하면 좋은가

상황 권장도 이유
보고서·IR·내부 브리핑을 매주 PowerPoint로 내야 하는 팀 높음 결과물이 ‘고칠 수 있는 초안’이라는 설계가 실무 흐름과 맞는다. 회사 템플릿은 Edit Native PPTX로 보존
자료 반출이 까다로운 금융·공공 조직 중간~높음 변환과 조판은 로컬. 단 모델 호출을 사내 모델이나 승인된 게이트웨이로 돌릴 수 있어야 한다
이미 Claude Code·Codex 구독이 있는 개인 높음 정액 구독 안에서 덱을 더 만들어도 추가 비용이 거의 없다는 게 프로젝트의 비용 논리
몇 초 만에 공유 링크가 필요한 영업·마케팅 낮음 생성이 느리고 공동 편집이 없다. SaaS가 낫다
PPTX 생성을 CI·서버에 넣으려는 개발팀 중간 검사기와 컴파일러는 결정론적이라 자동화에 쓸 만하다. 단 단일 메인테이너·빠른 릴리스 주기·라운드트립 종료 코드 문제를 감안해 버전 고정과 보고서 검사가 필요

평가 방법은 이렇게 권한다. 지난달 실제로 만든 덱 두세 개의 원자료를 골라 ① 지금 쓰는 방식, ② PPT Master Default(확인 포함), ③ Quick으로 각각 만든다. 비교할 것은 세 가지다. 첫째, 초안이 나오기까지 걸린 시간과 모델 비용. 둘째, ‘숫자 하나 바꾸기, 순서 바꾸기, 회사 템플릿에 맞추기’ 같은 후속 수정에 걸린 시간. 셋째, 검사 보고서의 경고 수와 사람이 직접 고친 개수. PPT Master의 강점은 두 번째 항목에서 드러나야 한다. 첫 번째 항목에서는 SaaS가 이길 가능성이 크다.

이 프로젝트가 던지는 메시지는 분명하다. AI 문서 도구의 경쟁력은 ‘한 번에 얼마나 예쁘게’가 아니라 ‘나중에 얼마나 쉽게 고칠 수 있게’에 있다. 그걸 위해 모델 대신 컴파일러와 검사기에 투자한 설계가, 오늘 Python 트렌딩 1위라는 관심으로 돌아오고 있다.