graphify 实战指南:用 /graphify add 摄入 URL、用 --watch 监听文件夹自动重建知识图谱
2026/9/7 7:25:23 网站建设 项目流程

graphify 实战指南:用 /graphify add 摄入 URL、用 --watch 监听文件夹自动重建知识图谱

【免费下载链接】graphifyTurn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.项目地址: https://gitcode.com/GitHub_Trending/graph/graphify

本文围绕 graphify 技能的两个非默认构建功能展开:/graphify add <url>将外部 URL(推文、arXiv、PDF、网页、图片、视频)抓取进语料库并合入图谱,以及--watch后台监听文件夹、在文件变化时自动重建graph.jsonGRAPH_REPORT.md。读完后你可以直接在 Claude Code 等 Agent 中执行这两条指令,并理解其底层实现(URL 分类、frontmatter 落盘、watchdog 防抖、增量 reconcile 与并发锁)是如何保证图谱在持续变化中保持正确的。

这两个功能在技能中的位置

/graphify add <url>--watch都不属于 graphify 的默认构建流程。技能入口文件 skill-amp.md 明确列出了/graphify add的用法变体:

/graphify add <url> # fetch URL, save to ./raw, update graph /graphify add <url> --author "Name" # tag who wrote it /graphify add <url> --contributor "Name" # tag who added it to the corpus

并规定:当用户执行/graphify add <url>抓取 URL 入语料库,或传入--watch让图谱在文件变化时自动重建时,加载参考文档 references/add-watch.md(本文的原始文档)。也就是说,它是 Agent 在特定触发条件下才读取的操作手册,本文将其两条操作路径完整展开。

两条命令都依赖同一个前置约定:构建完成后,graphify-out/.graphify_python中记录了当时使用的 Python 解释器路径,命令一律以$(cat graphify-out/.graphify_python)开头来保证与构建时同一环境,避免系统python3缺少 graphify 依赖导致导入失败。

用 /graphify add 把一个 URL 变成图谱节点

完整命令与参数

原始文档给出的标准执行方式如下(以graphify-out/.graphify_python指向的解释器运行内联脚本,调用 ingest 模块 的ingest函数):

$(cat graphify-out/.graphify_python) -c " import sys from graphify.ingest import ingest from pathlib import Path try: out = ingest('URL', Path('./raw'), author='AUTHOR', contributor='CONTRIBUTOR') print(f'Saved to {out}') except ValueError as e: print(f'error: {e}', file=sys.stderr) sys.exit(1) except RuntimeError as e: print(f'error: {e}', file=sys.stderr) sys.exit(1) "

参数替换规则与错误处理约定:

  • URL替换为实际要抓取的地址;AUTHORCONTRIBUTOR在用户提供了姓名时替换,否则保留占位语义(最终会落为unknown)。
  • 命令如果以错误退出,必须向用户说明出了什么问题,不能静默继续——这是原始文档对 Agent 的硬性要求。
  • 保存成功后,自动对./raw跑一次--update管道,把新文件合入现有图谱。
  • ValueErrorRuntimeError分别对应参数/URL 校验失败和抓取失败两类错误,源码中ingest函数正是这样抛出的:URL 未通过validate_url时抛ValueError(前缀ingest:),网络层失败(HTTPError/URLError/OSError)时包装为RuntimeError

六种 URL 类型如何被自动识别

原始文档列出 6 类受支持且自动检测的 URL。对照 ingest.py 中的 _detect_url_type,检测逻辑是对 URL 做小写子串/后缀匹配:

