ローカルLLMで情報を集約する - プライバシーを守りながらAI活用する未来

ローカルLLMで情報を集約する - プライバシーを守りながらAI活用する未来

作成日:

「あの情報、どこにあったっけ...?」

LINE、Slack、Chatwork、Gmail、Markdownファイル...情報が散らばりすぎて、探すだけで時間がかかる。

「AIに聞けばいいのに」と思っても、機密情報をクラウドAPIに送るのは怖い。

だったら、ローカルで完結させればいいじゃん。

というわけで、ローカルLLMを使った情報収集・要約・RAGシステムの設計を始めました。

これが完成すれば、あらゆる情報を一箇所に集約し、AIに検索・要約・作業を任せられる未来がやってきます。

問題:情報が散らばりすぎている

日常的な情報の散在

エンジニアの日常は、情報の嵐です:

  • チャットツール: LINE、Slack、Chatwork、Microsoft Teams
  • メール: Gmail、Outlook
  • ドキュメント: Markdown、Google Docs、Notion
  • コード: GitHub、GitLab
  • メモ: Obsidian、Evernote

全部、別々の場所に。

情報を探す時間の無駄

「先週の会議で話したあの機能、どこで決まったっけ?」

  • Slackを検索:見つからない
  • Chatworkを検索:見つからない
  • Gmailを検索:見つからない
  • Markdownファイルを検索:見つからない

30分探して、結局見つからない。

これ、めちゃくちゃストレスです。

クラウドAPIの限界

「AIに聞けばいいのに」と思っても:

  • プライバシー: 機密情報をクラウドAPIに送るのは危険
  • コスト: API呼び出しのたびに課金
  • 依存: インターネット接続が必要
  • 制限: レート制限、トークン制限

理想と現実のギャップが大きい。

解決策:ローカルLLMシステム

コンセプト

すべてローカルで完結する、情報収集・要約・検索システム。

[各種サービス]
  ↓ 収集
[ローカル環境]
  ├─ フィルタリング(機密情報除外)
  ├─ 要約(AI自動生成)
  ├─ 検索(RAG)
  └─ 質問応答(AI自動回答)

特徴:

  1. コストゼロ: クラウドAPI不使用
  2. プライバシー保護: すべてローカルで処理
  3. オフライン動作: インターネット不要
  4. 完全制御: 自分でカスタマイズ可能

システムの全体像

システム全体像

データフロー:

  1. 収集: 各サービスから情報を取得
  2. フィルタリング: 機密情報を除外
  3. 処理: テキスト正規化、チャンキング、埋め込み生成
  4. 蓄積: ChromaDB(ベクトルDB)とWhoosh(全文検索)に保存
  5. 要約: AIが自動で要約を生成
  6. 検索・質問: RAGエンジンで回答生成

技術スタック

コア技術

const techStack = {
  llm: 'Ollama (ローカルLLM)',
  embedding: 'Sentence Transformers',
  vectorDB: 'ChromaDB',
  fullTextSearch: 'Whoosh',
  metadata: 'SQLite',
  interface: 'MCP Server (Cursor連携)',
  language: 'Python',
};

1. Ollama - ローカルLLM

公式サイト: https://ollama.ai/

ローカルでLLMを実行できるツール。

特徴:

  • 無料: 完全無料
  • オフライン: インターネット不要
  • 高速: ローカル実行なので速い
  • カスタマイズ: モデルを自由に選択

使用モデル:

  • Mistral(推奨)
  • Llama 2
  • Gemma

2. Sentence Transformers - 埋め込み生成

公式サイト: https://www.sbert.net/

テキストをベクトルに変換するライブラリ。

特徴:

  • 日本語対応: 日本語モデルが豊富
  • 高速: GPUで高速実行可能
  • 軽量: ローカルで動作

3. ChromaDB - ベクトルデータベース

公式サイト: https://www.trychroma.com/

ベクトル検索に特化したデータベース。

特徴:

  • セマンティック検索: 意味で検索できる
  • 軽量: SQLiteベースで簡単
  • 高速: ベクトル検索が速い

4. Whoosh - 全文検索

