콘텐츠로 이동

회의와 전사

Control Center는 통화를 녹음하고 요약, 액션 아이템, 결정 사항이 담긴 깔끔한 정리본을 돌려줍니다. 음성 인식과 화자 분리는 여러분의 하드웨어에서 실행됩니다. Granola를 떠올리면 되지만, 이쪽은 셀프 호스팅이고 에이전트가 사는 바로 그 워크스페이스에 연결되어 있습니다.

회의는 녹음되고 전사된 세션입니다. 캘린더 이벤트와는 같지 않습니다. 이벤트는 Google에서 동기화된 예정된 일정이고, 회의는 실제로 녹음한 대상입니다. 이벤트에서 녹음을 시작할 수 있으므로 둘은 연결될 수 있지만, 서로 다른 레코드로 남습니다.

모든 회의는 Control Center의 다른 모든 것과 마찬가지로 워크스페이스 범위입니다. 한 워크스페이스에서 녹음한 회의는 다른 워크스페이스에 나타나지 않습니다.

“온디바이스”라는 표현은 방향은 맞지만 명사가 틀렸습니다. 클라이언트는 오디오를 캡처해 16 kHz PCM16 프레임을 cc_server가 실행 중인 머신으로 스트리밍합니다. 나머지는 모두 그 호스트가 처리합니다. 채널별 WAV를 <dataDir>/meetings/<meetingId>/ 아래에 쓰고, 워커 아이솔레이트에서 전사하고, 에코를 걸러 내고, 이후에 화자 분리를 수행합니다. 독립 실행형 데스크톱에서는 그 호스트가 같은 머신입니다. 원격 서버를 가리키면 그렇지 않으므로, “노트북을 떠나는 것은 없다”는 서버가 곧 여러분의 노트북일 때만 참입니다.

예외가 하나 더 있고, 그것이 중요한 예외입니다.

요약 이전의 모든 것, 즉 캡처, 전사, 에코 제거, 화자 분리, 음성지문 매칭은 네트워크 호출 없이 서버에서 실행됩니다.

임베딩, 화자 분리, 음성(ASR) 모델은 최초 부팅 시 강제 설치되므로(데모에서는 건너뜀) 설정을 방문하지 않아도 화자 분리와 녹음이 존재합니다. ASR은 여전히 선택 가능합니다. 수백 메가바이트에 달하고, 선택 목록에 네 가지 빌드가 있습니다. 음성 모델은 그 첫 다운로드 이후 한 번 더 재시작해야 합니다. 전사기가 가져오기가 끝나기 전에 모델을 확정하기 때문입니다.

크기, 언어 지원 범위, 정확도가 서로 다른 네 가지 선택 항목:

  • Parakeet TDT 0.6B v3 — 다국어, 권장 기본값(~600 MB)
  • Parakeet TDT 0.6B v2 — 영어(~480 MB)
  • Whisper large-v3-turbo — 다국어(~626 MB)
  • Whisper base.en — 영어 전용, 작은 역사적 기본값(~198 MB)

서버가 런타임에 가져오는 아티팩트는 모델뿐이며, 모든 네이티브 라이브러리는 번들에 포함되어 있습니다.

회의는 두 개의 오디오 채널을 동시에 녹음합니다:

  • 나(“me”): 여러분의 마이크.
  • 상대방(“them”): 회의의 오디오 출력으로, 드라이버 없이 동작하는 루프백으로 캡처합니다. macOS에서는 Core Audio 프로세스/장치 탭, Windows에서는 WASAPI 루프백, Linux에서는 PipeWire / PulseAudio 모니터입니다.

두 채널을 따로 캡처하기 때문에 트랜스크립트는 처음부터 화자가 지정되어 있습니다. 여러분의 발언에는 me가, 통화에 있는 다른 모든 사람의 발언에는 them이 태그됩니다.

여러분의 목소리는 시스템 출력에서 마이크로 새어 들어가며, 그대로 두면 두 번 전사됩니다. 두 가지 필터가 이를 막습니다. 신호 수준의 AEC3는 모든 원격 모드 녹음에서 실행되며 필수입니다. 네이티브 AEC 라이브러리를 로드할 수 없으면 에코가 섞인 마이크를 조용히 스트리밍하는 대신 녹음 시작을 거부합니다. (대면 모드에는 제거할 상대방 신호 기준이 없으므로 AEC는 그대로 통과시키기만 합니다.) 그 위에 모든 플랫폼에서 호스트 측 텍스트 수준 에코 필터가 실행됩니다.

모든 OS 수준 마이크 처리는 의도적으로 비활성화되어 있습니다. macOS에서 플랫폼 자체의 에코 제거나 자동 게인을 켜면 마이크가 Voice Processing I/O로 전환되는데, 이 빌드에서는 마이크와 시스템 오디오 탭 둘 다 죽었습니다.

녹음하는 동안 오디오는 UI 스레드 밖에서 롤링 윈도 단위로 디코딩됩니다. 윈도는 뒤따르는 짧은 무음 구간이나 최대 윈도 길이에서 잘립니다. 각 윈도는 밀리초 오프셋이 붙은 화자 태그 트랜스크립트 세그먼트가 됩니다.

RMS 임계값을 한 번도 넘지 않은 윈도는 디코딩조차 되지 않고 건너뜁니다. 음성 모델이 무음을 환각된 비음성 토큰으로 만들어 내고 그 디코딩은 낭비되는 CPU이기 때문입니다. 실제 결과는 이렇습니다. 계속 아주 조용한 화자는 트랜스크립트를 남기지 않습니다. 누군가 빈 결과로 돌아오면 모델을 탓하기 전에 그 사람의 입력 레벨을 확인하십시오.

