okf-rs:将代码库转成知识库

构建一个快速、开源的Rust工具包,用于从源代码生成、验证和提供Open Knowledge Format(OKF)知识库

okf-rs:将代码库转成知识库
AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo

如果你使用过AI编码代理——Claude Code、GitHub Copilot或任何其他支持MCP的工具——你可能看过它跳这样的舞蹈:它需要知道谁调用了某个函数,于是它grep代码库,打开一堆匹配的文件,阅读数百行代码来确认哪些命中实际上是调用点。它打开的每个文件都以其完整大小的上下文令牌为代价。在一个会话中这样做几十次,你就在本质上是一个查找操作上燃烧了大量的上下文。

这是我着手用okf-rs解决的问题,这是一个新的开源Rust CLI。

1、okf-rs实际做什么

核心上,okf-rs将代码库转换为可移植的Open Knowledge Format(OKF)知识库:带有YAML前置元数据的普通Markdown文件,交叉链接成真正的调用图,人类和AI代理都可以读取。

运行generate针对一个仓库,你会得到一个knowledge/目录,里面充满普通的.md文件——每个模块、结构体、枚举、函数或方法一个文件,每个文件都有一个小的YAML头部和描述签名和关系的主体。生成的概念看起来像这样:

就是这样。不需要专有数据库,不需要向量存储,不需要SDK来读回它。它支持git差异、grep,并且在GitHub上原生渲染。

2、为什么不是另一个图数据库或上下文块?

大多数代码库分析工具属于两个阵营之一:它们构建一个需要其运行时来查询的专有图数据库,或者它们生成一个除了消费它的模型之外对其他所有东西都不透明的AI特定上下文块。两者都无法用你已经拥有的工具检查。

okf-rs采取了不同的方法,基于几个明确的原则:

  • 开放——输出就是制品。读取或写入它不需要运行时或SDK。
  • 快速——使用tree-sitter进行解析的原生Rust核心,而不是启动完整的编译器前端。
  • 确定性——相同的源代码总是产生字节相同的输出。没有时间戳,没有无序映射噪声泄漏到结果中。
  • AI就绪但不需要AI——知识库结构良好,LLM可以直接消费它,但生产它时不涉及LLM。

3、底层原理

okf-rs是一个小型、单一用途crate的Cargo工作空间,okf-cli作为薄包装器,以便底层逻辑可以被其他Rust工具嵌入。以下是我最满意的几个部分:

  • 多语言语义提取。提取器理解十一种语言的包、模块、类型、函数和方法——Rust、Python、TypeScript、JavaScript、Go、Java、C#、PHP、Kotlin、C/C++和Swift——包括针对每种语言实际可见性规则调整的公共/私有API表面检测(Rust和Java的显式选择加入,PHP和Kotlin的默认选择退出,C++的基于部分,Go的基于大小写)。
  • 解析的调用图,涵盖裸调用、方法/self/this调用、静态和作用域调用以及限定模块调用,在所有支持的语言中保持一致。
  • 可选的LSP支持的消歧。仅tree-sitter通过名称解析无歧义的调用。当一个名称在项目范围内有歧义时,okf-rs generate --lsp可以询问项目的实际语言服务器(rust-analyzerpyright)通过textDocument/definition解析它——针对真实服务器进行端到端验证,具有超时处理和正确处理包含空格或非ASCII字符的路径。
  • 增量索引和监视模式。generate通过内容哈希缓存每个文件的提取,因此重新运行时只重新解析更改的内容。okf-rs watch在编辑时保持包最新,对文件更改突发进行防抖。
  • 为CI构建的验证。模式检查、悬空链接检测、孤儿检测和重复标识检查,带有一个--ci标志,一旦其他工具开始依赖包的正确性,就将孤儿概念视为硬失败。

4、对代理真正重要的部分:MCP服务器

