Community코딩 & 개발github.com

vietanhdev/edgevox

로봇을 위한 오프라인 음성 에이전트 프레임워크 — 에이전트, 스킬, 워크플로우, 서브초 음성 파이프라인, 2D/3D 시뮬레이션(IR-SIM + MuJoCo), 15개 언어, 56개 음성, ROS2 네이티브. CPU/CUDA/Metal에서 실행되며 클라우드 불필요.

edgevox란 무엇인가요?

EdgeVox는 로봇을 위한 완전한 오프라인 음성 에이전트 프레임워크입니다. 순수 Python 패키지로, 클라우드 종속성이 없으며 CPU, CUDA, Metal에서 실행됩니다. 이 프레임워크는 VAD(음성 활동 감지), STT(음성 인식), LLM(언어 모델), TTS(음성 합성)를 통합한 서브초 음성 파이프라인을 제공하며, 15개 언어와 56개 음성을 지원합니다. 플러그 앤 플레이 방식으로 모든 구성 요소를 교체 가능하게 설계되었으며, ROS2 네이티브 통합, FastAPI 웹 UI, React 프론트엔드를 포함합니다. 에이전트 하네스는 문서화된 6-파이어-포인트 루프, 훅 시스템, 메모리 관리, 멀티 에이전트 지원을 제공합니다. 개발 규칙으로는 모던 Python 구문(3.10+), ruff 포매팅, 하드웨어 인식 코드 경로의 우아한 fallback을 강조하며, pre-commit과 gitleaks를 통한 코드 품질 관리, Mermaid 다이어그램 사용을 권장합니다. 모델 파일은 Git에서 제외되며, 라이선스 확인 없이 새 의존성을 추가하는 것을 금지합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add vietanhdev/edgevox

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

EdgeVox — Claude Code 규칙

로봇을 위한 오프라인 음성 에이전트 프레임워크. 순수 Python 패키지, 클라우드 종속성 없음, CPU/CUDA/Metal에서 실행.

프로젝트 구조

edgevox/
├── edgevox/            # 소스 패키지
│   ├── audio/          # VAD, 마이크 캡처, 재생
│   ├── stt/            # STT 백엔드 (faster-whisper, sherpa-onnx)
│   ├── llm/            # llama.cpp / Gemma 통합
│   ├── tts/            # TTS 백엔드 (Kokoro, Piper, Supertonic, PyThaiTTS)
│   ├── core/           # 파이프라인 오케스트레이션
│   ├── cli/            # CLI 진입점
│   ├── ui/             # TUI 위젯
│   ├── integrations/   # ROS2 브리지 등
│   ├── tui.py          # 메인 TUI 앱
│   └── setup_models.py # 모델 다운로더
│   ├── server/         # FastAPI 웹 UI + WebSocket 서버
├── webui/              # React 프론트엔드 (Vite + Tailwind)
├── scripts/            # 유틸리티 스크립트 (모델 업로드 등)
├── voices/             # 음성 설정 파일
├── docs/               # 프로젝트 문서
├── website/            # VitePress 사이트
└── pyproject.toml

진입점 (pyproject.toml 참조):

  • edgevox → edgevox.tui:main (기본 TUI, --web-ui는 웹, --simple-ui는 CLI)
  • edgevox-cli → edgevox.cli.main:main
  • edgevox-setup → edgevox.setup_models:main

지원 언어 및 백엔드

언어STTTTS
영어, 프랑스어, 스페인어 등faster-whisperKokoro
베트남어sherpa-onnx (zipformer)Piper
독일어, 러시아어, 아랍어, 인도네시아어faster-whisperPiper
한국어faster-whisperSupertonic
태국어faster-whisperPyThaiTTS

모델은 nrl-ai/edgevox-models (HuggingFace)에 호스팅되며, 상위 저장소로 fallback이 가능합니다.

