GitNexus PDG 上下文切片构建指南:为规划 LLM 提炼语句级变更证据
导读
本指南围绕 GitNexus Claude 插件 gitnexus-plan 技能中的核心参考文档 pdg-slice.md,讲解如何在规划一次代码变更时,为最核心的 1~3 个函数构建有界的 PDG(程序依赖图)上下文切片——一组精炼到规划大模型能完整装进工作记忆、而绝非图转储的语句级证据。读完本文,你将掌握 pdg_query、impact、explain 三个 MCP 工具的正确调用姿势与契约陷阱、PDG 切片的包含准则与 YAML 表示结构,以及安全与性能两类任务下的专属增强模式,并能在仓库源码与测试中定位对应实现。
一、切片文档在规划技能中的定位
在 gitnexus-plan 技能的五阶段流程中,PDG 切片由 Phase 3 — Statement-level PDG slice 驱动:技能 SKILL.md 明确要求,对于变更最中心的 1~3 个函数,要构建有界的 PDG context slice,并且由 pdg-slice.md 全权负责工具调用、包含准则、深度上界、切片 schema、安全/性能模式以及"无 PDG 层"时的回退策略。
技能的定位决定了这份文档的价值取向:
- GitNexus 是导航层(告诉你该看哪里);
- 语句级 PDG 是约束层(告诉你什么条件门控并喂养该行为);
- 规划代理自身的定向源码阅读是验证层(告诉你当下真正的事实是什么)。
因此 pdg-slice.md 追求的目标非常明确:产出紧凑、可被规划 LLM 完整持有的切片,绝不产出图转储(a compact slice the planning LLM can hold, never a graph dump)。切片不是给人类看的分析报告,而是给后续实施环节消费的"工作记忆材料"。
二、构建切片前的四个工具调用
pdg-slice.md 开头给出了经过验证的问题 → 调用映射表(文档注明该表已在 gitnexus/src/mcp/tools.ts 中得到验证):
| 问题 | 调用 |
|---|---|
| X 在什么条件下运行?被哪些守卫(guard)门控? | pdg_query {mode: "controls", target} |
| 变量 Y 在函数内部流向哪里? | pdg_query {mode: "flows", target, variable} |
| 第 N 行语句依赖/被谁依赖? | impact {mode: "pdg", target, direction: "upstream", line: N} |
| Source→sink 污点路径(安全模式) | explain {target} |
这四个调用与 MCP 工具定义一一对应,在 tools.ts 中可以找到它们的完整输入契约:
pdg_query(行 696 起):控制/数据依赖查询工具,是 explain(污点消费方)的控制依赖与数据依赖类比。两个模式:
controls—— "X 在什么条件下运行"。返回被锚定函数内每条控制依赖边:控制谓词块、被依赖块、以及分支语义('T'= 谓词真/taken 分支,'F'= 假/fall-through 分支)。进入 early return/throw 块的边会打上guard: true标记(该标记吸收替代了历史遗留的 #559 guard 启发式);flows—— "变量 Y 流向哪里"。返回函数内 REACHING_DEF def→use 边;传variable可过滤到单一绑定。
两个模式均强制要求 mode 与 target(inputSchema required: ['mode', 'target']),且 PDG 查询永远必须被锚定——没有整仓枚举模式,因为无锚定的 basic-block 路径扫描无界且无索引(LadybugDB 没有 rel-property 索引)。
impact(行 463 起):爆炸半径引擎,mode 支持 "callgraph"(默认,符号→符号跨过程遍历)与 "pdg"(统一 PDG 面:基于持久化控制/数据依赖层的语句级 affectedStatements + 跨过程符号 interproceduralByDepth/pdgInterprocedural)。在 mode:'pdg' 下传入 line(目标符号内以 1 起始的源码行),即以该行语句为种子,返回其下游依赖它的语句集合。
explain(行 651 起):gitnexus analyze --pdg 持久化污点发现的专用消费方,覆盖函数内 source→sink 数据流(TAINTED 边)与跨函数流(TAINT_PATH 边,interprocedural: true),并给出 sink 类别(command-injection、code-injection、path-traversal、sql-injection、xss)与逐跳路径。
三、塑造解读方式的契约约束
pdg-slice.md 明确列出会影响解读方式的工具契约要点,其中不少细节只有在源码工具描述里才能看到完整来龙去脉:
1. impact 每种模式都强制要求 direction。 工具 schema 中 required: ['direction'](见 tools.ts)。mode: "pdg" 也不例外:"upstream" 表示"这条语句被谁依赖","downstream" 表示"它依赖什么"。漏传会直接 schema 校验失败。
2. CDG 分支语义是 'T'/'F',且守卫的方向由谓词决定。 语义存放在结果 label 字段中;而 if (!ok) return; 这样的守卫是骑在 'T'(真)分支上的。因此绝不能按固定标签过滤守卫。early return/throw 边携带 guard: true。原始边真正的语义保存在 reason 中,只能通过 cypher 才看得到。在 tools.ts 的 pdg_query 描述里同样重申:guard 的分支语义取决于其谓词,if (!ok) return; 走 'T' 分支,不要用固定标签去过滤守卫。
3. pdg_query 是函数内的(intra-procedural)且必须锚定。 跨函数的流是污点领域(explain)或 impact {mode:"pdg"} 的跨过程可达范围的职责。tools.ts 中对 PDG 粒度的定义是 basic-block,通过 BasicBlock id + 行跨度重建回函数;同一行内塞入大量语句的函数可能锚定得比较粗糙。
4. 每个 switch 的 case 臂都是 'T'。 per-case 条件尚未被区分(M5/M6 的 CDG 标签是二值 'T'/'F'),解读 switch 时要意识到这一点。
5. "无 PDG 层"不是错误,是仓库级的提示。 没有用 --pdg 建索引时,工具返回的是 "no PDG layer" 说明性 note 而不是 error,例如 pdg_query 会返回 { results: [], note: "no PDG layer …" }。这个 note 是仓库级的:探一次就够,不要对每个函数反复探测。该回退行为在配套技能文档 gitnexus-pdg-query.md(管理 pdg_query 与 CDG/REACHING_DEF 边)中有直接印证。
6. 有层时遵守新鲜度与重建纪律。 默认 freshness: strict 下需要先构建/升级 PDG 层再重探。正确做法是:通过 SKILL.md Phase 1 解析出的 runner 执行 analyze --index-only --pdg——这是 Phase 1 的刷新预算所允许的唯一一次 --pdg 升级。若 Phase 1 已用 --pdg 刷新过,则跳过这次升级;执行前先做 runner 构建检查(analyzer provenance 检查)。
7. 重建失败/不现实/传入 freshness: accept 时的降级路径。 此时应在 ledger 中记录 "PDG unavailable",跳过切片,在计划文档 §5 中明说原因并推荐补跑命令。永远不要手工从源码反推重建依赖边——这是硬性禁令。
四、包含准则:什么语句有资格进入切片
一条语句只有当它至少满足以下之一时才能进入切片:
- 与任务直接匹配;
- 是某条相关语句的数据流前驱或后继(深度在
pdg_data_depth内,默认 2); - 是某条相关语句的控制依赖(深度在
pdg_control_depth内,默认 2); - 是影响所请求行为的状态变更;
- 是执行路径上的外部调用;
- 是错误处理或回退分支;
- 属于受影响的返回值的一部分;
- 是解释某个测试断言所必需的。
其余一切全部裁掉。如果切片超过每个函数约 15 条语句,收紧相关性而不是调高深度——这是对抗"图转储"倾向的关键纪律。
两个深度参数与其余旋钮一起定义在 SKILL.md 的 Configuration 表中:pdg_data_depth(数据依赖跳数,默认 2)与 pdg_control_depth(控制依赖跳数,默认 2)。这意味着在构造切片时,数据流前驱/后继与控制依赖探索各被限制在两跳以内,从而天然为切片设定了有界上界。
在 Phase 0 分类中,任务的类别姿态(category posture)会进一步决定是否值得走到切片这一步:例如 Bug fix(local)默认不需要 PDG 大范围探索;而 Refactor/shared API change、Performance、Security、Concurrency/transactional 等类别才强制 full 计划并(在部分类别中)启用对应的 PDG 增强模式。
五、切片表示结构:可被 ledger 消费的 YAML
切片是工作记忆材料(working-memory material):规划期间在上下文里保留完整切片,在 ledger 中压缩成一行 pdg_slices 条目,再蒸馏进计划的 §5。pdg-slice.md 给出了规范化的 YAML 形态:
pdg_context:
entry_symbol: "processFileGroup"
source: { file: "gitnexus/src/core/ingestion/worker.ts", start_line: 120, end_line: 188 }
relevant_statements:
- id: "stmt-12" # stable id 或 "<file>:<line>"
lines: "128-130"
type: "condition | call | mutation | return | throw"
code: "if (request.retryable) {"
relevance: "Controls whether retry scheduling is entered"
defines: []
uses: ["request.retryable"]
control_dependencies: ["stmt-4"]
data_dependencies: []
execution_flow: # 有序的散文式步骤
- "Validate request"
- "Schedule retry"
critical_dependencies:
- { from: "stmt-7", to: "stmt-18", type: "data", explanation: "Validated request becomes scheduler input" }
behavioural_observations:
- "Persistence occurs before scheduler invocation"
planning_implications:
- "Changes to scheduling must account for partial failure"
对其各字段的解读:
entry_symbol+source:入口符号与文件级锚定(示例文件路径是文档的示意写法,实做中应替换为经验证的真实路径与行号)。relevant_statements[]:每条相关语句含id(建议用稳定 id 或<file>:<line>格式,与 context-ledger.md 的锚定习惯一致)、type(condition/call/mutation/return/throw 枚举)、code原文、relevance(为何进入切片)、defines/uses、以及control_dependencies/data_dependencies。execution_flow:以有序散文步骤呈现的执行次序,是相关语句浓缩后的叙述化表达。critical_dependencies:关键依赖三元组(from/to/type + 解释)。behavioural_observations:已被确认的事实。planning_implications:推断结论。
文档特意强调两点纪律:字段名要适配工具实际返回的内容(不要照抄模板导致失真),并且保持机器可读与简短;behavioural_observations 是确认事实,planning_implications 是推断——二者的区分必须保留。这与 SKILL.md 的硬性规则"Source beats graph""No fabrication"一脉相承:区分 [verified]/[graph]/[inferred]/[assumed] 四类主张是计划文档的证据纪律,切片里的观测/推断之分是它在语句级的前置落实。
注意这里的 YAML 文档是"无谓词约束"的工作记录,即使切片字段变化,也应保持这种"事实与推断分离"的结构形态;条目在写入 pdg_slices 单行时进一步压缩为 entry_symbol 粒度。
六、安全模式(任务类别:security)
当任务分类为 security 时,除常规切片外还要额外识别并记录:不可信输入(untrusted inputs)、校验点(validation points)、净化点(sanitisation points)、认证/授权检查(authn/authz checks)、特权边界(privilege boundaries)、敏感数据、持久化操作、网络调用、危险 sink、以及绕过校验的错误路径。
随后对与任务相关的发现,用 explain {target} 拉取持久化的 source→sink 污点路径(函数内 TAINTED 边与跨函数 TAINT_PATH 流),并把**逐跳路径(hop paths)**一并纳入切片。
最关键的一条警示:"没有污点发现"绝不是"安全"的证明。 pdg-slice.md 明确列出了污点模型的盲区,而在 tools.ts 的 explain 契约说明中给出了逐项印证:
- 闭包/回调流两个方向都不可见(如
arr.forEach(() => sink(y)))——这是最大的一类漏报; - 属性/字段流不追踪(
obj.x = taint; sink(obj.y)无链); - 守卫式净化器(
if (isValid(x)))与隐式流/控制依赖流不在模型内; - CommonJS 别名仅部分建模(
require('<literal>')可解析连接,动态 require 不行); - 异常路径的过度近似可能带来误报噪音。
因此当模型覆盖度影响结论时,文档要求明确说出这些局限,而不是默许"无发现即安全"的推断。这与 Phase 0 分类表中 Security 类别采取 Default + security PDG mode + explain taint findings · full · ~45 · strict 的姿态相互呼应:安全任务值得 full 计划预算、约 45 次工具调用配额和 strict 新鲜度。
七、性能模式(任务类别:performance)
当任务分类为 performance 时,需在切片中额外扫描这些结构特征:循环、重复调用、阻塞操作、网络调用、数据库调用、分配密集路径、缓存边界、并发、扇出(fan-out)、重复的数据转换。
对扫描结论的措辞有硬性要求:
- 标注可能的热点路径影响时应作为推断(inference)陈述;
- 绝不能在缺乏基准(benchmark)证据的情况下声称已测得的性能提升。
这背后的项目约束可以从仓库的评测资产中得到印证:GitNexus 将性能测量与 PDG 面做成了独立可复现的基准设施,例如 gitnexus/bench/impact-pdg/ 下既包含 PDG 面冲击分析基准(measure.mjs、baselines.json、mutation-oracle.mjs、blast-radius.mjs),也包含 gate-mutation-recall.mjs 这类用于把关变异召回率的度量——也就是说,"实测提升"必须走基准并对照 baselines,而不能凭静态扫描断言。规划文档里的性能类 planning_implications 天然就是这类推断:说清楚"疑似热点",把"是否真的变快"留给带基准的实施与验证环节(gitnexus-work)回答。
同样地,Phase 0 表中 Performance 类别采取 Default + performance PDG mode · full · ~45 · strict 姿态,即性能任务默认走完整计划并启用本增强模式。
八、切片与整套规划体系的衔接
pdg-slice.md 是 gitnexus-plan 技能参考文档族的一员,与 context-ledger.md(ledger 纪律)、plan-template.md(计划 §5/§11 结构)、context-pack.md(实施上下文包)互为补充。切片在其中承担"语句级约束证据"的职能,并遵守如下衔接规则:
与 Phase 1(新鲜度门禁)衔接。 切片要求 PDG 层存在且新鲜。Phase 1 的刷新预算在整个规划会话内被限制为:至多一次 --index-only 刷新 + 至多一次后续 --pdg 升级(仅当 Phase 1 的刷新未带 --pdg 时允许);Deepen 运行视为独立会话。所有命令、runner 身份与结果都要记录在 ledger 的 index_refresh 中。runner 的解析顺序为:项目内 .gitnexus/run.cjs analyze …(若存在)> 全局安装的 gitnexus analyze …(npm install -g gitnexus)> npx gitnexus analyze …。
与 Phase 4(定向源码验证)衔接。 证据层级最强的永远是当前源码与配置,其次当前测试与可执行行为,再往后才是 GitNexus 图与 PDG。切片指向的位置仍须源码复核;图/源码不一致时信任源码、记录分歧、建议重建索引。
与 Fallback mode 衔接。 当 GitNexus 或 PDG 完全不可用时,使用定向仓库探索(grep/glob/read)近似调用者、依赖、执行流与状态变更,但每个结论都要标注 source-derived,严禁伪装成 graph-derived,也严禁编造语句级边;同时推荐在有条件时补跑 analyze --index-only(需要 PDG 层则加 --pdg)。
与测试资产的对应关系。 这套工具契约并非纸面规范——仓库中存在对应的集成测试,例如 pdg-query.test.ts(pdg_query 的 controls/flows 行为)、impact-pdg-traversal.test.ts(PDG 面遍历与切片语义),以及 tools.test.ts(工具 schema 与分派)。当你在规划中引用 impact {mode:"pdg", line} 的语句级切片行为时,这些测试就是"契约边界应该长什么样"的落地参照。
结语:何时不建切片与最小可行纪律
把整份 pdg-slice.md 收敛成几条可操作纪律:
- 只对变更最中心的 1~3 个函数建切片,其余函数止步于更轻的图导航阶梯;
- 深度有界:数据流与控制流各限制在默认 2 跳内,语句数超过约 15 条/函数就收紧相关性而非放开深度;
- 先探测一次"无 PDG 层",仓库级 note 一次定论,别逐函数重探;需要升级时走 Phase 1 已解析 runner 的
analyze --index-only --pdg,遵守会话刷新预算; - 绝不手工从源码重建依赖边——做不到就在 ledger 记 "PDG unavailable"、跳过切片、在计划 §5 声明并推荐命令;
- 事实与推断分离:
behavioural_observations只能是确认事实,planning_implications只能是推断; - 安全任务补污点路径但承认模型盲区;性能任务把热点写成推断,没有基准不声称实测提升。
遵循这组纪律,PDG 切片就能始终保持在规划 LLM 工作记忆可承载的规模内——紧凑、可引用、忠实于工具真实返回,成为连接"图说什么"与"源码里真正是什么"的语句级证据桥。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00