녹음을 멈추면 화자 분리가 녹음 전체를 대상으로 오프라인으로 실행되어 원격 채널을 이름을 바꿀 수 있는 개별 화자(Person 1, Person 2, …)로 나눕니다. 화자 수는 여러분이 지정한 개수가 아니라 클러스터링 임계값에서 추론됩니다. 따라서 이는 임계값이 만든 결과이며, 조용하거나 겹쳐 말하는 화자는 옆 화자와 합쳐질 수 있습니다. 트랜스크립트는 [mm:ss] SPEAKER: text 줄로 렌더링됩니다.

화자 이름을 바꾸면 트랜스크립트 하나에 이름표를 붙이는 것 이상을 합니다. Control Center는 화자의 음성지문을 음성 프로필로 저장해 이후 회의에서 그를 자동으로 인식할 수 있습니다. 화자 분리된 화자의 이름을 지정하면 음성지문을 저장할지 묻습니다. 저장하면 그 이름의 계속 갱신되는 중심값에 섞이고 새 화자와 코사인 유사도로 대조되므로, 다음번에는 다시 이름을 붙이지 않아도 같은 사람이 자기 이름으로 나타납니다.

음성 프로필은 워크스페이스 범위이며 그 경계를 넘지 않습니다. 설정 → 워크스페이스 → 회의에서 관리합니다. 이전에 저장된 화자의 이름을 바꾸면 기존 이름의 등록이 해제되고 새 이름을 등록할지 묻습니다. 프로필을 삭제하면 저장된 음성지문은 제거되지만 지난 회의에 이미 적용된 이름은 그대로 남습니다.

녹음이 멈추면 서버가 MeetingRecordingStopped 도메인 이벤트를 게시합니다. 내장 meeting_summary 파이프라인 템플릿이 그 이벤트로 트리거됩니다. 녹음기는 이를 기다리지 않으며, 회의는 상태 수명주기를 거쳐 전이할 뿐입니다:

recording → processing → done

요약 에이전트는 제목, 여러분이 실시간으로 남긴 대략적인 노트, 트랜스크립트를 받아 구조화된 JSON을 돌려줍니다. 어떤 섹션을 쓸지는 워크스페이스의 활성 회의 노트 템플릿(설정 → 워크스페이스 → 회의)이 결정합니다. 활성 템플릿은 새 요약과 다시 실행한 요약 모두에 적용됩니다. 그다음 파이프라인의 저장 단계가 그 JSON을 개별 행에 씁니다:

  • enhancedNotes와 summary → 회의의 노트
  • 각 액션 아이템 → MeetingActionItem 행(콘텐츠, 담당자, 선택적 티켓 링크)
  • 각 결정 → MeetingDecision 행

액션 아이템과 결정은 자유 형식 마크다운에서 절대 파싱되지 않고, 에이전트의 구조화된 배열에서만 나옵니다. 실행이 구조화된 출력을 내지 않으면 저장 단계를 건너뛰고 원시 트랜스크립트를 폴백으로 보관하므로 기록을 잃지 않습니다. 파이프라인 어디에서도 회의를 done으로 표시하지 않습니다. 실행의 종료 이벤트를 받아 그 일을 하는 것은 단일 조정자이며, 덕분에 형제 단계가 실패해도 이미 끝난 것처럼 보이는 절반만 기록된 회의가 방치되지 않습니다.

표면 표시 내용
/meetings 회의 목록과 액션 아이템·결정 사항 개수
/meetings/record 실시간 녹음 HUD: 한쪽에는 노트, 다른 쪽에는 스트리밍 트랜스크립트
/meetings/:meetingId 회의 상세: 노트, 트랜스크립트, 액션 아이템, 결정 사항 탭
설정 → 워크스페이스 → 회의 이 워크스페이스의 노트 템플릿과 저장된 음성 프로필

캡처는 세 데스크톱 플랫폼 모두에서 드라이버 없이 동작합니다(macOS의 Core Audio 탭, Windows의 WASAPI, Linux의 PipeWire).

웹 클라이언트도 녹음합니다. 이 페이지의 나머지가 데스크톱을 전제로 해서 가리기 쉬운 사실입니다. 브라우저는 getUserMedia로 마이크를, getDisplayMedia(화면 공유)로 회의 오디오를 받아 16 kHz PCM16으로 다운샘플링한 뒤 같은 호스트로 스트리밍합니다. 여기에는 세 가지 제약이 있습니다:

  • 공유하는 화면에는 오디오 트랙이 반드시 있어야 합니다. Safari, Firefox, macOS의 전체 화면 공유는 오디오를 제공하지 않으며 녹음이 시작을 거부합니다.
  • 네이티브 AEC3가 없습니다. 브라우저 자체 에코 제거를 마이크에 요청하고, 호스트 측 텍스트 에코 필터는 여전히 실행됩니다. HUD에는 마이크 PCM으로 구동되는 입력 레벨 미터가 표시됩니다.
  • 요약 다시 실행과 처리 취소는 데스크톱 전용입니다.

캘린더의 녹음 시작 및 연결 동작은 데스크톱 전용이며, 회의 화면 자체의 녹음 흐름은 웹에서도 작동하는데도 웹에서는 그렇게 명확히 알립니다.