Dev Blog로 돌아가기 Dev Log

실제 회의 내보내기 구축: 원본 트랜스크립트에서 전문 리포트까지 — 3번의 반복

2026. 01. 28 VORA Team 11분 읽기

회의 내보내기 기능은 3번의 완전한 재설계를 거쳤습니다. 첫 번째는 텍스트 덤프였습니다. 두 번째는 좋아 보였지만 사용할 수 없는 콘텐츠를 포함한 HTML 리포트였습니다. 세 번째 — 오늘 배포되는 — Gemini를 사용하여 올바른 한국 비즈니스 작문 관례, 결정 표, 실행 항목 추적과 함께 전문적으로 구조화된 회의 리포트를 생성합니다. 덤프에서 문서까지의 여정은 완전히 기록할 가치가 있습니다.

버전 1: 텍스트 덤프 (그리고 왜 "내보내기" ≠ "유용함")

첫 번째 내보내기 기능은 this.data.fullTranscript를 수집하고 .txt 파일로 덤프하는 단일 버튼이었습니다. 모든 발화, 순서대로, 타임스탬프 포함. 다음과 같은 것:

[09:32:15] API 연동 부분에서 에러가 발생하고 있어요.
[09:32:28] 어떤 에러인지 확인했나요?
[09:32:41] 400 에러인데 아직 원인을 모르겠어요.
[09:33:02] 로그 한번 공유해줄 수 있어요?

이것이 사람들이 말한 것입니다, 순서대로. 당신이 축어적인 기록이 필요하면 유용합니다. 공통 필요를 위해서는 완전히 쓸모가 없습니다: "팀에 우리가 무엇을 결정했는지에 대한 요약을 보낼 필요가 있습니다." 실제 회의 문서화는 신호를 잡음에서 추출하는 것을 필요로 합니다. 45분 회의는 15-20페이지의 원본 트랜스크립트를 생성합니다. 아무도 15페이지를 읽지 않습니다. 그들은 결정을 강조하고, 실행 항목을 나열하고, 주요 논의 사항을 요약한 것을 필요로 합니다.

우리는 텍스트 덤프가 불충분함을 알았습니다. 하지만 그것은 없는 것보다 더 나았고 빠르게 배포했습니다. "회의 내보내기 기능 추가" 커밋이 이 버전을 나타냅니다.

버전 2: 템플릿 기반 HTML 리포트

두 번째 버전은 템플릿에서 스타일된 HTML 리포트를 생성했습니다. 우리는 섹션을 정의했습니다: 회의 개요, 주요 요점, 질문과 답변, 완전한 트랜스크립트. 템플릿은 전문적으로 보였습니다. 콘텐츠는 여전히 원본이었습니다: 주요 요점은 간단한 정규식으로 추출되었으며 질문 같은 문장을 위해, Q&A는 단지 세션의 문자 그대로 질문 및 AI 답변 쌍이었고, 전체 트랜스크립트는 이전과 동일한 덤프이지만 아름다운 상자에 있었습니다.

우리는 그것을 배포했고 우리 자신을 사용했습니다. 판정: 읽을 때까지는 실제 회의 리포트처럼 보였습니다. "주요 요점" 섹션은 물음표로 끝나는 문장을 뽑았기 때문에 "우리가 곧 점심을 먹을까요?"는 "우리는 GA 전에 적절한 속도 제한을 구현해야 합니다"와 함께 주요 회의 결정 포인트로 나타났습니다.

이 버전의 UI는 내보내기 버튼을 보였습니다. 드롭다운을 사용: "텍스트로 다운로드", "HTML로 다운로드", "AI 요약 생성." 3개의 옵션이 결정 마비를 유발했습니다 — 사용자들이 어떤 것을 필요한지 확실하지 않았습니다. "showExportMenu 및 exportMinutes 메서드 구현" 커밋이 이것을 단순화하려는 우리의 시도를 다룹니다. 우리는 결국 드롭다운을 단일 똑똑한 버튼으로 대체했습니다.

전문 리포트를 위한 프롬프트 엔지니어링 도전

버전 3는 Gemini를 사용하여 전체 리포트를 작성합니다. 이것은 프롬프트 엔지니어링 문제를 해결하는 것을 필요로 했습니다: 어떻게 AI에 특정 전문적 형식으로, 한국어로, 올바른 형식의 등록으로 출력을 생성하도록 지시하며 서문이나 설명 없이?

한국어 비즈니스 회의 기록은 개조식 (gaejojeok)이라고 불리는 특정 스타일을 가집니다 — ~습니다 형식 대신 ~함, ~하였음, ~임과 같은 문장 종결 어미를 사용하는 간결하고 명목화된 작문 스타일입니다. 이것은 형식적인 한국어 비즈니스 문서의 표준입니다. Gemini를 이 스타일을 안정적으로 생성하도록 하는 것은 프롬프트의 명시적 지침이 필요했습니다:

**작성 지침 (필수 준수):**
1. 문체: '~함', '~하였음', '~임' 등 개조식 종결 어미를 사용할 것 (~습니다 사용 금지).
2. 강조: 마크다운 강조 기호(**) 사용을 최소화하여 가독성을 높일 것.
3. 형식: 결정 사항과 실행 과제는 반드시 마크다운 표 형식을 사용할 것.
4. 구조: 
   ## 1. 회의 개요
   ## 2. 주요 논의 사항
   ## 3. 결정 사항 (표 형식: 항목 | 내용 | 비고)
   ## 4. 향후 실행 과제 (표 형식: 과제명 | 담당자 | 기한)
   ## 5. 핵심 키워드 (#태그)

