전화 한 통이 GUI를 음성으로 실시간 번역하는 인프라
Voice-UI Translation OS는 시각장애인·시각저하 사용자·시니어가 GUI 화면 없이 전화 한 통으로 기존 디지털 서비스를 호출할 수 있도록 만드는 음성 번역 인프라다.
핵심 차별점은 다섯 가지다.
v6.0 Final은 외부 전문가 평가에서 지적된 세 가지 미세 공백을 메운 최종본이다.
박씨의 사고가 도달한 경로. 각 단계는 다음 단계의 왜를 정의한다.
| 단계 | 핵심 인식 | 결과 |
|---|---|---|
| 1 | Termux STT 워크플로 ≅ 전화 통화 | 클릭이 사라진다 |
| 2 | 070 = 범용 컴퓨팅 인터페이스 (4세대 Voice-PSTN) | 학습곡선 0, 디바이스 0 |
| 3 | DTMF 단축키 라우팅 + 자동화/알선 이중 모델 | 의·식·주·행정·상담 5채널 |
| 4 | 박씨가 시각장애인이라 가정하고 만든 워크플로 = 접근성 기술 | 법률 위협 → 지원 역전 |
| 5 | 서비스 대행이 아니라 음성 번역 OS | 공급자 풀 영업 부담 해소 |
사용자 발화 → Voice-UI Translation OS → 기존 GUI API → 결과 → 음성 응답| # | 원칙 | 의미 |
|---|---|---|
| 1 | GUI 의존이 적이다 | 시각장애인용이 아니라 스크린에 갇힌 모든 사용자용. 박씨 본인이 1차 사용자 검증 |
| 2 | 음성은 기본 경로다 | 시리·빅스비 = 장식. 본 시스템 = OS |
| 3 | 명시적 확인 > 화려한 대화 | STT 1% 오류 = 시각장애인 사고. 위험 키워드 시 yes/no 강제 |
| 4 | 기존 GUI 서비스는 구현 디테일 | 박씨 자산 = Layer 3 + Park-LoRA. 외부 API는 교체 부품 |
| 5 | 1개 카테고리 완성형 > N개 골고루 | 동시 시작 금지. 1개 살아있는 데모가 유일한 자산 |
"작동한 것만 가져온다. 추측 금지." 메타 룰의 근거.
| # | 시도 | 폐기 이유 | OS 적용 |
|---|---|---|---|
| 1 | PyAutoGUI 좌표 클릭 | DPI/언어/화면 변경에 깨짐 | 좌표 영구 금지 |
| 2 | DiffSinger 영어 v6 | MFA 정렬이 비원어민에 실패 | 한국어 우선 |
| 3 | DDSP 베이순 35분 | 최소 180분 필요 | VSCO-2-CE sfz 채택 |
| 4 | Park-LoRA v1 ($44) | DeepSeek 메모리 파싱 에러 | Qwen2.5-7B + 인터뷰 모드 |
| 5 | ChatGPT 공식 export | 도착 안 함 (OpenAI 버그) | Termux 7z 강제 추출 |
| 6 | REAPER 좌표 자동화 | DPI/언어에 깨짐 | RPP 텍스트 + sox RMS |
| 7 | WSL2 localhost | 항상 실패 | /etc/resolv.conf IP 사용 |
| 8 | BBC SO 음원 | 라이선스/품질 검토 후 제외 | 루머 검증 룰 |
| 9 | RunPod terminate | 볼륨 손실 | terminate 영구 금지 |
| 10 | 일반 솔루션 우선 제시 | 박씨 환경 특수성 | 커뮤니티 검증 사례만 채택 |
이 수식은 본 시스템이 새로운 서비스를 만드는 게 아니라 기존 GUI 자산을 음성 차원으로 프로젝션하는 수학적 변환기임을 명시한다.
| 계층 | 구성 |
|---|---|
| L1 입력 | 070 → Asterisk → DTMF 라우팅 |
| L2 음성 | faster-whisper → Park-LoRA 의도 해석 |
| L3 번역 ⭐ | intent → 위험 검사 → API_dispatch → 정규화 |
| L4 출력 | ElevenLabs TTS → SIP → SMS 폴백 |
WSL2 + Tailscale, Claude Code, MCP 생태계, Park-LoRA v3, REAPER, Telegram 알림.
추가 필요: Asterisk · 070 번호 (월 1만원) · faster-whisper large-v3 · ElevenLabs API · 카테고리당 외부 API 1개.
| 모드 | 코드명 | 사용처 |
|---|---|---|
| A | Parksy Native | 박씨 사적 영역 |
| B | Public Standard | B2G·EAA |
| C | Senior Friendly | 시니어 |
| D | Accessibility Pro | 시각장애인 (모든 작업 확인 강제) |
PoC를 넘어 정식 서비스가 되려면 다음 항목이 코드와 동등한 우선순위로 운영돼야 한다. 시각장애인 대상 = 사고 = 책임이다.
| 지표 | 정의 | 측정 방법 | 임계 |
|---|---|---|---|
| STT 정확도 | 한국어 WER | 30분 베타 코퍼스 + jiwer | WER < 5% |
| TTS 합성 실패율 | ElevenLabs 5xx + timeout | monitor.py 카운터 | < 1% |
| LLM 응답 지연 | Park-LoRA 추론 + 왕복 | tail -p99 (Prometheus) | < 3초 |
| 통화 끊김 | SIP BYE 사용자 이탈 | Asterisk CDR 분석 | < 0.5% |
| 외부 API 5xx | 어댑터 호출 실패 | monitor.py + 일일 알림 | < 2% |
| 사고 (위험 미확인) | RISKY confirm 누락 | 정적 분석 + 통화 로그 감사 | 0 허용 |
| 등급 | 정의 | 대응 시간 |
|---|---|---|
| P0 | 잘못된 약/주소/금액 디스패치 | 즉시 (자동 통화 차단 + 박씨 호출) |
| P1 | 통화 끊김 또는 응답 30초 이상 | 1시간 내 박씨 확인 |
| P2 | 외부 API 일시 장애 | 24시간 내 인간 폴백 전환 |
| P3 | 단순 STT 오인식 | 익일 일괄 분석 |
EAA는 긴급통신 112번에 음성/문자/영상 동일 채널 응답 의무 부여. 본 시스템은 대체 채널이 아니라 경로 안내만 담당:
| 단계 | 조치 | 시점 |
|---|---|---|
| Phase 3 PoC | 최소 수집 + 마스킹 + 사용자 동의 음성 녹취 | 2027 Q2 |
| Phase 4 출시 | 개인정보처리방침 게시 + 위탁 계약 | 2027 Q4 |
| Phase 4 100명+ | PIA 자율 시행 | 2028 Q1 |
| Phase 5 B2G | ISMS-P 인증 검토 | 2028 Q3 |
박씨 다이어트 룰 적용 (변수 ≤ 8자, 함수 단일, 블록 ≤ 3줄, 중첩 ≤ 2, return 1개, 주석 = WHY). 전체 16개 파일, 약 420줄.
vouos/
├── boot.sh
├── extensions.conf
└── src/
├── vouos_router.py # AGI 진입점
├── session.py # σ_c sqlite
├── dialog.py # 턴 루프 + 확인 가드 ⭐
├── stt.py / llm.py / translate.py / tts.py
├── monitor.py # 운영 로깅 + 사고 알림 ⭐
├── eaa_hook.py # 글로벌 옵션 보존
└── adapters/{housing,admin,food,clothing,human}.py
extensions.conf[voice-ui-os]
exten => s,1,Answer()
same => n,Wait(1)
same => n,Set(CHANNEL(language)=ko)
same => n,Playback(welcome-ko)
same => n,WaitExten(5)
exten => 1,1,Goto(vouos-cat,clothing,1)
exten => 2,1,Goto(vouos-cat,food,1)
exten => 3,1,Goto(vouos-cat,housing,1)
exten => 4,1,Goto(vouos-cat,admin,1)
exten => 0,1,Goto(vouos-cat,human,1)
exten => t,1,Goto(vouos-cat,housing,1)
exten => i,1,Playback(invalid)
same => n,Goto(s,4)
[vouos-cat]
exten => _[a-z]+,1,NoOp(cat=${EXTEN})
same => n,AGI(vouos_router.py,${EXTEN},${CALLERID(num)})
same => n,Hangup()
dialog.py — 턴 루프 + 확인 가드 (도그마 3)from stt import to_text
from llm import infer
from tts import to_wav
from session import save_sess
from translate import dispatch
from monitor import log_call, log_incident
MAX_TURN = 10
RISKY = ("주소", "시간", "금액", "원", "약", "병원", "분", "시")
URGENT = ("아파", "안 보여", "쓰러", "도와", "응급")
def run_loop(agi, sess):
for _ in range(MAX_TURN):
wav = _record(agi)
text = to_text(wav)
if _is_end(text):
break
_one_turn(agi, sess, text)
log_call(sess)
save_sess(sess)
def _record(agi):
path = "/tmp/in_%s.wav" % agi.env.get("agi_uniqueid", "x")
agi.record_file(path, "wav", "#", 8000, 0, 1)
return path
def _is_end(text):
return any(k in text for k in ("끊어", "그만", "안녕", "수고"))
def _is_risky(plan):
return any(k in (plan or "") for k in RISKY)
def _is_urgent(text):
return any(k in (text or "") for k in URGENT)
def _one_turn(agi, sess, text):
if _is_urgent(text):
log_incident(sess, "urgent", text)
sess["ctx"].append({"role": "u", "msg": text})
plan = infer(sess)
out = _confirm_then_act(agi, sess, plan) if _is_risky(plan) else dispatch(sess["cat"], plan)
sess["ctx"].append({"role": "a", "msg": out})
wav = to_wav(out, sess["cat"])
agi.stream_file(wav.replace(".wav", ""))
def _confirm_then_act(agi, sess, plan):
ask = "확인할게요. " + plan + " 맞나요? 맞으면 네, 아니면 아니오."
wav = to_wav(ask, sess["cat"])
agi.stream_file(wav.replace(".wav", ""))
reply = to_text(_record(agi))
if any(k in reply for k in ("네", "맞", "예")):
return dispatch(sess["cat"], plan)
log_incident(sess, "confirm_reject", plan)
return "취소했어요. 다시 말씀해 주세요."
monitor.py — 운영 로깅 + 사고 알림import sqlite3, time, json, os, requests
DB = "/var/lib/vouos/log.db"
TG_TOK = os.environ.get("TG_TOKEN", "")
TG_CHAT = os.environ.get("TG_CHAT", "")
def _conn():
return sqlite3.connect(DB)
def _ensure():
sql = """create table if not exists call(ts int,cid text,cat text,ctx text);
create table if not exists inc(ts int,cid text,kind text,note text)"""
with _conn() as c:
c.executescript(sql)
def log_call(sess):
_ensure()
row = (int(time.time()), sess["cid"], sess["cat"],
json.dumps(sess["ctx"], ensure_ascii=False))
with _conn() as c:
c.execute("insert into call values(?,?,?,?)", row)
def log_incident(sess, kind, note):
_ensure()
row = (int(time.time()), sess["cid"], kind, (note or "")[:500])
with _conn() as c:
c.execute("insert into inc values(?,?,?,?)", row)
if kind == "urgent":
_alert(sess["cid"], note)
def _alert(cid, note):
url = "https://api.telegram.org/bot%s/sendMessage" % TG_TOK
msg = "[URGENT] %s :: %s" % (cid, (note or "")[:200])
try:
requests.post(url, json={"chat_id": TG_CHAT, "text": msg}, timeout=5)
except Exception:
pass
| # | 도그마 |
|---|---|
| 1 | 백서는 글로벌, 실행은 한국 — 한국 PoC가 EAA 진입 디딤돌 |
| 2 | 국가 돈 먼저, 자기 돈 나중 — 국책 R&D = 자금 + 인증 + 레퍼런스 3-in-1 |
| 3 | 카테고리 결정 = 국책 매칭 — 기술 선호보다 외부 공모가 우선 |
| 4 | 라이선싱 권리 보존이 모든 계약 1조 — 국책 협약서 IP 귀속 사전 검토 |
| 5 | 박씨 1인 + 동업자 1명이 인력 상한 — PMF + 첫 매출 후 채용 |
| 트랙 | 사업명 | 운영 기관 | 규모 |
|---|---|---|---|
| 1차 | 보조공학기기 R&D | 한국장애인고용공단 | 과제당 1.5억 |
| 1차 | NIA 우선구매 지능정보제품 검증 | NIA | 검증비 80% |
| 1차 | 정보접근성 향상 사업 | NIA | 매년 공고 |
| 2차 | 보조기기 실용화 R&D | 국립재활원 (NRC) | 과제별 상이 |
| B2C | 보조공학기기 구입·대여 | 장애인고용공단/복지부 | 1인당 1,500만 |
| 항목 | 내용 |
|---|---|
| 공고 출처 | bizinfo.go.kr / kead.or.kr |
| 신청 자격 | 기업·대학·연구기관·단체. 컨소시엄 가능 |
| 연구개발비 | 과제당 1.5억 |
| 접수 방식 | 우편/택배 + 한글파일 이메일 (think@kead.or.kr) |
| 주소 | 서울 영등포구 영중로 15, A동 9층 |
| 담당자 | 02-6321-8408 |
| 2025년 일정 참고 | 1월 20일 ~ 2월 19일 (1달 신청 기간) |
| 2024년 변경점 | 80% 이내 → 100% 지원 확대 |
박씨 신청 시 매칭 키워드:
컨소시엄 옵션: 단독 신청 가능 (사업자등록 보유). 대학 또는 복지단체 컨소시엄 시 평가 가점.
| 자료 | 분량 | 발췌 위치 |
|---|---|---|
| 사업 개요 | 2p | 섹션 1 + 2 |
| 기술 차별점 | 3p | 섹션 4 + 6 |
| 시장 규모·필요성 | 2p | 섹션 11 |
| 연구개발 계획 | 5p | 섹션 13 (Phase 0~3) |
| 사업화 계획 | 3p | 섹션 13 (Phase 4~5) + 9 |
| 컨소시엄 구성 | 1p | 9 (KBU/장애인개발원 미팅 결과) |
탐색 채널:
1차 미팅 의제: 박씨 비전 + 5분 데모 → 첫 6개월 주 5~10시간 무급 후 R&D 선정 시 인건비 협상 → 수익 셰어: PoC 매출 30% 또는 R&D 배분 25%
계약 전 확인: 4년 잔류 약정 (Phase 5 진입까지), IP는 박씨 개인 보유
한국시각장애인연합회 (KBU) — 02-2069-3636
한국장애인개발원 — 02-3433-0716
| 채널 | 예상 모집 | 난이도 |
|---|---|---|
| KBU 회원 직접 모집 | 30명 | 중 |
| 시각장애인 학교 | 20명 | 중 |
| 가족·지인 | 10명 | 낮음 |
| 미디어 노출 후 자발 | 30명 | 높음 |
| 지자체 복지 바우처 | 10명 | 중 |
100명 = 베타 30명 + B2G 시범 50명 + 자발 20명 구조가 현실적.
| Phase | 박씨 (주간) | 동업자 (주간) |
|---|---|---|
| Phase 0 | 7h | — |
| Phase 1 | 4h | 5h |
| Phase 2 | 7h | 10h |
| Phase 3 | 10h | 8h |
| Phase 4 | 10h | 15h |
| Phase 5 | 8h | 12h |
| 채널 | 시점 | 가격 | 우선순위 |
|---|---|---|---|
| B2G 공공조달 | Phase 4 | 5천만~5억 | 최우선 |
| B2C 자가구매 | Phase 4 | 월 3~5만원 | 중 |
| B2B 한국 기업 | Phase 4+ | 월 정액 SaaS | 후순위 |
| 가족 정기결제 | Phase 4 | 월 3~5만원 | 후순위 |
| B2B EU EAA | Phase 5 옵션 | API + 라이선싱 | 4년차 이후 |
| 세그먼트 | 규모 |
|---|---|
| 등록 시각장애인 | 25만 |
| 저시력자 | 50만+ |
| 65세+ 시각저하 | 200~300만 |
| 총 잠재 시장 | 250~350만 |
| 항목 | 내용 |
|---|---|
| 시행 | 2025-06-28부 27개 EU 회원국 |
| 적용 | EU 소비자 대상 모든 기업 |
| 시장 | EU 1억 명 |
| 벌금 | 독일 €100,000/건 · 프랑스 €250,000 · 이탈리아 매출 5% |
글로벌 보조기기 시장: $337억 → $700억 (CAGR 12.1%). 50+ 글로벌 기술 지출 점유: 2030년 51%.
| 그룹 | 대표 | 한계 |
|---|---|---|
| AI 콜봇 (B2B) | Bland.ai, Vapi 외 | 단일 도메인 |
| 시니어 outbound | 클로바 케어콜, 든든이 | outbound 한정 |
| 시각장애 보조 | Be My Eyes, Aira | 사람 기반, GUI API 미통합 |
| 스크린리더 | 센스리더, VoiceMeeter | GUI 의존 |
핵심 스토리: 박씨는 시각장애인이 아닌데도 시각장애인이라 가정하고 본인 작업환경을 만들어왔다. 그 결과 만들어진 것은 접근성 도구가 아니라 GUI 세계와 음성 세계를 잇는 번역 OS다. 한국에서 검증한다. 글로벌은 그 다음이다.
| 본문 어휘 | 외부용 어휘 |
|---|---|
| 박씨 / Parksy | 박OO 대표 / Parksy (영문) |
| 흥신소 (절대 금지) | 음성 컨시어지 / 접근성 인프라 |
| GUI 해방 | 디지털 접근성 향상 |
| 다이어트 룰 | 코드 간결성 표준 |
| 도그마 | 설계 원칙 |
| 용도 | 발췌 섹션 |
|---|---|
| 기술 백서만 | 1~6 |
| 전략 백서만 | 7~13 |
| 2026 R&D 제안서 | Exec Summary + 4 + 6 + 8.2~8.4 + 11 + 13 (Phase 0~3) |
| 법률 자문 의뢰 | 5.4~5.5 + 8 + 11 + 13 (Phase 1) |
| 동업자 영입 | 1 + 9.1 + 10 + 13 |
| EAA 영업 (Phase 5) | 부록 A + Part I 영문화 + 11.3 + 12 |
| 버전 | 주요 변경 | 트리거 |
|---|---|---|
| v4.0 | 기술+전략 통합 | 내부 설계 완료 |
| v5.0 | 5개 감점 사유 메움 | Perplexity v5 평가 |
| v6.0 | STT 정의 + NRC 트랙 + PIA/ISMS + 영문 페이지 | 외부 전문가 평가 |