URL 类型识别条件(源码实现)落盘结果
YouTube / 视频youtube.comyoutu.be通过 yt-dlp 下载音频,下次运行时转写为.txt(需要pip install 'graphifyy[video]'
Twitter/Xtwitter.comx.com通过 oEmbed 拉取,保存为带推文正文与作者的.md
arXivarxiv.org摘要 + 元数据保存为.md
PDF路径以.pdf结尾直接下载为.pdf
图片路径以.png/.jpg/.jpeg/.webp/.gif结尾下载保存,Claude vision 在下次运行时提取
任意网页以上均不匹配经 html2text/markdownify 转 markdown 保存为.md

从源码结构看,有两点值得注意,它们让实际行为比文档表格更精细:

  1. github.com 被识别但按网页处理_detect_url_type中还有github.com分支返回"github",但 ingest 主函数 只对pdf/image/youtube/tweet/arxiv做了特判,其余一律走_fetch_webpage的网页转换路径。
  2. 落盘文件都带 YAML frontmatter。推文、arXiv、网页三类生成的.md头部都写入source_urltypecaptured_atcontributor等字段(arXiv 另有arxiv_idpaper_authors,网页另有title),这些字段会被 graphify 的文档提取器读作节点元数据。正文还做了截断:网页正文取前 12000 字符;文件名由域名+路径清洗生成(非单词字符替换为_,最长 80 字符),同名冲突时自动追加_1_2计数器避免覆盖。
  3. 安全边界。所有抓取都经过 security 模块 的validate_url/safe_fetch/safe_fetch_text,URL 字符串进入 frontmatter 前还会经_yaml_str逐字符转义(含 U+2028/U+2029 等 YAML 换行符),防止恶意页面标题通过 frontmatter 注入额外键。

成功后自动走 --update 管道

原始文档要求“保存成功后自动对./raw运行--update管道”。这条管道本身的实现细节在姊妹参考文档 references/update.md 中:先用detect_incremental对比 manifest 找出新增/变更/删除的文件,再把变更子集写入.graphify_detect.json;若变更文件全是代码则只跑 AST 提取、跳过 LLM 语义提取;否则走完整的 3A–3C 管道(含视频转写前置步骤),最后用build_merge把新提取结果与现有graph.json合并,并只把本轮真正产出内容的文件盖章进 manifest(失败的 chunk 保留未盖章状态以便下次重排)。因此一次/graphify add <url>的完整闭环是:抓取 → 落盘(带溯源 frontmatter)→ 增量检测 → 提取 → 合并 → 图谱更新。

视频摄入的依赖前提

YouTube 一类 URL 只是先下载音频文件,转写发生在下一次运行时。对应的依赖声明在 pyproject.toml 的可选依赖中:

video = ["faster-whisper; python_version >= '3.11'", "yt-dlp>=2026.6.9"]

即需要 Python 3.11+ 并安装graphifyy[video]扩展,音频下载入口是 transcribe 模块 的download_audio

用 --watch 监听文件夹自动重建图谱

命令与 debounce 参数

原始文档给出的监听命令:

$(cat graphify-out/.graphify_python) -m graphify.watch INPUT_PATH --debounce 3

INPUT_PATH替换为要监听的目录。入口在 watch.py 的main段:path是位置参数(默认.),--debounce为浮点秒数,默认 3 秒

Debounce 的语义是“等到文件活动停止后再触发”,这样一波并行 Agent 写入不会每个文件都触发一次重建。对照 watch 函数 的实现可以确认这个机制:主循环每 0.5 秒检查一次time.monotonic(),只有当距最后一次事件 ≥ debounce 秒时才把累积的变更文件打包成一个 batch 触发后续动作。

代码变更与非代码变更的分流

原始文档描述了两类行为,源码中的判定条件比文档更精确(见 _batch_triggers_rebuild / _batch_needs_llm_flag):

  • 代码文件变更(.py、.ts、.go 等):立即重跑 AST 提取 + 重建 + 社区聚类,全程不需要 LLM,graph.jsonGRAPH_REPORT.md自动更新。源码里的触发条件是“batch 中含代码文件batch 中有已删除的文件”——任何被监听文件的删除同样会触发重建,因为驱逐过期节点不需要 LLM。
  • 文档、论文、图片变更:写入graphify-out/needs_update标志文件并打印提示,要求运行/graphify --update做 LLM 语义重提取(见 _notify_only)。注意只有仍存在于磁盘上的非代码文件才写标志;纯删除批次的节点驱逐已由重建完成,不会留下过期标志。

监听器本身还有一些保护性过滤,避免自身触发风暴:只关心代码/文档/论文/图片四类扩展名(CODE | DOC | PAPER | IMAGE);.graphifyignore模式在启动时一次性加载(避免高频文件系统事件上反复解析);跳过所有含点前缀路径段的文件和graphify-out目录自身;在 Linux 上还会过滤 inotify 的opened/closed_no_write只读事件(否则监视器自己读文件就会无限重触发);macOS 上使用PollingObserver轮询观察者,因为 FSEvents 可能漏掉快速保存。

一次代码重建的内部过程

代码变更触发的重建入口是 _rebuild_code。从源码结构看,它远不止“重新提取”那么简单,这是一条带并发保护和失败回滚的完整管道:

  1. 并发锁与排队。重建前后用fcntl.flockgraphify-out/.rebuild.lock加咨询锁(_rebuild_lock),进程被 kill 时锁自动释放,无需清理残留锁文件;持锁期间锁文件内写入持有者 PID 供外部轮询。若锁被占,增量调用会先把变更路径追加进.pending_changes队列(append 模式写,POSIX 下小写入原子),持锁方在重建前后各排空一次并合并变更集,保证并发 commit 的变更不会丢失;重建完成后还会做最多 20 轮“迟到排空”,让提交风暴最终收敛。
  2. 增量 reconcile。只重提取变更且仍存在的文件,未变更文件的节点从现有graph.json保留;删除文件对应的过期节点被驱逐。驱逐采取 fail-closed 策略:文件仍存在于磁盘但离开扫描语料时,必须有“活的忽略规则命中”(.graphifyignore或持久化的--exclude模式)才算有意排除并清理,否则保守保留并打印警告,防止过滤器回归导致节点被误杀。
  3. 缩图守卫。写入前 _check_shrink 会对比新旧节点数:如果新图节点变少,且减少的节点无法全部归因于本轮重提取或删除的文件,则拒绝覆盖并提示--force,用来拦截“半截提取导致数千节点无声消失”的事故。合法的删除(如重构删函数)则通过rebuilt_sources/deleted_paths核算放行,无需--force
  4. 落盘与派生物。原子替换(先写.graph.tmp.json再 rename)、生成GRAPH_REPORT.md、复用旧社区标签(社区成员签名校验后按 hub 节点确定性重命名)、必要时从graph.json中已存的社区信息重渲染graph.html,最后清除needs_update标志——所以一次代码重建会把此前文档变更留下的语义更新提醒一并冲掉,若那批文档确实要处理,仍需手动跑/graphify --update

无变更时的幂等性

如果一轮重建发现拓扑没有任何变化(canonical 拓扑对比相等),watch 会打印No code-graph changes detected; outputs left untouched.并不触碰磁盘上的产物;只有当graph.html缺失或被标记 stale 时才会顺带重渲染 HTML。这保证了长时间开着 watcher 也不会产生无意义的文件写入。

Agentic 工作流中的实践建议

原始文档给出的使用姿势:

  • 后台终端运行--watch,Agent 一波又一波的代码修改会在波次间隙被自动拾取并重建;
  • 如果 Agent 同时还在写文档或笔记,这些波次结束后需要一次手动/graphify --update做语义重提取;
  • Ctrl+C停止(源码中捕获KeyboardInterrupt,打印Stopped.并优雅停止 observer 线程)。

关键文件索引

路径作用
graphify/skills/amp/references/add-watch.md本文原始参考文档(add 与 watch 的 Agent 操作手册)
graphify/ingest.pyURL 分类、抓取、frontmatter 生成、落盘去重
graphify/watch.py文件监听、防抖、锁与排队、增量 reconcile、缩图守卫
graphify/skills/amp/references/update.mdadd 成功后自动执行的--update增量管道
graphify/skill-amp.md技能入口,/graphify add命令族与参考文档路由
tests/test_watch.pywatch 相关行为的测试用例(含 source_file 锚定、变更集合并等场景)

适用前提小结:以上命令均在“已至少完成一次构建、graphify-out/存在.graphify_python指针”的前提下运行;视频摄入额外要求 Python 3.11+ 与graphifyy[video]扩展;--watch需要watchdog已安装(缺失时会提示pip install watchdog)。

【免费下载链接】graphifyTurn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.项目地址: https://gitcode.com/GitHub_Trending/graph/graphify

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询