← 노하우 목록

FROM THE WORKSHOP / 노하우

자비스 제작기 2 — 호출 누락, 종료 확인, 원격 전원 켜기를 실사용으로 다듬기

영어 Jarvis 호출 누락과 짧은 음성 보정, 종료 확인·취소 오인식, 상태등, 빠른 시작으로 달라진 WOL을 실사용으로 다듬었다. 코드 통과·실제 재생·사용자 확인을 분리하고 v1.1.0 릴리스와 연결한다.

강대종 · 마이너스베타스튜디오

자비스 제작기 2 — 호출 누락, 종료 확인, 원격 전원 켜기를 실사용으로 다듬기

2026-09-24 · Mac 음성 비서 운영 기록

전날에는 Mac 마이크에서 들어온 질문을 Google Nest로 돌려주는 왕복을 만들었다. 오늘은 실제로 부르고, 기기를 켜고, 일을 마치는 과정에서 생긴 실패를 고쳤다. 호출 효과음이 났다는 사실과 기기가 실제로 움직였다는 사실을 따로 확인하는 것이 핵심이었다.

이전 제작기 · 공개 소스 · v1.1.0 릴리스

오늘 연결한 기능

기능동작확인한 범위
호출“자비스” 또는 영어 “Jarvis”, 접수 효과음 뒤 후속 명령영어 실제 호출 1회와 사용자 청취 확인
스마트기기로컬 별칭과 정해진 명령으로 제어선풍기 켜짐 사용자 확인
날씨설정한 기본 지역을 실시간 조회해 한국어로 응답실제 스피커 응답 사용자 청취 확인
상태등파랑 → 초록 → 노랑 → 꺼짐, 최저 밝기색상·밝기 사용자 확인
“일하자”Mac 두 대 밝기 6/16, Windows 두 대 WOL 요청Mac 값 실측, PC별 켜짐 확인; 전체 실음성 루틴 확인은 별도
“일 끝”확인 질문 후 새 “예/네”를 받아 밝기 0과 정상 종료 요청확인·취소 로직과 실제 스피커 경로; 해당 시험에서 PC 종료는 실행하지 않음

개인 기기 이름·주소·인증 정보는 공개 코드와 이 글에 넣지 않았다. 다른 환경에서는 자신의 기기와 명령을 별도로 연결해야 한다.

1. “민감도를 올리면 된다”는 첫 가설만으로는 부족했다

마이크 입력 음량은 80%였다. 100%로 올렸지만 사용자는 세 번 중 한두 번만 효과음이 들린다고 했다. 이어 네이티브 앱의 감지 기준을 조정했다.

항목이전조정 후
음성 감지 하한-42 dB-48 dB
주변 소음 대비 기준+10 dB+8 dB
최소 음성 길이250 ms180 ms
발화 앞부분 보존250 ms350 ms

낮은 문턱은 작은 소리를 더 받아들이지만 주변 소음도 늘릴 수 있다. 그래서 호출어 판별을 느슨하게 넓히지는 않았다. 이 값은 한 환경에서 조정한 실험값이지 모든 방과 마이크의 권장값이 아니다.

새 네이티브 앱으로 바뀌자 macOS가 마이크 권한을 다시 물었다. 코드가 설치됐어도 권한을 허용하기 전에는 들을 수 없었다. 허용 뒤 마이크·오디오 엔진·컨트롤러가 모두 정상인지 확인했다.

2. 영어 이름보다 짧은 음성 클립이 문제일 수도 있다

감지 기준을 낮춘 뒤에도 영어 호출은 실패했다. 모델을 바로 교체하는 대신, 설치된 모델에 짧은 영어 “Jarvis” 샘플을 넣어 비교했다. 두 영어 목소리와 한국어 샘플이 너무 짧은 조건에서는 빈 전사를 반환했고, 앞뒤에 무음을 붙이면 호출어가 나타났다.

중간 보정도 다시 확인했다. 앞 150 ms를 붙이고 총 길이를 2초로 맞춘 방식에서는 한 목소리가 “차비스”로 바뀌었다. 처음 비교에서 성공한 앞 350 ms·뒤 1초의 고정 무음으로 맞춘 뒤 두 영어 목소리가 각각 “자비스”, “Jarvis”로 인식됐다.

