원문 캡처 · github.com
원문 캡처 · github.com

Hey Spark는 노트북에서 항상 대기하다가 음성으로 질문이나 명령을 받는 오픈소스 비서다. 깨우기 단어 감지와 음성 인식·합성은 CPU에서 로컬로 처리하고, 답변을 만드는 두뇌는 Claude, Hermes Agent 또는 OpenAI 호환 모델 중에서 고를 수 있다. 프로젝트 저장소

“Hey Spark”라고 부르면 음성으로 질문하거나 명령할 수 있다. 예를 들어 내일 일정 확인, 10분 타이머 설정, 저장소의 열린 풀 리퀘스트 요약을 요청할 수 있다. 새 프로젝트를 만들 때는 폴더와 Git 저장소, 비공개 GitHub 저장소를 만들겠다고 먼저 설명하고 사용자의 음성 확인을 기다린다.

깨우기 단어 모델 openWakeWord, 음성 인식 faster-whisper, 음성 합성 Piper 또는 Kokoro를 로컬에서 CPU로 실행한다. Deepgram과 ElevenLabs는 선택 가능한 클라우드 백엔드다. 두뇌는 Claude Agent SDK, Hermes Agent, OpenAI·Azure OpenAI·OpenRouter·Groq·Together 등의 OpenAI 호환 API, 또는 Ollama·LM Studio·vLLM 같은 로컬 서버에서 선택한다. 설정 파일 config.yaml에서 깨우기 단어, 음성 인식·합성, 두뇌 백엔드를 바꿀 수 있다.

MCP 서버를 통해 GitHub, Gmail, Calendar 및 사용자가 구성한 시스템에 연결한다. 읽기 전용 도구는 바로 실행하지만, 메시지 전송·생성·수정처럼 상태를 바꾸는 도구는 실행할 내용을 말한 뒤 매번 음성으로 “예”라는 확인을 받아야 한다. 삭제 등 파괴적인 도구는 기본적으로 차단되며, 허용되지 않은 도구도 실행하지 않는다.

설치와 시작

데스크톱 앱은 Apple Silicon을 탑재한 macOS 14 이상과 Windows 11을 지원한다. Intel Mac과 Linux에서는 소스 코드로만 사용할 수 있으며, 이 환경은 테스트되지 않았다. CPU로 실행하므로 GPU는 필요하지 않다. 모델을 위한 디스크 공간은 약 1GB, 첫 실행 때 내려받는 음성 모델은 약 200MB다. 마이크와 두뇌용 계정 또는 API 키도 필요하다. 로컬 Ollama를 사용할 수도 있다. 에코 제거 기능이 있는 USB 스피커폰을 권장한다.

앱은 Releases에서 내려받는다. 각 파일 옆에는 .sha256 체크섬이 제공된다. macOS에서는 HeySpark-<version>-macos-arm64.dmg를 열어 앱을 Applications로 옮긴다. macOS가 앱을 확인할 수 없다고 알리면 시스템 설정의 개인정보 보호 및 보안에서 ‘Open Anyway’를 선택하거나 터미널에서 다음 명령을 한 번 실행한다.

bash
xattr -dr com.apple.quarantine /Applications/HeySpark.app

마이크 접근을 허용해야 한다. 설정, 로그, 모델과 .env 파일은 ~/Library/Application Support/HeySpark에 저장된다. Windows에서는 HeySpark-Setup-<version>.exe를 실행한다. 설치는 사용자별로 진행되며 관리자 권한은 필요하지 않다. 설치 프로그램은 아직 코드 서명을 받지 않아 Windows SmartScreen 경고가 나타날 수 있으며, 이때 ‘More info’와 ‘Run anyway’를 선택한다. 파일은 %LOCALAPPDATA%\HeySpark에 저장된다.

두 플랫폼 모두 앱의 두뇌 버튼에서 제공자를 선택해 키를 입력하거나 Ollama를 고른 뒤 Start를 누른다. 음성 모델을 처음 내려받은 다음 “Hey Spark”라고 부르면 된다.

소스에서 실행하려면 Python 3.11을 관리하는 uv를 설치하고 다음 명령을 사용한다.

bash
# 1. Install uv (https://docs.astral.sh/uv/); it manages Python 3.11 for you
git clone https://github.com/contextuai/hey-spark.git
cd hey-spark
uv sync --all-extras # plain `uv sync` skips the optional backends

# 2. Download the speech models into ./.models (about 200 MB)
uv run spark models download

# 3. Add your brain's key
cp .env.example .env # (Windows: copy) then set your key; see "Choose a brain"

# 4. Check everything, then talk to it
uv run spark doctor # every required check should show ✔
uv run spark # say "Hey Spark, what's the capital of Japan?"