知识库在磁盘上很有用,但真正的回报来自okf-mcp,一个模型上下文协议服务器,它将包的搜索和图查询——searchgraph_callersgraph_calleesgraph_apigraph_cyclesgraph_modulesgraph_path——直接暴露给任何支持MCP的编码代理。

注册到Claude Code只需一行:

claude mcp add okf-rs -- /path/to/okf-mcp /path/to/project

这就是真正的要点:因为okf-mcp通过stdio使用纯MCP协议,所以它不绑定到单一供应商或代理。相同的二进制文件适用于Claude Codeopencode或任何其他MCP客户端——你只需将该客户端的stdio传输指向okf-mcp二进制文件和项目根目录。无需代理集成,无需专有插件格式,无需为每个工具重新实现图查询。使用okf-rs generate构建一次包,工具链中的每个MCP兼容代理——无论你现在使用什么,明天切换到什么——都能获得相同的快速、结构化的访问。

5、Token节省来自哪里

一旦注册,像"谁调用了verify_token?"这样的问题就不再意味着grep、打开文件和阅读足够的周围代码来确认真正的调用点。它意味着一次graph_callers调用直接返回答案——根本没有源文件进入代理的上下文。

举个例子:在okf-rs代码库本身上,回答"谁调用了cmd_generate?"手动意味着打开一个672行、约24KB的文件并阅读足够的内容来找到调用者——根据通常的经验法则,大约6000个令牌。等效的graph_callers调用返回一行,大约15个令牌——减少了约400倍

这个差距不是一次性的,在真实的代理会话中以两种方式复合:

  • 每次查询。每个调用图或API表面问题——"谁调用了这个?"、"这个模块暴露了什么?"、"这里有循环吗?"——都支付相同的6000对15个令牌比率,因为昂贵的部分(解析和解析调用图)已经在okf-rs generate时发生了一次,而不是在每次查询时重新支付。
  • 每次会话。没有结构化索引时,代理在其上下文窗口填满并被压缩时会重复打开相同的大文件——每次重新打开都再次支付文件的完整大小。使用okf-mcp,代理每次询问有针对性的问题并获得有针对性的答案,因此上下文使用保持大致平坦,而不是随着会话长度增长。

实际上,这意味着在大型代码库上更长的代理会话才能达到上下文限制,更低的每任务令牌成本(因此如果按使用量付费则更低的API成本),并且——因为代理不是在浏览无关代码来回答结构问题——更少的错误假设潜入其推理。而且因为它只是MCP,这个好处不会锁定到一个编码助手;它随你穿越你运行的任何代理。

6、快速开始

预构建的二进制文件可从GitHub Releases页面获取,或者直接通过Cargo安装:

cargo install --git https://github.com/jyjeanne/okf-rs okf-cli

然后,从现有项目:

cd /path/to/your-existing-project
okf-rs init .
okf-rs generate
okf-rs validate

init写入一个okf.toml记录包的默认位置,并幂等地更新CLAUDE.mdAGENTS.md.github/copilot-instructions.md,用标记的部分指向代理到包——这些文件中的现有内容保持不变。从那里,okf-rs watch在你工作时保持内容最新,将okf-rs generate --no-cache && okf-rs validate --ci连接到CI确保过时的包永远不会默默发布。

7、新功能:从调用图工具到知识平台

