跳转至

RFC:文件级节点摘要

本 RFC 为 graphify 提出一种可选方式,以向 AI 编程智能体暴露紧凑的文件级摘要。

问题

graph.json 为智能体提供图结构、源文件、节点标签和关系。这有助于避免通读整个仓库,但智能体仍然经常需要检查原始文件,只为回答一个基本的导航问题:

这个文件或节点负责什么?

目标

  • 帮助智能体在更少的上下文中选择相关文件。
  • 默认保留 graphify 的离线性、确定性行为。
  • 保持首个实现小巧且易于评审。
  • 避免向 GRAPH_REPORT.md 添加冗长文字。
  • 为未来可选加入的 LLM 生成摘要后端留出空间。

非目标

  • 在首个版本中并不对每个函数、方法或局部符号生成摘要。
  • 默认不调用 LLM 或远程 API。
  • 不取代 graphify explain;摘要应让 explain 更有用。
  • 不把 GRAPH_REPORT.md 变成完整的逐文件索引。

两种方案共同遵循的约束

  • 仅从文件级节点开始。
  • 将每条摘要限制在合理范围内,例如一句话或大约 200-300 个字符。
  • 优先从现有的本地信号生成确定性摘要:模块文档字符串、顶部注释、导出符号、导入、关系计数以及社区/上下文数据。
  • 在存储模型达成一致之前,默认不输出摘要。
  • 当存在摘要时,在 graphify explain <node> 中显示。
  • 当存在摘要时,在 graphify serve / MCP 节点查找中包含摘要。

提议的摘要内容

每条文件级摘要都应给智能体足够的信号,使其决定是否查看该文件,而不会取代文件本身或使图输出臃肿。

推荐字段:

字段 为什么它对智能体有帮助
summary 用一句话描述文件职责并控制长度。这是主要的节省 token 的字段。
source_file 让智能体无需手动解析节点 ID 即可跳转到正确的文件。
label 使摘要可在 CLI、MCP 和 UI 上下文中保持可读。
generated_by 区分确定性摘要与未来 LLM 生成的摘要。
summary_version 允许格式演进,而无需猜测旧摘要的生成方式。

summary 句子中推荐的信号:

信号 为什么它属于该句子
模块文档字符串或顶部注释 通常是最优质、由人工撰写的用途说明。
导出的类/函数/符号 告诉智能体该文件提供哪些 API 接口。
重要导入或依赖 揭示文件属于认证、数据库、UI、CLI、测试等类别。
主要图关系 显示文件主要是调用、导入、定义、包含还是引用其他节点。
社区或邻近枢纽标签 无需阅读整个社区报告即可提供架构上下文。
可用时的源码位置覆盖 有助于区分文件级摘要与符号级解释。

示例:

{
  "label": "extract.py",
  "source_file": "graphify/extract.py",
  "summary": "Extracts source files into graph nodes and relationships; defines language parsers and import/call extraction helpers.",
  "generated_by": "deterministic",
  "summary_version": 1
}

摘要不应包含长调用链、完整依赖列表、原始代码或文件中的每个符号。这些细节已经属于图本身,可在需要时通过 graphify explain、graphify query 或直接读取文件获取。

方案 A:graph.json 中的 summary 属性

向文件级节点添加可选的 summary 字段:

{
  "id": "graphify_extract",
  "label": "extract.py",
  "file_type": "code",
  "source_file": "graphify/extract.py",
  "summary": "Extracts source files into graph nodes and relationships using language-specific parsers."
}

可能的用户流程:

graphify . --summarize-nodes
graphify explain "extract.py"

优点:

  • 为图消费者提供单一产物。
  • 与 NetworkX 节点属性和现有节点元数据匹配。
  • 便于 explain、serve、可视化工具和 MCP 工具使用。
  • 无需附属文件的时效性或节点 ID 关联逻辑。

缺点:

  • 向核心图产物添加文本。
  • 扩展了图 schema 的范围。
  • 那些把整个 graph.json 直接塞入 LLM 上下文的消费者,会一次性为所有摘要付出代价。

方案 B:附属文件 node-summaries.json

将摘要写入一个以节点 ID 为键的独立产物:

{
  "version": 1,
  "generator": "deterministic",
  "nodes": {
    "graphify_extract": {
      "label": "extract.py",
      "source_file": "graphify/extract.py",
      "summary": "Extracts source files into graph nodes and relationships using language-specific parsers."
    }
  }
}

可能的用户流程:

graphify summarize
graphify explain "extract.py"

优点:

  • 保持 graph.json 精简并聚焦于拓扑结构。
  • 使摘要明确可选。
  • 可独立重新生成。
  • 为未来的生成器元数据提供自然的位置。

缺点:

  • 新增第二个产物,消费者必须发现并加载它。
  • 引入了时效性和同步问题。
  • 每个需要摘要的消费者都必须按节点 ID 进行关联。

存储方式确定后的首个实施建议

  1. 添加确定性的文件级摘要生成。
  2. 使用所选方案存储摘要。
  3. 在 graphify explain 中呈现摘要。
  4. 在 graphify serve / MCP 节点查找中呈现摘要。
  5. 为默认行为、已生成摘要、缺失摘要以及受限的摘要长度添加测试。

后续设想

  • 添加选择启用的 LLM 生成摘要,并支持显式的 provider/后端选择。
  • 如果文件级摘要被证明有用,则将摘要扩展到类或模块级节点。
  • 允许 graphify query 在预算内为返回的节点包含摘要。
  • 如果摘要与主图分开生成,则添加缓存/时效性元数据。

给维护者和用户的问题

  1. graphify 应该偏好单个产物(graph.json),还是将生成的文本保留在伴随文件中?
  2. 是否应在图谱创建期间生成确定性的文件级摘要,还是仅通过显式命令(如 graphify summarize)生成?
  3. summary 是合适的术语,还是 synopsis 能更好地传达简短、有界描述的含义?
  4. 对于大型仓库,可接受的摘要长度预算是多少?

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 graph/graphify