마이크가 없어도 uv run spark --text로 질문을 입력하고 답변을 읽을 수 있다. uv run spark --brain mock --text는 키 없이 완전히 오프라인으로 실행한다.

두뇌별 준비 조건과 용도는 다음과 같다.

두뇌준비 조건적합한 용도
Claude(기본값)Claude Code에 로그인하거나 .env에 ANTHROPIC_API_KEY 설정제작자는 도구 사용과 커넥터 작업에 적합하며, 연구 하위 에이전트와 빠른/심층 모델 라우팅을 지원한다고 설명한다.
Hermes AgentHermes Agent의 API 서버와 API_SERVER_KEYHermes Agent 자체의 모델·도구·메모리·기능을 음성으로 사용
OpenAI 호환 클라우드(OpenAI, Azure, OpenRouter, Groq, Together)제공자의 키와 brain.backend: openai_compat이미 보유한 모델이나 계정 사용
로컬(Ollama, LM Studio, vLLM)서버를 실행하고 qwen2.5:7b 같은 도구 사용 가능 모델을 가져오기faster-whisper와 Piper를 함께 사용하면 기기 밖으로 데이터가 나가지 않음

데스크톱 앱의 Brain 창에서 제공자를 바꾸고 연결 및 모델의 도구 호출 가능 여부를 확인할 수 있다. 제공자별 설정은 docs/openai_brain.md에 있다. Claude에서는 brain.mode를 auto로 설정하면 빠른 요청은 brain.fast_model, 큰 요청은 brain.deep_model로 보낸다. deep은 모든 요청에 심층 모델을 쓰고 도구를 많이 쓰는 조회를 더 빠른 모델의 연구 에이전트에 맡긴다. 프로젝트 설명은 이 설정이 답변 품질을 높이는 대신 API 비용이 가장 많이 든다고 밝힌다. 음성으로 “use the deep model”, “back to auto”라고 바꿀 수도 있다.

음성 사용과 연결 도구

기본 깨우기 단어 모델은 assets/wakewords/hey_spark.onnx에 포함돼 있어 별도 설정이 필요 없다. 잘 반응하지 않거나 저절로 깨어나면 wakeword.options.openwakeword.threshold를 조정한다. Google Colab의 무료 GPU로 녹음 데이터 없이 약 한 시간 동안 원하는 문구의 모델을 학습하는 노트북도 제공한다. 학습 노트북과 설정 안내에서 절차와 Porcupine 대안을 확인할 수 있다.

답변 뒤에도 3분 동안(attention.awake_s) 대기해 깨우기 단어 없이 후속 질문을 받을 수 있다. Spark는 자신을 향한 말에만 답하고, 대기 시간이 끝나면 짧은 소리를 낸다. “new topic”, “go to sleep”, “never mind”, “mute yourself” 같은 명령도 지원한다. 음소거하면 창의 마이크 버튼을 누를 때까지 듣지 않는다. “stand down”, “belay that”, “clean slate protocol”, “full power”, “go dark” 같은 표현도 사용할 수 있다.

app.barge_in: true로 설정하면 Spark가 말하는 중에도 깨우기 단어로 말을 끊을 수 있다. 에코 제거 스피커폰을 사용할 때만 이 기능을 켜도록 안내한다. 깨울 때는 차임, 처리 중에는 짧은 소리, 오류가 나면 낮은 음을 낸다. 기본 말투는 짧고 담백하다. Personality & Voice 창에서 영국식 집사 성격과 영국식 음성을 선택할 수 있으며, 이 설정에서는 “sir”라고 부르고 깨우기 단어에 “Yes, sir?”라고 답한다. 성격과 음성 설정을 참고하면 된다.

각 연결 시스템에 대한 편집 가능한 Markdown 메모를 저장하며, “good morning” 같은 짧은 말을 상세 프롬프트에 연결하는 바로 가기도 지원한다. 기본 제공 바로 가기는 15개로, “rise and shine”, “what’s next?”, “sitrep”, “check the post”, “run a diagnostic”, “house party protocol” 등이 있다. 명령 안내에서 확인할 수 있다.

새 프로젝트를 요청하고 확인하면 projects.root_dir/weather-bot에 폴더와 Git 저장소, 첫 커밋을 만든다. 사용자 gh 로그인으로 비공개 GitHub 저장소와 추적 이슈도 만들지만, 원격 저장소로 푸시하지는 않는다. 폴더에서 Claude Code를 열 수도 있다. 타이머 설정·조회와 현재 시각 확인도 음성으로 요청할 수 있다.

