#アーキテクチャ概要
#技術スタック
| レイヤー | 技術 | 備考 |
|---|---|---|
| フロントエンド | React + TypeScript | Vite 推奨 |
| フロー図レンダリング | Mermaid.js | securityLevel: 'strict' + DOMPurifyでXSS対策必須 |
| バックエンド | Python + FastAPI | OpenAPI自動生成 |
| ORM | SQLAlchemy + Alembic | マイグレーション管理 |
| 認証 | JWT (python-jose) + HttpOnly Cookie | ロール: admin / employee。LocalStorage保存は禁止 |
| Orchestration | LlamaIndex | RAGパイプライン司令塔 |
| ベクトルDB | ChromaDB | 単一コレクション・メタデータフィルタ方式 |
| BM25相当 | PostgreSQL 全文検索 (tsvector + GIN index) | SudachiPy でトークナイズ後にDBへ格納 |
| Reranker | hotchpotch/japanese-reranker-cross-encoder-large-v1 | 日本語対応cross-encoder(ローカル実行) |
| LLM | Ollama (gemma3:27b 推奨) | ホスト直接起動(ollama serve)。Metal GPU使用。詳細は下記モデル比較表を参照 |
| Embedding | intfloat/multilingual-e5-large | ホスト直接起動(FastAPI内)。Metal MPS使用。query:/passage: prefix 必須 |
| 日本語トークナイザ | SudachiPy | BM25・全文検索のトークン分割に使用 |
| DB | PostgreSQL 16 | 構造化データ・バージョン管理・全文検索・監査ログ |
| コンテナ | Docker + docker-compose | DBのみ(PostgreSQL・ChromaDB)。named volume必須 |
| ファイル種別検証 | python-magic | MIMEタイプをバイナリシグネチャで検証(拡張子偽装対策) |
| バックエンドテスト | pytest + pytest-asyncio + httpx | 非同期テスト対応・FastAPI TestClient |
| テストカバレッジ | pytest-cov | カバレッジ計測・レポート出力 |
| テスト環境管理 | pytest-dotenv | .env.test を自動読み込み |
| フロントエンドテスト | Vitest + Testing Library | コンポーネント単体テスト(jsdom環境) |
| APIモック(FE) | MSW(Mock Service Worker) | フロントエンドテスト時のバックエンドAPIをモック |
#ポート対応表
| サービス | 開発 | テスト | 備考 |
|---|---|---|---|
| PostgreSQL | 5432 | 5433 | テスト用は開発DBと衝突しないよう別ポート |
| ChromaDB | 8001 | 8002 | テスト用は開発環境の8001と衝突しないよう別ポート |
| FastAPI (uvicorn) | 8000 | 8000 | テスト時は TestClient 経由のためポート不使用 |
| Frontend (Vite dev) | 3000 | — | 開発時のみ(本番は Nginx で配信) |
| Ollama | 11434 | 11434 | テストではモック(実サーバー不要) |
#LLMモデル選定(Mac Studio M4 Max 48GB 前提)
利用可能メモリの試算: 48GB − システム9GB − Embedding2.5GB − Reranker2GB − FastAPI1GB ≈ LLMに使える上限 ~33GB
| モデル | メモリ(Q4_K_M) | 日本語品質 | tok/s概算 | 採否 |
|---|---|---|---|---|
| gemma3:27b | ~17GB | ★★★★★ | 30〜40 | ✅ 推奨(デフォルト) Google製・128K文脈・日本語精度トップクラス |
| qwen2.5:32b | ~19GB | ★★★★★ | 26〜34 | 🔁 有力な代替候補。日本語品質はgemma3と拮抗。Alibaba製・Apache 2.0 |
| qwen3:30b | ~19GB | ★★★★★ | 26〜34 | 🔁 Qwen最新版(2025)。思考モード(thinking ON/OFF)あり |
| gemma3:12b | ~8GB | ★★★★ | 50〜60 | ⚡ 速度優先フォールバック。品質は27bに劣るが十分実用的 |
| llama3.3:70b | ~40GB | ★★★★ | 10〜15 | ❌ 33GBを超えるため48GB環境ではメモリ不足で搭載不可 |
| llama3.1:8b | ~5GB | ★★★ | 70〜90 | ❌ 速いが日本語の複雑な質問・長文理解に弱くRAG用途では非推奨 |
#開発途中でのモデル変更について
LLMモデルは開発中・本番稼働後でも自由に変更できる。 手順は以下のみ:
# 1. 新しいモデルをダウンロード(例: gemma3:27b → qwen2.5:32b)
ollama pull qwen2.5:32b
# 2. .env の OLLAMA_MODEL を変更
OLLAMA_MODEL=qwen2.5:32b
# 3. FastAPI を再起動するだけ(DBへの影響ゼロ)| 変更対象 | 影響範囲 | 対応作業 |
|---|---|---|
LLMモデル (OLLAMA_MODEL) | なし | ollama pull → .env 変更 → 再起動のみ |
Embeddingモデル (EMBEDDING_MODEL) | ⚠️ ChromaDB 全データ無効 | 全ドキュメントを再Ingestion必須(ベクトル空間が変わるため) |
⚠️ Embeddingモデルだけは変更コストが高い。
intfloat/multilingual-e5-largeは一度決めたら変えないこと。revision をconfigで固定しているのもこの理由。
#ディレクトリ構成(モノレポ)
/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPIエントリポイント・CORS設定
│ │ ├── config.py # pydantic-settings で環境変数読み込み・起動時バリデーション
│ │ ├── database.py # DB接続・セッション管理
│ │ ├── models/ # SQLAlchemy ORM モデル
│ │ │ ├── user.py
│ │ │ ├── document.py # documents + document_versions
│ │ │ ├── category.py
│ │ │ ├── chat.py # chat_sessions + chat_messages
│ │ │ └── audit.py # audit_logs
│ │ ├── schemas/ # Pydantic スキーマ(バリデーション)
│ │ │ ├── auth.py
│ │ │ ├── user.py
│ │ │ ├── document.py
│ │ │ └── chat.py
│ │ ├── api/ # APIエンドポイント
│ │ │ ├── auth.py # login / logout / refresh / me / reset-password
│ │ │ ├── documents.py # CRUD + バージョン管理
│ │ │ ├── categories.py # カテゴリ管理
│ │ │ ├── users.py # ユーザー管理 (admin only)
│ │ │ ├── chat.py # POST /chat (RAG呼び出し)
│ │ │ └── health.py # GET /health (全コンポーネント疎通確認)
│ │ ├── core/
│ │ │ ├── security.py # JWT発行・検証・Cookie操作
│ │ │ └── dependencies.py # require_admin / require_employee
│ │ └── rag/
│ │ ├── chroma_client.py # ChromaDBクライアント生成(環境別に切替)
│ │ ├── ingestion.py # ドキュメント取り込み・Embedding・tsvector更新
│ │ ├── retrieval.py # Hybrid Search(ChromaDB + PostgreSQL全文検索)+ Reranker
│ │ └── generation.py # Ollama呼び出し・プロンプト設計・Mermaidパーサー
│ ├── tests/ # テストコード(開発DBを汚染しない)
│ │ ├── conftest.py # DB・AIコンポーネントの共通フィクスチャ(モック集約)
│ │ ├── unit/ # 単体テスト(AIモデルはすべてモック)
│ │ │ ├── test_security.py
│ │ │ ├── test_ingestion.py
│ │ │ └── test_retrieval.py
│ │ └── integration/ # 統合テスト(テストDB使用・AIモデルはモック)
│ │ ├── test_auth.py
│ │ ├── test_documents.py
│ │ └── test_chat.py
│ ├── alembic/ # DBマイグレーション
│ │ └── versions/
│ ├── alembic.ini
│ ├── pyproject.toml
│ └── requirements.txt
├── frontend/
│ ├── src/
│ │ ├── __tests__/ # テストコード
│ │ │ ├── setup.ts # MSW(Mock Service Worker)セットアップ
│ │ │ ├── mocks/
│ │ │ │ └── handlers.ts # APIモックハンドラー
│ │ │ ├── components/ # コンポーネント単体テスト
│ │ │ └── pages/ # ページ統合テスト
│ │ ├── components/
│ │ │ ├── common/ # 共通UI部品(Button, Modal等)
│ │ │ ├── admin/ # 管理者画面コンポーネント
│ │ │ └── chat/ # チャット画面コンポーネント
│ │ ├── pages/ # ページコンポーネント
│ │ │ ├── LoginPage.tsx
│ │ │ ├── AdminDashboardPage.tsx
│ │ │ ├── DocumentListPage.tsx
│ │ │ ├── DocumentEditPage.tsx
│ │ │ ├── CategoryPage.tsx
│ │ │ ├── UserManagePage.tsx
│ │ │ └── ChatPage.tsx
│ │ ├── hooks/ # カスタムフック
│ │ ├── services/ # API呼び出し(axios等)
│ │ ├── types/ # TypeScript型定義
│ │ ├── store/ # 状態管理(Zustand等)
│ │ ├── App.tsx
│ │ └── main.tsx
│ ├── package.json
│ ├── tsconfig.json
│ └── vite.config.ts
├── scripts/
│ ├── init-env.sh # SECRET_KEY自動生成・.env初期化
│ ├── start-dev.sh # 開発環境起動(DB Docker + Ollama + FastAPI + Frontend案内)
│ ├── start-test.sh # テスト環境起動(テスト用DB Docker起動 → pytest実行)
│ └── start-prod.sh # 本番環境起動
├── docker-compose.yml # 開発用DB(PostgreSQL・ChromaDB)
├── docker-compose.test.yml # テスト用DB(別ポート・tmpfs使用・使い捨て)
├── docker-compose.prod.yml # 本番用DB設定
├── .env.example # 全環境変数の雛形
├── .env.test # テスト環境デフォルト値(git管理可・秘匿情報なし)
└── README.md