Table Topics 대회에 참가하게 되어, 실제 심사위원처럼 점수를 매기는 코치를 직접 만들었습니다
요약
이 글은 즉석 연설 대회(Table Topics)를 대비하여 개발한 'Confident Speaker Coach'라는 코칭 도구를 소개합니다. 이 코치는 사용자의 로컬 기기에서 실행되며, 주제 제시부터 실시간 전사, 그리고 Toastmasters 공식 평가 기준에 따른 점수 산출까지 자동화합니다.
핵심 포인트
- 로컬 환경에서 작동하여 개인 정보 보호에 강점
- Toastmasters의 55/30/15 가중치 기반으로 정교하게 채점
- 실시간 전사, 길이 측정, 필러 워드 분석 등 다각적 피드백 제공
_이 글은 Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle에 제출하는 내용입니다.
문제점
Table Topics는 Toastmasters의 즉석 연설(impromptu round) 시간입니다. 한 번도 본 적 없는 주제를 받으면 일어나서 1~2분 동안 연설해야 합니다. 준비할 노트나 시간이 없습니다.
저는 곧 대회가 예정되어 있는데, 저의 약점은 바로 그것입니다. 말이 장황하고, 시간을 초과하며, 제 자신의 채움말(filler words)을 듣지 못합니다. 인간 코치는 세션당 비용이 들고, 대회 전 주에 밤 11시에 저와 함께 앉아 있을 수 없습니다. 존재하는 피드백 도구들은 내 오디오를 서버에 올리기를 원하고 분당 요금을 부과하는데, 이는 매일 연습하기에는 정확히 잘못된 방식입니다.
그래서 저는 Confident Speaker Coach를 만들었습니다: 링크를 열고, 주제를 받고, 연설한 다음, 실제 Toastmasters 투표 양식(Content 55점, Delivery 30점, Language 15점)으로 점수를 매기고, 청중 한 명의 솔직한 반응, 가장 큰 개선점인 단 하나의 피드백, 그리고 구체적인 업그레이드 사항을 얻습니다. 이 코치는 판정 내용을 저에게 소리 내어 읽어줍니다.
데모
- 영상 설명: - 한 세션 전체: 주제 '과대평가된 것과 과소평가된 것은 무엇인가?', 실제 2분 1초 분량의 연설, 그리고 코치가 점수를 매긴 판정 내용.
- 소스 코드: https://github.com/viveknshah/confident-speaker-coach
호스팅된 데모는 의도적으로 없습니다. 핵심은 이 코치가 사용자의 기기에서 실행된다는 것이므로, 데모는 레포지토리와 영상으로 구성됩니다. 단 하나의 명령만 필요합니다:
직접 실행해보기
git clone https://github.com/viveknshah/confident-speaker-coach
cd confident-speaker-coach
docker compose up # 첫 실행 시 qwen2.5:3b-instruct (~1.9 GB) 다운로드
...
Docker가 없다면? ollama pull qwen2.5:3b-instruct && node server.js를 실행하세요. Node 18+ 환경에서 작동하며, npm 의존성이 전혀 없습니다. 모델은 OLLAMA_MODEL로 교체할 수 있습니다 (저는 한동안 gemma3:4b를 사용했습니다). 모델을 다운로드하면 코칭 루프가 로컬에서 실행됩니다. 참고로, 타이핑으로 대체되는 기능은 완전히 오프라인 환경에서의 입력 경로이며, Chrome의 실시간 전사(transcription)는 브라우저의 음성 서비스를 사용합니다.
작동 방식
- Table Topics 프롬프트를 제공합니다.
- 공식적인 1:00-2:30 시간 제한 타이머를 실행하고, 브라우저에서 연설을 실시간으로 전사(Web Speech API; 다른 브라우저에서는 타이핑 대체 기능)합니다.
- 연설에 점수를 매깁니다: 앱은 코드 레벨에서 길이, 분당 단어 수, 필러 워드(filler words)를 측정합니다. 이것들은 사실이므로, 저는 모델에게 이를 추측하도록 맡기지 않습니다. 로컬의 오픈 웨이트 모델이 내용, 구조, 언어를 심사하며, 이 모델이 매긴 점수는 실제 55/30/15 가중치에 맞춰 조정됩니다.
- 제가 속한 클럽 코치들이 알려주듯이 평가를 전달합니다: 먼저 길이, 다음으로 배점(ballot), 그다음 청중의 반응, 그리고 마지막으로 가장 큰 개선점 하나와 다음 시도를 위한 구체적인 업그레이드 사항 하나를 제시합니다.
- 3문장 분량의 평가를 소리 내어 말해주기 때문에 연습하는 것이 마치 사람이 같은 공간에 있는 것처럼 느껴집니다. 기본적으로 브라우저 내장 음성을 사용하며, ElevenLabs 키를 설정하면 서버 측에서 키가 유지되는 자연스러운 목소리로 업그레이드됩니다.
핵심의 오픈 소스 AI
이 코치는 qwen2.5:3b-instruct라는 오픈 웨이트 모델이며, Ollama 위에서 서버로 구동됩니다. 이 부분을 제거하면 제품은 단순한 주방 타이머가 됩니다. 판단을 요하는 피드백의 모든 부분(배점, 청중 반응, 개선점, 재작성된 비트)은 이 모델에서 나오며, UI가 직접 렌더링할 수 있도록 엄격하게 JSON 형식으로 제한됩니다.
왜 3B 모델인가: 저렴한 4 GB CPU 박스에서도 충분히 작게 구동 가능하며, 그 크기 대비 구조화된 출력(structured output)에 있어 신뢰성이 높습니다. 이는 UI가 반환하는 필드를 렌더링하기 때문에 중요합니다. 제 선택이 마음에 들지 않나요? OLLAMA_MODEL=gemma3:4b docker compose up을 사용해 보세요. 코칭의 두뇌 전체가 하나의 환경 변수로 관리됩니다.
업무 분담은 의도적입니다:
| 코드 측정 항목 (사실) | 모델 평가 항목 (의견) |
|---|---|
| 연설 길이 vs 1:00-2:30 대회 규칙 | 내용 및 구조 품질 |
| ... | |
| 소형 모델들은 관대한 채점관입니다. 제 코치는 점수를 부풀릴 수 없습니다. 왜냐하면 그 점수들이 스톱워치와 단어 카운터에서 나오기 때문입니다. |
오픈 혁신이 작동하는 이유
- 비용 때문에 비즈니스가 돌아갑니다. 무제한 연습이 제품입니다. 매주 10가지 드릴을 진행하는 30명 규모의 클럽은 한 달에 수천 개의 모델 호출(model calls)을 발생시킵니다. 이는 오픈 가중치(open weights)에서는 무료이지만, 토큰당 API를 사용하면 비용 청구서가 늘어납니다. 구독료 계산이 마진 비용 제로에서만 성립합니다.
- 개인 정보 보호는 규정 준수 사항이 아니라 기능입니다. Table Topics 연설은 개인적입니다. 사람들은 자신의 직업, 가족, 실패에 대해 이야기합니다. 자체 호스팅(self-hosted) 클럽 인스턴스에서는 녹취록과 점수가 클럽이 통제하는 인프라를 벗어나지 않습니다. (솔직한 주의사항: 마이크를 사용한다면 Chrome의 실시간 음성 인식은 브라우저의 음성 서비스를 사용합니다. 텍스트 입력 대체 방식은 모든 것을 장치 내에 유지합니다.)
- 종속성이 없습니다. 모델, 프롬프트(prompt), 채점 규칙 모두 저장소(repo) 안에 있습니다. 클럽은 자체 대회 형식에 맞게 미세 조정(fine-tune)할 수 있고, 더 나은 오픈 가중치가 나오면 모델을 교체할 수 있으며, 저나 다른 누구와도 재협상할 필요가 없습니다.
누가 비용을 지불하는가
Toastmasters는 13,800개 이상의 클럽에 걸쳐 265,000명 이상의 회원을 보유하고 있으며, 이들 모두는 매주 Table Topics를 연습하지만 회의 사이에 피드백을 받을 좋은 방법이 없습니다. 클럽들은 호스팅된 버전에 대해 월별 구독료를 지불합니다. 이는 공유된 연습 공간, 회원 진행 상황, 그리고 자체 주제에 대한 것입니다. 개인은 무료로 자체 호스팅할 수 있습니다. 이 모든 것은 단 하나의 docker compose up으로 가능합니다. 왜냐하면 말하기 연습이 가장 필요한 사람들이 종종 세션당 비용을 지불할 능력이 가장 적기 때문입니다.
첫 사용자: 저의 구축기. 저는 이 코치에게 실제 Table Topics 시도를 맡겼습니다. 주제는 '과대평가된 것(overrated)은 무엇이고, 과소평가된 것(underrated)은 무엇인가?'였고, 영화에 대한 과장된 기대감에 대해 2분 동안 장황하게 이야기했습니다. 코치는 저에게 100점 만점에 28점을 주었고, 그 점수는 정확했습니다. 분당 37단어의 느린 속도(말하는 것이 아니라 생각하고 있었기 때문에), 연설이 산만하다는 지적을 했고, 유일한 개선점은 '과대평가된 것과 과소평가된 것을 처음에 정의하고, 그것을 중심으로 구조화하라'였습니다. 이것은 제가 밤 11시에 무료로 받았어야 할 피드백이며, 오디오는 노트북에서 벗어나지 않았습니다.
구축 방식
의존성 제로(Zero-dependency) Node 18 서버(npm install 불필요), 정적 프론트엔드, Ollama와 모델 풀링을 통합한 Docker compose:
Browser (마이크, 실시간 STT, 타이머) --> Node 서버 --> Ollama (qwen2.5:3b-instruct, 엄격 JSON)
|
+--> 선택적 ElevenLabs TTS (기본 브라우저 음성)
/api/topic, /api/coach, /api/speak (선택적 속도 제한 ElevenLabs 프록시; 설정되지 않은 경우 브라우저 음성). 테스트는 타이밍 규칙, 채움말(filler) 측정, 점수 클램핑, 그리고 모의(mock) 모드에서의 API를 다룹니다.
솔직히 부족한 점
- 3B 모델은 세계 챔피언 심사위원이라기보다는 괜찮은 동아리 코치 수준입니다. 측정된 사실들이 이를 정직하게 유지해주지만, 산문 피드백(prose feedback) 부분에서는 더 큰 오픈 모델(또는 실제 투표 용지에 대한 파인튜닝)이 도움이 될 것입니다.
- 실시간 전사(Live transcription)는 브라우저의 Web Speech API를 사용하므로 현재 Chrome/Edge에서만 가능합니다. 로컬 Whisper로 교체하는 것이 당연한 다음 단계이며, 이 역시 오픈 웨이트입니다.
- 실제 구동 과정에서 문제가 된 부분: 이 노트북의 Ollama GPU 러너가 고장 났습니다. 모든 코칭 호출이
CUDA error: shared object initialization failed오류와 함께 실패했기 때문에, 검증된 설정은 CPU 전용 Ollama 서버입니다. 관련하여, gemma3:4b를 CPU에서 구동했을 때 약 1.3 tok/s의 속도를 보였고 (평가 하나에 6분 이상 소요), 이것이 데모에서 qwen2.5:3b-instruct(~3 tok/s로 워밍업 시, 평가당 약 3분 소요)를 사용하는 이유입니다 (비디오는 생각하는 순간을 편집하지 않고 자막으로 처리했습니다.).
나의 에이전트 세션
Confident Speaker Coach: CPU 전용 실행 및 End-to-End 검증
당신
Confident Speaker Coach runbook Part 1: 노트북에서 실행 (저장소 https://github.com/viveknshah/confident-speaker-coach).
에이전트
사전 요구 사항 확인: Docker 29.7.2, Ollama 0.40.3, Node 24 사용 가능; winget을 통해 Git 2.55 설치 및 저장소 클론 완료. 종속성 없는 Node 앱이며, 테스트 4/4 통과.
▸ shell docker --version; ollama --version; node --version; git clone repo; node --te...
입력
$ docker --version; ollama --version; node --version; git clone repo; node --test test/*.test.js
출력
Docker 29.7.2, Ollama 0.40.3, Node v24.19.0; tests 4 pass, 0 fail
에이전트
이미 다운로드된 gemma3:4b로 코치를 시작함. 모든 /api/coach 호출 실패: Ollama 500 CUDA error shared object initialization failed. 데스크톱 앱의 GPU 러너가 이 기기에서 작동하지 않음.
▸ shell OLLAMA_MODEL=gemma3:4b node server.js; POST /api/coach
입력
$ OLLAMA_MODEL=gemma3:4b node server.js; POST /api/coach
출력
502 Bad Gateway; server log: Ollama 500 CUDA error: shared object initialization failed
에이전트
Ollama 트레이 앱을 종료하고, OLLAMA_NUM_GPU=0으로 CPU 전용 서버를 시작했으며, 백그라운드에서 저장소 기본값인 qwen2.5:3b-instruct (1.9 GB)를 다운로드함. Gemma가 CPU에서 관리한 속도는 1.3 tok/s에 불과하여 코칭 판정에는 너무 느림.
▸ shell OLLAMA_NUM_GPU=0 ollama serve; ollama pull qwen2.5:3b-instruct; chat speed pr...
입력
$ OLLAMA_NUM_GPU=0 ollama serve; ollama pull qwen2.5:3b-instruct; chat speed probes
출력
qwen pulled; gemma3:4b 1.3 tok/s on CPU, qwen ~3 tok/s warm
에이전트
qwen을 통한 전체 End-to-End 코칭 라운드 진행: 301단어 Table Topics 연설, 85초 소요. 61/100점 (C35/D11/L15) 반환. 코드 측정 사실(212 wpm fast, 필러 매핑, 전달 페널티 적용)을 포함한 정직한 중간 점수 부여. 약 3분간의 예열 시간이 필요했으므로 데모는 생각하는 멈춤(thinking pause)을 캡처함. 브라우저에서 콘솔 오류 없이 페이지 검증 완료.
▸ shell POST /api/coach full transcript; 브라우저 스냅샷 + 콘솔 확인
Input
$ POST /api/coach full transcript; 브라우저 스냅샷 + 콘솔 확인
Output
scores C35/D11/L15 total 61; length 1:25; footer Model qwen2.5:3b-instruct; no JS errors
5 of 5 messages
시상 부문 (Prize Categories)
전체 심사(overall judging)에만 참가합니다. ElevenLabs는 선택적 음성 업그레이드로 코드에 남아 있지만, 데모는 브라우저 음성을 사용하므로 파트너 카테고리 주장은 하지 않습니다.
Ollama + qwen2.5로 구축되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기