커넥터는 mcp_servers.json에 MCP 서버로 정의하며 ${VAR} 자리표시자만 사용할 수 있다. 값은 .env에서 가져온다. 직접 추가하거나 데스크톱 앱의 Connectors 창에서 설정할 수 있다. 서버별 도구 정책은 config.yaml의 connectors:에 둔다.

  • allowed_tools는 읽기 전용 도구로, 사전 승인돼 바로 실행된다.
  • side_effecting 도구는 매번 음성 확인을 받아야 한다. Spark가 수행할 일을 한 문장으로 말한 뒤 기다리며, 침묵하거나 답이 명확하지 않거나 “아니오”라고 하면 실행하지 않는다.
  • destructive 도구는 해당 서버에 allow_destructive: true를 설정하지 않는 한 차단된다.
  • 이 목록 어디에도 포함되지 않은 도구는 거부된다.

GitHub를 연결할 때는 Spark가 접근할 저장소에 한정한 fine-grained token을 만든다. 권한은 이슈 읽기 및 쓰기, 풀 리퀘스트 읽기, 콘텐츠 읽기로 설정한다. Connectors 창에서 설정의 github 항목을 편집하고 ${SPARK_GITHUB_PAT}을 토큰으로 바꾼 뒤 Save and test를 누르면 Spark가 토큰을 .env로 옮긴다. 연결 설정은 다음과 같다.

json
{ "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/", "headers": { "Authorization": "Bearer YOUR_TOKEN" } } }

연결을 켜면 GitHub의 도구 분류를 따른다. 읽기는 바로 실행하고, 이슈 생성은 먼저 확인을 요청하며, 삭제는 차단한다. 프로젝트는 GitHub가 호스팅하는 공식 github-mcp-server를 사용한다. GitHub 문서에 따르면 호스팅 서버를 이용하려면 Copilot 접근 권한이 필요하며 Copilot에는 무료 요금제가 있다. 계정이 거부되거나 서버를 직접 실행하려면 커넥터 안내를 참고한다. 토큰 자체를 붙여 넣어야 한다. GitHub의 VS Code 예제에서 쓰는 ${input:...}은 VS Code 프롬프트이므로 Spark에서는 표시할 수 없다.

Connectors 창의 Add connectors에서 MCP 서버의 JSON(mcpServers 블록)을 붙여 넣거나 Claude Desktop 서버를 한 번에 가져올 수 있다. 커넥터 안내는 mcp_servers.json과 config.yaml을 이용한 수동 설정 및 Composio를 통한 Gmail, Google Calendar, Outlook 연결을 설명한다. claude.ai의 Gmail 및 Calendar 커넥터는 기본적으로 꺼져 있다. 사용자의 Claude CLI에서 claude.ai 계정으로 로그인해야 작동하므로 개인 설정용이다.

개인정보와 설정

깨우기 단어를 감지하기 전에는 오디오가 기기 밖으로 나가지 않는다. --debug-audio를 사용하지 않는 한 오디오를 저장하지도 않는다. 깨운 뒤에는 선택한 두뇌에 요청 텍스트를 보낸다. 음성은 로컬에서 텍스트로 변환하며, Deepgram을 선택한 경우에는 예외다. 오디오는 클라우드 음성 인식 백엔드를 선택할 때만 기기 밖으로 나간다.

비밀 값은 .env 또는 환경 변수에만 보관한다. 로그에는 비밀 값과 일반적인 토큰 형식을 가리는 필터가 적용된다. 대화 기록(logs/transcripts.log)과 활동 기록(history/)은 기기에 저장되며 기기 밖으로 전송되지 않는다. 대화 기록은 logging.transcripts: false로 끌 수 있고, 활동 기록은 config.yaml의 activity: 설정에서 확인할 수 있다. 로그는 사용자가 읽고 삭제할 수 있다.

모든 설정은 주석이 포함된 config.yaml에 있다. 환경 변수(SPARK_<SECTION>__<KEY>)나 명령줄 옵션으로 실행할 때 설정을 덮어쓸 수 있다.

yaml
wakeword: { backend: openwakeword } # openwakeword | porcupine
stt: { backend: faster_whisper } # faster_whisper | deepgram
tts: { backend: kokoro } # kokoro | piper | elevenlabs | print
brain: { backend: claude_agent } # claude_agent | openai_compat | mock

$env:SPARK_STT__BACKEND = "deepgram"; uv run spark
uv run spark --stt deepgram --tts kokoro

주요 명령은 다음과 같다.