自第一个版本以来,okf-rs已经发布了整个额外的工作阶段——第二阶段(深度语言覆盖、LSP消歧、增量索引、MCP服务器)和第三阶段(搜索、互操作性和智能)都已完成,以及与相邻代码库知识图工具的完整竞争差距关闭。核心理念——确定性的、支持git差异的Markdown包——没有改变。改变的是包存在后你可以用它什么。

  • 排名和语义搜索。除了原始的精确/子字符串搜索,okf-rs search --ranked现在通过Tantivy对标题、描述、签名和标签进行相关性评分的全文搜索,具有camelCase/snake_case边界匹配,因此查询verifyToken仍然能找到verify_token。更进一步,okf-rs search --semantic在任何OpenAI兼容的/embeddings端点上分层余弦排名嵌入搜索。
  • 可选的AI丰富——真正可选。okf-rs generate --enrich通过调用任何OpenAI兼容的chat/completions端点(Ollama、LM Studio、LocalAI或云提供商,绝不硬依赖一个供应商)为函数、方法、模块和包填充缺失的描述。它从不重新查询或覆盖已存在的描述,无论是人类编写的还是之前生成的。在此之上,okf-rs suggest-links使用相同的丰富层来提议语义接近的概念之间合理的缺失关系——仅建议,没有东西被默默写入包。
  • 确定性架构提取——不需要AI。一个新的okf-archcrate直接从调用图得出真实的结构洞察:okf-rs graph layers计算每个包在依赖图中的深度,graph domains找到哪些包实际协作,graph communities更进一步进行基于模块化的聚类(Clauset–Newman–Moore),这——通过在项目自己的18个crate工作空间上进行dogfooding验证——实际上将普通连接组件折叠成一个块的代码库进行了分割。graph patterns标记Builder、Singleton、Factory和Visitor的结构信号;graph features通过命名约定标记REST端点、数据库模型和事件流参与者。
  • 变更影响分析和PR审查自动化。okf-rs impact <ref-a> <ref-b>通过传递调用者计数("爆炸半径")、公共API成员资格和循环参与度对两个git引用之间添加、删除或更改的每个概念进行评分。okf-rs review <ref-a> <ref-b>将其渲染为可粘贴注释的Markdown报告,带有一个用于CI门控的--fail-on-risk标志——并附带一个开箱即用的GitHub Action(pr-review.yml)将其直接连接到拉取请求审查。
  • 更多导出格式。除了原始的HTML和Markdown,okf-rs docs现在还生成分页PDF(每个概念一个书签)、GraphML(用于Gephi、yEd或任何图形可视化工具)和Obsidian vaults([[wikilinked]]笔记)。一个新的okf-ditacrate添加了真正的双向DITA桥接:将包导出到DITA主题,以及将现有DITA语料库作为一流Document概念导入回来,参与与提取代码相同的搜索索引和图——通过将项目自己的715个概念DITA导出通过generate --dita进行往返验证,零数据丢失。
  • 复合explore查询。无需链接多个search/graph_*调用,okf-rs explore <concept>(和匹配的explore MCP工具)在单次调用中返回概念的签名、描述、调用者、被调用者、爆炸半径、公共API成员资格和循环成员资格——更进一步保持代理的令牌预算用于推理而不是工具调用开销。
  • 更健壮的验证。验证器现在检查关系目标(不仅仅是markdown链接),检测具有零个调用图边的孤立概念,标记冗余链接,并捕获整个包中Calls/CalledBy的不对称——加上okf-rs coverageokf-rs graph stats用于一目了然的包健康指标。

所有这些都以原始发布相同的方式到达用户:在okf-rs自己的、现在大约850个概念的代码库上进行dogfooding,每个功能都经过端到端验证而不是假设——包括一个dogfooding捕获真实bug的案例(DITA导出器和导入器之间的DTD处理不匹配),而手写的测试用例永远无法发现。

9、下一步

路线图的第1阶段到第3阶段,加上完整的竞争差距关闭,已经完成。第4阶段——生态系统——是下一个:okf-server(知识图之上的REST + GraphQL API,用于多仓库、组织范围的服务)、作为LSP服务器的okf-rs(悬停、转到定义和查找引用,可从任何支持LSP的编辑器访问)、交互式图形可视化器,以及组织规模的持续索引。该项目采用MIT/Apache-2.0双重许可,欢迎问题和拉取请求。

如果你正在构建或维护AI编码代理,并且发现上下文预算是真正的瓶颈而不是模型能力,我真的很想听听这种方法是否有帮助——或者它在哪里在你的代码库上崩溃。


原文链接: okf-rs: A New Rust Tool for Turning Codebases into AI-Readable Knowledge Bases

汇智网翻译整理,转载请标明出处