公式サイト: https://whoosh.readthedocs.io/

Python製の全文検索エンジン。

特徴:

  • 軽量: 依存関係が少ない
  • 高速: インデックス検索が速い
  • 日本語対応: 日本語の形態素解析に対応

5. MCP Server - Cursor連携

MCP: Model Context Protocol

Cursorから直接、システムを操作できる。

できること:

  • 情報の検索
  • 要約の生成
  • 質問への回答
  • データの収集

システムの主要コンポーネント

1. Collectors(収集層)

各サービスから情報を取得:

# src/collectors/
├── line_collector.py      # LINE API
├── slack_collector.py     # Slack API
├── chatwork_collector.py  # Chatwork API
├── teams_collector.py     # Microsoft Teams API
├── gmail_collector.py     # Gmail API
└── markdown_collector.py  # Markdownファイル

共通フォーマット:

{
    'id': 'unique_id',
    'source': 'slack',
    'channel': 'general',
    'author': 'user_name',
    'content': 'メッセージ内容',
    'timestamp': '2025-11-18T10:00:00Z',
    'metadata': {...}
}

2. Filters(フィルタリング層)

機密情報を除外:

# src/filters/
├── channel_filter.py      # チャンネル許可リスト
├── keyword_filter.py      # NGキーワード
├── pii_filter.py          # 個人情報検知
└── filter_manager.py      # フィルタの組み合わせ

フィルタリングの流れ:

1. チャンネル許可リストで絞り込み
2. NGキーワードで除外
3. PII(個人情報)を検知して除外
4. 除外したレコードは監査ログへ

3. Processors(処理層)

テキストを処理して、検索可能にする:

# src/processors/
├── text_normalizer.py     # テキスト正規化
├── chunker.py             # チャンキング
└── embedder.py           # 埋め込み生成

処理の流れ:

1. テキスト正規化(全角→半角、改行処理など)
2. チャンキング(適切なサイズに分割)
3. Sentence Transformersで埋め込み生成
4. ChromaDBに保存

4. Storage(ストレージ層)

データを保存・管理:

# src/storage/
├── chroma_wrapper.py      # ChromaDBラッパー
├── metadata_db.py         # SQLiteメタデータ
└── audit_log.py           # 監査ログ

保存先:

data/
├── raw/              # 生データ
├── vectors/          # ベクトル(ChromaDB)
├── index/            # 全文検索インデックス(Whoosh)
├── summaries/        # 要約結果
└── metadata.db       # SQLiteメタデータ

5. LLM(LLM統合層)

Ollamaと連携:

# src/llm/
├── base_llm.py           # LLM抽象クラス
├── ollama_client.py      # Ollamaクライアント
└── prompt_builder.py     # プロンプト構築

LLMの使い分け:

# config/llm.yaml
models:
  summarization: mistral
  qa: llama2
  embedding: sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2

6. Summarizers(要約層)

AIが自動で要約を生成:

# src/summarizers/
├── individual_summarizer.py  # 個別要約(メッセージ単位)
├── group_summarizer.py       # グループ要約(チャンネル/スレッド)
└── temporal_summarizer.py    # 時系列要約(期間集計)

要約の粒度:

  • 個別: 1つのメッセージを要約
  • グループ: チャンネルやスレッド全体を要約
  • 時系列: 1日/1週間/1ヶ月単位で要約

7. Search & RAG(検索・質問応答層)

セマンティック検索とRAG:

# src/search/
├── semantic_search.py    # セマンティック検索(ChromaDB)
├── fulltext_search.py    # 全文検索(Whoosh)
└── hybrid_search.py      # ハイブリッド検索

# src/qa/
├── rag_engine.py         # RAGエンジン
├── query_expander.py     # クエリ拡張
└── answer_generator.py   # 回答生成

検索の流れ:

1. クエリを拡張(類義語、関連語を追加)
2. セマンティック検索(意味で検索)
3. 全文検索(キーワードで検索)
4. ハイブリッド検索(両方の結果を統合)
5. 上位N件をRAGエンジンに渡す
6. LLMが回答を生成(ソース引用付き)

8. MCP Server(Cursor連携)

