首页
/ graphify 导出流水线全解:Wiki、Neo4j、FalkorDB、SVG、GraphML 与 MCP 服务的源码级实操

graphify 导出流水线全解:Wiki、Neo4j、FalkorDB、SVG、GraphML 与 MCP 服务的源码级实操

2026-09-06 15:37:07作者:吴年前Myrtle

graphify 在完成本地 AST 抽取后,真正决定知识图谱“能走向多远”的,是它的导出层。本文以 Kilo 技能包中的 references/exports.md 参考文档为主线,完整覆盖 --wiki--neo4j/--neo4j-push--falkordb/--falkordb-push--svg--graphml--mcp 六个导出标志对应的命令、默认值与凭据处理方式,并逐条对照 graphify/cli.pygraphify/exporters/graphdb.py 等源码,说明每种导出的底层实现与可验证的测试依据。读完你可以独立完成从生成 Wiki 到把图推送到图数据库、再到让其他 Agent 通过 MCP 实时查询图谱的全套操作。

导出步骤的调度规则:每个 Step 只服务于自己的 Flag

参考文档(graphify/skills/kilo/references/exports.md)的开篇就定下了一条调度原则:该参考文档只在用户传了某个导出标志时才加载,且每个 Step 只在其对应标志存在时执行。这与主技能文档 graphify/skill-kilo.md 中的标志清单一一对应:

/graphify <path> --svg                                  # also export graph.svg
/graphify <path> --graphml                               # export graph.graphml
/graphify <path> --neo4j                                # generate graphify-out/cypher.txt
/graphify <path> --neo4j-push bolt://localhost:7687     # push directly to Neo4j
/graphify <path> --falkordb                             # generate graphify-out/cypher.txt
/graphify <path> --falkordb-push falkordb://localhost:6379  # push directly to FalkorDB
/graphify <path> --mcp                                  # start MCP stdio server
/graphify <path> --wiki                                 # agent-crawlable wiki

skill 文档中也有同样的说明:这些步骤“only when their flag is present … or, for the token-reduction benchmark, when total_words exceeds 5,000. A default run with no export flags skips all of them”(见 graphify/skill-kilo.md)。也就是说,一次不带任何标志的默认运行不会触发下面任何导出动作,全部六个 Step 加上 benchmark 都是按需触发的。

在 CLI 层面,这些标志最终都收敛到 graphify export <format> 子命令,由 graphify/cli.py 中的 subcmd not in ("html", "callflow-html", "obsidian", "wiki", "svg", "graphml", "neo4j", "falkordb") 分支统一分发;所有导出默认从 graphify-out/graph.json 读取图,从同目录的 .graphify_labels.json.graphify_analysis.json 读取社区标签与社区划分,并可用 --graph PATH / --labels PATH 显式覆盖。

