idea_world_labDEV JOURNAL
2026年6月21日星期日

Godot 官方文档 RAG 分类器模式与架构

编写日期:2026 年 6 月 21 日

目的

整理将 Godot 官方文档完整收集版通过 JSONL -> PostgreSQL -> Retriever -> Validator -> Qwen 3.6 流程连接的基准架构。本文档并非用于直接生成训练数据的实现文档,而是定义如何将已聚集在 outputs/godot_docs_full/pages 中的官方文档 Markdown 进行结构化并构建可检索的依据数据库的设计基准。

Godot 初始 RAG 分类器架构

当前输入数据

官方文档收集结果位于仓库的 outputs/godot_docs_full 下。

路径 作用
outputs/godot_docs_full/pages/ Godot 官方文档各页面的 Markdown 原始文件
outputs/godot_docs_full/manifest.json 原始 URL、本地文件路径、收集状态、字节大小
outputs/godot_docs_full/summary.json 整体收集计数与验证摘要
outputs/godot_docs_full/urls.txt 实际收集的 URL 列表
outputs/godot_docs_full/searchindex_urls.txt 从 Sphinx 搜索索引恢复的目标 URL 列表
outputs/godot_docs_full/failed.json 收集失败列表
outputs/godot_docs_full/missing_from_searchindex.txt 基于搜索索引的缺失列表

当前基准线:

项目
Search index target pages 1568
Collected pages 1570
Page files 1570
Failed fetches 0
Missing from search index 0

整体流水线

  1. crawler 从互联网收集 Godot 官方文档。
  2. 将收集结果保存为页面级别的 Markdown。
  3. 对 Markdown 进行规范化并附加元数据,转换为 JSONL 记录。
  4. 将 JSONL 注入 PostgreSQL。
  5. PostgreSQL 将文档块、API 映射、标签原型分离存储。
  6. 当用户请求分析 Godot 源代码时,AST Parser 对项目代码进行结构化。
  7. Retriever 根据用户问题和 AST 分析结果在 PostgreSQL 中检索依据。
  8. Validator 将问题、AST 结果、检索依据组合后传递给 Qwen 3.6。
  9. Qwen 3.6 并非最终裁决者,而是使用已验证的依据整理答案。
  10. Validator 检查响应的依据/格式/禁用模式后返回给用户。

从 Markdown 转换为 JSONL

