xIPnexxIPnex

代码索引(三档能力)

一句话讲清楚

代码不是文档。把代码当文档塞向量库里能用,但回答"这个函数被谁调用了?""改这一行影响哪些测试?"这种问题,向量检索完全做不到

平台把"代码进库"拆成 三档索引能力——你愿意付出多少初始化时间,决定了之后能回答多深的问题。

索引侧 ≠ 检索侧。这一页讲的是"代码怎么进库、建什么索引"。 "建好之后怎么搜"是检索工具的事——读 unified_searchcode_search。 关系:索引档位决定了检索工具能用哪些 mode——零索引只能 text/ast grep,轻索引解锁 semantic,重索引解锁 navigate(精确跨文件导航)。


Ragbase 代码索引全栈(L1〜L6)

销售材料里包装的 「零 / 轻 / 重」三档,是产品在下面 L1〜L6 之上做的组合卖法; 研发对齐、写标书或做验收时请以这一张分层表为准——它覆盖 任何 parser,不止 code-aware

索引类型来源触发条件干什么用
L1文本分块 + embeddings任何 parser永远语义检索 / 相似度召回
L2BM25 全文倒排(content_ltks 等)任何 parser永远关键词检索
L3AST 分块tree-sitterparser_id=code-aware 且语言在矩阵里 L3 ✓按函数 / 类 / 方法切 chunk,单 chunk 是完整语义单元
L4R8 关键词字段(function_decls / class_decls / import_decls / unresolved_refs / fqn / outline_path …)tree-sitter AST 派生parser_id=code-aware 且 L3 跑通「这段代码里有什么符号」——可精准 filter / facet
L5audit_findingsast-grep YAML 规则parser_id=code-aware 且 ast-grep 二进制可用静态分析告警(NPE / 硬编码 / 危险 API …)
L6SCIP 语义图(index.scipscip-java / scip-python / tree-sitter emitparser_id=code-aware parser_config.index_tier=heavy 且语言在矩阵里 L6 ✓跨文件 go-to-def / find-references / impact

怎么跟「零 / 轻 / 重」大致对齐

  • 零索引:业务上仍可上传;多数文件 L1/L2/L3 不写库——靠 LLM / grep 兜底。
  • 轻索引:L1+L2 必开code-aware 再叠 L3+L4+L5(不要求 heavy)。
  • 重索引:在轻索引基础上,为满足条件的语言再做 L6 SCIP 全图(最重、最慢、最准)。

三档对比一张图

能力档位你需要做什么多久能用能回答的问题适合谁
零索引直接扔仓库就能搜即时"这个仓库里有处理鉴权的代码吗?""哪些文件提到了某个 API?"临时排查、刚接手的代码、不打算长期维护的小仓库
轻索引等首次同步(仓库大小决定,分钟级)改一个文件后秒级就能搜到"这个函数定义在哪?""谁调用了它?""它的所有 import 是啥?"日常代码评审、新人 onboarding、绝大多数业务仓库
重索引提前接好编译环境(项目结构决定,10 分钟~小时级)全量分析完后才可用"改这一行影响哪些下游?""这个继承层级长什么样?""跨编译单元的所有引用"老旧 C/C++ 项目、安全审核、跨模块大重构

零索引:拿来就搜

不建索引,全靠语法层面的智能匹配 + LLM 自己读相关文件。

适合的提问

  • "这个仓库主要做什么?给我一个概览"
  • "搜一下处理超时的代码片段"
  • "我记得有个文件叫 payment_*.py,帮我找出来"

不适合的

  • "这个函数被谁调用了"——零索引看不到调用关系,只能告诉你字面包含了这个名字的地方
  • 跨语言调用、跨文件继承推理

务实的建议:如果你只是想让 AI 帮你"看一眼这个仓库",零索引就够了。它最大的优点是没有等待


轻索引:日常用的主力

平台用本地工具(基于 tree-sitter 一类的语法分析)建轻量索引,对每种语言抽出函数、类、变量、import 的位置,存进搜索引擎。

Rendering diagram…

关键升级(M4 / R8 之后)

  • 改一个文件,新内容秒级可搜——以前要等几分钟,现在不用了
  • 老的"批量等待 / 批量重建"机制取消了,写完代码立刻就能问

适合的提问

  • "processOrder 这个函数定义在哪、谁调用了它"
  • "这个类继承自哪?子类有哪些"
  • "整个项目里有几个地方在用 redis.Pipeline"

不适合的

  • 需要类型推导才能解的问题(比如 C++ 模板实例化、Python 鸭子类型的真实运行时类型)
  • 跨编译单元、跨链接边界的引用

重索引:审计 / 重构 / 老 C/C++ 项目

把项目真的"半编译"一遍,建立类型完整的代码图谱。这一档最贵也最准。

适合的场景

  • 老 C/C++ 项目:宏、模板、include 关系复杂,没有类型信息根本审不动
  • 安全审计:跟踪用户输入流到敏感函数的完整路径(污点分析)
  • 跨模块重构:改一个核心接口,必须先看清所有下游
  • 代码合规审核:MISRA / ASPICE 等标准要求"完整调用链可追溯"

前置条件

  • 你的项目能在我们的环境里编过去(CMake / Bazel / Maven 等其中一种)
  • 接受一次性 10 分钟到小时级的初始化时间

例子:在汽车 ECU 代码上,能回答"我改了 can_send_frame 这个函数,最终影响哪几条 CAN 总线、对应哪几个 ASIL 等级的需求条目"——这种问题轻索引和零索引都给不了答案。


怎么选?决策三问

  1. 你需要"调用关系"吗?

    • 不需要 → 零索引
    • 需要 → 至少轻索引
  2. 你的代码会持续改、需要 AI 跟得上吗?

    • 是 → 轻索引(增量秒级)
    • 否,就一次性看 → 零索引
  3. 你的项目是 C/C++ 老代码,或要做安全 / 合规审核吗?

    • 是 → 重索引
    • 否 → 轻索引一般够用

一个知识库放几个仓库?单 repo vs 多 repo

平台默认支持 multi-repo——一个知识库(KB)可以同时装多个代码仓库,靠顶层文件夹区分:

my-code-kb/
├── repo-vehicle-bsw/         ← 仓库 A,整库一个顶层目录
│   ├── src/...
│   └── ...
├── repo-mes-platform/        ← 仓库 B
│   ├── apps/
│   └── ...
└── repo-shared-libs/         ← 仓库 C
    └── ...

平台按顶层目录名自动认作 repo_kwd,每个 repo 各自维护:

  • 自己的符号索引(symbol_index_<repo>
  • 自己的 repo 大纲(repo_map_<repo>
  • 自己的 audit / 引用关系

多 repo 模式给你什么

能力说明
单 repo 真增量改 / 加 / 删 repo-A 的某个文件,只动那一个文件的索引,repo-B / repo-C 完全不动
跨 repo 引用反查repo-B 里 import com.foo.UserService、repo-A 提供这个类——一次检索就能跨 repo 命中
per-repo 重建单独重建某个 repo 的重索引(SCIP),不影响其他 repo 的服务可用性
同名歧义自动消解两个 repo 里都有 UserService?检索结果会按 repo_kwd 标注归属,不会混

单 repo 怎么用?

完全等价——KB 里就放一个顶层目录:

my-code-kb/
└── my-only-repo/
    └── ...

或者直接把代码摊在 KB 根目录(平台会用一个默认 repo_kwd)。单 repo 是 multi-repo 的退化,不需要额外配置。

文件夹组织建议

场景推荐组织
单一代码仓kb/<repo-name>/... 或直接 kb/...
多个微服务 / 多个组件库每个 repo 一个顶层目录
Monorepo(一个 git 仓但多个子项目)把 monorepo 当一个 repo(一个顶层目录),子项目靠 outline_path 自动区分
同一项目多个分支 / 版本对比每个分支一个顶层目录(repo-A-main / repo-A-release-2026Q2

不要把多个 repo 拍平到 KB 根目录混一起——那样平台没法做 per-repo 隔离,跨 repo 引用反查也会失准。


支持的代码类型

本节第二张表就是你要找的 「语言 ×(L3–L6)矩阵」
底座 L1〜L6 对每个 parser(含文档)都一样;本节只展开 code-aware + 内置语言包

以下专指 parser_id = code-aware——普通 PDF / Markdown 走别的 parser(只有 L1/L2 或字符级兜底,见矩阵末行)。

控制台上在哪儿改解析方法 / 索引档位?

不走 API 时:Combospace知识库 → 点进任一知识库 → 左侧 配置 Tab。

字段对应关系一览(界面文案随语言略有差异,中文版如下):

Rendering diagram…

知识库 · 配置 Tab:切片方法 code-aware 与代码索引档位(演示 KB:robot-代码)

插图说明:控制台 UI 会因版本迭代微调;上图由仓库内脚本自动截取。更新命令:Hikari/scripts/capture-kb-configuration-screenshot.py(直达 /combospace/combospace/knowledge/dataset/configuration;冷启动慢时可加大 DOC_CAPTURE_NAV_TIMEOUT_MSDOC_CAPTURE_SELECTOR_TIMEOUT_MSDOC_CAPTURE_SETTLE_MS)。若本地路径前缀不同,设 KB_CAPTURE_PATH_PREFIX

下面是 每个语言分别在 L3 / L4 / L5 / L6 开到哪一档——与上文 L1〜L6 表逐项对应。

平台对每种语言能开到的能力分四层(表中列名缩写),先看图例再看矩阵:

干什么哪一档用到
L3 AST 分块按 tree-sitter 语法树切片,得到带 outline_path 的 chunk轻索引、重索引
L4 R8 字段抽出 function_decls / class_decls / import_decls / references / unresolved_refs / fqn / outline_path轻索引(定义 / 调用 / facet)
L5 audit (ast-grep)静态扫描规则命中(unified_search code_search mode=audit轻索引 + 重索引
L6 SCIP编译器级 indexer,得到跨编译单元的精确类型图重索引

语言 × 索引层 矩阵

语言后缀L3 AST 分块L4 R8 字段L5 audit (ast-grep)L6 SCIP
Python.py .pyiscip-python,无需 build 文件
Java.javascip-java,必须 pom.xml / build.gradle*
Kotlin.kt .kts✓ 两条路:① 有 build → scip-java;② loose → tree-sitter emit(无需 build)
Scala.scala✗(无 tree-sitter 配置)scip-java,必须 build 文件
Go.go✗ 未集成 indexer
TypeScript / TSX.ts .tsx✗ 未集成
JavaScript / JSX.js .jsx .mjs .cjs✗ 未集成
C / C++.c .cpp .cc .cxx .h .hpp⚠ aarch64-linux 无 scip-clang 二进制 → cpp_stub fail-soft
Rust.rs✗ 未集成
Ruby / PHP / Swift / Dart / Lua / C# / Elixir✓(ast-grep 支持)
其他文本.md / .txt / Dockerfile / Makefile …)字符级回退

读这张表的三条规则:

  1. L3 ✓ 的 9 种语言(Python / Java / Kotlin / Go / TS / JS / C·C++ / Rust)——上传后自动走轻索引档(带符号字段),开箱可用。
  2. L5 audit ✓ 的语言比 L3 多——Scala / Ruby / PHP / Swift / Dart / Lua / C# / Elixir 即使没有 L3 切片,也能用 unified_search code_search mode=audit 跑 ast-grep 静态规则。
  3. L6 SCIP(重索引)只对 Python / Java / Kotlin / Scala / C·C++ 开通——其它 L3 语言(Go / TS / JS / Rust)走 L4 R8 字段反查也能拿到 ~90% 的实用能力,需要补 indexer 联系 info@nox-lumen.com 评估。

C/C++ 当前限制:生产宿主机为 aarch64-linux,没有上游 scip-clang 预编译二进制,L6 走 cpp_stub fail-soft(仍能基于 L3/L4 给出符号视图,但跨编译单元导航降级)。x86_64 部署不受影响。

不在列表里的语言怎么办

需要其他语言(PHP / Ruby / Swift / Scala / C# / Dart / Lua / Solidity / DSL ...)走轻索引档?自己用 parser-sdk 加一个—— 不需要等平台升级,半天到一天就能补上:

  1. 确认 tree-sitter-language-pack 已包含目标语言的 grammar(覆盖 ~80 种)
  2. fork 内置 code-aware-parser,在 language_configs/ 里加一个 LanguageConfig
    _RUBY = LanguageConfig(
        language="ruby",
        file_extensions=(".rb",),
        atomic_nodes=frozenset({"method", "class", "module"}),
        scope_nodes=frozenset({"class", "module", "method"}),
        import_nodes=frozenset({"call"}),  # require 等通过 call 节点
    )
  3. queries/ruby/ 放对应 tree-sitter query
  4. ragbase-cli skill push 上线

详细步骤见 parser-sdk · 自定义代码切片器,里头有完整可下载的参考实现。

落地后会自动接入零/轻/重三档检索,跟内置语言完全等价(L3 / L4 都有;L5 audit 自动可用;L6 SCIP 是否覆盖见上文矩阵)。


跨行业举例

汽车研发(auto)

  • 轻索引:日常的 ECU 业务代码评审、新人 onboarding
  • 重索引:ASPICE 合规审核 / SOTIF 安全分析 / 跨 ECU 接口重构

智能制造(mfg)

  • 轻索引:MES / SCADA 业务代码评审
  • 零索引:临时接入一个第三方 PLC 厂商的示例代码仓库,看一眼就行,没必要专门建索引

索引档位 vs 检索 mode 对照表

平台对外的两个检索工具(unified_searchcode_search)能做什么,取决于这个 KB 建的是哪一档索引

检索工具 + mode零索引轻索引重索引
code_search(scope="kb", mode="text") rg grep
code_search(scope="kb", mode="ast") 结构匹配
unified_search.code_search(mode="text")✅(trigram 加速)
unified_search.code_search(mode="ast")
unified_search.code_search(mode="semantic") 自然语言
unified_search.code_search(mode="navigate") 精确跨文件⚠️ ES 字段反查(够用)✅(SCIP 精确)
unified_search.code_search(mode="hybrid") text+semantic 融合

怎么读这张表

  • 你要用某个 mode,先看你 KB 在哪一档;档位不够就升档(KB 设置里改一个开关)
  • 升档可以事后做,原数据保留——加一档索引不会丢东西
  • 想拿 mode="navigate"编译器级精确语义图:必须重索引,且语言在下方矩阵里 L6 ✓(见上文 语言矩阵

这一档跟"代码评审 SKILL"的关系

代码索引是底层能力代码评审 SKILL上层应用——它会自动按 KB 已开档位选用合适的检索 mode,给你出审核结论。

  • 提交评审(PR/MR/CR 三个场景):轻索引就够
  • 全分支审 / 全仓审:跑重索引,结果会更深
  • 临时看一个无主仓库:零索引,立等可取

相关概念

On this page