---

* 設計概要

完全ローカル · 猫キャラクター家電AIエージェント

6–9
tok/s
~10s
レイテンシ(ツール無)
~30s
レイテンシ(ツール有)
3.4GB
llama-server RAM
6
ツール数
7
SwitchBot devices
768d
埋込ベクトル次元
30–50
自律呟き / 日

システム概要

graph LR subgraph HW["Raspberry Pi 5 + Whisplay HAT"] Mic["マイク · WM8960"] Btn["ボタン · GPIO"] end subgraph Core["neko.py - メインループ"] VAD["silero-vad 16kHz"] SM["State Machine 5 states"] Auto["Autonomous Loop 15-90min"] end subgraph ADK["agent.py - ADK + LiteLLM"] Agent["LlmAgent function calling"] Gemma["Gemma 4 E2B Q4_K_M port8080"] end subgraph ToolBox["tools.py - 6 Tools"] T1["observe"] T2["control_device"] T3["remember"] T4["activity"] T5["broadcast"] T6["web_search"] end subgraph IO["I/O"] SPK["スピーカー"] LCD["LCD 240x280"] BSKY["Bluesky"] SB["SwitchBot"] CAM["Camera"] end Mic --> VAD --> SM Btn --> SM SM --> Agent Auto --> Agent Agent <--> Gemma Agent --> T1 & T2 & T3 & T4 & T5 & T6 T1 --> CAM & SB T2 --> SB T5 --> SPK & BSKY SM --> LCD

技術スタック

採用技術と不採用の経緯
領域採用理由
推論エンジンllama.cpp --jinja --ctx-size 12288Gemma 4 音声入力対応、ローカル完結
LLMGemma 4 E2B Q4_K_M + mmproj-BF16音声・画像・テキスト 3モーダル、Apache 2.0
エージェントGoogle ADK + LiteLLMfunction calling 標準、モデル切替可
VADsilero-vad軽量・常時稼働
TTSVOICEVOX Engine 0.25.2 ARM64自然な日本語、43話者
TTS fallbackpyopenjtalk + Nitech HTSVOICEVOX不調時
短期記憶Python deque(maxlen=5)同プロセス内、起動毎リセット
長期記憶SQLite + sqlite-vec + gemini-embedding-001ローカルDB + クラウド埋込 (768d)
家電SwitchBot v1.1 API(7デバイス)Hub Mini でIR家電含む
SNSBluesky atproto / MoltbookBluesky 動作確認済

状態機械

5状態 · LED色 · LCD吹き出し · 遷移条件
stateDiagram-v2 direction LR [*] --> IDLE : 起動 IDLE --> LISTENING : マイク開放 LISTENING --> RECORDING : VAD 3block or ボタン RECORDING --> THINKING : 1秒無音 / 10秒経過 THINKING --> SPEAKING : 意味ある応答 THINKING --> LISTENING : skip / JSON漏れ SPEAKING --> LISTENING : 再生終了
状態LEDLCD遷移
IDLE暗青 呼吸「高所より人間を観察中である」→ LISTENING
LISTENING明青「声を待っておる」→ RECORDING
RECORDING「聞いておるぞ…」→ THINKING
THINKING「聞いた: <書き起こし>」→ SPEAKING / LISTENING
SPEAKING応答テキスト→ LISTENING

会話フロー

1ターンのデータフロー — 録音から発話まで
sequenceDiagram actor U as ユーザー / Button participant VAD as silero-vad participant SM as State Machine participant LLAMA as llama-server participant ADK as ADK Agent participant TOOLS as Tools x6 participant TTS as VOICEVOX participant LCD as LCD + LED U->>VAD: 発話 or ボタン押下 VAD->>SM: speech_start SM->>LCD: RECORDING(赤) VAD->>SM: speech_end(無音1s / 10s) SM->>LCD: THINKING(黄) SM->>LLAMA: 16kHz WAV base64 LLAMA-->>ADK: 日本語テキスト ADK->>LLAMA: テキスト + tools=[6] loop ツール呼び出し LLAMA-->>ADK: tool_calls ADK->>TOOLS: 実行 TOOLS-->>ADK: 結果 ADK->>LLAMA: 結果 + continue end LLAMA-->>ADK: 最終回答 ADK->>TTS: 日本語 1〜3文 SM->>LCD: SPEAKING(緑) TTS-->>U: 24kHz WAV 再生 SM->>LCD: LISTENING(青)

自律ループ — autonomous.py

flowchart TD S(["起動 60秒待機"]) B{"busy?"} SK["20秒スキップ"] R["reset_session()"] P["OBSERVATION_PROMPT"] RS{"出力タイプ"} SOC["broadcast social Bluesky / Moltbook"] VOI["broadcast voice VOICEVOX"] SIL["沈黙 skip"] W(["15〜90分スリープ"]) S --> B B -->|Yes| SK --> B B -->|No| R --> P --> RS RS -->|social| SOC --> W RS -->|voice| VOI --> W RS -->|skip| SIL --> W W --> B

ツール(6個)

tools.py — ADK Agent が呼び出す全ツール
observe(target)
センサ読取・カメラ描写・家電一覧・PTZ首振り
"room""view""devices""meter:NAME""look:DIR"
control_device(name, action, ...)
SwitchBot 7デバイス + Hub Mini IR を1関数で統合制御
"on"/"off""brightness""curtain""color""aircon"
remember(query, limit)
SQLite + sqlite-vec ベクトル類似検索で過去会話を想起
gemini-embedding-001768次元
activity(op, ...)
人間活動 DB の CRUD
"record""list""search""get""update""delete"
broadcast(channel, text)
外部発信チャネルへの統合インターフェース
"voice""social""alexa_say""alexa_routine"
web_search(query)
Tavily → Brave → DuckDuckGo フォールバックチェーン
TavilyBraveDDG

ストレージ

~/.neko/memory.db · SQLite + sqlite-vec
★ conversations + conv_vec(長期記憶)
CREATE TABLE conversations (
  id           INTEGER PRIMARY KEY AUTOINCREMENT,
  ts           REAL NOT NULL,
  user         TEXT NOT NULL,
  assistant    TEXT NOT NULL
);
CREATE VIRTUAL TABLE conv_vec USING vec0(
  embedding float[768]   -- gemini-embedding-001
);
★ activities(人間活動DB)
CREATE TABLE activities (
  id           INTEGER PRIMARY KEY AUTOINCREMENT,
  ts           REAL NOT NULL,
  activity     TEXT NOT NULL,   -- working/eating/sleeping/...
  description  TEXT, location TEXT, duration_min INTEGER,
  mood TEXT, evidence TEXT,
  confidence   REAL NOT NULL DEFAULT 0.7
);

デプロイ

systemd 4サービス · 運用コマンド
サービスポート役割
llama-server.service:8080Gemma 4 E2B 推論エンジン
voicevox-engine.service:50021VOICEVOX TTS ずんだもん
neko.service:4001メインアプリ + Web API
neko-bt-autoconnect.serviceBTEcho Dot 自動再接続
# Pi接続
ssh neko-pi

# 同期
rsync -avz --exclude='.git' --exclude='venv' ./ neko-pi:~/neko/

# 再起動
sudo systemctl restart neko.service

# ログ
sudo journalctl -u neko.service -f