尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

graphify 语义抽取子代理规范:extraction-spec.md 的边分类、JSON Schema 与节点 ID 确定性契约

graphify 语义抽取子代理规范:extraction-spec.md 的边分类、JSON Schema 与节点 ID 确定性契约 graphify 语义抽取子代理规范extraction-spec.md 的边分类、JSON Schema 与节点 ID 确定性契约【免费下载链接】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/graphifygraphify 把代码库连同文档、SQL、配置和 PDF 一起构建成可查询的知识图谱其流程分为 AST 结构抽取Part A与语义抽取Part B两路。graphify/skills/amp/references/extraction-spec.md是 Part B 下发给每个语义抽取子代理extraction subagent的逐字提示词模板——它规定了子代理应输出什么样的 JSON 碎片、边如何按 EXTRACTED / INFERRED / AMBIGUOUS 三级分类、置信度分数字段取哪些离散值、节点 ID 如何做到与 AST 抽取器逐字符一致。读完本篇你可以完整复现 graphify 语义抽取的输入输出契约理解每条规则背后在源码与测试中的落点校验器、ID 归一化模块、碎片清洗器以及为什么这些规则能防止图谱中出现幽灵重复节点与跨语言幻影调用边。规范何时被加载、由谁执行extraction-spec.md 开头就明确了自身的触发条件Load this in Step 3 Part B when the corpus has at least one doc, paper, or image chunk. A pure-code corpus skips Part B and never reads this file.即只有当语料中至少存在一个文档、论文或图片块时宿主代理才会加载该文件纯代码语料常见的/graphify .场景直接跳过 Part BAST 通道独立完成全部抽取该规范永远不会被读取。每个语义子代理收到的都是同一份提示词仅替换五个占位符FILE_LIST、CHUNK_NUM、TOTAL_CHUNKS、DEEP_MODE、CHUNK_PATH。从 skill-amp.md 的主流程可以看到这条规范在管线中的位置Step B0缓存检查调用check_semantic_cache(all_files, root..., prompt_fileSPEC_PATH)把 SPEC_PATH 指定为与 SKILL.md 同目录的references/extraction-spec.md绝对路径。缓存条目归属到这份提示词本身——一旦 graphify 升级改变了提示词旧提示词产出的缓存条目会被重新抽取而非直接回放提示词未变则命中缓存仓库注释标注为 #1939。Step B1分块未缓存文件按每块 20–25 个文件切分每个图片单独成块视觉任务需要独立上下文同目录文件尽量归入同一块以提高跨文件关系命中率。Step B2下发CHUNK_PATH 必须是绝对路径如${PROJECT_ROOT}/graphify-out/.graphify_chunk_0N.json规范末尾也警告相对路径会被 Write 工具解析到未定义的 cwd 上导致文件静默丢失。Step B3收集合并逐个检查.graphify_chunk_NN.json是否落盘、JSON 是否含nodes与edges缺失或非法的块打印警告并跳过而非中断超过一半块失败则停止并要求检查子代理类型必须是有写盘权限的 general-purpose 代理只读的 Explore 代理会静默丢掉结果。也就是说这份 Markdown 不只是一个建议文档它的字面内容本身参与了缓存键的构成。输出契约只能输出裸 JSON模板第一行就设定了硬约束Output ONLY valid JSON matching the schema below - no explanation, no markdown fences, no preamble.子代理的输出会直接经由 merge 路径落入图谱构建任何解释性文字都会破坏 JSON 解析。完整输出结构在规范第 63–64 行给出{ nodes: [{ id: auth_session_validatetoken, label: Human Readable Name, file_type: code|document|paper|image|rationale|concept, source_file: FILE_LIST path verbatim, source_location: null, source_url: null, captured_at: null, author: null, contributor: null }], edges: [{ source: node_id, target: node_id, relation: calls|implements|references|cites|conceptually_related_to|shares_data_with|semantically_similar_to|rationale_for, confidence: EXTRACTED|INFERRED|AMBIGUOUS, confidence_score: 1.0, source_file: FILE_LIST path verbatim, source_location: null, weight: 1.0 }], hyperedges: [{ id: snake_case_id, label: Human Readable Label, nodes: [node_id1, node_id2, node_id3], relation: participate_in|implement|form, confidence: EXTRACTED|INFERRED, confidence_score: 0.75, source_file: FILE_LIST path verbatim }], input_tokens: 0, output_tokens: 0 }input_tokens/output_tokens在块 JSON 中固定为占位零值由宿主代理在 Agent 调用返回后从usage字段读回真实 token 数并写回再参与合并统计见 skill.md Part B 的 B3 合并脚本。边分类规则EXTRACTED、INFERRED、AMBIGUOUS规范把每条边划分为三档EXTRACTED关系在源文件中显式存在import、调用、引文、see §3.2 这类指针INFERRED合理推断共享数据结构、隐含依赖AMBIGUOUS不确定——必须标记出来供人工复核不得省略。在此基础上规范对几类高频出错场景做了针对性限定1. 代码文件的职责边界。语义子代理只关注 AST 找不到的语义边调用关系、共享数据、架构模式并明确不要重新抽取 import——AST 已经有了。这划清了 Part A 与 Part B 的分工重复抽取会造成重复边与重复节点。2.calls边的方向与语言边界。添加calls边时 source 必须是调用方发起调用的函数/类、target 必须是 callee禁止反向且calls边必须停留在单一语言内部——Python 函数不能callsJS/TS/Go/Rust/Java 符号反之亦然跨语言调用边被定性为幻影产物phantom artifacts一律禁止输出。3. rationale 的存放位置。文档/论文中的决策理由、权衡、设计意图要作为rationale属性挂在相关概念节点上不得为理由单独建节点或碎片节点只有本身是有名实体或概念的东西才配拥有节点。对思想、原则、机制、设计模式这类概念型节点使用file_type:rationale。4. 图片的视觉理解规则。图片不能只做 OCR要理解图片是什么并按类型提取图片类型应提取的内容UI 截图布局模式、设计决策、关键元素、用途图表指标、趋势/洞见、数据来源推文/帖子声明作为节点、作者、提到的概念示意图组件及其连接研究配图证明了什么、方法、结果手写/白板想法与箭头指向读不确定的内容标记 AMBIGUOUS5. DEEP_MODE。当构建时带--mode deep子代理应对 INFERRED 边更激进间接依赖、共享假设、潜在耦合都应提出不确定的标 AMBIGUOUS 而不是丢弃。置信度分数的离散量表confidence_score是每条边的必填字段且规范禁止把 0.5 当默认值使用给出的是离散量表而非连续区间档位取值语义EXTRACTED 边固定 1.0关系在源中显式存在直接结构证据0.95共享数据结构、具名的跨文件引用强推断0.85功能对齐清晰但无直接符号链接合理推断0.75同一问题域 形态相似需要解读弱推断0.65仅主题相关无形态证据投机但可信0.55只有表层共现AMBIGUOUS 边0.1–0.3不确定留待复核规范还解释了为什么用离散档模型遵循离散量表的表现优于连续区间生产环境观察到的双峰分布50% 的边落在 0.5 上、40% 落在 0.85 以上说明连续区间指引会被模型坍缩成二值选择。若没有合适档位宁可把边标成 AMBIGUOUS也不要取 0.4 及以下的分数。这套量表的下游消费在源码中可以得到印证validate.py 定义VALID_CONFIDENCES {EXTRACTED, INFERRED, AMBIGUOUS}非法置信度值会在抽取 JSON 校验阶段直接报错。节点 ID 格式与 AST 抽取器逐字符一致的确定性规则这是全规范最长、约束最密集的一条第 61 行核心公式{stem}_{entity}只允许小写字母、数字与下划线[a-z0-9_]无点号、无斜杠stem是完整的仓库相对路径去掉扩展名每一级目录都保留、依次小写并以_连接每段中非字母数字字符替换为_entity是符号名做同样的归一化顶层文件无父目录如setup.py直接用文件名主干例如setup_my_func严禁在 ID 末尾追加块编号、序列号或任何后缀_c1、_c2、_chunk2之类——ID 必须仅由 label 决定是确定性的同一实体无论落在哪个块里被处理都必须产生同一个 ID。规范给出的四个示例源路径 符号节点 IDsrc/auth/session.pyValidateTokensrc_auth_session_validatetokenlib/utils/helpers.pyparse_urllib_utils_helpers_parse_urltests/test_foo.py_helpertests_test_foo_helperdocs/v1/api/README.mdgetUserdocs_v1_api_readme_getuser使用仅文件名session_validatetoken或仅直接父目录auth_session_validatetoken都会制造孤儿幽灵重复节点——这正是规范要求全路径每一级的原因不同目录下的同名文件必须得到不同 ID。对于按旧格式直接父目录构建过的项目规范要求用户运行graphify extract --force重建。在源码侧这条规则不是纸面约定而是有单一实现锚点的。ids.py 的模块 docstring 开宗明义AST 抽取器、语义子代理、图构建器这三个独立的 ID 生产者必须对同一个节点产生一致的 ID否则一个实体会被分裂成互不相连的幽灵节点历史上归一化配方曾在extract._make_id与build._normalize_id间复制粘贴、仅靠镜像 docstring 保持同步恰恰是这一类 ID 漂移 bug 的来源#811、#550、#1033、#1104。该模块把配方收敛到一处def normalize_id(s: str) - str: cur s for _ in range(6): nxt unicodedata.normalize(NFKC, cur.casefold()) if nxt cur: break cur nxt cur re.sub(r[^\w], _, cur, flagsre.UNICODE) cur re.sub(r_, _, cur) return cur.strip(_)即迭代casefold再 NFKC 直到不动点İ会展开为i U0307 组合符NFKC 再重排组合然后把非单词字符串折叠为单个下划线。test_id_normalization_contract.py 用一组契约用例锁死了这条规则——大小写、标点、重复分隔符、café的组合/分解形式、CJK 与西里尔字符、以及İslemYap这类 casefold 展开字符——逐一断言extract._make_id、build._normalize_id、graphify.ids三者输出逐字符相等且归一化幂等。换句话说规范中必须匹配 AST 抽取器生成的 ID这一要求在仓库里由这套契约测试强制执行。一个值得注意的细节规范文本要求每段路径小写、非字母数字替换为_而上述normalize_id的实现保留的是\w字符含 CJK、西里尔、带音标拉丁字母。从源码结构看规范面向的是英文路径的常见场景四个示例均为纯 ASCII而非 ASCII 的标识符则由构建器的build._normalize_id对边端点做最终调谐测试用例如日本語クラス不得坍缩为空、café组合/分解等价进一步说明实际管线对 Unicode 标识符是保留而非丢弃的。file_type六个且仅有六个合法值规范规定file_type必须且只能是这六个值之一code、document、paper、image、rationale、concept任何其他值都非法将被拒绝。源码在两层实施这一点validate.py 与 semantic_cleanup.py 各自维护了同一份集合{code, document, paper, image, rationale, concept}但注意一个分工validate_extraction会因非法file_type直接报错而面向不受信任的子代理产物的validate_semantic_fragment有意不拒绝file_type——因为构建器build_from_json会用同义词表把未知值强转为concept_FILE_TYPE_SYNONYMS见 build.py 与 semantic_cleanup.py 的注释拒绝一个本可被映射的同义词如 markdown/tool 属于纯数据丢失。semantic_cleanup.py还承担另一项职责把句式的 rationale 节点label 超过 80 字符或 8 个词清洗为相关节点上的属性与规范中不要把 rationale 建成独立节点的规则互为呼应——提示词负责预防清洗器负责兜底。semantically_similar_to边无结构链接的语义相似当块内两个概念解决同一问题或表达同一思想、但不存在任何结构链接无 import、无 call、无引文时加一条semantically_similar_to边标为 INFERREDconfidence_score取 0.6–0.95 区间内反映相似度的值。规范给出三个正例两个都校验用户输入但从不互相调用的函数代码里的一个类与论文里描述同一算法的概念处理同一失败模式但方式不同的两个错误类型。同时限定只在相似性真正非显然且跨切面时才加对平凡相似不要加——防止边爆炸。超边hyperedge捕捉成对边之外的群体关系当 3 个及以上节点明显共同参与一个成对边无法表达的共享概念、流程或模式时加入顶层hyperedges数组。规范给的例子实现同一协议/接口的所有类一个认证流程中的所有函数即便它们并非两两互调论文某一节里构成一个连贯思想的全体概念。使用要节制仅当群体关系提供了超越成对边的信息时才加每个块最多 3 条超边。超边的relation取participate_in、implement、form三者之一置信度只允许EXTRACTED或INFERRED没有 AMBIGUOUS 档。semantic_cleanup.py的常量MAX_SEMANTIC_HYPEREDGE_NODES 256表明单个超边的成员数在下游也有硬上限_normalize_hyperedge_members还会把members/node_ids之类的别名键折叠回nodes键注释标注 #1561说明对子代理输出键名漂移做了工程化防御。源文件元数据与 frontmatter 传播如果某文件带 YAML frontmatter--- ... ---其中的source_url、captured_at、author、contributor要复制到来自该文件的每个节点上。这解释了为什么 schema 中节点带有这四个默认null的字段——它们不是可选项而是 frontmatter 的传播落点。source_file逐字规则与 CHUNK_PATH 绝对路径两条关于路径的规则共同服务于增量构建的正确性1.source_file必须逐字取自 FILE_LIST。每个节点、每条边、每条超边的source_file都要写成 FILE_LIST 中原样出现的路径不缩成 basename、不重新相对化、不剥离目录前缀、不改分隔符——逐字符复制 FILE_LIST 条目。引擎在下游会统一做分隔符归一与相对化所以子代理这一层必须保持原样。规范解释的动机是只有全量构建与增量--update使用同一基准build_merge的 replace-on-re-extract 才能在重新抽取时匹配并替换既有节点而不是累加出一个重复节点。2.CHUNK_PATH必须是绝对路径。模板末尾要求子代理用 Write 工具把 JSON 写到给定的确切绝对路径因为 Write 对相对路径的解析基于一个未定义的 cwd文件会被静默写丢。skill-amp.md 中 Step B2 同样以PROJECT_ROOT$(pwd)推导块文件路径Step B3 把块文件是否存在于磁盘当作子代理成功的唯一信号。子代理产物的安全边界规范规定子代理只输出 JSON、不得输出解释——这条最小面约定在下游有对应的工程强制。semantic_cleanup.py 对不受信任的语义碎片定义了硬性配额常量上限MAX_SEMANTIC_FRAGMENT_BYTES25 MiBMAX_SEMANTIC_FRAGMENT_NODES10,000MAX_SEMANTIC_FRAGMENT_EDGES100,000MAX_SEMANTIC_FRAGMENT_HYPEREDGES10,000MAX_SEMANTIC_HYPEREDGE_NODES256MAX_SEMANTIC_ID_LENGTH256ID 需匹配^[\w.:-]$且显式拦截路径分隔符与..防止通过构造的节点/边 ID 逃出graphify-out块目录注释标注 #825load_validated_semantic_fragment在read_text()之前先对文件大小做 stat 检查拒绝超大的恶意块文件。从源码结构看这套校验位于 skill merge 路径与graphify merge-chunks命令之前是提示词约束 进程内强制边界的双保险extraction-spec.md 管住正常子代理的行为validate_semantic_fragment管住失控或恶意的响应。小结一份提示词如何成为确定性契约把 graphify/skills/amp/references/extraction-spec.md 放回 graphify 的整体架构中它的角色可以概括为三点分工契约AST 通道负责结构事实import、类、函数定义语义子代理只补 AST 看不见的边语义调用、共享数据、跨文档引文、图片含义双方通过同一套节点 ID 命名空间在 Part C 合并确定性契约ID 只由 label 决定、source_file逐字保留、confidence_score取离散档——这三条规则共同保证同一实体在不同块、不同次运行中产出可对齐的节点这也是 ids.py 单一归一化实现与 tests/test_id_normalization_contract.py 契约测试存在的原因可缓存契约规范文件自身作为缓存键参与check_semantic_cache提示词变更即触发重抽取提示词不变则复用缓存使语义抽取在增量--update时保持可重放。对阅读或维护 graphify 的开发者而言若需要核对某条抽取规则是否被真实实施检索路径是现成的graphify/validate.pyschema 校验、graphify/ids.pyID 归一化、graphify/semantic_cleanup.py碎片清洗与安全边界、tests/test_id_normalization_contract.py三方一致性契约、graphify/skill.md与 graphify/skill-amp.mdPart B 分块、下发与合并的宿主侧流程。【免费下载链接】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),仅供参考
返回列表