아키텍처 원칙

  • 플러그 앤 플레이, 기본적으로 사용자 정의 가능. 모든 구성 요소 — STT 백엔드, TTS 백엔드, LLM, VAD, 에이전트 루프 동작, 파이프라인 단계, 도구, 스킬, 훅 — 은 코어 코드를 수정하지 않고 교체 가능해야 합니다. 하드코딩된 경로보다는 프로토콜, 레지스트리, 데코레이터를 선호합니다. 새로운 동작은 기존 모듈에 대한 패치가 아닌 새로운 플러그인/훅/백엔드로 추가됩니다. 특정 사용 사례를 위해 코어에 조건문을 추가하는 상황이 발생하면, 한 걸음 물러서서 이를 주입 지점으로 추출하십시오.

에이전트 하네스 아키텍처

에이전트 하네스 (edgevox/agents/ + edgevox/llm/hooks_slm.py + edgevox/llm/tool_parsers/)는 docs/documentation/ 아래에 완전히 문서화되어 있습니다:

  • agent-loop.md — 6-파이어-포인트 루프, 병렬 디스패치, 핸드오프 쇼트서킷.
  • hooks.md — 훅 작성 규약, 내장 훅, 순서 규칙.
  • memory.md — MemoryStore / SessionStore / NotesFile / Compactor.
  • interrupt.md — Barge-in 신호 + 취소 토큰 파이프라인.
  • multiagent.md — Blackboard, BackgroundAgent, AgentPool.
  • tool-calling.md — 파서 체인 + 문법 제약 디코딩 로드맵.

