プロジェクト

全般

プロフィール

バグ #265

未完了

RAG機能プラグイン化検討: 設定ベース制御 vs 動的プラグインシステム

Redmine Admin さんが3日前に追加.

ステータス:
新規
優先度:
通常
担当者:
-
開始日:
2025-06-05
期日:
進捗率:

0%

予定工数:

説明

RAG機能プラグイン化検討: Redmine カスタムUIのモジュラー設計

🔍 現状分析

現在のアーキテクチャ

task2.call2arm.com
├── Redmine UI (React SPA) → 固定統合
├── Redmine API → dev.call2arm.com (プロキシ)
└── RAG API → task2-api:3002 (固定統合)

発見事項

  1. UI統合: RedmineカスタムUIにAIアシスタント機能が固定実装
  2. API統合: RAG機能がserver.jsに直接組み込み
  3. プラグイン機能: 現状では未実装 (enable/disable機能なし)
  4. 機能一覧: vector検索、Multi-LLM、チャット、ドキュメント処理

🎯 プラグイン化の必要性と利点

なぜプラグイン化が必要か?

1. 運用柔軟性

  • 🔄 RAG機能の停止/再開: メンテナンス時やリソース制限時
  • 段階的導入: 小規模テスト → 本格運用
  • 🛡️ 障害分離: RAG問題がRedmine機能に影響しない

2. ライセンス・コスト管理

  • 💰 OpenAI API: 使用量課金のコスト制御
  • 📊 リソース管理: ベクトルDB、Redis、Meilisearchの選択利用
  • 🔒 セキュリティ: AI機能の一時的無効化

3. 開発・テスト効率

  • 🧪 独立テスト: Redmine機能とRAG機能の分離テスト
  • 🔧 部分更新: RAG機能のみのアップデート
  • 📈 段階的機能追加: 新しいAI機能の安全な導入

🏗️ 提案するプラグイン化アーキテクチャ

レベル1: 設定ベース制御(推奨・即座実装可能)

環境変数による機能制御

# .env 設定例
ENABLE_RAG=true                    # RAG機能全体の有効/無効
ENABLE_AI_CHAT=true               # チャット機能
ENABLE_VECTOR_SEARCH=true         # ベクトル検索
ENABLE_DOCUMENT_PROCESSING=true   # ドキュメント処理
ENABLE_LLM_INTEGRATION=true       # LLM統合

# 外部サービス制御
OPENAI_API_ENABLED=true
CLAUDE_API_ENABLED=false
DEEPSEEK_API_ENABLED=false

サーバー側実装例

// app/api/src/middleware/FeatureToggle.js
class FeatureToggle {
    static requireFeature(featureName) {
        return (req, res, next) => {
            const enabled = process.env[`ENABLE_${featureName.toUpperCase()}`] === 'true';
            
            if (!enabled) {
                return res.status(503).json({
                    status: 'disabled',
                    message: `Feature '${featureName}' is currently disabled`,
                    feature: featureName
                });
            }
            next();
        };
    }
    
    static isEnabled(featureName) {
        return process.env[`ENABLE_${featureName.toUpperCase()}`] === 'true';
    }
}

// 使用例
app.use('/api/embeddings', FeatureToggle.requireFeature('RAG'), embeddingsRouter);
app.use('/api/chat', FeatureToggle.requireFeature('AI_CHAT'), chatRouter);

UI側制御例

// RedmineUI での機能表示制御
const features = {
    aiAssistant: await checkFeature('AI_CHAT'),
    vectorSearch: await checkFeature('VECTOR_SEARCH'),
    documentProcessing: await checkFeature('DOCUMENT_PROCESSING')
};

// 機能が無効な場合は非表示
{features.aiAssistant && <AIAssistantPanel />}
{features.vectorSearch && <VectorSearchBox />}

レベル2: モジュラープラグインシステム(高度実装)

プラグインマネージャー

// app/api/src/plugins/PluginManager.js
class PluginManager {
    constructor() {
        this.plugins = new Map();
        this.loadedPlugins = new Set();
    }
    
    registerPlugin(name, plugin) {
        this.plugins.set(name, plugin);
    }
    
    async loadPlugin(name) {
        const plugin = this.plugins.get(name);
        if (plugin && !this.loadedPlugins.has(name)) {
            await plugin.initialize();
            this.loadedPlugins.add(name);
            console.log(`Plugin '${name}' loaded`);
        }
    }
    
    async unloadPlugin(name) {
        const plugin = this.plugins.get(name);
        if (plugin && this.loadedPlugins.has(name)) {
            await plugin.shutdown();
            this.loadedPlugins.delete(name);
            console.log(`Plugin '${name}' unloaded`);
        }
    }
    
    isLoaded(name) {
        return this.loadedPlugins.has(name);
    }
}

RAGプラグイン実装