bash
All commands
uv run spark # voice mode
uv run spark --text # type questions, print answers (no audio devices)
uv run spark --text --speak # type questions, hear answers
uv run spark --no-tts # voice in, printed answers out
uv run spark --debug-audio # also save the last utterance to debug_audio/
uv run spark -v # debug logging (shows tool calls by name)
uv run spark desktop # the desktop window
uv run spark doctor # environment checks, each with a fix
uv run spark models download # whisper + the configured voice (Kokoro George by default)
uv run spark bench stt|tts|brain # latency benchmarks (median / p90)
uv run spark bench latency # live: wake word to first audio, end to end
uv run spark bench false-wake --minutes 30 # live: count false wakes on background audio

요청별 지연 시간 분석은 logs/latency.jsonl에 추가된다. spark bench stt|tts|brain은 중앙값과 p90 지연 시간을 측정하고, spark bench latency는 깨우기 단어부터 첫 음성까지와 전체 처리 시간을 실시간으로 잰다. spark bench false-wake --minutes 30은 배경 오디오에서 잘못 깨어나는 횟수를 측정한다.

지원 환경과 라이선스

환경지원 범위
macOS 14 이상, Apple Silicon데스크톱 앱(.dmg)과 소스 실행. 각 빌드는 CI에서 자체 테스트를 거친다. 0.1.0에서 추가된 지원이므로 이상 사항을 제보해 달라고 안내한다.
Windows 11데스크톱 앱 설치 프로그램과 소스 실행. Hey Spark를 개발한 플랫폼이며 WASAPI 오디오를 사용한다.
Intel Mac, Linux소스 실행만 가능하며 테스트되지 않았다. Python 코드는 크로스 플랫폼이고 제보와 풀 리퀘스트를 받는다.

앱은 macOS에서 Xcode 명령줄 도구를 설치한 뒤 bash scripts/build_macos.sh로 빌드한다. 앱을 build/dist/HeySpark.app으로 묶고 임시 서명과 자체 테스트를 수행한 다음 build/installer/HeySpark-<version>-macos-arm64.dmg를 만든다. Developer ID 서명과 공증을 하려면 MACOS_SIGN_IDENTITY와 APPLE_ID, APPLE_TEAM_ID, APPLE_APP_PASSWORD를 설정한다.

Windows에서는 다음 명령으로 빌드한다.

powershell
powershell -ExecutionPolicy Bypass -File scripts\build_windows.ps1

앱은 build\dist\HeySpark\HeySpark.exe로 묶인다. Inno Setup 6을 설치하면 설치 프로그램 build\installer\HeySpark-Setup-<version>.exe도 만든다. 설치는 winget install JRSoftware.InnoSetup으로 할 수 있다. 릴리스는 GitHub Actions에서 빌드하며, 데스크톱 앱이나 패키징을 변경하는 풀 리퀘스트에서도 두 플랫폼 앱을 빌드한다.

오프라인 테스트는 다음 명령으로 실행한다. 가짜 구성 요소와 합성 오디오를 이용하며 약 1분이 걸린다. 실시간 테스트는 실제 Claude 또는 클라우드 API를 호출하므로 키가 필요하다.

bash
uv run pytest -q # offline suite: fakes and synthesized audio, about a minute
uv run pytest -q -m live # hits real Claude / cloud APIs (needs keys)
uv run ruff check . && uv run ruff format --check .

프로젝트 설명에 따르면 각 구성 요소는 spark/interfaces.py의 추상 클래스로 정의하고 spark/registry.py가 config.yaml의 백엔드 이름을 구현에 연결한다. spark/app.py는 상태 기계다. 백엔드 추가와 테스트, 풀 리퀘스트 제출 방법은 CONTRIBUTING.md, 최초 설계 문서는 docs/design/SPEC.md에 있다. 실제 마이크가 필요한 하드웨어 점검은 docs/dev/MANUAL_QA.md에서 설명한다. Hey Spark는 Claude Code로 만들었으며 에이전트와 스킬은 .claude/, 단계별 계획과 보고서는 docs/dev/history에 있다.

코드는 Nagendra Rao Jogi의 MIT 라이선스다. 다만 포함된 깨우기 단어 모델 assets/wakewords/hey_spark.onnx는 학습 데이터의 라이선스가 혼합돼 있어 비상업적 이용 조건인 CC BY-NC-SA 4.0을 별도로 따른다. 상업적으로 사용하려면 적법하게 이용할 수 있는 데이터로 모델을 직접 학습하거나 Porcupine을 사용해야 한다. 의존성과 내려받는 음성 모델의 라이선스는 THIRD_PARTY_NOTICES.md에 있다. 취약점은 보안 안내에 따라 비공개로 제보할 수 있으며, 변경 기록은 CHANGELOG.md에서 확인할 수 있다. 프로젝트는 ContextuAI가 공개했으며, 이 회사는 ContextuAI Solo도 제공한다.