최종 구현은 2초 미만 클립에만 이 무음을 붙인다. 원래 말소리 바이트는 바꾸지 않으며, 기존 모델·한국어 설정을 유지한다. 호출어를 억지로 출력하게 하는 프롬프트도 넣지 않았다. 무음 보강은 파일 처리이므로 사용자가 그만큼 더 기다려 말할 필요는 없다.

이후 사용자가 영어로 부르고 효과음을 들었다고 확인했다. 같은 시점의 성공 기록은 음성 입력 종료부터 접수음 재생까지 약 1.10초였다. 이는 실제 영어 호출 1회의 성공이다. 세 번 모두 성공했다거나 장기 인식률이 100%라는 뜻은 아니다. 합성 음성 성공만으로 사용자의 발음 문제까지 해결했다고 보고하지 않은 이유다.

3. 자주 쓰는 명령은 로컬 코드가 처리한다

날씨·스마트기기·작업 루틴은 정해진 의도로 분류되면 Python 코드로 실행한다. 모델에 매번 “무슨 일을 할지” 묻지 않고, 사용자 발화에서 임의 셸 명령을 만들어 실행하지도 않는다. 기기별 인자는 개인 설정의 신뢰된 목록에서 가져온다.

이렇게 하면 해당 경로의 언어 모델 호출을 줄일 수 있다. 다만 이날 전체 토큰 절감률을 측정하지 않았으므로 몇 퍼센트 절약했다고 수치로 말하지는 않는다. 일반 질문은 기존 답변 경로에 남고, 지원하는 근거가 없으면 추측하지 않는다.

날씨는 사용자가 정한 기본 지역을 Open-Meteo에서 조회한다. 날짜·단위·데이터 시각을 검증하고, 예보를 실내 센서 측정값처럼 표현하지 않는다. 지원하지 않는 지역이나 조회 실패를 기본 지역 결과로 조용히 바꾸지 않는다.

4. 종료는 질문과 승인을 분리했다

“일하자”는 바로 준비 동작을 요청하지만, “일 끝”은 두 PC의 종료를 포함한다. 따라서 별도의 확인을 둔다.

  1. “자비스, 일 끝” → “오늘의 작전을 종료할까요?”
  2. 질문 재생이 끝난 뒤 12초 안에 새로 말한 “예/네”만 승인한다.
  3. 승인되면 **“작전 종료 절차를 시작합니다.”**라고 안내한다.
  4. “아니요”, 다른 답변, 시간 초과는 취소한다. 취소 응답은 **“작전 종료 취소. 대기하겠습니다.”**다.

질문 없이 한 “예”, 질문이 끝나기 전에 이미 녹음된 음성, 질문 재생 실패, 앱 재시작, 중복 “예”는 실행 권한을 만들지 않는다. 승인 상태는 실행 전에 소모한다. Windows에는 강제 종료 옵션 없이 정상 종료를 요청한다.

시작 멘트는 **“작전 개시. 시스템 기동을 요청했습니다.”**로 맞췄다. 멋있는 문구라도 WOL 송신을 부팅 완료로 바꾸어 말하지 않는다. 종료 때는 사용자가 원하지 않은 Mac 밝기 상태 안내를 빼되, 내부 성공·실패 기록과 Windows 종료 요청 문제 안내는 보존했다.

5. “근거가 없어 답하기 어렵다”는 말은 경로를 잘못 탄 증상일 수 있다

사용자는 “취소”라고 했는데 일반 질문용 근거 부족 안내가 나왔다. 최신 기록에서는 **“치솔 치솔”**로 전사돼 있었다. 또 “일 끝”을 말한 경우에는 **“끝!”**만 인식돼 같은 일반 답변 경로로 넘어갔다.

해결은 일반 모델을 더 설득하는 일이 아니었다. 이미 확인된 짧은 표현을 로컬 의도로 연결했다.

  • 정확한 “끝”도 호출어 또는 호출 대기를 통과했다면 종료 확인 질문으로 연결한다.
  • “취소”, 반복한 취소, 관측된 취소 오인식은 실행 권한을 없애는 쪽으로만 처리한다.
  • “끝내지 마”, “회의 끝”처럼 다른 문장은 부분 문자열만 보고 종료 요청으로 분류하지 않는다.
  • “예/네” 승인 조건은 넓히지 않는다.

