0.はじめに
フリーランスとして活動しているものです。
他の人の役に立つかは分かりませんがせっかく個人開発をするなら日記代わりに記事を残そうと思って書いてみることにしました。
これまでの人生幾度となくQiitaやブログに助けられた経験があるため誰かの助けになる部分があったらうれしいです。
1.開発しようとしたキッカケ
Notionで色々管理していたがスマホの操作に不便を感じたりもっと手軽に操作したかった
現在のNotionのイメージ
2.要件定義を始めてみる
そもそも
まず初めに手の空いた時間などでイメージを膨らませてメモをしていました
私のメモ方法はスマホのObsidianで書いたメモをGitHub経由でPCへ送って連携していました。
以下記事を参考にしてiPhoneに入れて移動中や寝る前などに書いていました。
スマホのObsidianをGitで同期(2024.11)
作成した原文が以下になります
## 現在の状態
現在Notionで管理している
冷凍庫や冷蔵庫に入っている料理を管理している
作ってあるものに食べる予定日や食べた日を入れて予定管理
その他にも買いたいものや話したいことなどのタスクを記録している
## 今プロジェクトでの目的
以下技術の習得を目指す
Raspberry Pi/Python/gemini API/Docker/音声認識AI
AIの高速な進化を考慮しクリーンアーキテクチャで開発し、将来的にAIを差し替えたりを想定する
テストコードを用いたCI/CDで安定した運用を目指す
## どうやって作りたいか
前提として全ての機能を一気に実装するわけでなく少しずつ進める
しかし、将来的に足枷にならないように未来のことも考えて汎用性を持たせたり疎結合な設計を行う
全ての実装はまず設計書を作ってから進める
設計書はマークダウンでリポジトリに含める
設計書を人間が確認してokなら実装を進める
テストコードは必ず書く
作業工程をQiitaの記事にするため作業を章に分けて進める
## 使用する開発環境
ハードウェアはRaspberry Pi 3 Model B+を使用する
言語はPython
Dockerを使用する
AIはgeminiを無料の範囲で使用する
音声の認識もgoogleのaiを使う
NotionMCPを使う https://notion.notion.site/Notion-MCP-1d0efdeead058054a339ffe6b38649e1
## 満たすべき要件
GUIとして必要なのは会話内容を表示するチャットウィンドウのみ
声掛けで買いたいものの追加や作ったものの保存などのNotionの操作をする
声掛けは常にスタンバイでなく、外付けのボタンを押すことで録音が始まる
声掛けに対してとったアクションを音声で返す
大きなカレンダーがあって全ての日ごとのイベント(食べた料理や買ったもの)が見られる
## 実現可能か調査から行う
Netflixやアマプラビデオで見た動画などを自動で記録する
TimeTreeのイベントを自動で拾ってくる
返答の音声はvoiceroid+またはvoiceroid2を使用する
GUIとして3dモデルまたはlive2dのキャラクターを表示する
表示されたキャラクターにリップシンクを追加する
日々の食べたものの画像をLINEなど何らかの画像を送る手段からnotionに保存する
3.AIと相談する
そしてそのノートをGemini CLIに読み込ませて以下のことをしてもらいました
- 整形
- アプリ名の提案
- 他の追加機能のアイディアを考えてもらう
作ってもらった要件定義書が以下になります
## 1. プロジェクト概要
本プロジェクトの名称は **NotiGenie (ノティジーニー)** とする。
この名称は、「Notion」と「Genie」(ランプの魔人)を組み合わせた造語であり、呼びかけるだけであらゆる情報整理やタスク管理を正確にこなしてくれる賢いアシスタント、というコンセプトを表している。
### 1.1. 背景
現在、Notionを利用して冷蔵庫・冷凍庫の在庫管理、食事の予定管理、日々のタスク管理を行っている。これらの操作をより効率的かつ直感的に行うため、音声対話型AIアシスタントを開発する。
### 1.2. 目的
本プロジェクトを通じて、以下の技術スタックの習得を目指す。
- Raspberry Pi
- Python
- Gemini API
- Docker
- 音声認識AI
また、将来的な技術の進化に追従できるよう、メンテナンス性の高いクリーンアーキテクチャを採用し、安定した運用を実現するためのCI/CDパイプラインを構築する。
---
## 2. 開発方針
- **設計思想**: AIモデルや外部サービスを容易に交換できるよう、クリーンアーキテクチャを採用し、疎結合な設計を徹底する。
- **開発プロセス**:
- 全ての機能は、まずMarkdown形式の設計書を作成してから実装に着手する。
- 段階的な機能リリースを基本とし、アジャイルに進める。
- 全てのロジックにはテストコードを記述し、品質を担保する。
- **ドキュメンテーション**: 開発の過程や得られた知見は、章ごとにQiitaの記事としてまとめる。
- **開発環境**:
- **エディタ**: Visual Studio Code
- **開発アシスタント**: Gemini CLI
- **開発スタイル**: Gemini CLIを活用し、要件定義、設計、実装、テストといった一連のサイクルをAIと対話しながら進める「AI駆動開発」を実践する。
---
## 3. 技術スタック
- **ハードウェア**: Raspberry Pi 3 Model B+
- **言語**: Python
- **プラットフォーム**: Docker
- **AI**:
- **LLM**: Gemini API (無料枠)
- **音声認識**: Google Cloud Speech-to-Text
- **連携サービス**: Notion (NotionMCPを利用)
---
## 4. 機能要件
### 4.1. コア要件 (MVP)
プロジェクトの初期段階で実現する必須機能。
- **音声入力**:
- 外部物理ボタンの押下をトリガーとして、音声録音を開始する。
- 「常に待機」状態にはしない。
- **Notion操作**:
- 音声指示により、Notionのデータベースを操作する。
- 例: 「〇〇を買いたいものリストに追加して」
- 例: 「カレーを作ったことを記録して」
- **音声フィードバック**:
- 実行したアクションの内容を音声で応答する。
- 例: 「買いたいものリストに〇〇を追加しました」
- **カレンダー表示**:
- 食事の履歴や買い物の履歴など、日付に紐づくイベントを一覧できるカレンダーをGUIに表示する。
### 4.2. 拡張要件
コア機能の実装後、段階的に追加する機能。
- **外部サービス連携**:
- TimeTreeと連携し、予定を自動で取得・同期する。
- NetflixやAmazon Prime Videoの視聴履歴を自動で記録する。
- **画像連携**:
- LINEなどの外部アプリケーションから送信された画像を、自動でNotionのデータベースに保存する。
### 4.3. 提案機能
今後、追加実装を検討すると便利な機能案。
- **インテリジェント・リマインダー**:
- NotionDB上のタスクの期限を認識し、適切なタイミングで音声通知する。
- カレンダーの空き時間とタスク量を連携させ、「午後にタスク〇〇を進めてはいかがですか?」のように能動的に提案する。
- **デイリー・ブリーフィング**:
- 毎朝、その日の天気、カレンダーの予定、Notionのタスクなどをまとめて音声でレポートする。
- **レシピ提案**:
- Notionで管理している食材在庫を基に、作れる料理のレシピを提案する。
- **自動要約**:
- Notionに保存したWebページや議事録などを指定し、内容を要約させて音声で確認する。
- **習慣トラッカー**:
- 「今日の勉強時間を記録」のように、定型的な活動を手軽にNotionへ記録する。
### 4.4. 要調査
実現可能性や具体的な方法を調査する必要があるアイデア。
- **高度な音声合成**:
- 返答の音声をVOICEROID+またはVOICEROID2に変更する。
- **高度なGUI**:
- 3DモデルまたはLive2DのキャラクターをGUIに表示する。
- キャラクターにリップシンク(発話に合わせた口の動き)を実装する。
---
## 5. 非機能要件
- **ユーザーインターフェース (GUI)**:
- 基本的なGUIは、ユーザーとの対話履歴を表示するチャットウィンドウのみとする。
4.タスクを分けて簡単なロードマップを作成する
ここもAIに手伝ってもらいました。
必要なタスクを優先度と難易度をつけてもらい何をすればよいかまとめてもらいます。
まとめてもらったロードマップが以下になります。
# NotiGenie 開発ロードマップ
このドキュメントは、NotiGenie開発の作業順序とタスクを定義します。
各タスクには、★☆☆☆☆(簡単)から★★★★★(困難)の難易度評価と、具体的な作業内容の説明が付与されています。
---
## Phase 0: 開発環境構築・セットアップ
開発に着手するための準備段階です。
- [ ] **[★★☆☆☆] Raspberry PiのOSセットアップとネットワーク接続**
- Raspberry Pi Imagerを使い、OSをSDカードに書き込みます。
- SSHを有効化し、Wi-Fiに接続してリモートで操作できるようにします。
- [ ] **[★☆☆☆☆] PythonおよびDockerのインストール**
- aptコマンドを使い、最新のPythonとDockerをインストールします。
- これにより、アプリケーションの実行環境とコンテナ基盤を整えます。
- [ ] **[★☆☆☆☆] プロジェクト用のGitリポジトリを作成し、Obsidianと連携**
- GitHub上でリポジトリを作成し、ローカルにクローンします。
- Obsidian Gitプラグインを設定し、ドキュメントの変更をGitで管理できるようにします。
- [ ] **[★★☆☆☆] Notion APIのセットアップと接続情報の取得**
- Notionのインテグレーションを作成し、APIキー(Internal Integration Token)を取得します。
- 操作対象のデータベースをインテグレーションに共有設定します。
- [ ] **[★★☆☆☆] NotionMCPの仕様を確認し、基本的な操作を試す**
- 公式ドキュメントを読み、NotionMCPのコンセプトを理解します。
- 簡単なPythonスクリプトで、ページの取得や作成ができることを確認します。
- [ ] **[★☆☆☆☆] Gemini APIキーを取得し、サンプルコードで動作確認**
- Google AI StudioからAPIキーを発行します。
- 公式のサンプルコードを使い、APIにリクエストを送信して正常なレスポンスが返ってくることを確認します。
- [ ] **[★★☆☆☆] Google Cloud Speech-to-Text APIを有効化し、動作確認**
- Google Cloud Platformでプロジェクトを作成し、APIを有効化します。
- 認証情報(サービスアカウントキー)を設定し、サンプル音声ファイルで文字起こしを試します。
- [ ] **[★☆☆☆☆] テキストを音声に変換するライブラリ(gTTSなど)を選定し、動作確認**
- Pythonで利用できるText-to-Speechライブラリをいくつか比較検討します。
- 選定したライブラリで、簡単なテキストを音声ファイルに変換・再生できることを確認します。
---
## Phase 1: MVP(コア機能)開発
アプリケーションの核となる、最低限の機能を実装する段階です。
### Step 1.1: 基本的な音声入出力
- [ ] **[★★☆☆☆] 物理ボタンの押下を検知するスクリプトを作成**
- Raspberry PiのGPIOピンに接続した物理ボタンの入力を監視します。
- ボタンが押されたことを検知し、特定の処理を呼び出すイベント駆動のスクリプトを作成します。
- [ ] **[★★☆☆☆] マイクから音声データを録音し、ファイルとして保存する機能を実装**
- USBマイクなどの入力デバイスから音声ストリームを取得します。
- 無音区間を検知して録音を自動で停止し、WAVなどの標準的な形式でファイルを保存します。
- [ ] **[★★★☆☆] 録音された音声ファイルをSpeech-to-Text APIに送信し、テキストに変換する機能を実装**
- 保存された音声ファイルをAPIのエンドポイントに送信します。
- 返却されたJSONから、変換後のテキストデータを抽出する処理を実装します。
- [ ] **[★★☆☆☆] 任意のテキストを音声ファイルに変換し、再生する機能を実装**
- アプリケーションからの応答メッセージ(テキスト)をText-to-Speechライブラリに渡します。
- 生成された音声をリアルタイムで再生し、ユーザーにフィードバックします。
### Step 1.2: クリーンアーキテクチャとAI連携
- [ ] **[★★★★☆] クリーンアーキテクチャに基づいたディレクトリ構造と、主要なクラスのひな形を作成**
- 関心事を分離するため、Entities, Use Cases, Interface Adapters, Frameworks & Driversの4層に対応するディレクトリを作成します。
- 各層の責務に応じたクラスのインターフェースと基本的な実装を定義します。
- [ ] **[★★★★☆] ユーザーの発話から、その意図とパラメータを抽出するよう、Gemini APIに指示するプロンプトを設計**
- 「[買い物リスト]に[牛乳]を追加して」といった自然言語から、意図(Intent)とパラメータ(Entity)をJSON形式で返すようにプロンプトを工夫します。
- 精度向上のため、Few-shot-learningなどのテクニックも検討します。
- [ ] **[★★★☆☆] 抽出した意図とパラメータを基に、Notionを操作するロジックを実装**
- AIが返したJSONを解釈し、対応するNotion操作(DBへの行追加、更新など)を実行する処理を実装します。
- 様々な意図に対応できるよう、汎用的なディスパッチャを設計します。
### Step 1.3: コア機能の実装と連携
- [ ] **[★★★★☆] Step 1.1と1.2を連携させ、一連の流れを実装**
- ボタン入力、録音、文字起こし、意図解釈、Notion操作、音声応答という一連の処理をパイプラインとして結合します。
- 各モジュール間のデータの受け渡しを定義し、全体を統合します。
- [ ] **[★★★☆☆] 同様に、「作ったもの(料理在庫)の保存」機能を実装**
- 「買い物リストへの追加」機能で実装したロジックを拡張します。
- 新しい意図「料理在庫の保存」を追加し、対応するNotionデータベースへの操作を実装します。
### Step 1.4: GUIの実装
- [ ] **[★★☆☆☆] GUIライブラリ(Tkinter, PySimpleGUIなど)を選定**
- Pythonで利用可能なGUIライブラリの特性(学習コスト、表現力、Raspberry Piでの動作実績)を比較検討し、プロジェクトに最適なものを選択します。
- [ ] **[★★★☆☆] ユーザーとの対話履歴を表示する、基本的なチャットウィンドウを作成**
- ユーザーの発話とAIの応答を時系列で表示するシンプルなUIを作成します。
- テキストの表示エリアと、必要に応じてスクロールバーを実装します。
- [ ] **[★★★★☆] Notionから日付に紐づくイベントを取得し、カレンダー形式で表示するコンポーネントを実装**
- Notion APIを定期的に呼び出し、食事履歴などのデータを取得します。
- 取得したデータを整形し、月間カレンダーの該当日付にイベントとして表示するウィジェットを作成します。
---
## Phase 2: 拡張機能と運用の安定化
アプリケーションをより便利にし、継続的な開発を容易にする段階です。
- [ ] **[★★★☆☆] TimeTree APIの仕様を調査し、イベント取得機能を実装**
- TimeTreeのAPIドキュメントを確認し、OAuth認証フローを実装します。
- 特定カレンダーの予定を取得し、アプリケーション内で利用できる形式に変換します。
- [ ] **[★★★★☆] LINE Messaging APIなどを利用し、受信した画像をNotionにアップロードする機能を実装**
- LINE Botを作成し、Webhook URLを設定します。
- ユーザーから送信された画像メッセージを受け取り、そのバイナリデータをNotion API経由で特定のページにアップロードします。
- [ ] **[★★★☆☆] GitHub Actionsなどを利用したCI/CDパイプラインを構築し、テストの自動化を行う**
- リポジトリへのpushをトリガーに、自動でテストコードを実行するワークフローを作成します。
- 将来的には、テスト成功後にDockerイメージをビルドし、自動デプロイする仕組みを目指します。
---
## Phase 3: 高度化と発展
アプリケーションをより洗練させ、新たな価値を付加する段階です。
- [ ] **[★★★★☆] `提案機能`としてリストアップした機能の設計と実装**
- リマインダーやレシピ提案など、複数の情報を組み合わせて価値を生む機能を設計します。
- どのデータを使い、どのタイミングで、どのようにユーザーに提示するかを定義し、実装します。
- [ ] **[★★★★★] `要調査`としてリストアップした項目の実現可能性調査と技術検証**
- VOICEROID連携や3Dモデル表示など、未知数の多い技術の調査を行います。
- 実現方法、必要なライブラリ、開発コストなどを評価し、小規模なプロトタイプ(PoC)を作成して技術的な実現性を検証します。
5.まとめ
AIに手伝ってもらうことでこれまでよりも楽に要件をまとめてやるべきことの方針が見えるようになったかと思います。
ObsidianとGemini CLIの組み合わせは考え事や調査にとても適した組み合わせだと思います。
実際の開発をやったことがない方でもそもそも何がしたいのか、どんなことをやればいいのかを考えるのにとても優秀な相棒となってくれると思います。
また時間のある時に地道に進めていこうと思っています
次回: まだなし