히스토리
- 타이틀 변경: 눈귀코혀몸뜻. 六根 프레임으로 재구성
- Claude Code 다중 세션 오케스트레이터 설계 추가. SQLite 큐 + 마이크로 로깅 + i3wm 창 순환. 별도 Golang 프로젝트로 분리 예정
- 전역 음성 입력 워크플로우 확장. 후처리까지 고려. API콜로 변환이 한글 입력에 더 적합하고 안전
- 음성 입력 워크플로우
- #음성인식: #SpeechtoText #음성텍스트변환 #받아쓰기
- #한글: #소리내어읽기 #이맥스 #텍스트음성변환 #한국어 ¤piper ¤espeak ¤EdgeTTS
관련메타
관련노트
눈귀코혀몸뜻
에이전트와 인간을 나누지 않는다.
멀티 에이전트 오케스트레이션의 흐름에는 스워밍으로 밀어붙이는 방식이 있고, 이미 현재 수준에서도 엄청난 결과를 낸다. A를 B로 재구현한다면 의미 있다. 그러나 없던 것을 고민하면서 나아갈 때는 개입이 필요하다.
클로드는 이미 충분히 뛰어나서 인간이 따라가기도 어렵다. 그렇다면 인간은 집중해서 하려면 눈귀코혀몸뜻 — 존재를 다 털어서 합일해야 한다. “다중 에이전트 몇 개 쓴다”는 말로는 이것을 다 품을 수 없다. 시간을 잊고 빨아들이듯 들어간다. 자기 없음의 경계를 벗어난다.
그렇다면 무엇이 나오는가? 복제품이 아니다. 같은 기능의 프로그램이 수백 수천 개 생기는 와중에, 그것 말고 — 창조.
| 근(根) | 감각 | 도구 | 연결 |
|---|---|---|---|
| 눈(眼) | 시각 | claude-focus + i3 창 순환 | 대기 세션 파악, 맥락 전환 |
| 귀(耳) | 청각 | peon-ping + dunst 알림 | 에이전트 상태를 몸이 먼저 앎 |
| 코(鼻) | 후각 | — | (아직 열려 있음) |
| 혀(舌) | 미각/언어 | whisper + Groq API 음성입력 | 말로 지시, 키보드보다 빠른 순간 |
| 몸(身) | 촉각 | 키바인딩 + 키보드 중심 조작 | 손끝의 판단이 곧 의사결정 |
| 뜻(意) | 의식 | SQLite 큐 + 마이크로 로깅 | 패턴 인식, 자율성 위임의 근거 |
이 노트는 도구의 기술을 담되, 글의 내용은 ‘연결’이다. 각 꼭지는 감각 하나를 여는 도구 이야기이며, 살을 붙여가는 중이다.
2026 Claude Code 다중 세션 오케스트레이터 (눈·뜻)
3-4개 Claude Code 세션을 동시에 돌리며 빠르게 의사결정을 내리기 위한 도구. 눈(시각 전환)과 뜻(큐 우선순위 판단)의 영역.
문제
- Claude Code 3-4개가 동시에 사용자 응답을 기다림
- 알림이 쏟아지는 와중에 키 하나로 해당 창에 도달해야 함
- Ghostty, WezTerm 등 터미널 종류가 혼재
- 모든 터미널이 Claude Code를 돌리는 것은 아님
탐지: 창 타이틀 ✳ 기호
Claude Code는 터미널 종류와 무관하게 ANSI escape로 타이틀을 ✳ <프로젝트명> 으로 설정한다. 2026-02-14 검증:
| 터미널 | 타이틀 예시 |
|---|---|
| Ghostty | ✳ Emacs 레이어 아키텍처 |
| Ghostty | ✳ Tmux 오케스트레이터 |
| WezTerm | ✳ peon-ping project review |
| (미실행) | Ghostty |
따라서 xdotool search --name "✳" 또는 i3-msg -t get_tree | jq '.. | select(.name | test("✳"))' 로 정확히 필터링된다.
PPID 체인 역추적
Notification hook에서 어떤 Claude Code 인스턴스인지 식별:
hook_script(PPID) → claude(pid) → bash(ppid) → terminal(gppid) → X window(wid)for pid in $(pgrep -x claude); do
ppid=$(ps -o ppid= -p $pid | tr -d ' ')
gppid=$(ps -o ppid= -p $ppid | tr -d ' ')
wid=$(xdotool search --pid $gppid 2>/dev/null | tail -1)
title=$(xdotool getwindowname "$wid" 2>/dev/null)
echo "claude=$pid → term=$gppid → wid=$wid title='$title'"
donePhase 1 구현: i3 창 순환 (MVP, nixos-config)
scripts/claude-focus.sh — ✳ 타이틀 기반 순환.
# i3 tree에서 ✳ 창 목록 → 현재 포커스 기준으로 next/prev
mapfile -t WINDOWS < <(
i3-msg -t get_tree | \
jq -r '.. | select(.name? // "" | test("✳")) | .id'
)
# 현재 포커스 인덱스 찾고 → (idx ± 1) % count 로 순환
i3-msg "[con_id=${WINDOWS[$NEXT_IDX]}]" focusi3 키바인딩:
| 키 | 동작 |
|---|---|
Win+Tab | 다음 Claude Code 창 |
Win+Shift+Tab | 이전 Claude Code 창 |
Phase 2 설계: SQLite 큐 + 마이크로 로깅 (별도 Golang 프로젝트)
왜 SQLite인가
여러 Claude Code 인스턴스가 동시에 알림을 보내므로 동시성이 필수.
| 방식 | 동시성 | 구조화 | 쿼리 |
|---|---|---|---|
| 텍스트 파일 | ✗ race condition | ✗ | grep |
| flock + 파일 | ○ (검증됨, 10병렬 OK) | ✗ | 없음 |
| nq (flock job queue) | ○ | ✗ | 없음 |
| pueue (Rust daemon) | ○ | △ | 없음 |
| SQLite WAL | ○ (트랜잭션) | ○ | SQL |
| POSIX mq | ○ | ✗ | shell 비친화적 |
SQLite WAL 모드의 BEGIN IMMEDIATE 트랜잭션으로 원자적 enqueue/dequeue. 큐 자체가 곧 로그 — 별도 로깅 불필요.
스키마
CREATE TABLE claude_events (
id INTEGER PRIMARY KEY,
window_id INTEGER,
project TEXT,
title TEXT,
event TEXT, -- 'notify' | 'focus' | 'dismiss'
ts DATETIME DEFAULT (datetime('now','localtime'))
);
CREATE VIEW pending AS
SELECT e.* FROM claude_events e
WHERE e.event = 'notify'
AND NOT EXISTS (
SELECT 1 FROM claude_events f
WHERE f.window_id = e.window_id
AND f.event IN ('focus', 'dismiss')
AND f.ts > e.ts
)
ORDER BY e.ts ASC;아키텍처
┌──────────────┐ INSERT ┌─────────────────────┐
│ claude-notify│ ──────────→ │ claude_events │
│ .sh (hook) │ │ (SQLite WAL) │
└──────────────┘ │ │
│ window_id | project │
┌──────────────┐ SELECT+DEL │ event | timestamp │
│ claude-focus │ ←────────── └─────────────────────┘
│ .sh (i3키) │ ↑
└──────────────┘ Emacs sqlite-mode
│ 로 직접 쿼리 가능
↓
i3-msg [con_id=X] focus마이크로 로깅: “atuin for AI sessions”
커밋 로그와의 차이
- 커밋 로그 = 매크로 기록 (결과물 중심, 대부분의 작업이 기록됨)
- 이 시스템 = 마이크로 기록 (과정 중심, 매 대화마다 커밋하진 않음)
- atuin이 쉘 커맨드 히스토리에 하는 것을 AI 세션 인터랙션에 적용
패턴 분석으로 얻을 수 있는 것
- 어떤 프로젝트에서 평균 응답 대기 시간이 긴가?
- 어느 주기로 몇 개의 터미널을 처리하고 있는가?
- 어떤 지점에서 병목(고민)이 생기는가?
- 패턴이 나오면 → 에이전트에게 자율성을 점진적으로 더 줄 근거
현황 (2026-02-14 조사)
- 전용 도구 없음 (블루오션)
- aider:
.aider.chat.history.md— 가장 체계적이지만 aider 전용 - Claude Code:
~/.claude/projects/*JSONL — 분석 도구 없음 - Anthropic/Google은 내부 텔레메트리로 분석 중이나 개인용 도구 없음
Phase 3 비전: Emacs 통합
- Emacs에서 SQLite DB 직접 쿼리 (
sqlite-mode/emacsql) - org-mode 대시보드로 세션 상태 시각화
- 직접 응답 전송 인터페이스
- 궁극적으로 음성입력(whisper) + 시각(창 순환) + 판단(큐 우선순위) = 오감 워크플로우
기술 스택
- 프로그램: Golang 싱글 바이너리 (flake.nix)
- 저장소: SQLite WAL
- 탐지: xdotool (X window 타이틀
✳) - WM 연동: i3-msg
- 알림: dunst + peon-ping hooks
- 이슈 트래커:
br nixos-334(P1 epic)
2026 전역 음성 입력 스크립트 (혀)
질문
앗! 전역으로 입력되야 편하다. 클로드코드 터미널 어디든 말이다.배경
- Emacs whisper.el은 Emacs 내부에서만 작동함.
- Claude Code(터미널)나 다른 앱에서도 음성 입력이 필요함.
- i3wm 키바인딩으로 어디서든 음성 입력 → 텍스트 변환 → 붙여넣기.
검토한 솔루션들
| 솔루션 | 특징 | 적합성 |
|---|---|---|
| VoiceMode MCP | Claude Code 내부만 | ❌ 전역 불가 |
| BlahST | whisper.cpp 로컬 | ❌ Groq 미지원 |
| nerd-dictation | VOSK 기반 | ❌ 한글 품질 낮음 |
| 커스텀 스크립트 | sox + Groq API | ✅ 채택 |
최종 솔루션: whisper-input.sh
핵심 구성요소
sox rec: 녹음 + silence detection (자동 종료)Groq API: whisper-large-v3 (한글 품질 우수)xsel: 클립보드 관리xdotool: 자동 붙여넣기
스크립트 위치
~/.local/bin/whisper-input.sh코드 스크립트
#!/usr/bin/env bash
# whisper-groq.sh - 전역 음성 입력 (Groq Whisper API + sox silence detection)
# 사용법: 키바인딩으로 실행 → 말하기 → 2초 침묵 시 자동 종료 → 변환 → 붙여넣기
# 마이크 소음 레벨 확인 (숫자가 높을수록 시끄러움)
# rec -n stat 2>&1 | grep "Maximum amplitude"
# 1. 마이크 입력 볼륨 낮추기 (권장) pavucontrol → 입력 장치 탭 → 마이크 볼륨을 **50-70%**로 낮추기
# 2. 임계값을 대폭 올리기 25%
set -e
#---USER CONFIG---
TEMPD="/dev/shm"
AUDIO_FILE="$TEMPD/whisper-groq.wav"
LOG_FILE="$TEMPD/whisper-groq.log"
# Groq API 키 (환경변수 또는 pass)
GROQ_API_KEY="${GROQ_API_KEY:-$(/usr/bin/pass api/groq/junghanacs 2>/dev/null || echo "")}"
# 자동 붙여넣기 (1=활성화, 0=클립보드만)
AUTOPASTE=1
#---END CONFIG---
log() { echo "[$(date '+%H:%M:%S')] $*" >> "$LOG_FILE"; }
# 후처리 함수 (커스터마이징 가능)
postprocess() {
local text="$1"
# 예: 티먹스 → tmux, 클로드 → Claude 등
# text="${text//티먹스/tmux}"
# text="${text//클로드/Claude}"
echo "$text"
}
# API 키 확인
if [[ -z "$GROQ_API_KEY" ]]; then
notify-send -u critical "Whisper" "API 키 없음"
exit 1
fi
# 이미 실행 중이면 종료 (녹음 중지)
if pidof -q rec; then
pkill rec
exit 0
fi
log "=== 녹음 시작 ==="
notify-send -t 1500 "Whisper" "녹음 중... (2초 침묵 시 자동 종료)"
# sox rec: silence detection
# silence 1 0.1 3% → 0.1초 동안 % 이상 소리 있어야 녹음 시작
# silence 1 2.0 10% → 2초 동안 % 이하면 종료
rec -q -t wav "$AUDIO_FILE" rate 16k silence 1 0.1 3% 1 2.0 10% 2>/dev/null
# 파일 크기 확인
filesize=$(stat -c%s "$AUDIO_FILE" 2>/dev/null || echo "0")
log "파일 크기: $filesize bytes"
if [[ "$filesize" -lt 1000 ]]; then
log "녹음이 너무 짧음"
notify-send -u low "Whisper" "녹음이 너무 짧음"
rm -f "$AUDIO_FILE"
exit 0
fi
notify-send -t 1000 "Whisper" "변환 중..."
# Groq API 호출
RESPONSE=$(curl -s https://api.groq.com/openai/v1/audio/transcriptions \
-H "Authorization: Bearer $GROQ_API_KEY" \
-F file=@"$AUDIO_FILE" \
-F model="whisper-large-v3" \
-F language="ko" 2>>"$LOG_FILE")
log "API 응답: $RESPONSE"
TEXT=$(echo "$RESPONSE" | jq -r '.text // empty')
if [[ -z "$TEXT" ]]; then
ERROR=$(echo "$RESPONSE" | jq -r '.error.message // "알 수 없는 오류"')
log "변환 실패: $ERROR"
notify-send -u critical "Whisper" "변환 실패: $ERROR"
rm -f "$AUDIO_FILE"
exit 1
fi
# 후처리
TEXT=$(postprocess "$TEXT")
log "최종 텍스트: $TEXT"
# 클립보드에 저장 (xsel 사용)
echo -n "$TEXT" | xsel -ib
# 자동 붙여넣기
if (( AUTOPASTE )); then
sleep 0.1
xdotool key ctrl+shift+v
fi
notify-send -t 1500 "Whisper" "완료 (${#TEXT}자)"
rm -f "$AUDIO_FILE"
i3 키바인딩
regolith 용
# /usr/share/regolith/common/config.d/15_base_launchers
## Launch // Whisper Voice Input // <> e ##
set_from_resource $wm.binding.whisper wm.binding.whisper e
bindsym $mod+$wm.binding.whisper exec --no-startup-id /home/goqual/.local/bin/whisper-input.sh사용법
| 동작 | 설명 |
|---|---|
$mod+e | 녹음 시작 |
| 말하기 → 2초 침묵 | 자동 종료 → 변환 → 붙여넣기 |
$mod+e 다시 | 수동 종료 (녹음 중일 때) |
후처리 함수
스크립트에 postprocess() 함수가 준비되어 있음. 음성 인식 결과를 자동 변환 가능:
postprocess() {
local text="$1"
# 예: 티먹스 → tmux, 클로드 → Claude 등
text="${text//티먹스/tmux}"
text="${text//클로드/Claude}"
echo "$text"
}해결한 문제들
ffmpeg 토글 방식 → sox silence detection
기존: ffmpeg 백그라운드 실행 + 토글 (불안정) 해결: sox rec + silence detection (자동 종료)
터미널 붙여넣기 안 됨
원인: ctrl+v vs ctrl+shift+v 해결: 터미널용 키바인딩으로 변경
마이크 소음으로 침묵 감지 안 됨
원인: Maximum amplitude 0.999 (마이크 포화) 해결: pavucontrol에서 입력 볼륨 낮추기 또는 임계값 상향 (10% → 30%)
의존성
sudo apt install sox libsox-fmt-all xsel xdotool jq curl libnotify-bin참고 자료
- BlahST - sox silence detection 참고
- Groq Whisper API 문서
다음 단계
- 마이크 볼륨 조정하여 침묵 자동 종료 안정화
- 후처리 규칙 추가 (한글 → 영어 용어 변환)
- Emacs whisper.el과 키바인딩 통합 검토
2025 Emacs + Claude Code + 음성입력 워크플로우 (혀·몸)
질문
● 1. agent-shell은 comint-mode/shell-maker 기반인데, eca-emacs는
어떤 기반인가?
2. whisper.el 연동으로 음성 입력이 가능한데, 이를 구축하고 싶다
3. Emacs + Claude Code + 음성제어 + 한글 입력 = 특화된 워크플로우
이건 좋은 방향이네요. 한국어 사용자를 위한 Emacs AI
워크플로우입니다.
먼저 eca-emacs의 인터페이스 방식을 확인하고, whisper.el에 대해서도
조사해봐야겠습니다.editor-code-assistant/eca
(“Editor-Code-Assistant/Eca” 2025)
2025
Editor Code Assistant (ECA) - AI pair programming capabilities agnostic of editor
editor-code-assistant/eca-emacs
(“Editor-Code-Assistant/Eca-Emacs” 2025)
2025
Editor Code Assistant (ECA) integration for Emacs
natrys/whisper.el: Speech-to-Text interface for Emacs using OpenAI’s whisper model and whisper.cpp as inference engine.
(“Natrys/Whisper.El: Speech-to-Text Interface for Emacs Using Openai’s Whisper Model and Whisper.Cpp as Inference Engine.” n.d.)
로컬 음성 처리 시 노트북 스팩!?
@레노버 §씽크패드 #AI노트북 #라이젠 #가격 #스펙 #
배경
Claude Code 정액제를 사용하면서 gptel을 잘 안 쓰게 됨. Emacs에서 Claude를 활용하고 싶은데, 터미널 기반 도구들은 한글 입력이 불편함.
조사한 패키지들
Emacs Claude Code 통합 패키지 비교
| 패키지 | 스타 | 프로토콜 | 특징 |
|---|---|---|---|
| agent-shell | 377 | ACP | xenodium 개발, shell-maker 기반 |
| ai-code-interface.el | 70 | CLI 래핑 | 워크플로우 통합, Org 프롬프트 관리 |
| eca-emacs | 237 | JSONRPC | Eric Dallo 개발, LSP 스타일 |
| claude-code-ide.el | - | MCP | 양방향 브릿지 |
선택: ECA (Editor Code Assistant)
- gfm-view-mode 기반 → 한글 입력 문제 없음 (comint 아님!)
- Claude Max OAuth 지원
- MCP 서버 연동 지원
- Eric Dallo (clojure-lsp 개발자) 품질
ECA 설정
설정 파일 구조
~/claude-config/eca/config.json
↓ symlink
~/.config/eca/config.jsonconfig.json 내용
{
"defaultModel": "anthropic/claude-sonnet-4.5",
"toolCall": {
"approval": {
"byDefault": "ask",
"allow": {
"eca__read_file": {},
"eca__list_dir": {},
"eca__grep": {},
"eca__glob": {}
}
}
},
"mcpServers": {
"Context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"]
},
"nixos": {
"command": "uvx",
"args": ["mcp-nixos"]
},
"google-workspace-work": {
"command": "/home/goqual/claude-config/mcp-wrappers/google-workspace-mcp-wrapper-work.sh",
"args": []
},
"org-mcp-server": {
"command": "/home/goqual/.local/bin/org-mcp-server",
"args": []
}
}
}OAuth 로그인
M-x eca/login→anthropic- 브라우저 인증 → 코드 붙여넣기
Whisper.el 음성 입력
모드 선택
| 모드 | 설명 | 비용 |
|---|---|---|
| 로컬 (whisper.cpp) | CPU 오프라인 | 무료 |
| Groq API | 클라우드 whisper-large-v3 | 무료 (rate limit) |
| OpenAI API | gpt-4o-transcribe | $0.006/분 |
선택: Groq API
- 무료
- 로컬 설치 불필요 (ffmpeg만 필요)
- 한국어 CER ~11% (충분히 사용 가능)
한국어 ASR 벤치마크 (AI-Hub 기준)
| 순위 | 모델 | 평균 CER |
|---|---|---|
| 1 | Return Zero | 5.91% |
| 2 | Return Zero Whisper (파인튜닝) | 6.59% |
| 3 | Naver ClovaSpeech | 7.52% |
| 5 | OpenAI Whisper large-v3 | 11.39% |
Elisp 설정
설정 파일: ~/sync/emacs/emacs-fulllab-config/+ai-eca-whisper.el
핵심 설정
;; Whisper - Groq API
(setq whisper-server-mode 'openai
whisper-openai-api-baseurl "https://api.groq.com/openai/"
whisper-openai-api-key (lambda ()
(string-trim
(shell-command-to-string "pass api/groq/junghanacs")))
whisper-openai-model "whisper-large-v3"
whisper-language "ko")
;; ECA
(setq eca-chat-window-side 'right
eca-chat-window-width 0.45
eca-chat-use-side-window t)키바인딩
| 키 | 기능 |
|---|---|
| SPC v w | 음성 녹음 시작/중지 |
| SPC a e | ECA 시작 |
| SPC a v | ECA + 음성 입력 통합 |
해결한 문제들
ANTHROPIC_API_KEY 환경변수 충돌
ECA가 OAuth 대신 API 키를 먼저 사용하려고 함.
해결:
- ~/.spacemacs.env에서 ANTHROPIC_API_KEY 제거
- ~/.cache/eca/ 캐시 삭제 후 재로그인
아키텍처 요약
┌─────────────────────────────────────────────────────┐
│ whisper.el (음성 → 텍스트) │
│ └── Groq API (whisper-large-v3, 무료) │
│ ↓ │
│ ECA 채팅 버퍼 (gfm-view-mode, 한글 OK) │
│ ↓ │
│ Claude Max (OAuth) → 응답 │
│ ↓ │
│ MCP 서버들 (Context7, nixos, org-mcp-server) │
└─────────────────────────────────────────────────────┘다음 단계
- ffmpeg 설치 확인 및 테스트
- ECA + Whisper 실제 워크플로우 테스트
- 한국어 파인튜닝 모델 검토 (EZWhisper KR 등)
참고 자료
다른 모델 - 오픈라우터 계열
Mistral: Voxtral Small 24B 2507
mistralai/voxtral-small-24b-2507
Created Oct 30, 202532,000 context
$0.10/M input tokens$0.30/M output tokens$100/M audio tokens
Voxtral Small is an enhancement of Mistral Small 3, incorporating state-of-the-art audio input capabilities while retaining best-in-class text performance. It excels at speech transcription, translation and audio understanding. Input audio is priced at $100 per million seconds.
그록 무료 어디까지?
Groq 문서의 rate limits 테이블에 따르면, Whisper 모델의 Free plan
제한사항은 다음과 같습니다:
**whisper-large-v3**
- RPM (분당 요청): 20
- RPD (일일 요청): 2K
- ASH (시간당 오디오 초): 7.2K
- ASD (일일 오디오 초): 28.8K
**whisper-large-v3-turbo**
- RPM (분당 요청): 20
- RPD (일일 요청): 2K
- ASH (시간당 오디오 초): 7.2K
- ASD (일일 오디오 초): 28.8K
두 모델 모두 동일한 제한을 가지고 있으며, 시간당 최대 7.2K초(약
2시간), 하루에 최대 28.8K초(약 8시간)의 오디오를 처리할 수
있습니다.
● Groq Whisper Free Tier 제한
| 항목 | 제한 |
|---------|---------------|
| 분당 요청 | 20 RPM |
| 일일 요청 | 2,000건 |
| 시간당 오디오 | 7,200초 (2시간) |
| 일일 오디오 | 28,800초 (8시간) |
실사용 환경에서
| 시나리오 | 충분 여부 |
|----------------|--------------|
| 음성 메모 (30초) | ✅ 하루 960건 가능 |
| ECA 음성 입력 (1분) | ✅ 하루 480건 가능 |
| 회의 녹음 (1시간) | ✅ 하루 8회 가능 |
| 연속 딕테이션 | ✅ 시간당 2시간분 |
결론: 개인 사용자에겐 사실상 무제한이나 다름없습니다. 하루 8시간
오디오면 충분!
Sources:
- https://console.groq.com/docs/rate-limits
Comments