Cursorから直接操作:

# src/mcp/
├── server.py            # MCPサーバー
├── tools/
│   ├── search_tool.py   # 検索ツール
│   ├── summarize_tool.py # 要約ツール
│   ├── ask_tool.py      # 質問ツール
│   └── collect_tool.py  # 収集ツール
└── resources.py         # リソース定義

Cursorでの使い方:

CursorのComposerで:
「先週の会議で話した機能について検索して」
→ MCPサーバーが検索を実行
→ 結果をCursorに返す

実装のポイント

1. プライバシー保護

フィルタリングで機密情報を除外:

# NGキーワードの例
NG_KEYWORDS = [
    'パスワード',
    'APIキー',
    'クレジットカード',
    '個人情報',
    # ...
]

# PII検知
def detect_pii(text: str) -> bool:
    # メールアドレス、電話番号、クレジットカード番号などを検知
    patterns = [
        r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
        r'\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}',  # クレジットカード
        # ...
    ]
    # 検知したらTrue

2. 差分同期

効率的なデータ収集:

# 最後に取得した時刻を記録
last_sync = metadata_db.get_last_sync('slack', 'general')

# その時刻以降のメッセージのみ取得
messages = slack_api.get_messages(
    channel='general',
    after=last_sync
)

# 更新時刻を記録
metadata_db.update_last_sync('slack', 'general', now())

3. エラーハンドリング

失敗しても続行:

def collect_with_retry(collector, max_retries=3):
    for attempt in range(max_retries):
        try:
            return collector.collect()
        except Exception as e:
            log.error(f'Attempt {attempt + 1} failed: {e}')
            if attempt < max_retries - 1:
                time.sleep(2 ** attempt)  # 指数バックオフ
            else:
                log.critical('Max retries reached')
                return None

4. チャンキング戦略

適切なサイズに分割:

def chunk_text(text: str, chunk_size: int = 500, overlap: int = 50):
    """
    テキストを適切なサイズに分割
    - chunk_size: チャンクのサイズ(文字数)
    - overlap: オーバーラップ(前後のチャンクと重複)
    """
    chunks = []
    start = 0
    
    while start < len(text):
        end = start + chunk_size
        chunk = text[start:end]
        chunks.append(chunk)
        start = end - overlap  # オーバーラップ
    
    return chunks

5. ハイブリッド検索

セマンティック + 全文検索:

def hybrid_search(query: str, top_k: int = 10):
    # セマンティック検索(意味で検索)
    semantic_results = chroma_db.query(
        query_texts=[query],
        n_results=top_k
    )
    
    # 全文検索(キーワードで検索)
    fulltext_results = whoosh_index.search(query, limit=top_k)
    
    # 結果を統合(スコアで重み付け)
    combined = merge_results(
        semantic_results,
        fulltext_results,
        semantic_weight=0.7,
        fulltext_weight=0.3
    )
    
    return combined[:top_k]

期待される効果

1. 情報検索が劇的に速くなる

Before:

  • Slack検索:5分
  • Chatwork検索:5分
  • Gmail検索:5分
  • 合計:15分

After:

  • システムに質問:「先週の会議で話した機能について」
  • 回答:10秒

時間削減:99%

2. 要約で全体像を把握

「このチャンネル、最近何話してたっけ?」

→ AIが自動で要約:

【今週の要約】
- 新機能の設計について議論(3件)
- バグ修正の報告(5件)
- 次回ミーティングの日程調整(2件)

全体像が一目瞭然。

3. AIに作業を任せられる

CursorのComposerで:

「先月のプロジェクトの進捗をまとめて、Markdownで出力して」

→ AIが自動で:

  1. 関連情報を検索
  2. 要約を生成
  3. Markdown形式で出力

作業の自動化が可能に。

4. ナレッジベースの構築

蓄積された情報が、組織のナレッジベースに。

  • 過去の議論を検索
  • 決定事項を確認
  • ベストプラクティスを発見

組織の知恵が、一箇所に集約される。

実装のフェーズ

Phase 1: 基盤整備(1週間)

  • プロジェクト構造の作成
  • 依存関係の設定
  • 設定ファイルのテンプレート
  • ロギングの整備

