Launch HN: Vespper (YC F24) – SOTA Docx MCP
요약
본 글은 법률, 금융 등 전문 분야에서 필수적인 .docx 파일 편집의 어려움을 다룹니다. 현재 AI 에이전트가 Word 문서를 안정적으로 편집하는 것은 복잡하며, 기존 방식들은 저수준 SDK 사용, 의견 제시 도구(opinionated tools) 제공, 또는 Markdown/HTML 변환 후 재변환 등 여러 한계를 가집니다.
핵심 포인트
- DOCX는 OOXML 사양을 따르는 ZIP 압축 파일이며, 내부 XML 구조가 매우 복잡합니다.
- 단순 텍스트 편집도 스타일 및 메타데이터 때문에 수천 개의 토큰으로 변할 수 있습니다.
- AI 에이전트에게 Word 문서 편집은 단순한 코드 편집보다 훨씬 까다로운 작업입니다.
- 복잡한 사내 솔루션 유지에 많은 시간과 노력이 필요합니다.
서론
Word 문서는 어디에나 있습니다. 법률, 금융, 의료와 같은 분야에서는 Word 문서가 결과물입니다. 계약서, 규제 제출 자료, 감사 보고서는 .docx 형식으로 작성되고 수정되며 서명됩니다. 그리고 회사들은 보통 정기적으로 사용하는 Word 템플릿 라이브러리를 가지고 있습니다.
이 작업은 점점 에이전트(agent) 쪽으로 이동하고 있습니다. Microsoft Copilot과 Word의 Claude는 문서 내 AI를 주류로 만들었으며, 특히 법률 기술 분야에서 수직적인 에이전트가 늘어나면서 .docx 파일과 상호 작용할 필요성이 생기고 있습니다.
하지만 AI 에이전트는 여전히 Word 문서에서 훌륭한 작업을 수행하는 데 어려움을 겪고 있습니다.
저희는 법률 기술 및 의료 분야의 소프트웨어 엔지니어 수십 명과 이야기를 나눴는데, 그들은 Word 문서를 안정적으로 편집하기 위해 몇 주 또는 심지어 몇 달 동안 자신들의 장치를 조정(tuning)하는 데 시간을 보내며, 이제 매우 복잡한 사내 솔루션을 유지해야 하는 상황에 놓여 있다고 말했습니다.
일반적으로 현재 에이전트가 Word 문서를 편집할 수 있는 방법은 여러 가지가 있으며, 이는 주로 세 가지 범주로 나뉩니다:
- agent가 python-docx / aspose / Open XML SDK와 같은 저수준(low-level) SDK를 사용하는 코드를 작성하게 하는 방식.
- SuperDoc, Office CLI, safe-docx 또는 Adeu와 같이 에이전트에게 의견을 제시하는 도구(opinionated tools)를 제공하는 MCP 연결.
- Word 문서를 손실성 투영(lossy projection)을 거쳐 왕복 처리하는 것; 즉, pandoc/mammoth.js 같은 것을 사용하여 Markdown/HTML로 변환한 다음, agent가 편집하게 하고 다시 .docx로 변환하는 방식.
현재의 솔루션들은 간단한 경우에는 작동하지만, 복잡한 시나리오에서는 부족합니다.
솔루션과 그 단점에 대해 깊이 파고들기 전에, 먼저 .docx 파일이 무엇인지 이해해 봅시다.
문제점
DOCX 파일은 본질적으로 OOXML (Office Open XML) 사양을 따르는 계층적 XML 파일들의 ZIP 파일입니다. 이 ZIP 내부에는 다음 파일들이 포함되어 있습니다: document.xml에는 주요 텍스트가, styles.xml에는 재사용 가능한 스타일(CSS 스타일시트와 유사함)이 정의되며, numbering.xml에는 목록/번호 매기기 동작이 정의되고, 헤더, 푸터, 각주, 관계, 미디어 및 문서 메타데이터를 저장하는 별도의 XML 파일들이 있습니다.
이러한 XML 파일들은 상당히 장황합니다. 예를 들어, document.xml에서 짧은 4~5문장짜리 단락조차도 스타일, 메타데이터, 서식 정보, 실행 분할(run splitting), 그리고 XML 상용구(boilerplate)가 추가되면 수천 개의 토큰으로 변할 수 있습니다. 사용자가 Microsoft Word에서 보는 텍스트는 여러 XML 노드에 걸쳐 분리될 수 있으며 매우 장황한 방식으로 영속화됩니다.
간단한 .docx 파일이 내부적으로 어떻게 작동하는지 보여주는 인터랙티브 위젯입니다:
DOCX 편집의 이러한 특성은 코드를 편집하거나 HTML을 편집하는 것과는 다르고 더 까다롭습니다. 간단한 파일의 경우, 텍스트 표현은 대부분 그 자체이며 변경 사항은 국소적입니다.
예를 들어 Markdown/간단한 HTML을 가져가면 구조는 적어도 익숙하고 스타일도 국소적입니다.
이 문제는 수직 AI 에이전트에게 훨씬 더 심각해집니다.
Harvey와 같은 회사들은 이미 이 문제에 직면했습니다. 그들이 문서 편집 시스템을 재구축했을 때 내린 진단은, 하나의 에이전트에게 법률 비서 역할과 Word 상태 기계(state machine) 역할을 동시에 요구하고 있었다는 것이었습니다.
Harvey의 에이전트와 같은 것은 이미 힘든 임무를 가지고 있습니다. 상대방의 수정 사항(redlines)을 읽고, 회사의 플레이북을 적용하며, 정의된 용어가 3절에서와 27절에서 동일한 의미인지 확인하고, 방금 변경한 면책 한도가 두 페이지 위 섹션의 책임 조항과 모순되는지 포착해야 합니다. 그것이 업무입니다. 실행 분할(Splitting runs)을 처리하고 번호 참조를 추적하는 것은 아니지만, 같은 컨텍스트 창을 놓고 경쟁합니다.
현황 (Status quo)
위의 해결책들로 돌아가 보면, 각각은 다른 트레이드오프(trade-offs)를 가지고 있지만, 모두 같은 지점에 도달합니다. 즉, 에이전트가 실제 작업에 필요한 컨텍스트 예산(context budget)을 Word 메커니즘에 소모한다는 것입니다.
저수준 라이브러리 (Low-level libraries) (python-docx, aspose, Open XML SDK)
장점: 에이전트에게 직관적입니다. 이 라이브러리들은 사전 학습 데이터(pre-training data)에 포함되어 있기 때문입니다. 완전한 표현력(full expressiveness)을 제공하며, 보통 금지된 것이 없습니다.단점: 느리고 비용이 많이 듭니다. 긴 법률 문서를 다루는 에이전트는 대부분의 시간을 스크립트를 작성하고 디버깅하는 데 사용하며, 하이퍼링크나 변경 추적(tracked change) 같은 간단한 것조차도 에이전트가 큰 노력을 기울여야 합니다.
MCP 서버 (MCP servers) (SuperDoc, Office CLI, safe-docx, Adeu)
장점: 코드를 작성하는 것에 비해 빠르고 저렴합니다.단점: 각각은 에이전트가 즉석에서 배워야 하는 새로운 DSL(Domain Specific Language)이며, 방대한 도구와 옵션의 표면적을 가지고 있습니다. 또한 이들은 일반적인 80%를 다루는 경향이 있으며, 실제 문서가 존재하는 나머지 20% 영역이 문제입니다.
라운드 트립핑 (Round-tripping) (DOCX ↔ Markdown/HTML)
장점: 에이전트는 Word에 대해 전혀 생각할 필요가 없습니다. 단순히 텍스트만 편집하면 됩니다.단점: 한 방향으로 변환 시 손실(lossy)이 발생하며, 다른 방향으로는 되돌릴 수 없습니다. 특히 Markdown은 문서가 템플릿으로부터 상속받는 스타일 관계를 표현할 수 없습니다.
이 모든 접근 방식 중에서 우리는 세 번째 방법인 라운드 트립핑을 신뢰합니다. 에이전트들이 Word에 대해 생각하는 것에서 해방된다면, 그들은 자신의 작업에서 더 나은 성능을 발휘할 수 있다고 믿기 때문입니다.
하지만 라운드 트립핑의 큰 문제는 어떻게 손실 없는 변환(lossless conversion)을 만들 것인가 하는 것입니다?
해결책 (Solution)
리컨실러(reconciler)가 어떻게 작동하는지 설명하기 전에, 우리가 이 솔루션 형태에 대해 왜 그렇게 낙관적인지 말씀드리고 싶습니다. 영감은 Infrastructure as Code 분야에서 얻었습니다.
IaC 도구들이 인기를 얻기 전에는 개발자들이 클라우드 계정에 직접 접속해서 '클릭하며 작업'해야 했습니다. 그들은 AWS/GCP 콘솔을 탐색하고, 버튼을 클릭하고, 인프라를 수동으로 관리하는 데 몇 시간을 소비하곤 했습니다. 게다가 스테이징(staging), 프로덕션(production), QA, 고객 환경 등 모든 것이 동기화되어야 하는 여러 환경이 있거나, 새로운 환경을 구축해야 할 경우, 이는 순식간에 악몽이 되었습니다.
그때 Terraform과 Pulumi가 등장했습니다. 이제 개발자는 단순히 코드를 변경하기만 하면 되고, 도구가 클라우드에서 무엇을 변경해야 하는지 알아냅니다 (혹은 더 정확하게는 **재조정(reconciles)**합니다). 콘솔에서 몇 시간을 보낼 필요가 없어졌습니다.
저희는 이 아이디어가 에이전트와 Word 문서에 잘 적용될 수 있다고 생각했습니다. 에이전트는 자신에게 직관적인 읽기 가능한 내용을 편집하고, 다른 무언가가 이것이 실제 파일에 무엇을 의미하는지 파악하게 하는 방식입니다. 하지만 말씀드렸듯이, 필요한 도구들이 존재하지 않았습니다. pandoc이나 mammoth.js 같은 도구들은 과정에서 너무 많은 정보를 잃어버리고, 원본 파일로 어떤 것을 '재조정'하지 못합니다. 즉, 매우 손실이 큰 접근 방식인 것입니다.
요약하자면: 아이디어는 좋았지만, 도구가 충분히 좋지 않았습니다. 그래서 저희는 더 나은 방법을 찾기로 했습니다.
저희가 가장 먼저 던진 질문은 어떤 표현 방식을 사용할 것인가 하는 것이었습니다.
Markdown이 당연한 첫 후보였지만, 저희는 빠르게 포기했습니다. 그 이유는 스타일을 표현하거나 요소와 연관시키지 못하기 때문입니다. 대신, 저희는 HTML에 착안했습니다:
- HTML은 OOXML과 구조적으로 유사합니다:
<w:p>
→<p>
,<w:hyperlink>
→<a>
,<w:tbl>
→<table> - CSS는 스타일을 특정 요소와 연관시키는데, 이는 OOXML의 스타일이 작동하는 방식과도 대략적으로 유사합니다.
하지만 여전히 정보 손실 문제는 남아 있었습니다. 변환기(pandoc, mammoth.js)들은 DOCX를 HTML로 바꿀 수는 있지만, 그중 어느 것도 최소화되고, 깨끗하며, 동시에 높은 충실도를 가진 HTML을 생성하지 못했습니다. 그래서 저희는 처음부터 자체적으로 구축했습니다.
결국 이론적으로 에이전트는 이제 우리의 HTML만 편집하면 되고, 남은 것은 그것을 원래의 .docx 파일로 재조정하는 것뿐입니다. 바로 이 지점에서 문제가 복잡해집니다.
OOXML은 방대한 표면(surface)을 가지고 있습니다. 끝없는 요소, 옵션, 스타일들이 존재합니다. 여기에 독점적인 HTML 표현을 추가하면 처리해야 할 매우 긴 꼬리(long tail)의 케이스가 발생합니다. 거대한 조정 엔진(reconciliation engine)을 구축하고 수작업으로 코드를 작성하며 모든 예외 케이스를 추적하는 대신, 우리는 모델을 훈련시켜 그 자체가 조정자 역할을 하도록 결정했습니다. 즉, 많은 HTML ↔ OOXML 변경 사항들을 보여주고, 주어진 HTML 변경에 대해 어떤 OOXML 대응물이 되어야 하는지 예측하도록 가르치는 것입니다.
이 모델이 솔루션의 중심에 위치합니다. 이 모델은 에이전트의 HTML 의도(intent)를 받아 해당 블록에 대한 유효한 OOXML을 생성합니다. 그런 다음 우리는 그 결과를 원래 블록과 비교하여 차이점(diff)을 계산하고, 변경된 내용(tracked changes)을 결정론적으로 산출하며, 이를 파일에 패치(patch)한 후 호출자에게 반환합니다.
다음은 저희 솔루션이 엔드투엔드로 어떻게 작동하는지 보여주는 상호작용 순서 다이어그램입니다:
다음 섹션에서는 대안들과 비교하여 저희 솔루션을 어떻게 평가했는지 설명합니다.
평가 (Evaluation)
저희 접근 방식을 벤치마크하기 위해, 내부 벤치마크 테스트 세트의 279개 DOCX 편집 작업에 대해 다른 5가지 솔루션과 비교했습니다. 각 작업은 두 모델(GPT 5.6 Sol 및 GPT 5.6 Terra)에서 실행되었으며, 모두 중간 수준의 추론 능력(medium reasoning)을 사용했습니다:
-
MCP 서버 (MCP servers)
-
Vespper MCP (저희 솔루션)
-
SuperDoc MCP - v0.18.1
-
Office CLI (MCP를 통해) - v1.0.145
-
Adeu MCP - v3.0.2
-
스킬/하네스 (Skills/Harnesses)
-
Anthropic의 DOCX 스킬
-
일반 python-docx 하네스
저희는 LangChain의 create_agent를 사용한 하네스를 이용했습니다. 이는 에이전트 인스턴스화와 모델 교체가 쉽고 공식 mcp 패키지와 잘 작동하기 때문입니다. 저희는 가장 많은 제어권을 갖고 그리고 백그라운드에서 발생하는 마법(예: 자동 압축, 시스템 프롬프트 수정 등)을 최소화하고 싶었기 때문에 배터리 포함형 하네스(LangChain의 deepagents, Vercel의 eve)는 건너뛰었습니다.
위 후보군에 대한 몇 가지 추가 참고 사항은 다음과 같습니다:
모두에게 동일한 시스템 프롬프트 적용 - 솔루션별 프롬프트 튜닝은 포함하지 않았습니다. 모든 후보군에서 설정 작업을 제거했습니다 - 거의 모든 솔루션이 에이전트가 무언가를 편집하기 전에 일부 하우스키핑(housekeeping)을 수행하도록 요청합니다: 스킬 로드, 파일 열기, 세션 추적, 완료 시 저장 및 닫기. 우리는 이러한 부분을
최종 데이터셋: 2046개의 태스크로 구성되며, 데이터 누수(data leakage)를 방지하기 위해 문서 수준에서 약 70/15/15로 분할되었고, 문서 주제, 태스크 도메인 등 메타데이터별로 계층화되었습니다. 각 태스크는 세 가지 요소로 구성됩니다:
original.docx - 에이전트에게 입력으로 제공되는 수정되지 않은 원본 문서.
modified.docx - 예상되는 편집을 보여주는 참조 '골드(gold)' 버전의 파일.
Prompt - 요청된 편집을 설명하는 자연어 프롬프트.
다음은 저희 데이터셋의 예시 태스크입니다:
Add a new entry to Schedule 1 (Entities, and extent, to which this Act does not apply) for 'The Western Australian Planning Commission under the Planning and Development Act 2005.' Insert it in alphabetical order, after 'The State Administrative Tribunal established under the State Administrative Tribunal Act 2004.'
그리고 예상 출력물은 다음과 같습니다:

보시다시피, 스타일링이 유지되어야 합니다. 이 경우, 에이전트는 다른 항목들과 동일한 들여쓰기를 사용하고 법률(act) 부분을 기울임꼴로 처리해야 하는 것이 기대됩니다. 주의: 저희는 새로운 콘텐츠가 어떤 스타일을 가져야 하는지 알려주지 않습니다. 저희는 에이전트들이 이를 암묵적으로 이해할 것으로 기대합니다.
채점 (Scoring)
평가 과정에서, 저희는 특정 에이전트(예: GPT 5.6 Sol + DOCX Skill)를 위의 태스크에 대해 실행합니다. 각 에이전트 실행은 output.docx 파일을 생성하므로, 다음과 같은 파일들이 생겨납니다:
- original.docx
- modified.docx - '정답' (즉, 요청된 수정 작업 후 파일이 보여야 할 모습)
- output.docx - 에이전트에 의해 생성된 파일
그런 다음 저희는 다음을 수행합니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 HN Game Dev의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기