Step 6b:Wiki 导出(仅当 --wiki

文档给出的命令与执行时机约束:

graphify export wiki

只有在原始命令显式带了 --wiki 时才运行本步骤,并且必须在 Step 9(清理)之前执行,确保 .graphify_labels.json 仍然可用。

“先导出、后清理”不是随意的顺序要求。从源码看,CLI 的 wiki 分支(graphify/cli.py)会读取 .graphify_analysis.json 中的 communitiescohesiongods,并在 graphify-out/wiki/ 目录下调用 graphify/wiki.pyto_wiki 生成文章。这里有两条值得注意的防护逻辑:

  • 缺失社区数据时拒绝导出:如果 .graphify_analysis.json 缺失或为空,CLI 会直接报错退出——“refusing to export wiki to prevent data loss”,并提示先运行 graphify extract .(或 graphify cluster-only .)重新生成社区数据。
  • 输出结构:生成成功后打印 Wiki: {n} articles written to .../wiki/,并指出 wiki/index.md 是 agent 的入口。graphify/wiki.py 的模块注释说明了产物形态:Wikipedia 风格的 Markdown 文章,包含 index.md + 每个社区一篇文章 + god node 文章,且刻意做成 agent 可爬取——文章间用原始相对链接(而非 Obsidian 的 [[wiki link]])互链,非 ASCII 字符(CJK、西里尔等)在 slug 中不被剥离,链接目标与磁盘文件名逐字一致(_safe_filename_md_link 的共同设计,见 graphify/wiki.py)。

Wiki 导出的行为有专门的测试覆盖,见 tests/test_wiki.py

Step 7:Neo4j 导出(仅当 --neo4j--neo4j-push

文档区分了两种形态:

形态一:--neo4j——生成 Cypher 文件供手工导入

graphify export neo4j

形态二:--neo4j-push <uri>——直推运行中的 Neo4j 实例(未提供凭据时向用户索取):

graphify export neo4j --push bolt://localhost:7687 --user neo4j --password PASSWORD

默认 URI 为 bolt://localhost:7687,默认用户为 neo4j;使用 MERGE 语义,重复执行不会产生重复节点,可安全重跑。

源码层面这两条路径的分工很清晰(graphify/cli.py):

  • 不带 --push 时调用 graphify/export.pyto_cypher,在 graphify-out/cypher.txt 中为每个节点生成 MERGE (n:{Filetype} {id, label})、为每条边生成 MATCH (a), (b) MERGE (a)-[:REL {confidence}]->(b)。Cypher 字符串经过 _cypher_escape 转义(反引号、引号、换行、CR、控制字节),节点 label 与关系类型这两个无法在 Cypher 中安全转义的标识符位置则做 [A-Za-z0-9_] 白名单清洗,非法时回退为 Entity / RELATES_TO(见 graphify/export.py)。CLI 提示的导入方式是 cypher-shell < graphify-out/cypher.txt
  • --push 时调用 graphify/exporters/graphdb.pypush_to_neo4j,通过官方 Python 驱动直连。前置依赖是 pip install neo4j(缺失时抛出带安装提示的 ImportError)。推送时只携带标量属性并剔除下划线开头的内部属性,节点会额外写入所属 community 编号;节点与关系均使用 MERGE ... SET ... += 参数化查询,与文档“safe to re-run”的描述一致。函数返回 {"nodes": N, "edges": M},CLI 打印 Pushed to Neo4j: N nodes, M edges

两个安全细节值得实操时留意:

  1. 密码不留在 argv 上:CLI 优先读取环境变量 NEO4J_PASSWORD,显式 --password 可覆盖(F-031,见 graphify/cli.py);且 --push 场景下若拿不到密码会直接报错退出。
  2. 凭据清洗:label 清洗在 graphify/exporters/graphdb.py 中标注为“prevent Cypher injection”,把任意 label 压回 [A-Za-z0-9_]

Step 7a:FalkorDB 导出(仅当 --falkordb--falkordb-push

文档对 --falkordb 的告诫非常具体:

生成的语句是 OpenCypher,但 FalkorDB 的 GRAPH.QUERY 一次只执行一条语句(没有 Neo4j cypher-shell 那样的批量脚本导入),所以加载图应优先使用 --falkordb-push;仅当你想要可移植的 cypher.txt 产物时才用文件导出。

# 生成可移植的 OpenCypher 文件
graphify export falkordb
# 直推运行中的 FalkorDB 实例;凭据可选,仅当实例要求鉴权时才向用户索取
graphify export falkordb --push falkordb://localhost:6379

默认 URI 为 falkordb://localhost:6379,文档特别指出 scheme 只是信息性的——redis:// 或直接 host:port 都等价;鉴权可选;目标图名默认 graphify;同样使用 MERGE,可安全重跑。

实现上,push_to_falkordbgraphify/exporters/graphdb.py)的 docstring 把与 Neo4j 路径的差异逐条列出,与文档描述完全吻合:

  • 前置依赖 pip install falkordb,通过 FalkorDB(host, port, username, password) 连接,只从 URI 解析 host/port(默认端口 6379),因此三种 URI 写法等价;
  • 通过 db.select_graph(graph_name) 选择命名图(默认 "graphify"),同一实例内按图名隔离;
  • 查询经 graph.query(cypher, params) 执行,没有 session 对象
  • 鉴权可选:FalkorDB 默认无凭据运行。代码里有一个细节——只有提供了 password 才会发送用户名,否则匿名连接并忽略 bolt 风格默认用户名(如 neo4j),因为 FalkorDB 会把未知 ACL 用户拒绝(见 graphify/exporters/graphdb.py);
  • MERGE 语义与 Neo4j 路径一致,返回 {"nodes": N, "edges": M}

不带 --push 时 CLI 复用 to_cypher 写出 cypher.txt,但会额外打印一段提示:由于 GRAPH.QUERY 逐条执行、没有批量脚本导入,应改用 graphify export falkordb --push falkordb://localhost:6379 加载(graphify/cli.py)。密码同样支持环境变量 FALKORDB_PASSWORD 替代 --passwordgraphify/cli.py)。该路径的集成测试见 tests/test_falkordb_integration.py

Step 7b 与 7c:SVG 和 GraphML 导出

这两个是最轻量的静态产物,文档各给出一条命令:

# Step 7b - 仅当 --svg
graphify export svg
# Step 7c - 仅当 --graphml
graphify export graphml

从 CLI 实现看(graphify/cli.py):

  • svg 分支调用 graphify/export.pyto_svg,输出 graphify-out/graph.svg,成功时提示 “graph.svg written - embeds in Obsidian, Notion, GitHub READMEs”;
  • graphml 分支调用 to_graphml,输出 graphify-out/graph.graphml,提示 “open in Gephi, yEd, or any GraphML tool”。

两者都接受 --graph / --labels 参数(svg 支持 --labels,graphml 仅 --graph,见 CLI 用法说明 graphify/cli.py)。GraphML 路径在写盘前会用 _strip_xml_illegal 剔除 XML 1.0 无法承载的控制字符(如终端 ANSI 转义、某些源码里的表单进符),避免单个标签毁掉整个导出(graphify/export.py)。

Step 7d:MCP Server(仅当 --mcp

文档给出的启动命令:

$(cat graphify-out/.graphify_python) -m graphify.serve graphify-out/graph.json

这启动一个 stdio MCP server,把知识图谱暴露成七个工具供 Claude Desktop 或任何 MCP 兼容的 Agent 编排器实时查询:query_graphget_nodeget_neighborsget_communitygod_nodesgraph_statsshortest_path。这七个工具名与 graphify/serve.pylist_tools 注册的 name 完全一致,可以逐一对上。

文档同时指出了在 Claude Desktop 中配置的三个坑,配置方式如下(claude_desktop_config.json):

{
  "mcpServers": {
    "graphify": {
      "command": "<absolute path from: cat graphify-out/.graphify_python>",
      "args": ["-m", "graphify.serve", "/absolute/path/to/graphify-out/graph.json"]
    }
  }
}

三个坑分别是:Claude Desktop 不会执行 $(...) 命令替换;在 uv tool install 场景下系统 python3 无法导入 graphify 包;因此必须把 command 写成 cat graphify-out/.graphify_python 打印出的绝对解释器路径,而不是 shell 动态展开。服务端自身还有若干与文档互补的运行细节(graphify/serve.py):图文件必须是 .json 且存在、受大小上限检查保护,并支持 GRAPHIFY_MAX_CONTEXTS 环境变量控制多项目上下文的 LRU 容量(默认 8)。查询工具 query_graph 的实现在 _query_graph_text 一带,shortest_path 则通过 NetworkX 的 nx.shortest_path 在有向/无向图上求路径(graphify/serve.py)。

Step 8:Token 缩减基准测试(仅当 total_words > 5000)

文档的触发条件与行为:

如果 graphify-out/.graphify_detect.json 中的 total_words 大于 5,000,则运行:

graphify benchmark

把输出直接打印在聊天里。若 total_words <= 5000静默跳过——小语料下,图的价值在于结构清晰度而非 token 压缩。

CLI 的 benchmark 分支(graphify/cli.py)会先从 .graphify_detect.json 读取 total_words 作为语料规模,再调用 graphify/benchmark.pyrun_benchmarkprint_benchmark。实现细节可以帮你正确解读输出:

  • 语料 token 估算:按“100 words ≈ 133 tokens”换算(corpus_words * 100 // 75),字符级估算按每 4 字符约 1 token(graphify/benchmark.py);
  • 查询成本模拟:对 5 个内置样例问题(如 “how does authentication work”),先用问题词元对节点 label 打分取 top-3 起点,再做 3 层 BFS,把子图内的 NODE/EDGE 行折算成 token 数(_query_subgraph_tokens);
  • 输出报告:打印语料 token、图规模(nodes/edges)、平均查询 token 成本与总体缩减比,以及每个问题各自的 Nx 缩减系数(graphify/benchmark.py)。

该基准有专门的单测覆盖,见 tests/test_benchmark.py

小结:按标志对照表收尾

Flag 命令 产物 / 默认值 关键约束
--wiki graphify export wiki graphify-out/wiki/index.md 为 agent 入口) 需在 Step 9 清理前运行;缺社区数据直接拒绝导出
--neo4j graphify export neo4j graphify-out/cypher.txt cypher-shell 批量导入;需 pip install neo4j(push 时)
--neo4j-push graphify export neo4j --push bolt://localhost:7687 --user neo4j --password PASSWORD 直推 Neo4j MERGE 可重跑;可用 NEO4J_PASSWORD 替代明文密码
--falkordb graphify export falkordb graphify-out/cypher.txt(OpenCypher) GRAPH.QUERY 逐条执行,加载优先 --push
--falkordb-push graphify export falkordb --push falkordb://localhost:6379 直推 FalkorDB,默认图名 graphify scheme 信息性、鉴权可选;可用 FALKORDB_PASSWORD
--svg graphify export svg graphify-out/graph.svg 可嵌入 Obsidian / Notion / README
--graphml graphify export graphml graphify-out/graph.graphml Gephi、yEd 等工具可打开
--mcp $(cat graphify-out/.graphify_python) -m graphify.serve graphify-out/graph.json stdio MCP server,7 个查询工具 Claude Desktop 配置需用绝对解释器路径
自动(total_words > 5000 graphify benchmark 打印 token 缩减报告 语料过小则静默跳过

所有命令都以本地生成的 graphify-out/graph.json 为单一事实源,导出物彼此独立、可单独重跑;图数据库类导出统一采用 MERGE 幂等语义,凭据处理上优先环境变量——这套组合让导出层在“可移植产物”与“直连推送”之间提供了完整的可选项。

登录后查看全文
热门项目推荐
相关项目推荐