Phase 2: ストレージ層(1週間)

  • ChromaDBのセットアップ
  • SQLiteメタデータDBの設計
  • Whoosh全文検索の設定
  • バックアップ機能

Phase 3: フィルタ層(1週間)

  • チャンネル許可リスト
  • NGキーワードフィルタ
  • PII検知機能
  • 監査ログ

Phase 4: Collector実装(2週間)

  • LINE Collector
  • Slack Collector
  • Chatwork Collector
  • Teams Collector
  • Gmail Collector
  • Markdown Collector

Phase 5: 処理パイプライン(1週間)

  • テキスト正規化
  • チャンキング
  • 埋め込み生成
  • インデックス構築

Phase 6: LLM統合(1週間)

  • Ollamaクライアント
  • プロンプトビルダー
  • エラーハンドリング
  • タイムアウト制御

Phase 7: 要約モジュール(2週間)

  • 個別要約
  • グループ要約
  • 時系列要約
  • バッチ処理

Phase 8: 検索・RAG(2週間)

  • セマンティック検索
  • 全文検索
  • ハイブリッド検索
  • RAGエンジン

Phase 9: MCP & CLI(2週間)

  • MCPサーバー実装
  • Cursor設定
  • CLIコマンド
  • スケジューラ

Phase 10: ドキュメント・運用(1週間)

  • README作成
  • 設定手順
  • 監視・ロギング
  • テスト自動化

合計:約12週間(3ヶ月)

今後の展望

1. 自動化の拡大

現在:

  • 情報の検索
  • 要約の生成
  • 質問への回答

将来:

  • レポートの自動生成
  • タスクの自動抽出
  • 会議議事録の自動作成
  • ドキュメントの自動更新

2. マルチモーダル対応

テキストだけでなく:

  • 画像のOCR
  • 音声の文字起こし
  • 動画の要約

すべての情報を統合。

3. 予測・提案機能

AIが提案:

  • 「この情報、関連する人に共有すべきでは?」
  • 「このタスク、期限が近いです」
  • 「この議論、過去の決定と矛盾していませんか?」

能動的な情報提供。

4. 組織への展開

個人のシステムから、組織全体のナレッジベースへ。

  • チーム全体の情報を集約
  • 部署を超えた情報共有
  • 組織の知恵の可視化

まとめ:情報の未来

ローカルLLMシステムを構築することで、情報の扱い方が根本的に変わると確信しています。

このシステムで実現できること:

  1. 情報検索の高速化: 15分 → 10秒
  2. 要約の自動化: AIが自動で要約生成
  3. 作業の自動化: AIに作業を任せられる
  4. ナレッジベースの構築: 組織の知恵を集約
  5. プライバシー保護: すべてローカルで完結
  6. コストゼロ: クラウドAPI不使用

技術的なポイント:

  • ローカルLLM: Ollamaでコストゼロ
  • RAG: セマンティック検索 + 全文検索
  • MCP連携: Cursorから直接操作
  • プライバシー: フィルタリングで機密情報を除外
  • 拡張性: プラガブル設計で柔軟に拡張

こんな人におすすめ:

  • 情報が散らばって困ってる人: 一箇所に集約したい
  • プライバシーを重視する人: ローカルで完結させたい
  • コストを抑えたい人: クラウドAPIを使いたくない
  • 自動化したい人: AIに作業を任せたい
  • ナレッジベースを作りたい人: 組織の知恵を蓄積したい

実装の難易度:

  • 設計: ★★★☆☆(複雑だが明確)
  • 実装: ★★★★☆(時間はかかるが実現可能)
  • 効果: ★★★★★(劇的な改善)

最後に: 情報が散らばっている時代は、もう終わりです。

ローカルLLMで、すべての情報を一箇所に集約し、AIに検索・要約・作業を任せる。

それが、このシステムが実現する未来です。

プライバシーを守りながら、AIの力を最大限に活用する。

それが、ローカルLLMシステムの価値です。


参考リンク:

次回は、実装の進捗や具体的なコード例について書く予定です。お楽しみに!