// app/api/src/plugins/RAGPlugin.js
class RAGPlugin {
    async initialize() {
        // ベクトルDB接続
        this.vectorDB = await connectVectorDB();
        // Redis接続
        this.redis = await connectRedis();
        // Meilisearch接続
        this.search = await connectMeilisearch();
        
        console.log('RAG Plugin initialized');
    }
    
    async shutdown() {
        await this.vectorDB?.close();
        await this.redis?.quit();
        await this.search?.close();
        
        console.log('RAG Plugin shutdown');
    }
    
    getRoutes() {
        return {
            '/api/embeddings': embeddingsRouter,
            '/api/chat': chatRouter,
            '/api/search': searchRouter
        };
    }
    
    getUIComponents() {
        return {
            aiAssistant: '/plugins/rag/ai-assistant.js',
            vectorSearch: '/plugins/rag/vector-search.js'
        };
    }
}

📊 実装優先度と段階的導入

Phase 1: 設定ベース制御(即座実装)

所要時間: 2-3時間
メリット: 即座にon/off制御可能

# 実装手順
1. .env にフィーチャーフラグ追加
2. FeatureToggle ミドルウェア作成
3. 既存ルートに適用
4. UI側で機能チェック実装
5. 管理画面で設定変更UI追加

Phase 2: 動的プラグインシステム(高度実装)

所要時間: 1-2週間
メリット: 完全なプラグイン分離

# 実装手順
1. PluginManager 実装
2. RAGPlugin 分離
3. 動的ルート管理
4. UI コンポーネント動的ロード
5. 管理画面でリアルタイム制御

🔧 即座実装案: 設定ベース制御

1. 環境変数設定

# /var/docker/task2-service/.env 追記
# ========== RAG機能制御 ==========
ENABLE_RAG=true
ENABLE_AI_CHAT=true
ENABLE_VECTOR_SEARCH=true
ENABLE_DOCUMENT_PROCESSING=true
ENABLE_LLM_INTEGRATION=true
OPENAI_API_ENABLED=true
CLAUDE_API_ENABLED=false

2. FeatureToggle実装

// app/api/src/middleware/FeatureToggle.js
// 上記コード実装

3. 既存ルート修正

// app/api/server.js
const FeatureToggle = require('./src/middleware/FeatureToggle');

// RAG機能にフィーチャーフラグ適用
if (FeatureToggle.isEnabled('RAG')) {
    app.use('/api/embeddings', FeatureToggle.requireFeature('RAG'), require('./src/routes/embeddings'));
    app.use('/api/chat', FeatureToggle.requireFeature('AI_CHAT'), chatRouter);
    app.use('/api/search', FeatureToggle.requireFeature('VECTOR_SEARCH'), searchRouter);
}

4. 管理UI追加

// 設定画面でリアルタイム制御
const toggleRAG = async (enabled) => {
    await fetch('/api/admin/features', {
        method: 'POST',
        body: JSON.stringify({ feature: 'RAG', enabled }),
        headers: { 'Content-Type': 'application/json' }
    });
    
    // UI更新
    location.reload();
};

📋 実装メリット・デメリット

設定ベース制御の場合

✅ メリット

  • 即座実装: 2-3時間で完成
  • 🛡️ 安全性: コンテナ再起動で確実に制御
  • 🔧 シンプル: 理解しやすい実装
  • 💰 コスト制御: API使用量の即座制御

❌ デメリット

  • 🔄 再起動必要: 設定変更時にコンテナ再起動
  • 🔒 静的制御: リアルタイム変更不可
  • 📊 粗い制御: 機能単位での制御

動的プラグインシステムの場合

✅ メリット

  • 🔄 リアルタイム: 無停止での機能切り替え
  • 🎯 細かい制御: 機能詳細レベルでの制御
  • 🚀 拡張性: 新プラグイン簡単追加
  • 📈 運用性: 本格的なエンタープライズ対応

❌ デメリット

  • ⏱️ 実装時間: 1-2週間必要
  • 🧩 複雑性: アーキテクチャが複雑化
  • 🐛 バグリスク: 動的制御による潜在的問題

🎯 推奨実装案

即座対応: 設定ベース制御

理由: Phase B完了後の即座実装で最大効果

長期計画: 動的プラグインシステム

理由: Phase C/D完了後の本格運用対応


⚡ 今すぐ実行可能なRAG制御

# RAG機能を一時停止
cd /var/docker/task2-service
echo "ENABLE_RAG=false" >> .env
docker-compose restart task2-api

# RAG機能を再開
echo "ENABLE_RAG=true" >> .env  
docker-compose restart task2-api

現在のRAG機能はRedmineカスタムUIに密結合していますが、提案する設定ベース制御により、柔軟な運用制御が実現できます。

表示するデータがありません

他の形式にエクスポート: Atom PDF