---

← ドキュメント一覧

★ Architecture

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

システム概要

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

全体アーキテクチャ

すべての入力・処理・出力・接続の関係

graph LR subgraph HW["HARDWARE — Pi 5 + Whisplay HAT"] MIC["Mic · WM8960"] BTN["Button · GPIO"] end subgraph SENSE["SENSORS + CAMERA"] SBM["Meter Pro · 温湿度"] CAMDEV["Pan/Tilt Cam 2K · RTSP+ONVIF"] end subgraph NEKO["neko.py — メインループ"] VAD["silero-vad · 16kHz"] SM["State Machine · 5 states"] SHRT["deque x 5 · 短期記憶"] end subgraph AUTOMOD["autonomous.py"] ALOOP["15-90min 乱数ループ"] end subgraph INFER["llama-server :8080"] GEMMA["Gemma 4 E2B · Q4_K_M + mmproj-BF16 · 6-9 tok/s"] end subgraph ADK_MOD["agent.py — Google ADK + LiteLLM"] AGENT["LlmAgent · function calling"] end subgraph TOOLS_MOD["tools.py — 6 Tools"] T1["observe(target)"] T2["control_device(name, action)"] T3["remember(query)"] T4["activity(op, ...)"] T5["broadcast(channel, text)"] T6["web_search(query)"] end subgraph STORE["STORAGE · memory.db"] CONV[("conversations + conv_vec 768d")] ACTDB[("activities")] end subgraph SBDEV["SwitchBot v1.1 — 7 devices"] BULB["Color Bulb 金"] CUR["Curtain 0-100%"] BOT["Bot 開錠"] HUB["Hub Mini -> IR AC"] end subgraph OUTCH["OUTPUT CHANNELS"] VOICEVOX["VOICEVOX :50021 · ずんだもん"] BSKY["Bluesky · atproto"] MOLT["Moltbook · Bearer"] ALEXA["Alexa · Voice Monkey"] end MIC --> VAD --> SM BTN --> SM SM --> AGENT ALOOP --> AGENT SHRT --> AGENT AGENT <--> GEMMA AGENT --> T1 & T2 & T3 & T4 & T5 & T6 T1 --> SBM & CAMDEV T2 --> BULB & CUR & BOT & HUB T3 --> CONV T4 --> ACTDB T5 --> VOICEVOX & BSKY & MOLT & ALEXA

会話データフロー

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 (3ブロック検出) SM->>LCD: RECORDING(赤LED) VAD->>SM: speech_end(1秒無音 / 10秒経過) SM->>LCD: THINKING(黄LED) SM->>LLAMA: 16kHz WAV base64 -> 書き起こし要求 LLAMA-->>ADK: 日本語テキスト ADK->>LLAMA: テキスト + tools=[6] + system_prompt loop ツール呼び出し(0-N回) LLAMA-->>ADK: tool_calls JSON ADK->>TOOLS: 実行 TOOLS-->>ADK: 結果テキスト ADK->>LLAMA: 結果 + continue end LLAMA-->>ADK: 最終回答テキスト ADK->>TTS: 日本語 1-3文 SM->>LCD: SPEAKING(緑LED) TTS-->>U: 24kHz WAV 音声再生 SM->>LCD: LISTENING(青LED)

状態機械

5状態 · LED色 · LCD吹き出し · 遷移条件

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

自律ループ

猫が勝手に観察・呟く仕組み — autonomous.py

flowchart TD START(["起動 60秒待機"]) BUSY{"busy? RECORDING / THINKING / SPEAKING"} SKIP["20秒スキップ"] RESET["reset_session()"] PROMPT["OBSERVATION_PROMPT 送信"] RESULT{"出力タイプ"} SOCIAL["broadcast('social') -> Bluesky / Moltbook"] VOICE["broadcast('voice') -> VOICEVOX スピーカー"] SILENT["沈黙 (skip)"] WAIT(["15-90分 乱数スリープ"]) START --> BUSY BUSY -->|Yes| SKIP --> BUSY BUSY -->|No| RESET --> PROMPT --> RESULT RESULT -->|social| SOCIAL --> WAIT RESULT -->|voice| VOICE --> WAIT RESULT -->|skip| SILENT --> WAIT WAIT --> BUSY

ツール — 6個

ADK Agent が呼び出すすべてのツール — tools.py

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 フォールバックチェーン
TavilyBraveDuckDuckGo

ファイル構成

neko/
src/
neko.pyメインループ · VAD · 状態機械 · web_api 起動
agent.pyADK LlmAgent + LiteLLM → llama-server :8080
tools.py6ツール定義 + @_trace デコレータ
memory.py短期 deque + 長期 SQLite+sqlite-vec+Gemini埋込
activity.py人間活動 DB CRUD (activities テーブル)
home_control.pySwitchBot デバイス抽象化レイヤー
switchbot.pySwitchBot v1.1 API · HMAC-SHA256署名
camera.pyRTSP取得 + ONVIF PTZ制御 · cv2 / PIL
whisplay_ui.pyLCD / LED / Button · rpi-lgpio + PIL 描画
tts.pyVOICEVOX → pyopenjtalk フォールバック
autonomous.py15〜90分乱数の自律観察ループ
web_api.pyHTTP API :4001 · /ask /broadcast /tool /ui_state
scripts/systemd/4 services
.env.localシークレット(git 管理外)

systemd サービス

Pi 起動時に自動立ち上がる 4 サービス

llama-server.service
:8080 · OpenAI互換API
Gemma 4 E2B Q4_K_M + mmproj-BF16。音声・画像・テキスト 3モーダル入力。
voicevox-engine.service
:50021 · REST API
VOICEVOX 0.25.2 ARM64。ずんだもん (id=3)。43話者対応。
neko.service
:4001 · Web API
メインアプリ。VAD常時待機・ADKエージェント・自律ループ・Web API 同居。
neko-bt-autoconnect.service
Bluetooth
Echo Dot BT自動再接続。bluez_output 経由で音声出力。
コマンド用途
ssh neko-piPi接続
sudo systemctl restart neko.serviceメインアプリ再起動
sudo journalctl -u neko.service -fリアルタイムログ追跡
curl http://localhost:8080/healthllama-server ヘルスチェック
rsync -avz --exclude='.git' --exclude='venv' ./ neko-pi:~/neko/Mac → Pi 同期