Ian Chou's Blog

Memgraph vs HelixDB vs 手刻 Semantic Graph:200 節點知識圖譜的務實選擇

Memgraph vs HelixDB vs 手刻 Semantic Graph:200 節點知識圖譜的務實選擇

當你只有 200 個 node 的個人知識圖譜,什麼時候該從 NetworkX 升級到專業圖資料庫?答案可能是:現在不用,但你可以用現有元件做出更聰明的語意圖。

現有架構回顧

目前的 Graph Stack 長這樣:

knowledge_graph.py  →  NetworkX (in-memory DiGraph)
                       ↕ 讀寫
                    skill-graph.json (磁碟持久化)

hybrid_retrieval.py →  vector search (LanceDB) + graph expansion (NetworkX)

核心特點:嵌入式、無伺服器、JSON 檔案儲存。全部元件零外部依賴,一個 uv run 就能跑。

候選方案評估

Memgraph

面向 評估
是什麼 高效能 in-memory 圖資料庫,Cypher 查詢語言,需 Docker 容器
Python 整合 ✅ 非常成熟(GQLAlchemy OGM、LangChain 整合、NetworkX 互通)
能取代什麼 knowledge_graph.py + skill-graph.json
優勢 Cypher 查詢強大、內建 PageRank / community detection、Memgraph Lab 視覺化
問題 ⚠️ 需要 Docker 容器(現有架構零伺服器依賴)
⚠️ 200 個 node 用 Memgraph 像大砲打蚊子
⚠️ 現有 NetworkX 功能(neighbors、shortest_path、subgraph)10 行搞定

HelixDB

面向 評估
是什麼 Rust 寫的 graph + vector 融合資料庫,自帶 HelixQL 查詢語言
Python 整合 ⚠️ SDK 還很早期(2026 初才到 production release)
能取代什麼 理論上可取代 LanceDB + NetworkX(同時做 vector + graph)
優勢 概念吸引人——一個 DB 同時處理 vector search 和 graph traversal
問題 🔴 Pre-production,API 不穩定
🔴 HelixQL 是自創查詢語言,學習成本高且社群小
🔴 不支援 metadata filter
🔴 中文支援未知

核心問題:你要解決什麼痛點?

如果痛點是… 解法 需要 Memgraph / HelixDB?
NetworkX 效能不夠 200 nodes 不存在效能問題
skill-graph.json 難維護 可改用 SQLite / LanceDB 存 graph
想要 Cypher 查詢語法 Python 操作 NetworkX 也很直覺 看偏好
想要 graph + vector 統一 HelixDB 概念對但太早期
想學新技術 / portfolio Memgraph 值得學 ✅ Memgraph

結論:對 200 筆資料的個人知識庫,兩者都不需要加。 如果非要選一個,Memgraph > HelixDB,因為生產級穩定(v7.0)、Python 生態完整、跟 NetworkX 可以互通。但這是「想學」的理由,不是「需要」的理由。


那真正值得做的是什麼?—— Semantic Graph

比起換資料庫,一個更有價值的升級方向是:用 embedding 相似度自動建構圖的邊,取代手動維護的 skill-graph.json 關係。

AI 能直接「讀」embedding 嗎?

不能。 Embedding 是 512 維的浮點數向量(例如 [0.023, -0.187, 0.441, ...]),LLM 看到這些數字完全無意義。LLM 處理的是 token(文字),不是浮點數。Embedding 的用途是給機器做數學運算(cosine similarity),不是給 AI 閱讀的。

從 Keyword Graph 到 Semantic Graph

目前的 graph 是基於關鍵字的手動關係:

現在(keyword graph):
  "Python" --implies--> "FastAPI"     ← 節點是字串,邊是人工定義
  "Python" --relatedTo--> "Django"

想要的是基於語意相似度的自動連結:

理想(semantic graph):
  chunk_A (vec=[0.2, 0.1, ...]) ──相似度 0.92──> chunk_B (vec=[0.3, 0.1, ...])
  不是靠關鍵字匹配,而是靠「語意接近」自動建立連結

這個概念在學術界有正式名稱:Vector-Augmented GraphSemantic Graph


三種實作方式

方式 A:kNN Graph(最簡單,現在就能做)

用已有的 LanceDB embedding,自動建立語意相似圖:

import networkx as nx

def build_knn_graph(table, chunks, top_k=5, threshold=0.75):
    """用 embedding 相似度自動建立 chunk 之間的語意圖。"""
    graph = nx.Graph()

    for chunk in chunks:
        graph.add_node(chunk["id"], text=chunk["text"][:100])

    for chunk in chunks:
        # 用每個 chunk 的 vector 去找最相似的其他 chunk
        results = table.search(chunk["vector"]).limit(top_k).to_list()
        for r in results:
            if r["id"] != chunk["id"] and r["_distance"] < threshold:
                graph.add_edge(chunk["id"], r["id"], weight=1 - r["_distance"])

    return graph

查詢時:

