ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

graphify 实战:`/graphify add` 的 URL 摄取与 `--watch` 的文件夹自动重建

graphify 实战:`/graphify add` 的 URL 摄取与 `--watch` 的文件夹自动重建 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负责抓取网页、推文、论文、PDF、图片甚至视频并把它们落盘到语料目录而--watch则在后台上监控一个文件夹在代码变更时无需 LLM 即可自动重建graph.json与GRAPH_REPORT.md遇到文档/论文/图片变更时再提示你执行一次/graphify --update做语义级重提取。本文基于项目内 VSCode 等各平台 Agent 共用的技能参考文档 graphify/skills/vscode/references/add-watch.md 展开并结合 graphify/ingest.py、graphify/watch.py 等源码说明其底层实现。读完你将掌握两种能力的触发场景与确切命令、6 类 URL 的自动识别与落盘规则、错误处理与摄取后自动更新的完整闭环以及如何把--watch接入多 Agent 波次式开发工作流。该参考文档的加载条件写得很明确仅当用户执行了/graphify add url或显式传入--watch时才加载它——这两个能力都不属于默认构建流程是图构建之外的增量扩展通道。它在agents、amp、claude、codex、kiro、opencode、vscode、windows等各平台技能目录下都有同名副本本文以vscode目录为例讲解其他平台完全一致。一、/graphify add把一个 URL 变成语料并立即入图/graphify add的目标是抓取一个 URL → 保存为 graphify 可消费的文件 → 随后把新文件合并进既有图谱。整个动作由两段组成——先调用ingest()完成抓取与落盘成功后自动对./raw跑一遍--update流水线。1.1 摄取调用的标准写法参考文档给出的调用脚本如下其中的$(cat graphify-out/.graphify_python)用于读取构建时记录在graphify-out/.graphify_python中的 Python 解释器路径确保与当初构建图谱的解释器一致避免 PATH 漂移$(cat graphify-out/.graphify_python) -c import sys from graphify.ingest import ingest from pathlib import Path try: out ingest(URL, Path(./raw), authorAUTHOR, contributorCONTRIBUTOR) print(fSaved to {out}) except ValueError as e: print(ferror: {e}, filesys.stderr) sys.exit(1) except RuntimeError as e: print(ferror: {e}, filesys.stderr) sys.exit(1) 需要替换的三个占位符占位符替换内容URL用户给出的真实链接AUTHOR用户提供姓名时填写否则保持占位语义上为空CONTRIBUTOR团队图谱场景下的贡献者名规则同AUTHOR这两个元数据会被写进落盘文件头部的 YAML frontmatter其中contributor字段的取值逻辑在 graphify/ingest.py 的各抓取函数中统一为contributor or author or unknown——也就是说即使调用方只传了author它也会被继承到contributor保证图谱节点永远带有可溯源的人名信息。1.2 错误处理契约绝不静默继续脚本对ingest()抛出的异常做了分类处理这一点值得强调它是 skill 的硬性行为契约ValueErrorURL 校验失败。在 graphify/ingest.py 中ingest()会先调用graphify.security的validate_url()配合safe_fetch系列函数做安全抓取校验不通过即以ValueError抛出——这可以拦截私有 IP、非法 scheme 等不安全目标。RuntimeError抓取阶段失败。ingest()会把urllib.error.HTTPError / URLError / OSError统一包装成RuntimeError(ingest: failed to fetch ...)再抛出。无论哪种失败参考文档都要求把错误原样转告用户解释清楚哪里出了问题然后用sys.exit(1)退出而不是假装成功继续往下走。只有print(fSaved to {out})正常输出、保存成功之后才允许自动触发--update流水线把新文件 merge 进既有图谱。1.3 六类 URL 的自动识别与落盘规则ingest()会根据 URL 形态自动分流不要求用户声明类型。类型判定集中在_detect_url_type()见 graphify/ingest.py规则与最终处理如下URL 类型判定依据抓取与落盘方式后续管线YouTube / 任意视频域名含youtube.com/youtu.be通过yt-dlp下载纯音频流默认存为yt_url_hash.ext.m4a/.opus等见download_audio()graphify/transcribe.py下次运行时由faster-whisper转写成.txt文本Twitter / X域名含twitter.com/x.com走 oEmbed APIpublish.twitter.com/oembed剥离 HTML 后连同作者名存为.md见_fetch_tweet()直接可被 Markdown 提取arXiv域名含arxiv.org从摘要页 API 提取标题、作者列表与 Abstract存为带 frontmatter 的.md见_fetch_arxiv()直接可被 Markdown 提取PDF路径以.pdf结尾直接以二进制方式下载为.pdf下一次/graphify --update时经语义管线切片提取图片路径以.png/.jpg/.jpeg/.webp/.gif结尾直接下载原图下一次运行时由Claude vision做视觉提取任意网页以上皆非将 HTML 清洗为 Markdown 后存为.md见_fetch_webpage()直接可被 Markdown 提取几点值得注意的源码细节网页转 Markdown 的实现graphify/ingest.py 中的_html_to_markdown()会先用正则剥掉所有script/style内容防止页面脚本文本泄漏进正文然后优先使用markdownify转换缺少该依赖时退化为去标签 压缩空白的基础清洗正文上限 8000 字符。视频下载需要可选的videoextra依赖声明在 pyproject.toml 的[project.optional-dependencies]中即video [faster-whisper; python_version 3.11, yt-dlp2026.6.9]。参考文档明确指出需要pip install graphifyy[video]注意包名是双 y 的graphifyytranscribe.py在缺依赖时抛出的ImportError提示信息也与之一致。音频文件名稳定可缓存download_audio()用 URL 的 SHA-1 前 12 位命名yt_hash.ext二次抓取同一视频时直接命中缓存返回不重复下载。落盘防覆盖Markdown 类抓取产物若与既有文件重名ingest()会用_1、_2…… 递增后缀上限 999自动改名绝不静默覆盖已有语料。文件名安全化_safe_filename()会把 URL 的 netlocpath 中非[\w\-]的字符替换为下划线并截断到 80 字符避免 URL 中的特殊字符污染文件系统路径。1.4 命令行等价入口ingest.py自带__main__因此在终端里也能以同样的方式单发抓取python graphify/ingest.py URL [target_dir] [--author NAME] [--contributor NAME]target_dir缺省为./raw与/graphify add的落盘位置保持一致。--contributor用于团队图谱场景输出会以Ready for graphify: path提示文件已经可以进入提取管线。二、摄取成功之后把新文件合并进既有图谱/graphify add的成功路径并不会停留在文件已保存。参考文档要求保存成功后自动对./raw运行一次--update流水线把新落盘的文件增量合并进现有graph.json而不是等到用户下次手动触发。这条流水线的完整分步脚本记录在同目录的技能参考 graphify/skills/vscode/references/update.md 中核心机制是增量重提取detect_incremental()对比上次 manifest找出 new/changed/deleted 文件并把结果写入graphify-out/.graphify_incremental.json将增量结果改写成.graphify_detect.json供后续 AST 提取与语义提取步骤读取分流判断若变更全部是代码文件.py/.ts/.js/.go/.rs/.java/.cpp/.c/...则只跑 AST 提取无需 LLM、零 token 消耗一旦混入 doc/paper/image/video才进入完整语义子代理管线用build_merge()把新提取结果与graph.json合并——它直接读图而不走 NetworkX 往返从而保留calls/implements/imports等有向边的方向语义directed参数需与初始构建一致用graph_diff()展示新旧图差异摘要并把本次状态写回 manifest让下一次--update从今天的状态开始 diff。简言之代码变更走零成本 AST 通道非代码变更走 LLM 语义通道二者共用同一个 merge 骨架。这个分层思想在下一节--watch中会再次出现。三、--watch后台监听文件夹让图谱自动跟随演进--watch是实时增量的另一面在后台启动一个文件夹监听器当文件发生变化时自动更新图谱。它与/graphify add互为补充——前者管外部新内容进图后者管仓库内部日常演进。3.1 启动方式$(cat graphify-out/.graphify_python) -m graphify.watch INPUT_PATH --debounce 3把INPUT_PATH换成要监听的目录默认.。--debounce的单位是秒默认3。按CtrlC即可停止。从 CLI 层面看graphify watch子命令graphify/cli.py以及graphify watch.py的__main__graphify/watch.py都支持该调用--debounce是float类型允许小数。watch能力依赖可选 extrawatch [watchdog]pyproject.toml文件系统事件正是由 watchdog 提供的。3.2 核心行为按变更类型走双通道监听器对发生了什么变化极其敏感处理策略由变更类型决定这同时也是整个watch.py设计的灵魂只改了代码文件.py、.ts、.go等一切 AST 可解析扩展名立即重跑AST 提取 重建 社区聚类全程不需要 LLM。graph.json与GRAPH_REPORT.md会被自动更新源码中的重建路径还会顺带 reconcile 缺失或过期的graph.html可视化。改了文档、论文或图片此时写入一个graphify-out/needs_update标志文件并打印通知提示运行/graphify --update——因为这类文件的语义级重提取需要 LLM。也就是说watch把零成本可自动与需花钱需人工确认的两类变更物理隔离了。needs_update标志的实现见 graphify/watch.py 的_notify_only()它创建标志文件并写入1check_update()同一文件 L2083-L2090则检查该标志并打印Pending non-code changes in ...。graphify check-update path子命令暴露了这一检查能力graphify/cli.py适合被 CI 或外部脚本轮询。值得补充的判定细节来自源码注释graphify/watch.py删除任何被监听文件也触发立即重建因为驱逐从图中移除已删源文件的节点/边同样不需要 LLM全语料 reconcile 会直接依据磁盘存在性把对应记录清掉——否则纯文档删除会被错误地挂到needs_update后面直到下一个代码事件或手动 update 才被处理。文件被读不算变更只有创建、修改、移动、删除和写入后关闭才算。这样当 Agent 正在阅读语料文件时watcher 不会把读操作误判为变更而陷入自我触发的死循环。3.3 debounce抵御一波并行写入参考文档对 debounce 的解释是等待文件活动完全停止后才触发避免一波并行 Agent 写入让每次写文件都触发一次重建。默认 3 秒实践中通常无需修改。源码层面的循环实现印证了这一点graphify/watch.pywatcher 把一段时间内积累的变更收集进一个changed集合记录最后触发时间last_trigger主循环每0.5s醒来一次只有当存在 pending 变更、且距last_trigger已超过debounce秒时才把整个批次合并成一次重建batch list(changed)。这保证了一次git pull、一次多文件格式保存或一波 Agent 并发写操作最终只产生一次重建而不是 N 次。--debounce 0可以用于调试时需要立即响应的场景。3.4 增量重建的可靠性设计源码纵深代码通道的自动重建远比检测到变化就全量重跑精细。watch.py内的增量 rebuild_rebuild_codegraphify/watch.py具备一套面向并发与失败场景的保护机制值得了解便于排查线上问题按变更集增量提取调用方如 git post-commit hook提供changed_paths时只对这批文件重跑 AST 提取未变更文件的 AST 节点与所有 semantic/LLM 层节点从既有graph.json中保留并合并删除的路径则从保留集合中驱逐。_reconcile_existing_graph()负责新旧合并与逐源驱逐。并发安全_rebuild_lock()基于fcntl.flock实现仓库级 advisory lock进程被杀时内核自动释放锁无需清理陈旧锁文件拿不到锁的调用方例如并发的多仓库 post-commit hook会先把变更写入graphify-out/.pending_changes排队_queue_pending持锁进程在重建前、后各 drain 一次把队列内容并入自己的变更集避免变更集被静默丢弃。重建时锁文件.rebuild.lock内记录持锁进程 PID供外部发布脚本轮询。失败防护fail-closed_check_shrink()是防塌缩守卫——若新图节点数骤降且丢失无法归因于被重提取/被删除的文件例如上一轮语义分块文件缺失导致的批量丢失重建会拒绝覆盖并提示Pass --force to override而不是默默写坏一个几千节点的图。排除规则持久化初次extract时的--exclude/.gitignore设置会被写入graphify-out/.graphify_build.json_write_build_config后续 watch/hook 重建自动重新应用避免当初排除的路径被无声重新纳入。hook 环境的健壮性detached git hook 可能继承一个已被删除的临时工作目录此时相对路径全部失效通过GRAPHIFY_REPO_ROOT环境变量可以指定仓库根以便重建前chdir回去_stabilize_rebuild_cwd。另有GRAPHIFY_REBUILD_MEMORY_LIMIT_MB可对重建进程做 best-effort 的内存上限与nice(10)降优先级_apply_resource_limits。目录名可配置所有产物目录名统一由 graphify/paths.py 的GRAPHIFY_OUT决定默认graphify-out可用同名环境变量覆盖支持相对名或绝对路径watcher 的needs_update标志、锁文件等全部随之迁移。这些机制共同保证了一个跑在后台的 watcher即使面对多 Agent 并发写、进程被杀、部分提取失败等恶劣情况也只会产出一致、完整、不塌缩的图谱。四、Agentic 工作流把--watch变成 Agent 的后台队友参考文档专门给出了面向多 Agent 编程工作流的建议这也是--watch最有价值的应用场景在后台终端里运行--watch。Agent 波次之间产生的代码变更会被自动拾取并重建图谱如果 Agent 同时也在写文档或笔记那么这些波次结束后需要你手动执行一次/graphify --update。推荐的落地姿势启动前先做一次完整的首次构建生成graph.json、GRAPH_REPORT.md、graphify-out/.graphify_python。启动 watcher开一个独立后台终端执行上文python -m graphify.watch INPUT_PATH --debounce 3。派出 Agent 波次每个 Agent 波次改完代码后watcher 会在 debounce 静默期自动完成 AST 重建——你随时拿到的graph.json/GRAPH_REPORT.md都是刚刚的代码对应的图谱查询时不需要再担心图过期。文档波次后收尾当某波 Agent 大量写文档/笔记/图片时终端会打印needs_update通知此时跑一次/graphify --update让 LLM 语义提取把这些文档节点并进图谱。这套组合的逻辑闭环在于代码进图零成本、可全自动文档进图成本高、需要人在场确认——watcher 用needs_update标志把高成本动作推迟到你有空的时候而不是悄悄烧 token。五、依赖与产物速查把add/watch两条通道跑通所需的可选依赖全部声明在 pyproject.toml 的[project.optional-dependencies]能力对应 extra关键依赖文件夹监听watchwatchdog视频 URL / 转写videoyt-dlp、faster-whisperPython ≥ 3.11PDF / 网页正文清洗pdfpypdf、markdownify产物约定一切中间态都落在graphify-out/可被GRAPHIFY_OUT环境变量整体迁移其中needs_update是待语义更新标志.graphify_incremental.json/.graphify_detect.json/.graphify_extract.json是--update流水线各阶段的交接文件graph.json与GRAPH_REPORT.md是最终图谱与人类可读报告。六、快速检查清单/graphify add的脚本把ValueErrorURL 校验失败与RuntimeError抓取失败都转译为带明确消息的非零退出——任何错误都要转告用户不要静默继续视频 URL 需要先pip install graphifyy[video]否则transcribe.py会提示缺 faster-whisper / yt-dlp代码文件变更走 AST 通道graph.json/GRAPH_REPORT.md立即更新无需 LLM文档/论文/图片变更只写needs_update标志并打印通知需要你执行/graphify --update--debounce默认 3s把一波并行写入合并为一次重建避免每写一文件就重建一次纯代码场景请始终让 watcher 跑在后台终端文档密集的 Agent 波次结束后记得手动补一次/graphify --update。更细的增量 merge 分步命令见同技能下的 update.mdwatch 的并发与驱逐逻辑测试覆盖在 tests/test_watch.py 与 tests/test_watch_manifest_location.pyURL 摄取的输入输出样例可参考 tests/test_ingest.py需要进一步下钻时可结合源码与用例一起阅读。【免费下载链接】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),仅供参考
返回列表