확인 질문을 더 잘 띄우는 것과 실제 종료를 더 쉽게 허용하는 것은 별개의 변경이다. 이 구분을 테스트로 남겼다.

6. 상태등은 눈에 보이는 접수 확인이다

상태등은 파랑으로 호출 인식을, 초록으로 후속 입력 대기를, 노랑으로 처리를 알린다. 밝기는 최소로 맞추고, 평상시에는 꺼지게 했다. 종료 후 흰색 모드로 돌아가지 않는다.

전구 제어에는 한 가지 함정이 있었다. 색·모드·전원을 묶어 보냈을 때 일부 값이 반영되지 않거나 다른 값이 바뀌었다. 실제 장치 값을 읽어 보며 색·밝기, 모드, 전원 순서를 분리했다. 복구 시 사용자가 직접 바꾼 상태까지 덮어쓰지 않도록 소유한 상태를 대조한다. 기기 제어 명령 전에는 표시등 제어를 해제해 명시적인 조명 명령을 취소하지 않게 했다.

스피커 재생도 성공 상태와 사용자 청취를 따로 봤다. 오디오 오류 복구는 음성만 재전송하고, 가전 명령까지 다시 실행하지 않게 했다.

7. WOL은 “전송 성공”과 “PC가 켜졌다”를 나눠야 한다

한 Windows PC는 전날 검증한 WOL 경로로도 켜지지 않았다. 릴레이 Mac의 내부망 인터페이스와 목적지 설정은 같았고, 사용자는 전원과 랜선이 연결됐지만 꺼진 PC의 랜포트 불빛이 없다고 했다. 불빛만 보고 랜선이나 BIOS가 원인이라고 단정하지 않았다.

수동 부팅 후 랜카드의 Magic Packet, PME, 깨우기 허용은 켜져 있었다. 빠른 시작도 켜져 있었고, 전날 시험과 이번 부팅의 Windows 이벤트 유형이 달랐다. Microsoft의 WOL 설명도 빠른 시작의 종료 상태와 일반 종료를 구분한다.

사용자 관리자 승인 후 빠른 시작 값만 1에서 0으로 바꾸고 이전 값을 백업했다. 실행 중이던 앱이 있었으므로 먼저 작업이 없는지 확인하고 종료·켜기 시험 승인을 받았다. 이후 다음 경로를 검증했다.

정상 종료 → SSH 실패 → 내부망 WOL 1회 → 새 부팅 시각·호스트명·SSH 복귀 → 사용자 자동 켜짐 확인

송신기가 두 네트워크에 연결돼 있다면 기본 브로드캐스트가 어느 인터페이스로 나가는지도 확인해야 한다. 이번에는 이미 검증된 내부망 경로를 유지했고, 빠른 시작 변경 뒤 실제 켜짐을 확인했다. 이것을 모든 메인보드·종료 상태에서의 WOL 보장으로 일반화하지 않는다.

코드·재생·실제 사용 결과를 따로 남긴다

이날 확인은 네 층으로 나눴다. 코드 검사와 빌드, 설치 파일과 실행 상태, 실제 스피커·장치 경로, 사용자 청취와 물리 동작이다. 인식 문장을 주입해 제어기와 Nest를 검증한 시험은 사용자 마이크 시험이라고 부르지 않았다. 모의 기기 결과를 넣은 종료 검사도 실제 PC를 껐다고 기록하지 않았다.

공개 릴리스에는 설치 스크립트와 소스만 들어간다. 개인 설정, 모델 파일, 인증 정보는 포함하지 않는다. 현재 버전의 기능과 설치 조건은 v1.1.0 변경 내역에서 확인할 수 있다. “일하자” 전체 동작을 실제 음성으로 확인하는 항목은 이 기록 시점에 별도 확인 대기로 남겼다.

기록은 다음 시작이 됩니다.노하우 더 읽기 ↗이 작업장의 제품 ↗
작업장 전체 페이지 목적에 맞는 페이지 찾기