第二章:三层索引架构
在 opengis-skills 仓库中,三层索引架构是整个系统设计的灵魂。它决定了 AI 工具如何发现、加载和利用 67 个技能文件,是所有上层功能的基础。本章将从设计动机出发,逐层深入解析 L1(全局入口)、L2(分类索引)和 L3(项目技能)的结构与协作方式,并通过完整的 AI 加载决策流程展示这套架构在真实场景中的运作机制。
2.1 设计动机
在讨论具体架构之前,理解它要解决什么问题比理解它是什么更重要。
2.1.1 上下文窗口的约束
所有主流 AI 编程助手——Claude、Cursor、Cline、GitHub Copilot Chat、DeepSeek Chat——都有一个共同约束:上下文窗口(context window)是有限的且按 Token 计费。opengis-skills 仓库包含 67 个技能文件,每个 SKILL.md 文件从 200 行到 1500 行不等。如果 AI 工具在每次对话中都全量加载 67 个文件,会产生以下问题:
| 问题 | 影响 |
|---|---|
| Token 消耗爆炸 | 67 个文件 × 平均 800 行 × 约 40 Token/行 ≈ 210 万 Token,远超大多数模型的窗口上限 |
| 注意力稀释 | AI 难以在海量信息中定位真正相关的 1-2 个技能 |
| 成本翻倍 | 每次全量扫描消耗大量输入 Token,无意义增加 API 费用 |
| 响应变慢 | 大上下文导致推理延迟显著增加 |
因此需要一个按需加载(on-demand loading)的机制,让 AI 工具在 1-3 个技能文件内就能获取足够的知识来完成任务。
2.1.2 不同场景需要不同粒度的知识
用户的问题千差万别,对应的知识需求粒度也不同:
| 用户场景 | 知识需求粒度 | 对应层级 |
|---|---|---|
| “我想做 GIS 数据处理,有什么工具?” | 概览级:了解可选工具范围和分类 | L1 全局入口 |
| “我需要 Python 做空间分析,有哪些库?” | 概要级:了解某个领域内的工具和对比 | L2 分类索引 |
| “用 GDAL 的 ogr2ogr 怎么把 Shapefile 转成 GeoPackage?” | 深度级:某个工具的具体命令、参数和最佳实践 | L3 项目技能 |
如果只有一个层级的索引,要么信息不足(只有概要)、要么信息过载(每次都加载深度内容)。三层架构天然匹配这三种粒度需求,做到”刚好够用的信息量”。
2.1.3 AI 工具需要快速定位
AI 工具在接收用户问题后,需要在数百毫秒内判断应该加载哪个技能文件。这要求索引系统具备以下特性:
- 可搜索性:能通过标签、关键词、分类快速命中目标技能
- 递增精度:从 L1(67 个技能的全貌)→ L2(一个分类下的 8-23 个技能)→ L3(1 个技能的深度知识),每一步都缩小范围
- 低 Token 成本:L1 和 L2 索引文件本身要足够精简(控制在 200-400 行),确保搜索成本可忽略不计
2.1.4 技能之间需要清晰的引用关系
GIS/CAD 等领域的工具不是孤岛。例如:
geopipe-agent引用了gdal、qgis-process、geopandasopengis-all聚合了 GDAL → QGIS → GeoServer 的全流程shapely和geopandas常组合使用
三层架构通过相对路径引用(../gdal/SKILL.md)构建了一个层级化的知识图谱,让技能之间可以互相导航,AI 工具可以沿着引用链加载相关技能。
2.2 三层架构全景
2.2.1 层级表
| 层级 | 名称 | 文件路径 | 数量 | 内容量级 | 适用场景 |
|---|---|---|---|---|---|
| L1 | 全局入口 | 根目录 SKILL.md |
1 个 | 67 个技能的全量索引 + 标签搜索系统 | 不确定具体工具时,先加载此文件获取全貌 |
| L2 | 分类索引 | gis/SKILL.md、cad/SKILL.md、csharp/SKILL.md、ai/SKILL.md、iot/SKILL.md、3d/SKILL.md、others/SKILL.md |
7 个 | 该分类下 1-23 个技能的概要 + 领域概述 | 明确大类但不确定具体工具 |
| L3 | 项目技能 | <category>/<project>/SKILL.md |
67 个 | 单个项目的深度知识(API、工作流、FAQ) | 已确定使用哪个工具 |
2.2.2 三层架构的目录结构映射
opengis-skills/
│
├── SKILL.md ← L1:全局入口(67 个技能全量索引 + 标签搜索)
│
├── gis/ ← 分类目录
│ ├── SKILL.md ← L2:GIS 分类索引(23 个技能概要)
│ ├── gdal/ ← 子项目
│ │ └── SKILL.md ← L3:GDAL 命令行技能(452 行深度知识)
│ ├── geopandas/
│ │ └── SKILL.md ← L3:GeoPandas 技能
│ ├── geoserver/
│ │ └── SKILL.md ← L3:GeoServer 技能
│ └── ...(共 23 个子项目)
│
├── cad/
│ ├── SKILL.md ← L2:CAD 分类索引(19 个技能概要)
│ ├── freecad/
│ │ └── SKILL.md ← L3:FreeCAD 技能
│ └── ...(共 19 个子项目)
│
├── csharp/
│ ├── SKILL.md ← L2:C# 分类索引(8 个技能概要)
│ └── ...(共 8 个子项目)
│
├── ai/
│ ├── SKILL.md ← L2:AI 分类索引(8 个技能概要)
│ └── ...(共 8 个子项目)
│
├── iot/
│ ├── SKILL.md ← L2:IoT 分类索引(1 个技能概要)
│ └── ke3036-keyes-pico/
│ └── SKILL.md ← L3:Raspberry Pi Pico 技能
│
├── 3d/
│ ├── SKILL.md ← L2:3D 分类索引(2 个技能概要)
│ └── ...(共 2 个子项目)
│
└── others/
├── SKILL.md ← L2:Others 分类索引(6 个技能概要)
└── ...(共 6 个子项目)
每个层级都是目录下的 SKILL.md 文件,命名完全一致,形成一种递归式的自描述结构。AI 工具只需记住一条规则:加载某个路径下的 SKILL.md 就能获得该层级的全部信息。
2.2.3 AI 加载决策树
下面是 AI 工具从接收用户提问到加载目标技能文件的完整决策路径:
用户提问:"帮我把 Shapefile 转成 GeoJSON"
↓
AI 加载 @SKILL.md(根,L1)
│ 成本:300 行 ≈ 12K Token
│ 获得:67 个技能的全量索引 + 标签搜索系统
↓
在标签索引中搜索匹配项
│ 搜索 #conversion #vector
│ 匹配:gdal(cli, raster, vector, conversion)
↓
定位到 L2 分类索引?
├─ 是 → 加载 @gis/SKILL.md 了解更多 GIS 工具选项
│ 成本:200 行 ≈ 8K Token
│ 获得:23 个 GIS 技能的概要 + GIS 数据处理链路
│
└─ 否 → 跳过 L2,直接定位到 L3 技能
↓
加载 @gis/gdal/SKILL.md(L3)获取详细指导
│ 成本:452 行 ≈ 18K Token
│ 获得:50+ 命令行的完整 API、参数说明、工作流示例、FAQ
↓
AI 根���技能内容生成回答
│ 输出:`ogr2ogr -f GeoJSON output.json input.shp`
│ 附带:参数说明、坐标系转换、批量处理脚本
↓
可选:加载 @gis/geopandas/SKILL.md 获取 Python 替代方案
总 Token 消耗:L1(12K)+ L2(8K)+ L3(18K)= 约 38K Token。相比于全量加载 67 个文件(约 210 万 Token),节省了 98.2% 的上下文窗口。
2.2.4 加载路径的两种模式
三层架构支持两种加载路径,AI 工具可以根据问题的明确程度自适应选择:
直钻模式(Drill-Down):当用户问题具体到某个工具时,直接跳入 L3。
提问:"ogr2ogr 怎么指定输出坐标系?"
→ 跳过 L1/L2 → 直接加载 gis/gdal/SKILL.md
渐进模式(Progressive):当用户问题模糊时,逐级下钻。
提问:"我想做空间数据处理,用什么好?"
→ L1:加载根 SKILL.md,浏览 67 个技能概览
→ L2:发现 GIS 分类有 23 个技能,加载 gis/SKILL.md
→ L3:确定用 GDAL,加载 gis/gdal/SKILL.md
这种双模式设计的关键在于:三层架构不强制逐级加载,而是提供了从任意层级切入的灵活入口。AI 工具只需根据用户问题的语义,选择一个最合适的起点。
2.3 L1:全局入口 SKILL.md
根目录的 SKILL.md 是整个仓库的唯一入口,也是三层架构的基石。它的设计目标是:让 AI 工具在加载这一个文件之后,就能回答以下三个问题:
- 这个仓库是做什么的?(概述)
- 有哪些技能可以用?(索引表)
- 如何找到我需要的技能?(标签搜索)
2.3.1 YAML Frontmatter 设计
根 SKILL.md 的 YAML 前置元数据是整个标签搜索系统的核心:
---
name: opengis-skills
description: "Use when AI coding assistant needs GIS/CAD/C#/AI/IoT/3D domain
expertise for 67+ open-source projects. One-stop skill index with tag-based search
and on-demand loading for GDAL, GeoServer, QGIS, PostGIS, JTS, CesiumJS, FreeCAD,
OpenSCAD, OCCT, NPOI, SqlSugar, Furion, Dify, SuperSplat, Go and more."
tags:
- gis
- cad
- csharp
- ai
- iot
- opensource
- skills
- geospatial
- spatial-analysis
- mapping
- 3d-modeling
- dotnet
- python
- java
- javascript
- go
- typescript
- cpp
---
name 字段:仓库标识名,与 GitHub 仓库名保持一致。AI 工具通过此字段识别仓库。
description 字段:采用 Anthropic Skill 最佳实践的 "Use when..." 格式。这种格式的核心思想是描述”何时使用”而非”这是什么”——对于 AI 工具而言,知道”什么时候应该加载这个技能”比”这个技能包含什么内容”更重要。description 限长 ≤500 字符,确保 AI 在扫描大量技能时能快速判断相关性。
tags 字段:18 个全局标签,覆盖了仓库涉及的 7 种编程语言和 11 个功能领域。标签系统设计的关键原则:
- 语言标签(
python、java、dotnet等)用于精确匹配用户的技术栈 - 领域标签(
gis、cad、3d-modeling等)用于按功能分类 - 通用标签(
opensource、skills)用于仓库级别的搜索
2.3.2 分类导航表
由于根 SKILL.md 是全局入口,它必须用最紧凑的信息密度呈现所有 67 个技能的概况。为此采用了一张按分类组织的导航表:
### 🌍 GIS — 地理信息系统(23 个)
| 技能 | 简介 | 关键标签 |
|------|------|---------|
| [gdal](./gis/gdal/SKILL.md) | GDAL 命令行:栅格/矢量处理事实标准 | `cli` `raster` `vector` `conversion` |
| [geoserver](./gis/geoserver/SKILL.md) | 开源地图服务器(WMS/WFS/WMTS/WCS) | `server` `wms` `wfs` `ogc` |
| [postgis](./gis/postgis/SKILL.md) | PostgreSQL 空间数据库扩展 | `database` `sql` `spatial` |
| ... | ... | ... |
导航表的设计要点:
- 表头三列:技能名称(带超链接)、一句话简介、关键标签——刚好满足”判断是否需要加载”的信息量
- 按分类分组:GIS 23 个、CAD 19 个、C# 8 个、AI 8 个、IoT 1 个、3D 2 个、Others 6 个——共七个分类,用 emoji 和中文标题区分
- 相对路径超链接:
./gis/gdal/SKILL.md是相对路径引用,AI 工具可以直接通过路径加载对应文件 - 标签列:3-5 个精选标签,提供比一句话简介更精确的匹配维度
2.3.3 标签索引系统(详见 2.6 节)
在导航表之后,根 SKILL.md 提供了按语言和按功能领域的双维度标签索引:
### 按语言/平台
| 标签 | 相关技能 |
|------|---------|
| `python` | gdal-api, pyqgis, geopandas, shapely, cadquery, freecad, docutranslate |
| `java` | geotools, jts, geometry-api-java, opengis-utils-for-java, ruoyi-cloud |
| `dotnet` / `csharp` | gdal-api, nettopologysuite, geometry-api-net, sharpmap, mapsui, ... |
| ... | ... |
### 按功能领域
| 标签 | 相关技能 |
|------|---------|
| `geometry` | jts, nettopologysuite, shapely, geometry-api-java, geometry-api-net, clipper1, clipper2, ... |
| `raster` | gdal, gdal-api, qgis-process |
| `server` / `wms` / `wfs` | geoserver, geoserver-cloud, geoserver-rest-api |
| ... | ... |
这种双维度索引的价值在于:AI 工具可以用用户问题中的关键词(如”python” + “向量”)在标签系统中做 AND 组合查询,比单纯的关键词匹配更精准。
2.3.4 场景推荐表
为了让 AI 工具在最短路径上找到目标技能,根 SKILL.md 还提供了一张典型场景 → 推荐加载技能的映射表:
| 用户需求 | 加载技能 |
|---------|---------|
| "帮我把 Shapefile 转成 GeoJSON" | `gis/gdal/SKILL.md` |
| "用 Python 计算两个面的交集" | `gis/shapely/SKILL.md` |
| "用 QGIS 批处理做缓冲区分析" | `gis/qgis-process/SKILL.md` |
| "如何发布矢量数据到 GeoServer?" | `gis/geoserver-rest-api/SKILL.md` |
| "PostGIS 怎么建空间索引?" | `gis/postgis/SKILL.md` |
| ... | ... |
这张表的特殊价值在于:它直接给出了答案而非让 AI 自行推断。对于高频场景,AI 工具可以跳过标签搜索,直接通过问题语义匹配表中的一个条目,实现零推理成本的技能定位。
2.3.5 AI 工具使用指南与加载策略
根 SKILL.md 的最后一节是面向 AI 工具的使用指南,核心是两种加载策略:
策略一:按需加载(推荐) 根据用户问题,只加载 1-3 个最相关的 SKILL.md。适用于绝大多数场景,Token 成本最低。
策略二:全量加载 当用户需求横跨多个领域或完全不确定具体工具时,先加载根 SKILL.md 获取全局索引,再按需下钻。这只是第一步的”全局扫描”,后续仍然是精准加载。
此外,文档还列举了不同 AI 工具的加载语法:
# Claude Code / Claude
@SKILL.md # 加载根入口
@gis/gdal/SKILL.md # 加载 GDAL 技能
# Cursor
在 .cursorrules 中引用或在对话中使用 @file 语法
# Cline / Roo Code
直接使用 @ 语法或通过 .clinerules 配置
2.3.6 文件间引用方式
根 SKILL.md 中的所有技能引用都使用相对路径:
[gdal](./gis/gdal/SKILL.md) ← 从根目录到子目录
而子技能文件中回引父目录时使用 ../ 语法:
[../SKILL.md](../SKILL.md) ← 从子目录回引根目录
这种基于文件系统路径的引用方式有两个优势:
- 不依赖外部 URL:即使仓库离线或迁移至 Gitee 等平台,引用链仍然有效
- AI 工具直接可用:大多数 AI 工具的
@语法就是基于文件路径的,引用路径和加载路径完全一致
2.4 L2:分类索引
L2 分类索引是 L1 和 L3 之间的减震层——当用户问题过于模糊无法直接定位到 L3 时,L2 提供了一个中等粒度的视图,用 200 行的文件覆盖一个领域内 1-23 个技能的关键信息。
仓库共有 7 个 L2 索引文件,对应 7 个分类目录:
| 分类索引 | 技能数量 | 领域覆盖 |
|---|---|---|
gis/SKILL.md |
23 | 空间数据处理、地图服务、Web GIS |
cad/SKILL.md |
19 | 参数化建模、几何内核、BIM/PCB |
csharp/SKILL.md |
8 | .NET 框架、ORM、Office 操作 |
ai/SKILL.md |
8 | LLM 应用、Agent 框架、AI 编程方法论 |
iot/SKILL.md |
1 | 物联网与嵌入式 |
3d/SKILL.md |
2 | 3D 高斯泼溅、AEC/BIM 三维数据处理 |
others/SKILL.md |
6 | Go 语言、RPA 自动化、邮件平台、Java 脚手架、SSL 证书 |
2.4.1 以 gis/SKILL.md 为例深度解析
gis/SKILL.md 是最大的 L2 索引文件,涵盖 23 个 GIS 技能。它的结构代表了所有 L2 索引的标准模式。
YAML Frontmatter:
---
name: gis-skills
description: "Use when processing geospatial data, publishing map services,
querying spatial databases, performing geometry operations, or building web map
applications. Index of 23 skills: GDAL, GeoServer, QGIS, PostGIS, JTS, GeoPandas,
Shapely, CesiumJS, OpenLayers, NetTopologySuite and more."
tags:
- gis
- geospatial
- mapping
- spatial-analysis
- vector
- raster
- server
- webmapping
---
L2 分类索引的 description 采用 "Index of N skills: ..." 的固定格式,让 AI 能立即知道这个索引文件下有多少个可用的子技能。
父级入口引用:
> **父级入口:** [../SKILL.md](../SKILL.md) — 全仓 66 技能总索引
每个 L2 索引的第一行都引用回 L1 根入口,形成一个双向导航:从 L1 可以下钻到 L2,从 L2 也能回溯到 L1。这种设计让 AI 工具在加载了过多上下文后可以”退回”到更高层级的视角。
领域数据流图:
gis/SKILL.md 在概述中用一段 ASCII 图描绘了 GIS 数据处理的全链路:
数据源 → 命令行处理 → 编程分析 → 空间数据库 → 地图服务 → 前端可视化
(GDAL) (GDAL CLI) (JTS/PyQGIS) (PostGIS) (GeoServer) (OpenLayers/Cesium)
这不是装饰,而是帮助 AI 理解工具之间关系的语义地图。当用户说”我想从数据处理到发布地图”时,AI 能立即沿着这条链路找到 GDAL(处理)→ PostGIS(存储)→ GeoServer(发布)→ OpenLayers(可视化)的完整组合。
子技能分组列表:
L2 索引将 23 个 GIS 技能按职能分为 8 个子类:
- 🧰 数据处理与命令行(4 个:gdal, gdal-api, qgis-process, geopipe-agent)
- 🗄️ 空间数据库(1 个:postgis)
- 🔧 几何运算库(5 个:jts, geometry-api-java, geometry-api-net, shapely, geopandas)
- 🌐 地图服务器(3 个:geoserver, geoserver-rest-api, geoserver-cloud)
- 🖥️ QGIS 生态(1 个:pyqgis)
- 🗺️ Web 地图可视化(2 个:cesiumjs, openlayers)
- 📦 .NET GIS 组件(5 个:nettopologysuite, geometry-api-net, sharpmap, mapsui 等)
- 🧩 综合/工具集(3 个:opengis-all, geotools, opengis-utils-for-java, opengis-utils-for-net)
每个子类的表格结构与 L1 相同:技能名(带链接)、一句话简介、关键标签。这种一致性让 AI 工具在处理不同层级的信息时无需切换解析逻辑。
快速导航表:
| 用户需求 | 推荐加载 |
|---------|---------|
| "Shapefile 转 GeoJSON" | `gdal/SKILL.md` |
| "Python 空间分析" | `geopandas/SKILL.md` + `shapely/SKILL.md` |
| "发布 WMS 地图服务" | `geoserver/SKILL.md` + `geoserver-rest-api/SKILL.md` |
| ... | ... |
与 L1 的场景推荐表不同,L2 的快速导航表粒度更细——同一个”GIS 数据处理”大类下,不同子场景推荐不同的技能组合。例如”Python 空间分析”推荐同时加载 geopandas 和 shapely,因为这两个库在实际使用中高度互补。
相关分类引用:
- **[cad/](../cad/SKILL.md)** — CAD 参数化建模、几何运算、BIM/PCB
- **[csharp/](../csharp/SKILL.md)** — .NET 框架、ORM、Office 操作
- **[ai/](../ai/SKILL.md)** — LLM 应用、Agent 框架
- **[3d/](../3d/SKILL.md)** — 3D 高斯泼溅与 Web 三维可视化
- **[iot/](../iot/SKILL.md)** — 物联网与嵌入式
L2 索引的末尾都会列出兄弟分类索引,让 AI 工具在发现”当前分类下没有最佳匹配”时,能横向跳转到其他分类。
2.4.2 其他 L2 分类索引概览
cad/SKILL.md(19 个技能):
与 gis/SKILL.md 结构完整对称,包含 CAD 数据流图:
几何内核 → 参数化建模 → CAD 应用 → 数据交换 → 可视化
(OCCT) (FreeCAD) (QCAD) (LibreDWG) (Chili3D)
19 个技能按职能分为 7 个子类:几何内核与算法(3 个)、参数化 3D CAD(5 个)、2D CAD 与制图(3 个)、PCB/EDA 设计(1 个)、BIM 与 IFC(2 个)、.NET AutoCAD 开发(4 个)、数据交换与可视化(2 个)。
csharp/SKILL.md(8 个技能)、ai/SKILL.md(8 个技能):结构与上述一致,规模较小。每个都有独立的快速导航表和相关分类引用。
iot/SKILL.md(1 个技能)、3d/SKILL.md(2 个技能)、others/SKILL.md(6 个):虽然技能数量较少,但仍遵循完全一致的 L2 模板。模板的一致性确保了 AI 工具在跨分类切换时不需要切换解析策略。
2.4.3 L2 索引的核心价值
L2 索引在架构中承担三个关键角色:
- 知识压缩:将 L1 中一行简介的信息展开为 200 行的领域全景,但比 L3 的单个技能文件仍然精简得多
- 智能路由:当用户说”我要做 CAD”但不说具体工具时,L2 帮 AI 判断该推荐 FreeCAD(参数化建模)还是 OpenSCAD(脚本建模)还是 LibreDWG(DWG 文件处理)
- 横向导航:L2 索引的相关分类引用让 AI 可以跨领域探索——例如用户问 GIF 数据处理,但又提及需要 .NET 平台,AI 可以从
gis/SKILL.md跳转到csharp/SKILL.md寻找 .NET 平台的 GIS 组件
2.5 L3:项目技能
L3 是整个三层架构的”最后一公里”——当 AI 通过 L1/L2 定位到具体的工具后,L3 提供可以立即用于代码生成的深度知识。
2.5.1 以 gis/gdal/SKILL.md 为例深度解析
GDAL 的 L3 技能文件是仓库中最成熟、最完整的典范,共 452 行。它的结构代表了所有 L3 技能的高质量标准。
完整的 Frontmatter:
---
name: gdal
description: "Use when processing geospatial raster/vector data via command line —
format conversion (Shapefile to GeoJSON), reprojection, DEM analysis, NDVI
calculation, mosaicking. GDAL/OGR CLI: the industry standard for batch geospatial
data processing with 50+ command-line tools (ogr2ogr, gdalwarp, gdal_translate,
gdal_calc)."
tags:
- gdal
- ogr
- cli
- raster
- vector
- conversion
- reprojection
- gis
- geospatial
---
L3 技能文件的 Frontmatter 有三个关键设计:
-
name字段:与项目名称完全一致(gdal),与目录名gis/gdal/对应,确保路径和名称的统一性 -
description字段:比 L1/L2 的 description 更长、更具体(但仍在 500 字符内)。前 100 个字符是最重要的——它们直接回答了 AI 工具最关心的问题:”何时加载?”(Use when processing geospatial raster/vector data via command line),然后列举了典型场景(format conversion, reprojection, DEM analysis),最后给出差异化定位(50+ command-line tools)。这种”触发条件 → 典型场景 → 大小估算”的三段式格式,让 AI 在扫描众多 L3 描述时能快速排除不相关的技能 -
tags字段:L3 的标签比 L1 更具体。L1 用python、java等语言标签,L3 用cli、raster、vector、conversion、reprojection等功能标签。这形成了标签的层级关系——L1 标签用于全局搜索,L3 标签用于精确匹配
头部引用块:
> **项目地址:** <https://github.com/OSGeo/gdal>
>
> **官方文档:** <https://gdal.org/en/latest/>
>
> **源码命令文档:** <https://gdal.org/en/latest/programs/>
>
> **许可证:** MIT
头部引用块是一个固定的四行元数据模板,每个 L3 技能都必须包含。它的作用是:
- 让 AI 工具知道可以到官方文档获取更实时的信息(减少幻觉)
- 让人类读者快速了解项目背景
- 让许可证合规性一目了然
正文结构:L3 技能的正文按以下固定章节编排(顺序保证一致):
| 章节 | 内容 | 行数占比 |
|---|---|---|
| 概述 | 项目定位、特性矩阵、能力边界 | 5% |
| 环境准备/安装 | 各平台安装命令、版本验证 | 10% |
| 核心 API/命令 | 50+ 命令行的完整参数表 + 代码示例 | 50% |
| 典型工作流 | 6 个端到端操作模式的 Shell 脚本 | 15% |
| AI 使用建议 | 推荐工作流、关键注意事项 | 10% |
| 常见问题(FAQ) | 常见错误与解决方案 | 5% |
| 参考资源 | 官方文档链接、相关技能引用 | 5% |
代码示例标准格式:
# 格式转换(Shapefile → GeoJSON)
ogr2ogr output.geojson input.shp
# 指定输出格式(Shapefile → GeoPackage)
ogr2ogr -f GPKG output.gpkg input.shp
# 重投影(WGS84 → Web Mercator)
ogr2ogr -t_srs EPSG:3857 output.shp input.shp
每个代码块遵循统一的规范:
- 注释行用中文描述操作目标(如”格式转换(Shapefile → GeoJSON)”),让 AI 立即理解示例的意图
- 命令本身使用标准的命令行格式,参数按出现频率排序(常用参数在前)
- 注释和命令之间无空行——保持紧凑,减少 Token 消耗
2.5.2 reference 子目录拆分策略
当 L3 技能文件超过 500 行时,会将详细参数表和高级示例拆分到 reference/ 子目录。以 gis/gdal/ 为例:
gis/gdal/
├── SKILL.md # 主文件(452 行):核心 API + 常用工作流
└── reference/
├── vector-tools.md # 矢量工具完整参数表和高级示例
└── raster-tools.md # 栅格工具完整参数表和高级示例
拆分原则:
- 主文件保留最少 80% 场景所需的最小知识量——核心命令、常用参数、典型工作流
- reference 文件存放 20% 高级场景所需的详尽内容——完整参数表、边界情况、性能调优细节
- 主文件和 reference 之间用相对路径链接:
[reference/vector-tools.md](reference/vector-tools.md)
这种”主文件 + reference”的模式,让 AI 在处理常规问题(如格式转换)时只加载主文件(452 行),处理高级问题(如矢量工具的特定参数组合)时才加载 reference 文件。它本质上是在 L3 内部也做了一层按需加载。
2.5.3 opengis-all:特殊的一站式聚合技能
在 L3 层级中,gis/opengis-all/ 是一个特殊的存在——它不是单个工具的技能,而是聚合了 5 个 L3 技能的端到端工作流文档:
> **涵盖工具与项目:**
>
> | 工具/接口 | 项目地址 | 文档 | 许可证 |
> |-----------|----------|------|--------|
> | GDAL 命令行 | <https://github.com/OSGeo/gdal> | <https://gdal.org/en/latest/programs/> | MIT |
> | GDAL API | ... | ... | MIT |
> | qgis_process | ... | ... | GPL-2.0+ |
> | PyQGIS | ... | ... | GPL-2.0+ |
> | GeoServer REST API | ... | ... | GPL-2.0+ |
它的正文按工作流阶段组织(而非按工具):
阶段一:数据获取与生成 → 阶段二:数据处理与转换 → 阶段三:空间分析 → 阶段四:服务发布
每个阶段同时展示多个工具的等价用法:
# 矢量格式转换的三种方式
## GDAL 命令行(ogr2ogr)
ogr2ogr output.geojson input.shp
## GDAL Python API
gdal.VectorTranslate("output.geojson", "input.shp", format="GeoJSON")
## qgis_process
qgis_process run native:reprojectlayer -- INPUT=input.shp TARGET_CRS=EPSG:4326 OUTPUT=output.geojson
opengis-all 的设计回答了”当用户需要一个完整的 GIS 工作流(从数据到服务),应该加载什么?”这一问题。它处理了跨工具协作场景,它本身是一个 L3 文件,但内部引用了其他 L3 文件作为”详细内容的入口”。
2.5.4 geopipe-agent:跨技能引用示例
gis/geopipe-agent/SKILL.md 展示了 L3 技能如何横向引用其他 L3 技能:
## 相关技能
- **gdal** — 命令行数据处理:[../gdal/SKILL.md](../gdal/SKILL.md)
- **qgis-process** — QGIS 命令行处理工具:[../qgis-process/SKILL.md](../qgis-process/SKILL.md)
- **pyqgis** — QGIS Python 绑定:[../pyqgis/SKILL.md](../pyqgis/SKILL.md)
- **geopandas** — Python 矢量数据处理:[../geopandas/SKILL.md](../geopandas/SKILL.md)
- **postgis** — 空间数据库:[../postgis/SKILL.md](../postgis/SKILL.md)
这些引用形成了跨技能的横向导航。例如,当 AI 加载 geopipe-agent 后发现某个功能(如栅格分析)在当前技能中没有覆盖时,可以通过横向引用加载 gdal 技能获取补充知识。
2.5.5 L3 技能的通用编写规范
所有 67 个 L3 技能遵循统一的编写规范(详见第三章),核心约束为:
- YAML frontmatter —
name、description("Use when..."格式,≤500 字符)、tags(用于搜索) - 头部引用块 — 项目地址、官方文档、许可证
- 正文章节(按固定顺序)——概述 → 安装 → 核心 API → 工作流 → 最佳实践 → FAQ → 参考资源
- 语言 — 中文为主,代码/命令/API 使用原文格式
- 规模控制 — 主文件 300-1500 行;超过 500 行时拆分到
reference/ - 代码示例 — 基于上游官方文档实地核对,避免编造 API
2.6 标签索引系统
标签索引是三层架构中最核心的搜索机制。它独立于文件层级,以横切方式连接所有技能。
2.6.1 标签体系设计
仓库使用双层标签体系:
第一层:语言/平台标签
| 标签 | 覆盖技能数 | 示例技能 |
|---|---|---|
python |
7 | gdal-api, pyqgis, geopandas, shapely, cadquery, freecad, docutranslate |
java |
5 | geotools, jts, geometry-api-java, opengis-utils-for-java, ruoyi-cloud |
dotnet / csharp |
17 | gdal-api, nettopologysuite, geometry-api-net, mapsui, furion, npoi, sqlsugar, … |
javascript / typescript |
4 | cesiumjs, openlayers, chili3d, admin-net-frontend |
cpp / c |
4 | gdal-api, occt, librecad, libredwg |
go |
3 | go, robotgo, robotgo-flow |
第二层:功能领域标签
| 标签 | 语义 | 覆盖技能数 |
|---|---|---|
geometry |
几何运算(布尔、缓冲区、拓扑) | 8 |
raster |
栅格处理 | 3 |
vector |
矢量处理 | 4 |
server / wms / wfs |
地图服务器与 OGC 服务 | 3 |
3d |
三维建模、可视化 | 10 |
2d |
二维制图、渲染 | 5 |
orm / database |
ORM 框架、数据库 | 3 |
agent / llm |
AI Agent、大语言模型 | 8 |
pipeline / workflow |
数据流水线、工作流编排 | 4 |
automation / rpa |
桌面自动化、RPA | 2 |
autocad |
AutoCAD 二次开发 | 4 |
2.6.2 标签搜索的工作原理
标签搜索不是传统意义上的全文搜索引擎——它依赖 AI 工具的语义理解能力,而非简单的字符串匹配。具体流程:
- 标签收集:AI 加载根 SKILL.md 后,获取所有的标签索引表
- 语义映射:AI 分析用户问题中的关键词(如”用 Python 处理栅格数据”),将其映射到
python+raster标签 - 交集运算:在两个标签的候选技能集中取交集
python标签命中:{gdal-api, pyqgis, geopandas, shapely, cadquery, freecad, docutranslate}raster标签命中:{gdal, gdal-api, qgis-process}- 交集:
{gdal-api}
- 结果排序:如果交集有多个技能,按标签匹配度(命中标签越多越靠前)排序
2.6.3 标签搜索优于关键词搜索的原因
| 维度 | 关键词搜索 | 标签搜索 |
|---|---|---|
| 精确度 | “vector” 可能匹配到”矢量”相关的任意文本 | vector 标签只匹配真正处理矢量数据的技能 |
| 覆盖率 | “gdal” 关键词搜不到 “geopandas” | python + raster 标签可以跨工具发现相关技能 |
| 歧义性 | “server” 可能匹配到 Web 服务器而非地图服务器 | server 标签只在 GIS 上下文中用于 GeoServer 等地图服务器 |
| 可组合性 | 难以做多条件组合 | python AND raster 天然支持组合查询 |
2.6.4 标签在 AI 工具中的实际使用
AI 工具使用标签搜索的典型提示(Prompt)模式:
用户问题:"用 Python 做矢量数据格式转换"
AI 内部推理:
1. 关键词提取:python, 矢量, 格式转换
2. 标签映射:python + vector + conversion
3. 在 L1 标签索引中匹配:
- python: {gdal-api, pyqgis, geopandas, shapely, ...}
- vector: {gdal, gdal-api, geopandas, geotools}
- conversion: {gdal}
4. 三标签交集: {gdal-api}(GDAL Python API)
5. 双标签交集: {gdal, gdal-api, geopandas}(后两者是 Python 生态)
6. 最优匹配: gdal-api(三标签命中)→ geopandas(双标签命中,更 Pythonic)
7. 决策:加载 gis/gdal-api/SKILL.md 和 gis/geopandas/SKILL.md
2.7 引用关系与导航
三层架构的引用系统形成了一个可遍历的知识图谱。
2.7.1 三个方向的引用
| 引用方向 | 语法 | 示例 | 触发场景 |
|---|---|---|---|
| 向上引用 | ../SKILL.md |
L2 → L1, L3 → L2 | “这个分类下没有合适的,回上级目录看看” |
| 向下引用 | ./subproject/SKILL.md |
L1 → L2 → L3 | “找到一个匹配的分类/技能,加载详情” |
| 横向引用 | ../other-project/SKILL.md |
L3 → L3 | “需要搭配使用其他工具” |
2.7.2 从 L1 到 L3 的逐级下钻
L1: SKILL.md(根) [67 个技能的全量索引]
├─→ gis/gdal/SKILL.md [GDAL 命令行]
├─→ gis/geopandas/SKILL.md [Python 矢量处理]
├─→ cad/freecad/SKILL.md [参数化 3D CAD]
└─→ ...
│
├─→ L2: gis/SKILL.md [23 个 GIS 技能概要]
│ ├─→ gdal/SKILL.md [GDAL 命令行]
│ │ └─→ reference/vector-tools.md [矢量工具详细参数]
│ └─→ ...
│
└─→ L2: cad/SKILL.md [19 个 CAD 技能概要]
└─→ ...
2.7.3 L3 间的横向引用网络
以 GIS 分类为例,展示 L3 项目技能之间的横向引用关系:
opengis-all ───────────→ gdal ──────────────→ gdal-api
│ 聚合引用 │ 兄弟引用 │
│ │ │
├──→ qgis-process ├──→ gdal-api ├──→ geopandas
├──→ pyqgis ├──→ qgis-process └──→ postgis
├──→ geoserver-rest-api├──→ postgis
└──→ geopipe-agent ├──→ pyqgis
└──→ opengis-all
每个箭头代表一个 [../xxx/SKILL.md] 的 Markdown 链接。这个网络的关键特性:
- opengis-all 是 Hub 节点:聚合了 5 个技能,作为一站式入口
- gdal 是核心节点:被最多技能引用(6 个),因为它是 GIS 数据处理的事实标准
- geopipe-agent 是叶子节点:引用了多个技能,但被引用较少(新兴项目)
2.7.4 引用链的实际利用
AI 工具可以利用引用链实现自动化的上下文扩展:
用户:"用 GDAL 做缓冲区分区分析并发布到 GeoServer"
↓ AI 加载 gis/gdal/SKILL.md
↓ 发现 gdal 的"相关技能"中引用了 geoserver-rest-api
↓ 自动加载 gis/geoserver-rest-api/SKILL.md
↓ 发现还需要 postgis 做数据存储
↓ 自动加载 gis/postgis/SKILL.md
↓ 形成完整方案:GDAL 处理 → PostGIS 存储 → GeoServer REST API 发布
这种”沿引用链自动扩展上下文”的能力,是三层架构相比独立文件集合的本质优势。
2.8 AI 工具中的实际加载流程
本节展示一个端到端的加载决策流程,从用户提问到 AI 生成最终回答的完整过程。
2.8.1 完整流程拆解
用户:"帮我把 Shapefile 转成 GeoJSON"
┌─────────────────────────────────────────────────────────┐
│ 第一步:意图分析与标签映射 │
│ │
│ AI 分析用户问题,提取关键信息: │
│ - 操作:格式转换(Shapefile → GeoJSON) │
│ - 数据格式:Shapefile(矢量) │
│ - 目标格式:GeoJSON │
│ - 隐含标签:#conversion #vector #cli │
│ │
│ AI 决策:问题具体且明确 → 跳��� L2,直钻 L3 │
└────────────────────────┬────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 第二步:L1 扫描与匹配 │
│ │
│ AI 加载 @SKILL.md(根,L1),扫描标签索引: │
│ │
│ 在标签索引中搜索 #conversion #vector: │
│ - conversion 标签匹配:gdal │
│ - vector 标签匹配:gdal, gdal-api, geopandas, geotools │
│ │
│ 交集 + 排序:gdal(2 标签命中,且 conversion 是精确匹配) │
│ │
│ 验证场景推荐表: │
│ "帮我把 Shapefile 转成 GeoJSON" → gis/gdal/SKILL.md │
│ │
│ 双重验证一致 → 确定目标:gis/gdal/SKILL.md │
└────────────────────────┬────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 第三步:L3 知识提取 │
│ │
│ AI 加载 @gis/gdal/SKILL.md(L3),提取相关章节: │
│ │
│ 1. 矢量数据工具 → ogr2ogr 命令 │
│ ogr2ogr output.geojson input.shp │
│ │
│ 2. 常见使用模式 → 批量格式转换脚本 │
│ for shp in *.shp; do │
│ ogr2ogr -f GeoJSON "${shp%.shp}.geojson" "$shp" │
│ done │
│ │
│ 3. 数据格式支持 → Shapefile (.shp), GeoJSON (.geojson) │
│ │
│ 4. AI 使用建议 → 使用 JSON 输出了解数据,再执行转换 │
└────────────────────────┬────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 第四步:回答生成 │
│ │
│ AI 根据 L3 知识生成结构化回答: │
│ │
│ 1. 基本转换命令: │
│ ogr2ogr -f GeoJSON output.json input.shp │
│ │
│ 2. 带额外选项的版本: │
│ ogr2ogr -f GeoJSON output.json input.shp \ │
│ -t_srs EPSG:4326 # 同时重投影到 WGS84 │
│ │
│ 3. 批量转换脚本: │
│ (完整的 for 循环脚本) │
│ │
│ 4. 补充说明: │
│ - 如果需要 Python 方案,可以加载 geopandas 技能 │
│ - 如果需要坐标系转换,使用 -t_srs 参数 │
│ - 安装方法:apt-get install gdal-bin │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 第五步(可选):横向扩展 │
│ │
│ 如果用户追问:"有没有 Python 的方式?" │
│ │
│ AI 回到 L1 标签索引,搜索 #python #vector: │
│ 匹配:gdal-api(GDAL Python 绑定) │
│ geopandas(Python 矢量处理) │
│ │
│ AI 加载 @gis/geopandas/SKILL.md │
│ 获取: │
│ import geopandas as gpd │
│ gdf = gpd.read_file("input.shp") │
│ gdf.to_file("output.geojson", driver="GeoJSON") │
│ │
│ AI 提供 Python 替代方案并对比两种方式 │
└─────────────────────────────────────────────────────────┘
2.8.2 不同场景的加载路径对比
| 用户提问 | 加载路径 | 文件数 | Token 估算 |
|---|---|---|---|
| “Shapefile 转 GeoJSON” | 直钻 L1 → L3 | 2(根 SKILL.md + gdal/SKILL.md) | ~30K |
| “Python 做 GIS 分析用什么?” | 渐进 L1 → L2 → L3(s) | 3+(根 SKILL.md + gis/SKILL.md + 多个 L3) | ~50K |
| “ogr2ogr 怎么指定输出坐标系?” | 直钻 L3 | 1(gdal/SKILL.md) | ~18K |
| “完整 GIS 管道:数据→分析→服务” | L1 → L3(opengis-all) | 2(根 SKILL.md + opengis-all/SKILL.md) | ~50K |
| “CAD 建模和 GIS 数据处理” | L1 → 两个 L2 → 两个方向的 L3 | 4+ | ~80K |
2.8.3 加载决策的优化策略
AI 工具在使用三层架构时可以应用以下优化策略:
- 缓存 L1 索引:根 SKILL.md 的标签索引表不常变化,可以缓存为结构化数据,后续查询无需重新加载整个文件
- 场景表优先:先检查场景推荐表——如果命中,跳过标签搜索,直接加载推荐的技能
- L2 作为备选:只有当 L1 的标签搜索返回 3 个以上候选时,才加载 L2 分类索引用以细化选择
- reference 延迟加载:先加载 L3 主文件(通常 < 500 行);只有当用户追问高级用法时才加载 reference 子文件
2.9 与其他知识组织方式的对比
理解三层索引架构的价值,最好的方式是对比其他常见的知识组织方法。
2.9.1 vs 官方文档(全量塞入)
| 维度 | 官方文档全量加载 | opengis-skills 三层索引 |
|---|---|---|
| Token 消耗 | 极大(官方文档动辄数百页) | 最小(每次只加载 1-3 个技能文件) |
| 信息密度 | 低(大量导航、版本说明、贡献指南等非核心内容) | 高(只保留 API、工作流、FAQ 等可操作知识) |
| 时效性 | 依赖文档版本 | 依赖 SKILL.md 的更新频率(可通过引用官方文档链接补充) |
| AI 友好度 | 低(官方文档为人类设计,结构复杂) | 高(专门为 AI 工具设计,”Use when…” 触发式描述) |
| 维护成本 | 零(直接引用) | 需要持续与上游文档同步 |
官方文档是”原材料”,三层索引是”经过预处理的半成品”。AI 工具真正需要的是半成品——已经提取出关键 API、典型工作流、常见问题的精华内容,而不是 XML 标签、版本迁移指南和贡献者名单。
2.9.2 vs RAG(向量检索)
| 维度 | RAG(向量检索) | 三层索引 + 标签搜索 |
|---|---|---|
| 搜索方式 | 语义相似度匹配(Embedding → 向量搜索) | 结构化标签匹配 + AI 语义理解 |
| 精度 | 依赖 Embedding 模型质量和分块策略 | 依赖标签设计质量和 skill description 的”Use when…“触发式描述 |
| 基础设施 | 需要向量数据库 + Embedding 服务 | 零依赖,纯文件系统 |
| 透明度 | 黑盒(为什么匹配到这个片段?) | 白盒(标签交集 + 层级路径清晰可见) |
| 上下文连贯性 | 返回零散片段,可能不完整 | 返回完整的技能文件,上下文自包含 |
| 部署难度 | 中高(需要搭建检索管线) | 极低(git clone + 加载文件) |
三层索引和 RAG 并非互斥关系。在实际使用中,可以结合两者:RAG 用于初步搜索(找到语义相关的技能),三层索引用于精确定位和深度加载。opengis-skills 当前选择了纯文件系统的标签搜索方案,是因为 GIS/CAD/3D 等领域的工具数量有限(67 个),结构化标签已经足够精准,不需要借助 Embedding 的模糊匹配能力。
2.9.3 vs 提示词模板(Prompt Templates)
| 维度 | 提示词模板 | 三层索引 |
|---|---|---|
| 可组合性 | 低(每个模板是独立的,难以组合) | 高(技能之间通过引用关系组合) |
| 可引用性 | 无(模板之间没有显式引用) | 强(相对路径引用形成知识图谱) |
| 更新维护 | 每个模板独立更新 | 修改一个技能文件,引用它的其他技能自动受益 |
| 组织方式 | 扁平列表 | 层级+标签双维度索引 |
| 适用规模 | 几个到几十个模板 | 几十到几百个技能 |
提示词模板适用于3-5 个高频场景的速查,三层索引适用于50+ 个工具的系统化管理。opengis-skills 的 67 个技能如果以扁平列表的方式组织,AI 工具需要线性扫描整个列表才能定位目标——这正是三层架构要解决的”搜索成本随技能数量线性增长”的问题。
2.9.4 vs 微调模型(Fine-tuned Models)
| 维度 | 微调模型 | 三层索引 |
|---|---|---|
| 知识更新 | 需要重新训练或持续预训练 | 编辑 SKILL.md 文件即可 |
| 知识范围 | 局限于训练数据中的版本 | 始终指向最新版本的官方文档 |
| 成本 | 高昂(GPU 训练 + 模型托管) | 极低(Markdown 文件) |
| 灵活性 | 固定(模型权重不可动态修改) | 灵活(可动态加载、组合、替换技能) |
| 跨模型适用 | 每个模型需要单独微调 | 一份技能文件适用于所有支持 @ 语法或文件加载的 AI 工具 |
微调模型的优势在于零加载延迟——知识已经编码在模型权重中。三层索引的优势在于动态性和可维护性——新增一个库的支持只需要创建一个 SKILL.md 文件,不需要重新训练模型。在开源 GIS/CAD 工具领域(新版本、新库频繁出现),三层索引的动态更新能力远比微调模型的固定知识更具实用价值。
2.9.5 三层索引的核心竞争力总结
| 特性 | 三层索引 | 传统方式 |
|---|---|---|
| 加载粒度 | 按需:1-3 个文件(30-80K Token) | 全量:所有文档(200万+ Token) |
| 搜索方式 | 结构化标签 + 层级导航 | 全文搜索或手动翻阅 |
| 知识更新 | 编辑 Markdown 文件 | 重新索引或替换文档 |
| 技能组合 | 引用链自动扩展上下文 | 需 AI 自行拼接知识 |
| 部署方式 | git clone + @ 语法 |
依赖特定工具或 API |
| 适用模型 | 所有支持文件加载的 AI 工具 | 视具体方案而定 |
三层索引架构的设计哲学可以用一句话概括:用最少的 Token 提供刚好够用的信息,让 AI 工具在正确的层级做出正确的判断。它不是最复杂的技术方案,但它是最适合当前 AI 工具上下文约束的方案——在 Token 窗口有限、按 Token 计费的现实下,信息密度的优化比搜索算法的精度更重要。
2.10 本章小结
三层索引架构是 opengis-skills 仓库的核心设计,它通过 L1(全局入口)→ L2(分类索引)→ L3(项目技能) 的三级分层解决了四个关键问题:
- Token 效率:按需加载 1-3 个技能文件(约 30-80K Token),相比全量加载(约 210 万 Token)节省 98% 以上的上下文窗口
- 粒度匹配:L1 提供 67 个技能的全局概览,L2 提供某个领域的 1-23 个技能概要,L3 提供单个工具的深度知识——每一层刚好匹配一种典型的知识需求
- 智能路由:标签索引系统让 AI 工具通过
语言 + 功能的双维度标签组合快速定位目标技能,场景推荐表让高频问题实现零推理成本的直接命中 - 知识网络:文件之间的相对路径引用构建了一个可遍历的知识图谱,AI 工具可以沿着引用链自动扩展上下文,实现跨技能的协作方案
在下一章中,我们将深入分析 L3 技能的核心组件——SKILL.md 编写规范,包括 YAML frontmatter 的精确字段定义、正文章节的编排原则、代码示例的格式化标准,以及如何将一个开源项目的官方文档转化为 AI 友好的结构化知识。