pages/*.md 是适合人阅读的页面原始文件,但对 RAG 来说粒度过大。因此转换脚本将页面拆分为章节/API 成员/示例单元,并保留原始 URL 与文档类型。

通用规范化规则

步骤 处理
文件加载 根据 manifest.json 中的 fileurlstatusbytes 读取 Markdown。
正文整理 去除重复标题、Sphinx UI 文本、损坏的锚点字符、过多空白。
文档类型划分 根据 URL 与路径将文档划分为 class_referencetutorialmigrationengine_detailsaboutother
章节拆分 依据标题层级和 Godot 类引用模式生成块候选。
代码块保留 GDScript、C#、shader、CLI 示例不从正文中移除,单独保存在 code_blocks 中。
provenance 赋予 为所有记录添加原始 URL、文件路径、原始哈希、转换脚本版本。

JSONL 输出物

文件 目的 目标表
work/godot_rag/jsonl/docs_chunks.jsonl 官方文档说明/教程/参考检索用块 docs_chunks
work/godot_rag/jsonl/api_mapping.jsonl Godot 3 → 4 API 变更、重命名、弃用、替代规则 api_mapping
work/godot_rag/jsonl/label_prototypes.jsonl 分类/转换/拒绝/修改示例原型 label_prototypes
work/godot_rag/jsonl/ingest_report.jsonl 转换过程中的警告、跳过、质量检查日志 用于 DB 注入前的验证

docs_chunks.jsonl 模式

{
  "chunk_id": "godot-stable:classes/class_node.html#description:0001",
  "doc_version": "stable",
  "source_url": "https://docs.godotengine.org/en/stable/classes/class_node.html",
  "source_file": "outputs/godot_docs_full/pages/classes__class_node__....md",
  "source_sha256": "...",
  "doc_type": "class_reference",
  "symbol": "Node",
  "section_path": ["Node", "Description"],
  "heading": "Description",
  "content": "Nodes are Godot's building blocks...",
  "code_blocks": [],
  "language_tags": ["gdscript"],
  "godot_version_tags": ["4.x", "stable"],
  "api_symbols": ["Node", "_ready", "_process", "queue_free"],
  "token_count": 420,
  "metadata": {
    "status": "copied_old",
    "bytes": 12345
  }
}

必填字段:

字段 说明
chunk_id 即使重新运行也不会改变的确定性 ID
doc_version stable, 4.6 等文档版本
source_url 官方文档原始 URL
source_file 仓库内 Markdown 路径
source_sha256 原始 Markdown 哈希
doc_type 文档类型
symbol 当为 class/API 文档时的代表符号
section_path 标题层级
content 用于搜索和嵌入的正文
code_blocks 从正文中提取的代码块数组
api_symbols 正文中检测到的 Godot API 符号

api_mapping.jsonl 架构

{
  "mapping_id": "godot3-to-4:kinematicbody2d-to-characterbody2d",
  "source_api": "KinematicBody2D",
  "target_api": "CharacterBody2D",
  "change_type": "rename_or_replacement",
  "godot_from": "3.x",
  "godot_to": "4.x",
  "confidence": "verified_from_docs",
  "evidence_chunk_ids": [
    "godot-stable:tutorials/migrating/upgrading_to_godot_4.html#..."
  ],
  "match_terms": ["KinematicBody2D", "CharacterBody2D"],
  "notes": "Godot 4 character movement node replacement candidate.",
  "negative_patterns": ["do not suggest KinematicBody2D for Godot 4 projects"]
}

原則:

項目 標準
confidence 有官方文件依據時為 verified_from_docs,規則候選項為 candidate
自動提取 可以從 migration 文檔和 class reference 中生成候選項。
核准標準 用於學習/標註的規則僅在人工審核後才提升為 approved 狀態。
exact index source_apitarget_apimatch_terms 為精確搜索對象。

label_prototypes.jsonl 結構

{
  "prototype_id": "label:godot3-api-in-godot4:kinematicbody2d",
  "label": "godot3_api_in_godot4",
  "task_type": "version_classification",
  "input_pattern": "extends KinematicBody2D",
  "expected_finding": "Godot 3 style physics body API detected.",
  "recommended_action": "Use CharacterBody2D or CharacterBody3D depending on project dimension.",
  "evidence_mapping_ids": [
    "godot3-to-4:kinematicbody2d-to-characterbody2d"
  ],
  "evidence_chunk_ids": [],
  "severity": "high",
  "validator_rules": {
    "requires_ast_symbol": "KinematicBody2D",
    "forbidden_answer_terms": ["KinematicBody2D is recommended in Godot 4"]
  }
}

标签候选:

标签 含义
godot4_valid_api 基于 Godot 4 的有效 API 使用
godot3_api_in_godot4 Godot 4 项目中混入了 Godot 3 API
deprecated_or_removed_api 使用了已删除/废弃的 API
migration_required 需要从 Godot 3 迁移到 4
ambiguous_version_signal 版本判断依据不足或冲突
non_godot_noise 与 Godot 无关的数据(Python、Web、Unity 等)
unsafe_or_obfuscated_code 混淆、控制字符、疑似恶意代码

PostgreSQL 模式草案

PostgreSQL 默认使用 pgvector。关键词搜索同时使用 tsvector 或 trigram 索引。

docs_chunks

类型 说明
id bigserial primary key 内部 ID
chunk_id text unique not null JSONL 的决定性 ID
doc_version text not null 文档版本
source_url text not null 官方文档 URL
source_file text not null Markdown 文件路径
source_sha256 text not null 原始哈希
doc_type text not null 文档类型
symbol text 代表 API / class 符号
section_path jsonb not null 标题层级
heading text 当前块标题
content text not null 可搜索正文
code_blocks jsonb not null default '[]' 代码块
api_symbols text[] not null default '{}' 提取的符号
metadata jsonb not null default '{}' 其他元数据
embedding vector 向量嵌入
search_tsv tsvector 关键词搜索
created_at timestamptz default now() 写入时间

索引:

索引 目的
unique(chunk_id) 防止重复写入
ivfflat/hnsw(embedding) 基于语义的搜索
gin(search_tsv) 关键词搜索
gin(api_symbols) API 符号过滤
btree(doc_type, symbol) class / API 文档过滤

api_mapping

类型 说明
id bigserial primary key 内部 ID
mapping_id text unique not null 决定性 ID
source_api text not null 旧 / 问题 API
target_api text 推荐 API
change_type text not null rename、removed、behavior_change 等
godot_from text 起始版本
godot_to text 目标版本
confidence text not null 依据等级
status text not null default 'candidate' candidate、approved、rejected
evidence_chunk_ids text[] not null default '{}' 官方文档依据块
match_terms text[] not null default '{}' 搜索关键词
notes text 说明
negative_patterns jsonb not null default '[]' 禁止模式

索引:

索引 目的
unique(mapping_id) 防止重复
btree(source_api) 精确查找
btree(target_api) 逆向查找
gin(match_terms) 关键词搜索
btree(status, confidence) 审批规则过滤

label_prototypes

类型 说明
id bigserial primary key 内部 ID
prototype_id text unique not null 决定性 ID
label text not null 分类标签
task_type text not null classification、migration_fix、patch_generation 等
input_pattern text not null 检测模式
expected_finding text not null 预期判定
recommended_action text 推荐操作
evidence_mapping_ids text[] not null default '{}' API 映射依据
evidence_chunk_ids text[] not null default '{}' 文档块依据
severity text not null low、medium、high
validator_rules jsonb not null default '{}' 验证规则
embedding vector 相似案例搜索
search_tsv tsvector 关键词搜索

索引:

索引 目的
unique(prototype_id) 防止重复
btree(label, task_type) 按标签查询
ivfflat/hnsw(embedding) 相似标签搜索
gin(search_tsv) 关键词搜索

AST Parser 输入/输出

AST Parser 在将用户源码直接交给 LLM 之前,将其转换为可搜索的结构。初始目标文件为 .gd.tscnproject.godot

输入

输入 说明
用户提问 例如:“请检查这个项目在 Godot 4 下是否安全”
源代码文件 .gd.tscn.tresproject.godot
项目结构 文件路径、场景关联、资源路径

输出模式

{
  "project_id": "local-analysis-...",
  "godot_project": {
    "config_version": 5,
    "features": ["4.4", "Forward Plus"]
  },
  "files": [
    {
      "path": "scripts/player.gd",
      "language": "gdscript",
      "extends": "CharacterBody2D",
      "class_name": "Player",
      "symbols": ["CharacterBody2D", "Input", "move_and_slide"],
      "annotations": ["@onready"],
      "version_signals": ["godot4_annotation_syntax"],
      "diagnostics": []
    }
  ],
  "version_evidence": {
    "godot4": ["config_version=5", "@onready"],
    "godot3": []
  }
}

初始提取字段:

字段 目的
extends 判断 Node/API 版本
class_name 项目内部符号映射
annotations @onready@export 等 Godot 4 信号
legacy_keywords onready varexport varKinematicBody 等 Godot 3 信号
method_calls 文档搜索和 API 映射查询
scene_dependencies 场景/脚本连接验证
resource_paths 缺失资源和资产连接验证

Retriever 工作原理

Retriever 是在 LLM 之前选择依据的层级。

  1. 从用户提问中提取意图和目标任务。
  2. 从 AST Parser 结果中获取 API 符号、版本信号、文件路径。
  3. api_mapping 中首先执行精确查找。
  4. docs_chunks 中同时执行 API 符号过滤 + 关键字搜索 + 向量搜索。
  5. label_prototypes 中获取相似标签和验证规则。
  6. 将搜索结果按依据捆绑进行排序。

依据捆绑:

{
  "query_id": "analysis-...",
  "task_type": "version_classification",
  "ast_summary": {},
  "doc_evidence": [],
  "api_mapping_evidence": [],
  "label_evidence": [],
  "retrieval_scores": {
    "exact_api_hits": 2,
    "keyword_hits": 8,
    "vector_hits": 12
  }
}

Validator和Qwen 3.6角色分离

Qwen 3.6是读取检索到的依据并整理答案的模型。最终标签、依据采纳、禁用模式验证由Validator负责。

构成要素 责任
Retriever 相关官方文档/API映射/标签依据检索
Validator 依据缺失、禁用模式、输出 JSON 格式验证
Qwen 3.6 向用户呈现的说明、修改方向、代码建议整理

Validator需要确认的项目:

项目 标准
依据 ID 存在 回答中使用的文档/映射/标签 ID 必须实际出现在检索结果中。
Godot 4 标准 在 Godot 4 项目中不应推荐 Godot 3 API。
不确定性标记 依据不足时禁止作出确定判断,使用 ambiguous_version_signal 标记。
代码建议验证 建议的代码不得与检测到的项目维度 2D/3D 冲突。
JSON 格式 内部流水线输出必须是可解析的 JSON。

注入顺序

  1. 检查 outputs/godot_docs_full/summary.jsonfailed.json
  2. 加载 manifest.jsonpages/*.md
  3. 生成 Markdown 规范化报告。
  4. 创建 docs_chunks.jsonl
  5. 在 migration/class 文档中生成 api_mapping.jsonl 候选。
  6. 使用已批准的规则和代表案例生成 label_prototypes.jsonl
  7. 仅将通过 JSONL 模式验证的记录 upsert 到 PostgreSQL。
  8. 生成嵌入并更新向量索引。
  9. 更新关键词索引和精确索引。
  10. 使用示例问题验证 Retriever 结果。

质量验证检查清单

步骤 通过标准
收集验证 failed_count = 0, missing_from_searchindex = 0
Markdown 正规化 无空块,保留原始 URL
JSONL 验证 所有行均可 JSON 解析,必需字段存在
重复验证 chunk_id, mapping_id, prototype_id 不重复
依据验证 api_mapping.evidence_chunk_ids 在实际 docs_chunks 中存在
搜索验证 在代表 API 问题中同时返回 exact hit 和 docs hit
响应验证 Qwen 响应不出现无依据的断言,也不推荐 Godot 3 API

实现优先级

  1. 编写 pages/*.md 结构分析报告
  2. 编写 docs_chunks.jsonl 转换脚本
  3. 编写 JSONL 模式验证脚本
  4. 编写 PostgreSQL DDL
  5. docs_chunks 注入与搜索验证
  6. 编写 api_mapping 候选生成与人工批准流程
  7. 编写 label_prototypes 初始标签集
  8. AST 解析器最小字段提取
  9. Retriever 依据捆绑输出
  10. 将 Validator + Qwen 3.6 响应整理循环连接

核心原则

  • 官方文档原始 Markdown 不修改,保持原样。
  • JSONL 作为可再生成的中间产物保存。
  • 数据库中必须记录原始路径、原始 URL、哈希、转换脚本版本。
  • 防止 LLM 发明标签。
  • 对 Godot 3/4 的判定结合 AST 信号、API 映射、官方文档依据进行。
  • 不确定的候选不直接用于训练数据,而是置于 candidate 状态。
  • Qwen 3.6 充当答案整理者,判定标准由 Retriever 和 Validator 提供。

接下来的工作

下一步是对 outputs/godot_docs_full/pages 的 Markdown 结构进行抽样分析。特别是 class reference、migration、tutorial 文档拥有不同的结构,因此不能使用统一的分块规则,需要先确定针对每种文档类型的分块策略。