하네스 규칙

  • 타입이 지정된 AgentContext 필드 (ctx.tool_registry, ctx.llm, ctx.interrupt, ctx.memory, ctx.artifacts, ctx.blackboard)는 공용 API 표면입니다. ctx.state는 사용자 전용 스크래치 영역입니다 — 프레임워크 코드는 여기에 매직 키를 쓰면 안 됩니다.
  • 훅 소유 상태는 ctx.hook_state[id(self)] 아래에 있습니다. id(self)로 키를 지정하면 동일한 훅 클래스의 두 인스턴스가 상태를 공유하지 않도록 보장합니다.
  • Barge-in은 권고가 아닌 강제 사항입니다. 모든 LLM.complete 호출은 stop_event=…를 통해 ctx.interrupt.cancel_token을 전달하므로 llama-cpp의 stopping_criteria가 실제로 한 디코드 단계 내에서 생성을 중단합니다.
  • 토크나이저 정확한 토큰 수. estimate_tokens(messages, llm) 및 LLM.count_tokens는 LLM을 사용할 수 있을 때 chars // 4 휴리스틱을 대체합니다. CJK / 베트남어 / 태국어에 대한 올바른 컨텍스트 윈도우 결정에 필요합니다.
  • 도구 호출 파싱은 원시 우선입니다. parse_tool_calls_from_content는 .. 생각 블록을 제거하기 전에 원시 콘텐츠에 대해 감지기를 시도합니다 — Qwen3는 추론 블록 내에서 도구 호출을 내보냅니다 (llama.cpp#20837 참조).
  • 사전 설정 파서는 로드 시 검증됩니다. resolve_preset(slug)는 tool_call_parsers=(...)의 모든 이름이 등록된 감지기임을 단언합니다. 오타는 자동 탐지를 자동으로 비활성화하는 대신 크게 실패합니다.
  • 모델이 생성한 도구 호출 ID는 왕복합니다. Mistral의 [TOOL_CALLS] 형식은 후속 role="tool" 메시지가 재사용해야 하는 9자 ID를 전달합니다. ToolCallItem.id는 이를 파서 체인과 에이전트 루프를 통해 연결합니다.

선호하는 임포트 표면

  • 에이전트 프레임워크: from edgevox.agents import LLMAgent, AgentContext, Session, Handoff, ...
  • 내장 훅: from edgevox.agents.hooks_builtin import MemoryInjectionHook, TokenBudgetHook, ...
  • SLM 강화: from edgevox.llm.hooks_slm import default_slm_hooks
  • 메모리: from edgevox.agents.memory import JSONMemoryStore, NotesFile, Compactor, estimate_tokens
  • 멀티 에이전트: from edgevox.agents.multiagent import Blackboard, BackgroundAgent, AgentPool
  • 인터럽트: from edgevox.agents.interrupt import InterruptController, InterruptPolicy, EnergyBargeInWatcher

비공개 모듈이나 _agent_harness.py에 직접 접근하지 마십시오.

코딩 규칙

  • Python ≥ 3.10. 최신 구문 사용 (X | Y 유니온, match, dict[str, int]).
  • ruff로 포맷 및 린트. 줄 길이 120. ruff format 후 ruff check --fix 실행.
  • 코드 주석에 후행 요약 금지. 무엇이 아닌 왜를 주석으로 남기세요.
  • 공용 함수에는 타입 힌트. 내부 헬퍼는 명확할 때 생략 가능.
  • 라이브러리 코드에 print 사용 금지. 사용자 대상 출력에는 rich/textual 사용, 진단에는 logging 사용.
  • 임포트는 파일 상단에 배치. 순환 임포트, 선택적/무거운 의존성 기능 확인, CLI 시작 지연 로딩 등 구체적인 이유가 있을 때만 함수 내부로 임포트를 이동하세요. 편의성이나 "한 곳에서만 사용됨"은 이유가 아닙니다. 위로 이동하세요.
  • 이유 없이 새로운 최상위 의존성 추가 금지. 표준 라이브러리를 선호하세요. 추가해야 한다면 pyproject.toml을 업데이트하세요.
  • 하드웨어 인식 코드 경로는 우아하게 저하되어야 함 — CUDA/Metal/CPU fallback, 가속기 누락 시 절대 충돌하지 않음.
  • 모델 파일을 커밋하지 마십시오 (.gguf, .onnx, .bin, 가중치). 이들은 models/ 아래에 있으며 gitignore에 포함됩니다.

오디오 / 모델 규칙

  • 샘플 레이트: 캡처 및 STT 입력에는 16 kHz 모노 int16.
  • TTS 출력: sounddevice를 통해 장치 레이트로 리샘플링.
  • VAD 프레임 크기: 32 ms (16 kHz에서 512 샘플).
  • 지연 시간 예산: STT < 0.5초, LLM 첫 토큰 < 0.4초, TTS 첫 청크 < 0.1초 (RTX 3080 기준).
  • 스트리밍 파이프라인을 계약으로 취급: 이벤트 루프를 차단하는 블로킹 호출을 도입하지 마십시오.

도구

  • uv 패키지 관리. uv pip install / uv venv를 기본 pip / python -m venv 대신 사용하세요. https://docs.astral.sh/uv/ 참조.
  • pre-commit은 ruff (린트 + 포맷), gitleaks, 표준 위생 훅을 실행합니다. pre-commit install로 한 번 설치하세요.
  • gitleaks는 모든 커밋에서 비밀을 검사합니다. 위양성인 경우 .gitleaks.toml에 이유를 설명하는 주석과 함께 허용 목록에 추가하세요 — 발견 항목을 삭제하지 마십시오.
  • pytest 테스트 (pytest, asyncio 모드 = 자동). 테스트는 tests/ 아래에 있습니다.

워크플로 기대사항

  • 파일을 편집하기 전에 읽으세요. 보지 않은 코드에 대한 변경을 제안하지 마십시오.
  • 작업 완료를 선언하기 전에 ruff format + ruff check --fix를 실행하세요.
  • 훅을 우회하지 마십시오 (--no-verify) — 근본 문제를 해결하세요.
  • 자신이나 Claude를 커밋 작성자/공동 작성자로 추가하지 마십시오. 구체적으로: Co-Authored-By: Claude … 트레일러, 🤖 Generated with Claude Code 푸터 금지 — 커밋 메시지는 본문 후에 끝나며, 다른 것은 없습니다.
  • 새 파일을 만드는 것보다 기존 파일을 편집하는 것을 선호하세요. 요청받지 않는 한 README/문서 파일을 만들지 마십시오.
  • 변경 사항이 스트리밍 파이프라인에 영향을 미치는 경우, PR 설명에 수동으로 지연 시간 영향을 기록하세요.
  • 마크다운 문서에서는 ASCII 아트보다 Mermaid 다이어그램을 선호하세요 (docs/, website/, README.md, PR 설명). GitHub와 VitePress는 mermaid 펜스 블록을 기본적으로 렌더링합니다. 손으로 그린 박스-라인 ASCII는 읽기 어렵고, 깔끔하게 편집이 불가능하며, 고정폭 글꼴 변경 시 깨집니다. 허용되는 유일한 ASCII 다이어그램은 디렉토리 트리 (├── / └──)입니다 — 이는 그대로 유지됩니다.

문서 작성 (docs/, README.md, website/)

  • (, ), @, :, ,, &, <br/>, 또는 문자, 숫자, _, - 이외의 구두점을 포함하는 Mermaid 레이블은 항상 따옴표로 묶으세요. 노드에는 ["foo(args)"]를, 엣지 레이블에는 -->|"@tool call"|를 사용하세요. [...] 또는 |...| 내부에 따옴표 없는 괄호는 플로우차트 파서를 조용히 깨뜨립니다 — 페이지는 여전히 로드되지만 다이어그램이 사라집니다. Mermaid 블록을 편집한 후, 로컬에서 페이지를 열고 (npm run docs:dev) 브라우저 콘솔에 Parse error on line N 항목이 없는지 확인하세요. 이러한 깨짐은 소스 리뷰에서는 보이지 않습니다.
  • 작업 완료를 선언하기 전에 개발 서버에서 문서를 테스트하세요. npm run docs:dev (VitePress, :5173)은 마크다운 소스가 숨기는 Mermaid 파싱 오류, 깨진 링크, 죽은 앵커를 잡아냅니다. 시각적 변경(새 다이어그램, 레이아웃, 히어로, 사이드바)의 경우, 리뷰어가 서버를 시작하지 않고 회귀를 발견할 수 있도록 영향을 받는 페이지의 Playwright 스크린샷을 캡처하세요.
  • 페이지 간 링크는 루트 절대 경로이며, 확장자가 없습니다 — /documentation/hooks, ./hooks.md 또는 hooks가 아님 (후자는 cleanUrls: true에서 잘못 해석됨). Mermaid 노드 클릭 대상도 동일한 규칙을 따릅니다.
  • 사이드바 등록은 필수입니다. docs/documentation/ 아래의 새 페이지는 docs/.vitepress/config.ts의 sidebar 블록에 추가될 때까지 보이지 않습니다. 둘을 동시에 업데이트하세요.

하지 말아야 할 것

  • 클라우드 API 호출이나 텔레메트리를 추가하지 마세요. EdgeVox는 오프라인 우선입니다.
  • GPL 라이선스 의존성을 도입하지 마세요 (프로젝트는 MIT).
  • 새 의존성을 추가하기 전에 라이선스 확인이 필수입니다. 패키지의 실제 라이선스(PyPI/GitHub/문서 — 단순 추측이 아님)를 확인하고 결과를 pyproject.toml의 dep 옆에 인라인으로 기록하세요 (예: # MIT / # LGPL-3 — dynamic-linked, compatible). 거부해야 할 카피레프트 라이선스: GPL-2/3, AGPL, SSPL. LGPL은 순수 동적 링크 라이브러리(PySide6, Qt Multimedia, rlottie)에만 허용됩니다. CC-BY-SA는 에셋(SVG 조각 세트 등)에 허용되며, 소스 수준 의존성에는 절대 허용되지 않습니다. 의심스러우면 허용적인 대안을 선택하거나 논의를 위해 플래그를 지정하세요.
  • dist/, build/, *.egg-info/, 모델 가중치 또는 녹음을 커밋하지 마세요.
  • 작업이 요구하는 것 이상으로 추측성 추상화나 "미래 보장"을 추가하지 마세요.

관련 스킬