
ローカル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自動回答)
特徴:
- コストゼロ: クラウドAPI不使用
- プライバシー保護: すべてローカルで処理
- オフライン動作: インターネット不要
- 完全制御: 自分でカスタマイズ可能
システムの全体像
データフロー:
- 収集: 各サービスから情報を取得
- フィルタリング: 機密情報を除外
- 処理: テキスト正規化、チャンキング、埋め込み生成
- 蓄積: ChromaDB(ベクトルDB)とWhoosh(全文検索)に保存
- 要約: AIが自動で要約を生成
- 検索・質問: 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が自動で:
- 関連情報を検索
- 要約を生成
- 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システムを構築することで、情報の扱い方が根本的に変わると確信しています。
このシステムで実現できること:
- 情報検索の高速化: 15分 → 10秒
- 要約の自動化: AIが自動で要約生成
- 作業の自動化: AIに作業を任せられる
- ナレッジベースの構築: 組織の知恵を集約
- プライバシー保護: すべてローカルで完結
- コストゼロ: クラウドAPI不使用
技術的なポイント:
- ローカルLLM: Ollamaでコストゼロ
- RAG: セマンティック検索 + 全文検索
- MCP連携: Cursorから直接操作
- プライバシー: フィルタリングで機密情報を除外
- 拡張性: プラガブル設計で柔軟に拡張
こんな人におすすめ:
- 情報が散らばって困ってる人: 一箇所に集約したい
- プライバシーを重視する人: ローカルで完結させたい
- コストを抑えたい人: クラウドAPIを使いたくない
- 自動化したい人: AIに作業を任せたい
- ナレッジベースを作りたい人: 組織の知恵を蓄積したい
実装の難易度:
- 設計: ★★★☆☆(複雑だが明確)
- 実装: ★★★★☆(時間はかかるが実現可能)
- 効果: ★★★★★(劇的な改善)
最後に: 情報が散らばっている時代は、もう終わりです。
ローカルLLMで、すべての情報を一箇所に集約し、AIに検索・要約・作業を任せる。
それが、このシステムが実現する未来です。
プライバシーを守りながら、AIの力を最大限に活用する。
それが、ローカルLLMシステムの価値です。
参考リンク:
次回は、実装の進捗や具体的なコード例について書く予定です。お楽しみに!