# 找到 seed chunk → 沿著語意圖走 2 hop → 找到語意相關但關鍵字不同的素材
seed = vector_search(query)
neighbors = nx.single_source_shortest_path_length(semantic_graph, seed, cutoff=2)

效果:不再依賴 skill-graph.json 的手動關係,靠 embedding 相似度自動發現語意相關素材。已有元件全部夠用——LanceDB + NetworkX,零新依賴。

方式 B:Entity Embedding Graph(推薦)

把 skill nodes 也做 embedding,用相似度取代手動的 implies / relatedTo

# 現在(手動維護)
"Kubernetes" --implies--> "Docker"       # 人工定義

# 改成(自動計算)
embed("Kubernetes") · embed("Docker") = 0.87   # cosine similarity
# 相似度 > 0.8 → 自動建邊

實作步驟:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("BAAI/bge-m3")
skill_names = ["Python", "FastAPI", "Kubernetes", "Docker", "LangChain", ...]

# 1. 對 skill list 做 embedding
embeddings = model.encode(skill_names)

# 2. 存進 LanceDB
table = db.create_table("skills", [
    {"id": i, "text": skill, "vector": vec}
    for i, (skill, vec) in enumerate(zip(skill_names, embeddings))
])

# 3. 用 kNN 邏輯自動建邊
graph = build_knn_graph(table, skill_entries, top_k=5, threshold=0.2)
# 自動產生 "Kubernetes" --0.87--> "Docker" 這種邊

好處:不再需要維護 skill-graph.json 裡的手動關係。新技能加進去時,自動跟語意相近的技能建立連結。

方式 C:HelixDB / LightRAG(最完整但 overkill)

把 vector 和 graph 融合在同一個 DB 裡。每個節點同時帶有文字內容、embedding 向量、與其他節點的圖關係。查詢時同時走 vector search + graph traversal。

概念很美,但對 200 nodes 規模是殺雞用牛刀。


三種方式比較

比較面向 A: chunk kNN B: Entity Embedding C: HelixDB 等
新程式碼行數 ~25 行 ~40 行 大量
需要新套件
對現有影響 只加 hybrid_retrieval.py knowledge_graph.py 建圖邏輯 換架構
適合 200 筆 ✅ 完美 ✅ 完美 ❌ overkill

效果差異

情境 方式 A (chunk) 方式 B (entity)
單 chunk Q&A 好(相似內容擴展) 中等
多 skill 比較(e.g. "Kubernetes 需要什麼?") 中等(依賴 chunk 提到) 優秀(skill 直接連)
整體 RAG 準確率提升 vs vector-only +10-20% +30-90%
你的 200 nodes 規模 快但雜訊 精準且穩定

方式 B 通常效果更好,特別適合 career knowledge graph,因為它捕捉 skill 之間的結構化語意關係,讓 retrieval 更精準且可解釋。


學術背景:這是主流趨勢

這不是冷門 hack,而是 2024–2025 後學術界和產業界的主流方向:

LightRAG 的差異

值得注意的是,LightRAG 的 graph 不是用 entity embedding 建的,而是用 LLM 自動從 chunk 提取 entity + relationship(符號式),然後 embed description text 來輔助 retrieval。

方法 Graph 邊來源 自動化程度 你的需求匹配
LightRAG LLM extract relations 高(全自動,但多 LLM call)
Entity Embedding(方式 B) 向量相似度(cosine > threshold) 中(只 embed) ✅ 高

如果 skill list 已知,純 embedding 比 LLM extract 穩定,尤其是小資料規模。


務實建議

現在                              如果真的要升級
──────────────────────────────────────────────────────────
NetworkX (in-memory)        →  Memgraph (需 Docker)
skill-graph.json (檔案)     →  Memgraph (Cypher 查詢)
10 行 neighbors + path      →  學 Cypher + OGM 設定
零依賴、零伺服器              →  多一個 Docker 容器

推薦路線

  1. 現在做:方式 B(Entity Embedding)—— 用 LanceDB 的 embedding 自動建 skill 之間的語意邊,取代手動維護的 skill-graph.json。改動量 ~40 行,零新依賴。
  2. 可選做:方式 A(kNN Graph)作為輔助,chunk 層級的語意擴展。
  3. 以後學:Memgraph 值得作為 portfolio 項目學習,但不是現在的需求。
  4. 暫時不碰:HelixDB,等它到 production release 再評估。

總結

元件 現有方案 建議升級
圖結構 NetworkX + 手動 JSON NetworkX + 自動 embedding 建邊
向量搜尋 LanceDB 保持不變
圖遍歷 BFS 2-hop 保持不變
外部依賴 繼續零

核心概念只有一句話:用語意相似度取代關鍵字匹配來建構圖的邊。你現有的 LanceDB + NetworkX 已經完全夠用,不需要 Memgraph 或 HelixDB。把 semantic kNN graph 做好,就是跟 2024–2025 學術趨勢對齊的做法,只是你在個人 scale 上用幾十行 Python 落地,而不是用大廠框架包起來。


Career Knowledge Base 是一個本地優先的履歷知識庫系統,使用 Python + LanceDB + NetworkX + LangChain 建構。