"~습니다를 사용하지 마세요" 지침은 필요했습니다. Gemini의 기본 한국어 출력은 정중한 형식 종결을 사용하며, 대화 AI에는 정확하지만 형식적인 기록에는 잘못됩니다. 이 지침 없이, 약 40%의 문장은 잘못된 등록을 사용했을 것입니다. 함께, 준수 속도는 거의 100%입니다.

"마크다운 강조를 최소화하세요" 지침은 다른 문제를 해결했습니다: Gemini는 강조를 위해 굵은 텍스트 (**bold**)를 과하게 사용합니다. 이것은 마크다운 렌더러에서 괜찮지만 앱의 HTML 내보내기에 표시될 때 산만합니다. Gemini에 마크다운 강조를 최소화하도록 지시하면 더 깨끗한 리포트가 생성되었습니다.

테이블 렌더링 문제

버전 3은 결정과 실행 항목에 대해 마크다운 표를 요청합니다. 생성된 마크다운은 다음처럼 보입니다:

| 과제명 | 담당자 | 기한 |
|--------|--------|------|
| API 에러 로그 분석 | 이팀장 | 2026년 2월 21일 |
| 수정 사항 스테이징 배포 | 김팀원 | 2026년 2월 22일 |

하지만 우리의 내보내기 대상은 HTML입니다. 마크다운 표를 HTML에 렌더링하는 것은 마크다운-투-HTML 파서 (우리는 종속성으로 추가하고 싶지 않음) 또는 사용자 정의 표 렌더링 논리가 필요했습니다. MeetingExporter 모듈은 이제 가벼운 마크다운 표 렌더러를 포함합니다: | 구분자에서 나누고, --- 구분자 행을 확인하여 헤더 행을 식별하고, 적절한 <table><thead><tbody> 구조로 감싸줍니다.

이것은 Gemini가 안정적으로 생성하는 공통 표 패턴을 처리합니다. 모든 마크다운을 처리하지는 않습니다 — 블록 인용문, 중첩 목록, 기록의 코드 블록 — 하지만 회의 기록은 그것들을 필요로 하지 않습니다. 당신이 사용하는 특정 패턴을 처리하는 좁은 파서는 당신이 절대 도달하지 않을 엣지 케이스가 있는 전체 마크다운 라이브러리보다 낫습니다.

내보내기 UX: 3개의 버튼에서 1개의 똑똑한 액션까지

최종 UX 결정은 내보내기 옵션을 단일 액션으로 축소했습니다. 사용자가 내보내기를 클릭할 때:

  1. 토스트를 보이세요: "AI가 다듬어진 회의 리포트를 생성 중입니다..."
  2. Gemini에 전체 형식화된 리포트를 생성하도록 호출합니다.
  3. 렌더링된 리포트와 함께 HTML 파일을 생성 및 다운로드합니다.

HTML 파일은 자체 포함입니다: 인라인 CSS, 회의 리포트 콘텐츠, 그리고 하단의 축소 가능한 섹션의 완전한 트랜스크립트. 수신자는 외부 종속성 없이 모든 브라우저에서 그것을 열 수 있습니다. 파일명은 회의 제목과 날짜를 포함합니다: VORA_Report_2026-02-18.html.

오디오 녹음 내보내기 (캡처된 마이크 오디오)는 별도의 버튼이며 녹음 중지 후에만 활성화됩니다. 이것들을 분리하면 "어떤 형식을 선택해야 할까요" 혼동을 피합니다 — 회의 기록과 오디오 녹음은 다른 사용 사례가 있는 다른 인공물입니다.

최종 내보내기가 생성하는 것: 개조식 스타일로 전문적으로 형식화된 한국어 비즈니스 회의 리포트, 표 형식의 결정, 담당자와 기한이 있는 표의 실행 항목, 핵심 논의 사항으로 요약 및 참조를 위한 완전한 트랜스크립트. Gemini 생성은 5-15초 걸립니다. 결과는 편집 없이 팀에 직접 보낼 수 있는 것입니다.

버전 3가 여전히 잘하지 못하는 것

버전 3이 여전히 잘하지 못하는 것에 대한 정직한 대답: 그것은 트랜스크립트에서 담당자 이름을 추출하지 않습니다. 실행 항목 표는 "담당자 (담당자)" 열을 가지지만, 회의 트랜스크립트가 누가 무엇을 책임질지 명시적으로 언급하지 않으면, Gemini는 자리 표시자를 채우거나 필드를 생략합니다. 우리는 스피커 식별 (이전 포스트에서 논의됨)이 없으므로, 특정 사람에게 자동으로 작업을 귀속시킬 방법이 없습니다.

우리가 고려하고 있는 해결책: 사전 내보내기 흐름이 사용자가 참여자 이름을 입력하도록 할 수 있고, 그것들이 Gemini 프롬프트에 컨텍스트로 주입되고, Gemini가 회의 논의에 기반한 담당자에 대해 교육된 추측을 할 수 있을 것입니다. 하지만 빨리 한 번의 클릭이 되어야 하는 것에 마찰을 추가합니다. 우리는 여전히 거래를 평가 중입니다. 지금 당분간, 내보내기는 회의 콘텐츠에서 탁월하며, 사용자들은 다운로드된 리포트의 담당자를 수동으로 채웁니다.