Cognee は、生データを永続的な知識グラフに変換するオープンソース AI メモリプラットフォーム。従来の RAG(検索拡張生成)を、ベクトル検索・グラフ DB・LLM によるエンティティ抽出を組み合わせた ECL(Extract, Cognify, Load)パイプラインで置き換える。
主要フロー:
add()(データ取り込み)→ cognify()(エンティティ/関係を抽出してグラフ構築)→ search()(多様な検索戦略で問い合わせ)→ memify()(グラフを追加文脈で拡充)
特徴:
cognee-cli)の両方を提供はい。生データをそのまま検索するのではなく、事前に インデックス化(Cognee では cognify()) が必要。具体的には:
従来の RAG が「チャンク + ベクトル検索」だけなのに対し、Cognee はここに 知識グラフ層 を追加することで、エンティティ間の関係をたどった検索(GRAPH_COMPLETION など)を可能にしているのが差別化ポイント。
両方ありえるが、設計思想的には 後者(AI エージェント/製品に組み込む長期メモリ基盤) 寄り。
codegraph extra で関数/クラスの依存関係をグラフ化)cognee-cli -ui はあるが開発者向け)「複数ユーザー・データセット分離・API で外から叩く」要件があれば製品向け、単に自分のメモを検索したいだけなら Obsidian+RAG の方が軽い。
LLM がテキストから抽出する 名前付きエンティティ が基本単位。フィールド:
id, name, type, descriptiontype は固定ではなく LLM が動的に命名(大文字)。典型例:
加えて、ドキュメント構造由来のノードも作られる:
TextContent / AudioContent 等)(source_node_id, target_node_id, relationship_name) の三つ組。
LLM 抽出の関係例(自由形式で動的に生成):
works_at, located_in, founded_by, part_of, causes …構造的に固定の関係(コード上で定義済み):
is_type(ドキュメントタイプ)categorized_as(カテゴリ分類)has_properties(属性保持)mentions(チャンク → エンティティ)Document ──has_chunk──> DocumentChunk ──mentions──> Entity(Einstein, PERSON)
│
└─developed─> Entity(Relativity, CONCEPT)
→「ドキュメント構造の層 + LLM 抽出の意味ネットワーク層」が重なったグラフ。検索時は両層をまたいで辿れるのが肝。
そう。プロンプト + 構造化出力強制の合わせ技。中核は 3 点。
generate_graph_prompt.txt が全体方針を指示:
snake_case(例: acted_in)YYYY-MM-DD 形式)プロンプトだけだと JSON がブレるので、KnowledgeGraph モデル(nodes: List[Node], edges: List[Edge])を response_model として渡す。
content_graph = await LLMGateway.acreate_structured_output(
content, system_prompt, response_model, **kwargs
)
内部は Instructor(または BAML)ライブラリがスキーマを tool_call/json_schema に変換し、LLM の出力を自動バリデーション。違反したら再試行。
extract_graph_from_data.py で全チャンクに対し asyncio.gather で並列実行。その後:
retrieve_existing_edges で重複チェック)ontology_resolver で既存概念に寄せる、デフォルトは fuzzy 80%)generate_graph_prompt_simple.txt - 軽量版generate_graph_prompt_strict.txt - 厳格版generate_graph_prompt_guided.txt - ガイド付きgenerate_graph_prompt_oneshot.txt - 例示ありLLM_CONFIG.graph_prompt_path で切替可、custom_prompt 引数で完全上書きも可能。
[Cogneeのエッジ] みたいな自由度はないよね?その通り。
| Cosense | Cognee | |
|---|---|---|
| ノード化の主体 | ユーザー([foo] と書けば即ノード) |
LLM(抽出アルゴリズムが判断) |
| 粒度の自由度 | 任意(思いつき・造語 OK) | エンティティ扱いできる名詞句に限定 |
| 型 | 無型(ページは全部等価) | PERSON/CONCEPT 等に分類される |
| 関係 | 双方向リンク(暗黙) | 有向 + 名前付き(works_at 等) |
Cosense の「[Cogneeのエッジ] と書けばそれがページ化される」は、ユーザーの意図でノードを立てる モデル。Cognee は逆で、プロンプトに「Person のような基本型に寄せろ」「あまり細かい型を作るな」と明示指示があるので、むしろ 多様性を抑えて収束させる設計 になっている。
extract_entities_system.txt が「common noun, pronoun, generic term は除外」と明示→ 結果として、Wikipedia 的な「固有名詞 + 明確な関係」グラフ に収束しがち。Cosense の「造語や概念ラベルが自由に飛び交う有機的ネット」にはならない。
DataPoint から派生させて渡すextract_content_graph にプロンプトを上書き注入ここで「[brackets] で囲まれたテキストを無条件でノード化しろ」というプロンプト + スキーマを書けば、Cosense 風の挙動を再現することは可能。ただし Cognee の想定ユースケースではない。
要は、Cognee は 「曖昧な文章から機械的に構造を取り出す」側、Cosense は 「人間の連想をそのまま残す」側 で、思想が正反対。
1 万ノードは 余裕で可能。むしろボトルネックは別の場所にある。
デフォルトバックエンド:
1 万ノード + 関連エッジ・ベクトルは、むしろ「小規模」の部類。Neo4j/PostgreSQL に切り替えれば数億ノードまで伸ばせる。
1 万エンティティを抽出するには、その背後に 数千〜数万チャンク があり、各チャンクで LLM 呼び出しが発生。extract_graph_from_data.py は asyncio.gather で並列化しているが:
LLM_RATE_LIMIT_ENABLED)に当たると実時間で数時間〜既存エンティティとの類似度マッチが 1 万ノード規模だと効いてくる。retrieve_existing_edges や expand_with_nodes_and_edges の実装次第では、ノード数に対して線形以上に遅くなる可能性あり。
GRAPH_COMPLETION 系は関連ノードを辿って LLM に渡すので、深さ制御 をしないと関連ノードが爆発してコンテキスト溢れを起こす。
distributed extra の Modal)を検討「耐えられない」のは ストレージじゃなくて LLM 課金と cognify 時間 の方、というのが正確な答え。
その理解が正確。Cognee は 「取り込み時に高コストを払って、検索時の質を稼ぐ」 アーキテクチャ。
GRAPH_COMPLETION/TRIPLET/CHUNKS/TEMPORAL/CYPHER…)→ 同じデータを多角的に引く前提| ベクトル RAG | Cognee | |
|---|---|---|
| 取り込みコスト | 低(埋め込みのみ) | 高(LLM 抽出 × チャンク数) |
| スケール上限 | データ量 | LLM 予算 |
| 強み | 「似た文を探す」 | 「概念の関係を辿る」 |
なので「10 億ドキュメントの全文検索基盤」ではなく、「中規模コーパスを濃密な意味ネットワークに変換して AI エージェントに与える」 のが本命用途。