Issue #85: 設計検討: CLIからサーバアーキテクチャへの移行提案 (2025年版)
Opened 2025/8/2 by @nyasuto Open
enhancement priority: high type: infrastructure
Description
設計検討: CLIからサーバアーキテクチャへの移行提案 (2025年版)
🎯 移行目的の明確化
個人利用に特化したアーキテクチャ改善
- マーケット展開予定なし
- 現在のObsidian連携機能の維持・強化
- パフォーマンスと開発効率の向上
📊 現在のCLI実装の課題
コード複雑度
- 73ファイル、400+関数の高度に結合したアーキテクチャ
- MCP (Model Context Protocol) サーバとしての複雑な統合
- プラットフォーム依存のSQLite統合(CGO、FTS5)
技術的負債
mory/
├── cmd/mory/ # CLI エントリポイント
├── internal/
│ ├── memory/ # コア記憶ストレージ
│ ├── mcp/ # MCP サーバ実装
│ ├── obsidian/ # Obsidian統合 (維持対象)
│ └── config/ # 設定管理
└── 複雑なビルドプロセス (CGO_ENABLED=1, sqlite_fts5 tags)
🚀 推奨技術スタック
主要選択肢: Python + FastAPI
選択理由:
- AIエコシステムとの最高の親和性
- 豊富な機械学習ライブラリ
- 迅速なプロトタイピング能力
- 個人プロジェクトに最適
# アーキテクチャ例
fastapi_app/
├── api/
│ ├── memories.py # 記憶管理API
│ ├── search.py # 検索API
│ └── obsidian.py # Obsidian連携API
├── core/
│ ├── storage.py # SQLite + ベクトルDB
│ ├── semantic.py # セマンティック検索
│ └── embeddings.py # OpenAI embeddings
└── integrations/
└── obsidian/ # Obsidian連携 (後期実装)
代替選択肢
- Rust + Axum (高性能重視)
- Go + Gin (バランス重視)
🗄️ データベース戦略: シンプルさ重視
SQLite継続の根拠(個人利用最適化)
✅ SQLiteの利点
- シンプルさ: ファイル1つで完結
- バックアップ容易:
cp memories.db backup.dbで完了 - 依存関係なし: 追加サービス不要
- 十分な性能: 個人利用では全く問題なし
- FTS5対応: 現在と同等の検索性能維持
❌ コンテナDB化のリスク
# 避けたい複雑化
services:
mory-server: {...}
postgres: {...} # ← 管理コンポーネント増加
redis: {...} # ← 障害ポイント増加
backup: {...} # ← 設定複雑化
📊 複雑度比較
| 構成 | コンポーネント数 | 起動手順 | 障害ポイント | 個人利用適性 |
|---|---|---|---|---|
| SQLite | 1個 | ./mory-server |
1個 | ✅ 最適 |
| SQLite + Docker | 2個 | docker-compose up |
2個 | ✅ 良好 |
| PostgreSQL + Docker | 3個 | docker-compose up |
3個 | ⚠️ 過剰 |
🎯 推奨構成: SQLite + FastAPI
# SQLAlchemy + SQLite (シンプル&高性能)
from sqlalchemy import create_engine
from sqlalchemy.pool import StaticPool
engine = create_engine(
"sqlite:///data/memories.db",
poolclass=StaticPool,
connect_args={
"check_same_thread": False,
"timeout": 20
}
)
# FTS5サポート継続
@event.listens_for(engine, "connect")
def enable_fts5(dbapi_connection, connection_record):
dbapi_connection.execute("PRAGMA journal_mode=WAL")
dbapi_connection.execute("PRAGMA synchronous=NORMAL")
🐳 デプロイメント戦略
推奨アプローチ: ハイブリッド構成
開発環境: Docker
# docker-compose.dev.yml
version: '3.8'
services:
mory-dev:
build:
context: .
target: development
volumes:
- .:/app # ライブリロード
- ~/Documents/Obsidian:/obsidian # 実際のヴォルト
- ./dev-data:/app/data # 開発データ
ports:
- "8080:8080"
environment:
- ENVIRONMENT=development
本番環境: systemdサービス (推奨)
# /etc/systemd/system/mory.service
[Unit]
Description=Mory Personal Memory Server
After=network.target
[Service]
Type=simple
User=mory
WorkingDirectory=/opt/mory
ExecStart=/opt/mory/venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8080
Environment=MORY_DATA_DIR=/home/mory/data
Environment=MORY_OBSIDIAN_VAULT_PATH=/home/mory/Documents/Obsidian
Restart=always
[Install]
WantedBy=multi-user.target
📂 データ永続化設計
ディレクトリ構造
/home/mory/
├── data/
│ ├── memories.db # SQLite メインDB
│ ├── vectors/ # ベクトルデータ(Pinecone等)
│ ├── backups/ # 自動バックアップ
│ └── logs/ # アプリケーションログ
├── config/
│ ├── server.yaml # サーバ設定
│ └── .env # OpenAI API Key等
└── Documents/Obsidian/ # 既存ヴォルト(変更なし)
自動バックアップ機能
@scheduler.scheduled_job('cron', hour=2) # 毎日2時
async def backup_data():
backup_path = f"/home/mory/data/backups/backup_{datetime.now().strftime('%Y%m%d')}.db"
shutil.copy2("/home/mory/data/memories.db", backup_path)
cleanup_old_backups(days=30) # 30日保持
🚀 デプロイメント利点
| 項目 | Docker開発 | systemd本番 | 利点 |
|---|---|---|---|
| 開発効率 | ✅ 高速セットアップ | - | 依存関係分離 |
| 本番安定性 | - | ✅ システム統合 | 自動再起動、ログ管理 |
| Obsidian連携 | ⚠️ マウント | ✅ 直接アクセス | ファイル監視、リアルタイム |
| パフォーマンス | ⚠️ 軽微オーバーヘッド | ✅ ネイティブ | 最大性能 |
| バックアップ | ⚠️ 手動 | ✅ 自動化 | cron統合 |
📋 段階的移行計画
Phase 1: コア機能移行 (4-6週間) 🎯 優先
- SQLite + FTS5 → Python SQLAlchemy移行
- セマンティック検索エンジン移植
- 基本API実装 (save/get/list/search/delete)
- OpenAI embeddings統合
- 既存データ移行ツール
Phase 2: 検索・AI機能 (3-4週間)
- ハイブリッド検索(キーワード + セマンティック)
- ベクトルデータベース統合検討
- パフォーマンス最適化
- REST API完成
Phase 3: 統合機能 (3-4週間) 📝 Obsidian連携
- Obsidian統合の完全移植
obsidian_importAPI化generate_obsidian_noteAPI化- ファイルシステム直接アクセス維持
- リアルタイム同期機能
- ファイル監視とWebhook対応
Phase 4: 完成・移行 (2-3週間)
- データ移行と検証
- パフォーマンステスト
- ドキュメント更新
- 本番デプロイ
💡 Obsidian連携の詳細方針
✅ 維持される機能
# 現在のMCPツールをREST APIに移植
@app.post("/api/obsidian/import")
async def import_vault(vault_path: str, options: ImportOptions):
"""既存のobsidian_import機能をAPI化"""
return await obsidian_service.import_vault(vault_path, options)
@app.post("/api/obsidian/generate")
async def generate_note(request: GenerateRequest):
"""既存のgenerate_obsidian_note機能をAPI化"""
return await obsidian_service.generate_note(request)
🚀 強化される機能
- リモートアクセス: 外出先からのObsidian連携
- リアルタイム同期: ファイル変更の即座反映
- 複数デバイス対応: 同一ヴォルトへの同時アクセス
🔄 2025年AIアシスタント対応
主要トレンド統合
- Vector Databases: Pinecone, Weaviate統合対応
- Microservices: FastAPI + AsyncIO
- Real-time Communication: WebSocket対応
- AI Agent Memory: 長期記憶アーキテクチャ
パフォーマンス期待値
- レスポンス時間: CLI 500ms → API 100ms以下
- 検索性能: 現在の391μs → 50μs未満(ベクトルDB使用時)
- 並行処理: 単一プロセス → 非同期マルチリクエスト
🔮 将来の拡張オプション
段階的複雑化が必要になった場合:
# 環境変数での切り替え対応
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///data/memories.db")
# SQLite: sqlite:///data/memories.db
# PostgreSQL: postgresql://user:pass@localhost/mory
engine = create_engine(DATABASE_URL)
結論: まずはSQLite継続で、必要に応じて後から選択肢を増やす
🎯 次のステップ
- 技術スタック最終決定 (Python + FastAPI + SQLite推奨)
- Phase 1詳細設計 - 基本機能移行計画
- 既存データ移行戦略 - データ完全性保証
- Obsidian連携は Phase 3で対応 - 基本機能安定後
💭 ディスカッション
- 技術スタック選択についてのご意見
- 移行スケジュールの妥当性
- デプロイメント戦略(Docker vs systemd)
- データベース戦略(SQLite継続 vs 複雑化)
- 優先度の調整
🤖 Generated with Claude Code## 🚀 Phase 1 実装開始:決定事項まとめ
✅ 確定仕様
- 技術スタック: Python + FastAPI + SQLite
- 開発方針: CLI版停止、Phase1から新アーキテクチャ開始
- デプロイ先: 自宅内サーバ(Linux) 🏠
- 重要要件: 複数マシンからのアクセス対応
- データ移行: 数MB、ダウンタイム制限なし
🌐 ネットワーク設計(重要)
自宅内サーバ構成
# 自宅内ネットワーク想定
自宅サーバ: 192.168.1.100:8080
├── MacBook Pro → http://192.168.1.100:8080
├── デスクトップPC → http://192.168.1.100:8080
└── その他デバイス → http://192.168.1.100:8080
systemd設定(自宅サーバ用)
# /etc/systemd/system/mory.service
[Unit]
Description=Mory Personal Memory Server
After=network.target
[Service]
Type=simple
User=mory
WorkingDirectory=/opt/mory
ExecStart=/opt/mory/venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8080
Environment=MORY_DATA_DIR=/home/mory/data
Environment=MORY_OBSIDIAN_VAULT_PATH=/home/mory/Documents/Obsidian
Restart=always
[Install]
WantedBy=multi-user.target
📋 Phase 1 実装スコープ(確定)
必須API (RESTful)
# 基本記憶管理
POST /api/memories # save_memory
GET /api/memories/{key} # get_memory
GET /api/memories # list_memories
POST /api/memories/search # search_memories
DELETE /api/memories/{key} # delete_memory
# 管理API
GET /api/health # ヘルスチェック
GET /api/stats # 統計情報
データ移行ツール
# 既存CLIデータ → 新SQLite変換
python migrate_cli_to_server.py
# - 既存memories.jsonを読み込み
# - 新しいSQLiteスキーマに変換
# - セマンティック検索データ移行
🛠️ Phase 1 開発ステップ
Week 1-2: 基盤構築
- FastAPI プロジェクト初期化
- SQLAlchemy + SQLite設定
- 基本的なCRUD API実装
- 既存データ移行スクリプト
Week 3-4: 検索機能
- FTS5検索エンジン統合
- OpenAI embeddings統合
- ハイブリッド検索実装
- パフォーマンステスト
Week 5-6: ネットワーク・デプロイ
- 複数マシンアクセステスト
- systemd設定とデプロイ自動化
- 基本的なWeb UI(Phase3準備)
- 運用テスト
🔮 Phase 3 準備(GUI要件)
# Web UI フレームワーク候補
- Streamlit(簡単、AI特化)
- React + TypeScript(フル機能)
- FastAPI + Jinja2(シンプル)
# 複数マシン対応の考慮点
- レスポンシブ設計
- リアルタイム同期(WebSocket)
- ブラウザ履歴管理
🎯 次のアクション
- Phase 1 開発環境セットアップ
- FastAPI プロジェクト初期化
- 既存データ移行計画詳細化## 🔐 認証戦略: シンプル化方針
個人利用における認証不要の判断
✅ 認証機能を省略する理由
- 利用者: 単一ユーザー(個人のみ)
- ネットワーク: 自宅内プライベート環境
- デバイス: 複数だが全て個人所有
- セキュリティ: ルーターレベルで十分
🏠 自宅内セキュリティモデル
# ネットワークレベル保護
自宅ルータ: 192.168.1.0/24
├── 外部ポート8080: 閉鎖
├── 内部アクセス: 全許可
└── WiFi認証: 既存セキュリティで十分
📡 API設計の簡素化
# 認証ヘッダー不要のシンプルAPI
@app.get("/api/memories")
async def list_memories():
"""認証チェックなし - 直接データ返却"""
return await memory_service.list_all()
@app.post("/api/memories/search")
async def search_memories(query: SearchRequest):
"""セッション管理なし - ステートレス検索"""
return await memory_service.search(query)
🚀 開発効率の向上
省略される実装:
- ユーザー登録・ログイン画面
- JWT/セッション管理
- 権限チェック機能
- パスワード管理
集中できる価値:
- 記憶管理の核心機能
- 検索性能の最適化
- Obsidian統合の完成度
- 複数デバイスでのUX
🔮 将来の拡張性
# 必要になった場合の追加方針
if os.getenv("ENABLE_AUTH", "false").lower() == "true":
# 後から認証機能を追加可能
app.add_middleware(AuthMiddleware)
結論: Phase 1-3において認証機能は実装せず、シンプルなAPI設計に集中
Comments
コメント機能は現在実装されていません。
GitHub API の comments エンドポイントを統合する予定です。
🤖 AI分析
分類結果
✨ 新機能
64%
🟠 高
76%
76 スコア
カテゴリ 40
優先度 36
0 適用されたルール
Enhanced Feature Request Detection
64%
• Has matching label: "enhancement"
Details
Assignees:
None
Milestone:
None
Created:
2025/8/2
Updated:
2025/8/2