OptiGen MCP 서버
회의록 생성과 음성 주소 검증을 위한 MCP 도구를 개발했습니다. 음성 처리 파이프라인을 최적화하고, 실제 건물 정보와 발음 유사도로 주소 오인식을 보정했습니다.
프로젝트 개요
회의록 생성과 음성 주소 검증 도구를 제공하는 MCP 서버입니다. MCP 서버 전반의 설계 및 구현을 담당했습니다.
회의 음성을 전사하고 화자별 발화를 요약해 Markdown과 DOCX 회의록을 생성하는 도구를 개발했습니다. 처리 단계별 병목을 개선하고, 사용자가 대화 화면에서 작업 진행 상태와 완성된 문서의 다운로드 링크를 확인할 수 있도록 구현했습니다.
음성으로 입력된 주소를 검증하는 MCP 도구도 개발했습니다. 실제 건물의 동 목록과 한글 발음 유사도를 활용해 동 번호의 오인식을 보정하고, 판단이 불확실하면 다시 확인하도록 구성했습니다.
프로젝트 정보
- Node.js
- TypeScript
- MCP SDK
- Express.js
- Zod
- FFmpeg
- Pino
- 시스템
- 회의록 생성과 음성 주소 검증을 지원하는 MCP 서버
- 사용 흐름
- 회의 음성에서 문서 생성 / 음성 주소 입력의 동 번호 확인과 보정
- 담당 범위
- MCP 서버 전반 설계 및 구현, 회의록 생성과 성능 개선, 발음 유사도 기반 주소 보정
OptiGen MCP 서버 시스템 아키텍처
OptiGen AI 에이전트가 Express 라우터를 통해 MCP 도구를 호출하는 서버 구조입니다. 하단에서 회의록 생성과 음성 주소 검증의 전체 프로세스 및 연결선 범례를 확인할 수 있습니다.
주요 작업
음성 회의록 생성 파이프라인 구축과 처리 시간 단축
개요
1시간 이상 이어지는 회의 녹음을 화자별 회의록과 전사 파일로 제공해야 했습니다. 전사 API의 파일 크기 제한에 대응하면서 분할 지점의 발화 문맥을 유지하고, 긴 전사 내용을 구간별로 정리해 하나의 회의록으로 통합하는 것이 과제였습니다.
세부 내용
구간 경계와 화자 정보를 보존하는 전사 처리 FFmpeg로 음성을 20분 단위로 나누고 청크 사이에 3분을 겹쳐 Whisper로 병렬 전사했습니다. 각 청크의 유효 범위에 발화의 중간 시각이 포함되는 전사만 선택해 중복을 제거했습니다. 원본 음성을 받는 pyannote의 화자 분리는 전사와 병렬로 실행하고, 두 결과를 시간 정보로 결합했습니다.
정보 추출과 최종 통합의 프롬프트 분리 화자가 연결된 전사 텍스트를 20분 단위, 2분 중첩으로 나눠 구간별로 병렬 처리한 뒤, 추출 결과를 최종 회의록으로 통합했습니다. 구간별 추출 단계에서는 발화자, 수치, 기한과 기술 용어를 보존하고, 업무 요청과 역할 정정 발언을 별도로 표시하도록 구성했습니다. 최종 통합 단계에서는 이를 바탕으로 논의 사항, 결정 사항과 후속 업무를 정리하도록 했습니다. 원문에 없는 날짜와 수치를 추정하지 않고, 불확실한 발언은 확정된 사실로 바꾸지 않도록 기준을 명시했습니다.
통합 결과의 문서 변환과 반환 최종 회의록을 Markdown과 중간 문서 구조로 정리하고 DOCX 회의록으로 변환했습니다. 회의록과 전사 파일의 다운로드 링크를 MCP 도구의 최종 결과로 반환해 같은 대화에서 문서를 받을 수 있도록 구성했습니다.
단계별 병목 측정과 실행 순서 개선 처리 시간을 측정한 뒤, 원본 음성으로 실행할 수 있는 화자 분리가 FFmpeg 완료를 기다리지 않도록 먼저 시작했습니다. 전사와 구간별 정보 추출의 동시 실행 수를 각각 3개에서 6개로 조정하고, 화자 분리 완료 확인 간격은 10초에서 5초로 줄였습니다.
세션별 연결 관리와 진행 알림 JSON 전용 응답에서 중간 상태를 전달하지 못하고, 공유 MCP 서버의 연결을 요청마다 교체하던 문제를 다뤘습니다. Streamable HTTP를 SSE 응답 모드로 전환하고 세션마다 McpServer와 Transport를 생성해 재사용했습니다. 종료 시 Transport를 닫고 연결 목록에서 제거하도록 구성했습니다.
처리 단계와 대화 화면 연결 서비스 계층은 진행 이벤트를 콜백으로 전달하고, 도구 핸들러에서 MCP 알림으로 변환하도록 분리했습니다. 실제 이벤트 사이의 진행률은 예상 시간으로 보간하고, 완료 시 임시 상태를 정리한 뒤 문서 링크를 표시했습니다.
성과
동일 파일 기준 21.8% 단축 캐시를 끈 로컬 macOS 환경에서 동일한 95분, 48MB m4a 파일로 개선 전후를 비교해 전체 처리 시간을 21.8% 줄였습니다.
진행 상태와 문서의 대화 내 전달 개발 서버의 실제 회의록 생성으로 전사, 화자 분리와 요약 단계의 진행 알림 전달과 완료 후 상태 정리를 확인했습니다.
주요 작업
실제 건물 정보와 발음 유사도를 이용한 동 번호 보정
개요
배송지 주소를 음성으로 받을 때 ‘102동’이 ‘배기동’이나 ‘대기동’으로 전사되어 동 번호를 확인하기 어려웠습니다. 숫자 표기를 정규화하는 ITN만으로는 이런 발음 오인식을 처리하기 어려워, 실제 주소 정보와 대조하는 보정이 필요했습니다.
올바른 주소를 다른 동으로 바꾸지 않는 기준 비슷한 발음만으로 동을 고르면 고객이 말하지 않은 주소를 제안할 수 있었습니다. 실제 건물에 존재하는 동으로 후보를 제한하고, 판단이 불확실하면 다시 묻도록 구성해야 했습니다.
세부 내용
주소 조회 결과에서 보정 후보 구성 도로명주소 API가 반환한 건물의 동 목록을 정리하고, 음성에서 받은 상세주소를 별도로 비교했습니다. ‘제101동’이나 숫자만 있는 항목을 같은 형식으로 맞추고, 중복된 동을 제거해 같은 후보가 동점으로 처리되지 않도록 했습니다.
한글 읽기와 실제 발음을 함께 비교 동 번호를 한글 수사로 읽은 형태와 연음, 비음화를 반영한 발음으로 변환했습니다. 전사 결과와 자음, 모음 단위의 편집 거리를 계산해 ‘대기동’에도 ‘102동’을 후보로 제안하도록 구현했습니다.
직접 대조와 유사도 비교의 적용 범위 분리 정확한 숫자와 수사 읽기는 동 목록과 직접 대조하고, ‘가동’, ‘B동’과 같은 이름은 숫자로 보정하지 않았습니다. 발음 비교에서는 편집 거리가 2 이하이며 최단 거리 후보가 하나일 때만 제안하고, 동점이거나 기준을 넘으면 동 번호를 다시 묻도록 했습니다.
성과
동 번호 오인식 전사 353건 중 259건에 정답 후보 제안 별도 오프라인 평가에서 STT가 동 번호를 놓친 전사와 각 주소의 실제 동 목록을 대조해 73.4%에 올바른 후보를 제안했습니다. 해당 평가에서 잘못된 후보 제안은 0건이었습니다.
