mcpField
O
open-context-engine

open-context-engine

本地服务
github.com/Dhaxor开发工具01 天前更新

关于 open-context-engine

open-context-engine 是面向开发者和编码 Agent 的本地优先代码检索引擎。它结合 AST 感知索引与语义、关键词混合搜索,并通过 MCP 提供代码检索,无需将代码发送到云端。

主要功能

  1. 01基于 AST 的代码分块
  2. 02向量与 BM25 混合搜索
  3. 03本地 SQLite 向量索引
  4. 04符号与代码图扩展
  5. 05可选结果重排序
  6. 06监视变更并更新索引

适用场景

  1. 01为编码 Agent 的回答提供代码依据
  2. 02用自然语言查询代码
  3. 03向 MCP 客户端提供实时代码上下文

MCP 相关

通过 stdio 或 Streamable HTTP 提供检索、文件和符号工具。服务启动时会索引工作区,也可监视变更以保持索引更新。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"dhaxor-open-context-engine": {
"command": "npx",
"args": [
"-y",
"@dhaxor/open-context"
]
}
}
}
启动命令npx -y @dhaxor/open-context

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@dhaxor/open-context0.7.1

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Open Context Engine

TypeScript SQLite MCP 许可证

本地。语义化。即时。
将任何代码库变成可供 AI 搜索的知识库。


Open Context Engine(OCE)是一款本地优先、高性能的检索引擎,可为整个代码库建立索引,将其嵌入为向量,并通过语义搜索、关键词搜索和模型上下文协议(MCP)将其提供给大模型。无需云服务。代码不会离开你的设备。

无论你是在构建编码助手、自动化 PR 审查,还是只想用自然语言询问自己的代码,OCE 都能为你的 AI 提供真实依据。

📘 文档、基准测试与指南: opencontextengine.com — Claude Code 和 Cursor 的 MCP 配置、Agent 工作流指南,以及经过测量的检索基准测试。

✨ 特别之处

特性说明
🧠 AST 感知分块使用 Tree-sitter 按语义边界(函数、类、方法)拆分代码,而非采用简单的行数切分。支持 TypeScript、JavaScript、Python、Go、Rust、Java、C#、C、C++、Ruby、PHP、Kotlin 和 Swift。
🔍 混合搜索通过倒数排名融合,将稠密向量相似度(余弦)与 BM25 关键词搜索相结合,让结果兼具语义相关性和词面精确度。
⚡ 本地 SQLite + 向量使用 sqlite-vec 将所有内容存储在本地 SQLite 数据库中——无需外部向量数据库、没有网络延迟,也无需订阅费用。
🏠 完全本地的嵌入默认采用进程内 ONNX 嵌入——无需 API 密钥、无需服务,模型缓存在磁盘上。也支持 Ollama;若要获得最佳代码检索效果,可直接升级为 Voyage。
🔗 符号扩展自动解析搜索结果中的标识符,补充片段所引用的函数、类和类型的定义。
🎯 可选重排序接入 Voyage 或 Cohere 重排序器,提升复杂查询的结果质量。
🕸️ 代码图谱通过 tree-sitter AST 遍历提取导入、调用和定义关系,构建可查询的图谱;搜索结果排名靠前的内容会进行图谱扩展,将调用者和被调用者一并纳入。
🔭 Trace在浏览器、终端或桌面中使用的 Agent 工作区:通过证据栏查看模型上下文中的内容(可排名、固定和移除),支持检查点回退、带影响范围评分的审批、可监视的子 Agent,以及在隔离的 git 工作树中并行运行会话,供你审查并合并。
🤖 Agent 工具框架完整的工具调用 Agent,支持代码库检索、文件编辑、Shell 执行和网页搜索——还支持并行只读工具执行、工具调用前后钩子、Token 使用量统计、会话导出/导入、模型路由和跨会话记忆。
🔌 原生支持 MCP通过标准输入/输出或 Streamable HTTP(共享端点,使用 bearer 身份验证),通过 Model Context Protocol 提供检索、文件和符号工具。适用于 Claude Desktop、Cursor 和任何兼容 MCP 的客户端。
🧰 VS Code 扩展基于索引内容的侧边栏聊天,支持逐文件差异查看、撤销和重做的 Agent 编辑、保存时实时重新索引,以及索引健康状态面板。按平台分发;一个 Node-API SQLite 绑定即可在所有 VS Code 1.103 及更高版本中运行。
🛡️ 策略控制可按工作区或组织固定引擎允许执行的操作:禁用 Shell、编辑或网页搜索,固定命令允许列表,强制使用纯本地嵌入,以及排除路径。由组织签名的策略锁不能在本地放宽。
🧾 防篡改审计日志将每次 Agent 运行、工具调用和 MCP 调用记录为哈希链式 JSONL。oce audit --verify 可检测任何篡改、删除或重排。
👥 团队索引同步在 CI 中构建一次索引,将其发布为构建产物(S3/HTTP/共享驱动器),团队成员再通过 oce pull-index 拉取——仅对本地差异重新生成嵌入。基于内容哈希的嵌入缓存确保相同代码不会重复计费。
🚀 并行索引大型仓库会自动启用工作线程解析/分块池;oce bench 可测量你自己的吞吐量。
🛟 降级运行,不会崩溃如果你的平台没有 sqlite-vec 构建版本,引擎会改为仅使用关键词(BM25),而不是崩溃——索引和搜索仍可正常工作,且每个界面都会显示当前模式。
📏 以测量为准,而非凭猜测根据已提交的黄金测试集评估检索质量——包括本仓库自身的测试集和一个外部代码库——涵盖两种搜索模式,并采用自适应融合,按查询特征调整 BM25/语义权重:此处的混合模式 recall@10 为 0.943 · 纯关键词模式为 0.886;在混合模式此前表现较差的 Flask 上则达到持平(0.926)。排名变更会附带前后对比数据。编码 Agent 本身也会接受评估:oce eval-agent 会运行端到端任务,并由验证脚本评分。

🚀 快速开始

1. 安装
npm install -g @dhaxor/open-context     # Node 22+
2. 选择模型——也包含免费选项
oce setup

oce setup 会检查你已有的资源(正在运行的 Ollama、环境中的密钥),并列出所有可用的模型获取方式,免费选项优先:

-p费用
ollama免费,本地运行在你的机器上运行。无需密钥、无配额限制,还能离线使用。
google免费层级Gemini——免费层级最慷慨;可在 aistudio.google.com/apikey 获取密钥
groq免费层级速度非常快;可在 console.groq.com/keys 获取密钥
cerebras免费层级可在 cloud.cerebras.ai 获取密钥
openrouter免费模型以 :free 结尾的模型无需付费;可在 openrouter.ai/keys 获取密钥
openai、anthropic付费

oce setup -p google 会记录你的选择;之后运行 oce trace 即可使用。

开箱即用的混合搜索——无需密钥或账户。 首次建立索引时,会使用本地 MiniLM 生成嵌入(进程内、设备上完成,不会向任何地方发送数据),因此语义搜索和关键词搜索都能立即使用。想要最强的代码检索能力?添加 Voyage 密钥即可升级嵌入模型——oce setup --embeddings voyage——然后系统会用该模型重建索引。如果你不需要升级,本地方案也完全够用。

3. 打开 Trace
oce trace      # the workspace, in your browser
oce            # the same thing, in your terminal

两者都会在启动时为当前目录建立索引,并保持同一段对话持续进行——请参阅下文的 Trace,了解它的不同之处。

4. 或者从命令行搜索
oce index                                        # full index (incremental afterwards: --incremental)
oce search "how does the auth middleware work?"

🔭 Trace

Trace 是 Agent 工作区。每个编码 Agent 都会展示它做了什么;Trace 还会展示它知道什么——因为检索由 OCE 负责,而不只是聊天循环。

  • 证据栏。 展示当前模型上下文窗口中的内容:每个检索到的文本块及其融合评分、将其引入的图边(“由 search.ts 调用”),以及按检索 / 文件 / 历史 / 系统划分的预算表。固定一个文本块,它就会在上下文压缩后保留;移除一个文本块,它就会从下一个请求中彻底删除。
  • 检索结果概览,而不是加载动画——retrieved 5 · top 0.94 · graph +2 · 251ms。
  • 主线。 按轮次记录检查点时间线,使用与审计日志相同的哈希链。点击某个检查点即可回退:对话以及 Agent 更改的文件都会还原,而你之后手动编辑过的文件则不会受影响。
  • 带影响范围提示的审批。 每次编辑和 Shell 命令都必须先通过 y / always / n 确认,并显示差异、风险评分,以及该文件有多少个已索引的调用方。
  • 可供观察的子 Agent。 委派的研究内容会流式显示在独立的可折叠区域中,不会悄无声息地持续几分钟。
  • 并行会话。 在 Git 仓库中,每个新会话都会获得独立的工作树和分支,因此各 Agent 不会编辑同一份检出内容。查看会话的差异,并在完成后合并(提交 + --no-ff 合并)——关闭会话时,未提交的工作绝不会被丢弃。
  • 输入区。 @path 可将文件固定到上下文中(根据索引进行模糊匹配),!command 可通过相同的审批流程运行 Shell 命令,/command 则用于其他所有操作——浏览器和终端中的用法相同。

oce trace 仅绑定到 127.0.0.1,并在每次启动时生成新的访问令牌。实用选项:--port、--no-open、--headless(仅 API)、--no-parallel。

在终端中

直接运行 oce,即可在终端全屏打开同一工作区:相同的证据栏(终端宽度至少为 100 列时显示,或按 Ctrl+R 打开)、相同的检查点侧栏、相同的审批流程。按 Esc 或 Ctrl+C 可中断运行;连续按两次 Ctrl+C 或输入 /exit 可退出。管道、--print 和不支持交互的终端会回退到经典的逐行 REPL;也可以运行 oce --classic 主动使用该模式。

作为桌面应用

desktop/ 在 Electron 外壳中封装了 Trace,添加了桌面通知 (仅在等待审批、后台回合结束或发生故障时)、应用程序菜单和 trace:// 深层链接。目前需要从源代码检出版本构建——参见 desktop/README.md。

经典 REPL

oce --classic 会流式输出带样式的内容,用实时旋转指示器和计时显示每次工具调用;并且在进行任何文件编辑或执行 shell 命令之前,都会显示 差异/命令预览并请求审批(y / always / n)。按 Ctrl+C 可中断当前运行,而不会退出会话。

审批模式(与其他领先的编码 CLI 相同):

  • 默认(suggest)——每次编辑和 shell 命令都先请求审批
  • --auto-edit——自动应用文件编辑;shell 操作仍需请求审批
  • --full-auto——不请求审批(适用于容器 / CI)

通过 /mode 可在会话中途切换模式。交互式会话可在审批机制下使用编辑和 shell 工具;非交互式 --print 路径则通过 --allow-edits / --allow-shell 明确启用这些工具。

斜杠命令: /help /reset /compact /plan /diff /usage /tools /mode /sessions /resume /exit。

会话会自动持久化到 .open-context/sessions/。oce --continue 会在工作区中恢复最近一次对话;oce --resume <id> 会恢复指定会话(使用 /sessions 查看列表)。

Harness 功能:

  • 计划跟踪——Agent 会为多步骤工作维护实时步骤清单,并在你查看时呈现。
  • 子 Agent 委派——范围较大的探索会交由限定为只读操作的子 Agent 执行,因此大量中间输出不会涌入主上下文。
  • 摘要式压缩——历史记录变长时,由模型将较早的回合压缩为上下文备注,而非直接丢弃,因此决策和文件路径都能保留下来;使用 /compact 可强制压缩。
  • 环境感知——平台、Git 分支/状态、日期和索引统计信息会注入系统提示词。
  • 成本与并行处理——每个回合结束时都会输出统计信息(步骤数、工具调用次数、令牌用量、耗时);回合中的只读工具调用会并行运行,而包含编辑或 shell 调用的回合则严格按顺序执行。
  • --route 会将每个查询发送到成本合适的模型层级;--memory 会跨会话记住代码库相关信息;--audit 会将运行记录到防篡改审计日志中。

供脚本和 CI 使用的非交互式模式:

oce --print "where is the auth middleware defined?"           # one answer, then exit
oce --print "list the exported symbols in src/core" --json     # {answer, stats, toolCalls}

编程 API 提供了对应的全部功能:除非传入 includeEdits/shell/plan/delegate,否则 defaultAgentTools({ context }) 保持只读;ContextAgent 则接受 hooks(可在此处组合 PermissionManager)、compaction 和 environmentProvider。

5. 通过 MCP 连接到 Claude / Cursor
oce mcp --workspace ./my-project

# Or serve a shared HTTP endpoint (e.g. one index for the whole team):
oce mcp --workspace ./my-project --http --port 8940 --auth-token "$TOKEN"

MCP 服务会在启动时为工作区建立索引,之后持续监视更改,因此无需手动重新建立索引即可保持索引实时更新。传入 --no-watch 可禁用监视器。(MCP 握手会在开始建立索引前完成,因此大型代码库的首次索引不会妨碍客户端连接。)

在 HTTP 模式下,服务使用 MCP 的 Streamable HTTP 传输协议,默认绑定到回环地址,响应 GET /health;如果设置了 --auth-token(或 OCE_MCP_AUTH_TOKEN),则每个请求都必须携带 Authorization: Bearer <token>。

然后添加到 MCP 配置中:

{
  "mcpServers": {
    "open-context": {
      "command": "oce",
      "args": ["mcp", "--workspace", "/path/to/project"]
    }
  }
}
6. 或使用 VS Code 扩展

extension/ 文件夹基于同一引擎提供完整的 VS Code 体验:侧边栏聊天基于你的索引(支持流式输出、Markdown、复制/插入/应用代码块)、Agent 编辑支持逐文件差异查看/撤销/重做,以及每轮的“全部撤销”、快速搜索 (Ctrl+Shift+K)、保存时自动建立索引,以及用于调试检索的索引健康面板。每个平台的软件包都包含一个 Node-API SQLite 绑定,可在 VS Code 1.103 及更高版本和远程主机(SSH、WSL、Codespaces)上运行——支持矩阵请参见 extension/PUBLISHING.md,或自行构建 VSIX:

cd extension && npm ci --ignore-scripts
npm run package -- linux-x64   # → ../artifacts/open-context-linux-x64-<version>.vsix

📖 使用指南

CLI 参考
oce <command> [options]

Commands:
  index <workspace>      Index a codebase
  search <query>         Search the indexed codebase
  watch                  Index, then keep the index live as files change
  mcp                    Start MCP server (stdio, or --http for a shared endpoint)
  agent                  Start interactive agent (auto-indexes on startup)
  eval                   Score retrieval quality against a labeled query set
  push-index <dest>      Publish the index as a team artifact (Team)
  pull-index <src>       Install a team index, re-embed only local changes (Team)
  bench                  Benchmark parse/chunk throughput on this workspace
  policy                 Show the effective policy (user + workspace + org lock)
  audit                  Inspect / verify the tamper-evident audit log
  activate <key>         Activate a Team/Enterprise license
  license / deactivate   Show or remove the active license

Options:
  -w, --workspace <path>   Project root (default: cwd)
  -p, --provider <name>    Embedding provider: voyage | openai | ollama | local
  -m, --model <model>      Embedding model name
  --api-key <key>          API key (falls back to env vars)
  --store-path <path>      Custom store directory (default: .open-context/)
  --max-file-size <bytes>  Skip files larger than this
  --chunk-size <lines>     Lines per chunk (default: 80)
  --chunk-overlap <lines>  Overlap between chunks (default: 15)
程序化 API
import { OpenContext, ContextAgent, defaultAgentTools } from "@dhaxor/open-context";

// 1. Create and index
const ctx = await OpenContext.create({
  workspaceRoot: "./my-project",
  embedding: {
    provider: "voyage",
    model: "voyage-code-3",
    dimension: 1024,
    apiKey: process.env.VOYAGE_API_KEY,
    batchSize: 32,
  },
});

await ctx.indexWorkspace();

// 2. Search
const results = await ctx.search("authentication middleware flow");
console.log(results);

// 3. Agent with tools
const agent = new ContextAgent({
  provider: "openai",
  model: "gpt-4o",
  apiKey: process.env.OPENAI_API_KEY,
  tools: defaultAgentTools({ context: ctx, includeEdits: true }),
  // Optional harness features:
  maxParallelTools: 4,                       // read-only tool calls fan out concurrently
  hooks: {
    preToolCall: (tc) => tc.name === "remove-file"
      ? { behavior: "deny", reason: "deletions are reviewed manually" }
      : { behavior: "allow" },
    postToolCall: (_tc, result) => result.replaceAll(process.env.HOME!, "~"),
  },
});

const answer = await agent.run("How does the auth middleware work?");
console.log(answer);
console.log(agent.getLastRunStats());        // steps, tool calls, token usage, duration
const saved = agent.exportSession();          // persist; importSession(saved) restores

// 4. Cleanup
ctx.close();
MCP 服务集成
import { runMCPServer } from "@dhaxor/open-context";

await runMCPServer({
  workspaceRoot: "./my-project",
  embedding: { provider: "voyage", model: "voyage-code-3", dimension: 1024, batchSize: 32 },
});

公开的 MCP 工具:

  • codebase-retrieval — 使用自然语言搜索代码
  • list-files — 按筛选条件浏览已建立索引的文件
  • read-file — 读取文件内容,可指定行范围
  • find-symbol-definition — 按名称精确查找函数/类/类型的定义位置
  • find-symbol-references — 查找标识符在索引中的所有使用位置
  • index-status — 分块数量、文件数量、搜索模式、嵌入模型

🏗️ 架构

┌─────────────────────────────────────────────────────────────┐
│                        Open Context Engine                   │
├─────────────────────────────────────────────────────────────┤
│  CLI / API / MCP / Agent                                     │
├─────────────────────────────────────────────────────────────┤
│  HybridRetriever                                             │
│  ├── Vector Search (sqlite-vec)                              │
│  ├── BM25 Search (SQLite FTS5, porter-stemmed)               │
│  ├── Reciprocal Rank Fusion + symbol/editor/recency boosts   │
│  ├── Optional Re-ranking (Voyage / Cohere)                   │
│  └── Graph Expansion (callers/callees via code graph)        │
├─────────────────────────────────────────────────────────────┤
│  AstChunker + CodeChunker                                    │
│  ├── Tree-sitter parsers (TS, JS, Py, Go, Rust, Java, C#)   │
│  └── Boundary-aware fallback chunking                        │
├─────────────────────────────────────────────────────────────┤
│  Embedding Providers                                         │
│  ├── Voyage Code-3 (recommended)                             │
│  ├── OpenAI text-embedding-3-*                               │
│  └── Ollama (local, nomic-embed-text)                        │
├─────────────────────────────────────────────────────────────┤
│  SqliteStore                                                 │
│  ├── chunks (metadata)                                       │
│  ├── chunks_vec (vector index — skipped in keyword-only)     │
│  ├── chunks_fts (full-text index)                            │
│  ├── graph_edges (import/call/definition graph)              │
│  └── files (index state)                                     │
└─────────────────────────────────────────────────────────────┘

⚙️ 配置

嵌入模型
提供商模型维度最适用于
Voyagevoyage-code-31024⭐ 代码检索(推荐)
OpenAItext-embedding-3-large3072通用用途
OpenAItext-embedding-3-small1536速度与成本
Ollamanomic-embed-text768通过 Ollama 服务实现 100% 本地运行
Localjina-embeddings-v2-base-code768100% 本地运行、进程内执行、针对代码调优——无需密钥或服务
Localall-MiniLM-L6-v2384100% 本地运行、进程内执行、体积最小/速度最快

local 提供商需要可选的 @huggingface/transformers 软件包;模型只需下载一次到 ~/.open-context/models(通过 OCE_MODEL_DIR 覆盖),之后即可离线运行。

Agent 大模型

openai、anthropic、google(Gemini,支持流式输出和工具)、ollama(完全本地运行——oce -p ollama --llm-model qwen2.5-coder:7b 无需 API 密钥),以及 custom(通过 --llm-base-url 使用任何兼容 OpenAI 的端点)。将 -p ollama 用于大模型、将 --embedding-provider local 用于嵌入,并设置 reranker: { provider: "local" },即可让整个技术栈离线运行——索引、搜索、重排序和 Agent。

配置文件

持久化设置位于 ~/.open-context/config.json(用户级)和 <workspace>/.open-context/config.json(项目级——请提交该文件)。命令行标志和环境变量始终优先。配置文件会有意拒绝 API 密钥;请使用环境变量。

{
  "embedding": { "provider": "local", "model": "jina-embeddings-v2-base-code" },
  "llm": { "provider": "ollama", "model": "qwen2.5-coder:7b" },
  "search": { "topK": 20, "minScore": 0.15 },
  "chunkSize": 80
}
搜索配置
{
  search: {
    topK: 15,              // Final results returned
    candidateK: 60,        // Candidates before fusion/rerank
    maxOutputLength: 80000,// Max chars in formatted output
    minScore: 0.0,         // Score floor
    bm25Weight: 1.0,       // Keyword search weight
    vectorWeight: 1.0,     // Semantic search weight
    rerank: true,          // Enable reranking if configured
    expandSymbols: true,   // Pull in referenced definitions
  }
}
重排序
{
  reranker: {
    provider: "voyage",    // or "cohere"
    model: "rerank-2",     // optional
    apiKey: "your-key",
  }
}

👥 团队索引同步(Team)

只需建立一次索引——在 CI 中或由负责人机器完成——然后让整个团队拉取结果,避免每个人都为同一个单体仓库重复付费生成嵌入:

# CI / lead machine: refresh the index and publish it (any file path or
# HTTP(S) PUT endpoint — S3/GCS presigned URLs work as-is)
oce push-index https://artifacts.example.com/oce/main.db.gz --token "$TOKEN"

# Each teammate: install it, then only their local diff gets embedded
oce pull-index https://artifacts.example.com/oce/main.db.gz --token "$TOKEN"
# → Installed team index: 12,481 chunks, 1,904 files, built ... at commit ab12cd34
# → Reconciled: 3 file(s) re-embedded locally, 1,901 reused from the artifact

产物就是存储本身(向量 + FTS + 代码图 + 文件哈希)的 gzip 压缩包,因此协调过程只是增量建立索引:只有与产物哈希不同的文件才会重新生成嵌入。不涉及 OCE 云服务——产物会存储在你控制的存储中。

此外,全机器范围的嵌入缓存(~/.open-context/embed-cache.db,在 CLI 和扩展中默认启用)以内容哈希作为向量的键:相同代码在不同仓库、分支和存储重建过程中都不会重复生成嵌入。可通过 --no-embed-cache 或 openContext.embedding.cache.enabled 禁用。

🛡️ 策略控制

提交策略文件后,所有 OCE 界面(CLI、扩展、库)都会强制执行该策略——--allow-shell 标志无法覆盖它,合并时始终采用限制最严格的规则:

// <workspace>/.open-context/policy.json (or ~/.open-context/policy.json for user-wide)
{
  "agent": {
    "shell": { "enabled": false },                  // or pin: { "allowlist": ["git", "npm"] }
    "edits": { "enabled": true },
    "webSearch": { "enabled": false }
  },
  "embedding": { "localOnly": true },               // only ollama/local providers may run
  "ignore": ["secrets/**", "*.pem"],                // never indexed, on top of .contextignore
  "audit": { "required": true }                     // force audit logging on
}

oce policy 会打印合并后的有效策略,并指出每条规则的来源。Team+ 计划的组织还可以额外发布由 Ed25519 签名的 policy.lock(使用 scripts/license-tool.mjs sign-policy 签发),开发者无法通过放宽规则或删除该文件来规避策略。

🧾 审计日志

oce agent --audit(或 openContext.agent.audit.enabled 设置)会将每次运行、工具调用和 MCP 调用追加到 .open-context/audit/audit.jsonl。每条记录都通过 SHA-256 与上一条记录形成哈希链,因此可以检测编辑、删除和重新排序:

oce audit                 # recent events
oce audit --type tool-call --since 2026-07-01
oce audit --verify        # ✓ chain intact — or exactly where it was tampered

审计日志记录是 Enterprise 功能;工作区或组织策略中的 "audit": { "required": true } 也会启用该功能。

🛠️ 开发

git clone https://github.com/Dhaxor/open-context-engine.git
cd open-context-engine
npm install
npm run build
npm test
项目结构
src/
├── core/
│   ├── context.ts          # Main OpenContext class
│   ├── ast-chunker.ts      # Tree-sitter chunking
│   ├── chunker.ts          # Fallback line chunking
│   ├── embedder.ts         # Embedding providers
│   ├── retriever.ts        # Hybrid search + RRF + boosts
│   ├── reranker.ts         # Re-ranking providers
│   ├── sqlite-store.ts     # SQLite persistence (vec + FTS5 + graph)
│   ├── code-graph.ts       # Import/call/definition edge queries
│   ├── ast-graph-extractor.ts # Single-DFS AST edge extraction
│   ├── graph-expander.ts   # Graph-aware result expansion
│   ├── chunk-pool.ts       # Worker-thread parse/chunk pool (auto on big repos)
│   ├── policy.ts           # Workspace/org policy loading + enforcement
│   ├── audit.ts            # Tamper-evident (hash-chained) audit log
│   ├── license.ts          # Offline Ed25519 license gate
│   ├── search.ts           # Output formatting
│   ├── file-filter.ts      # Gitignore-aware file collection
│   └── file-watcher.ts     # Watch for changes
├── agent/
│   ├── agent.ts            # ContextAgent + tools
│   ├── providers.ts        # LLM callers (OpenAI, Anthropic)
│   ├── model-router.ts     # Cost-appropriate tier per query
│   ├── session-memory.ts   # Cross-session insight memory
│   ├── edit-tools.ts       # File editing tools
│   └── extra-tools.ts      # Shell + web search
├── eval/
│   └── runner.ts           # Retrieval-quality scoring (oce eval)
├── mcp/
│   └── server.ts           # MCP server implementation
└── cli/
    └── index.ts            # oce CLI entrypoint
extension/                  # VS Code extension (chat, edit review, health)

🧪 搜索原理

  1. 分块:Tree-sitter 会将你的代码解析为语义单元(函数、类、方法)。不受支持的文件会回退到按边界感知的行分块。
  2. 嵌入:每个块都会使用你选择的提供方进行嵌入。Voyage Code-3 针对代码进行了优化,可提供最佳检索质量。
  3. 索引:向量存入 sqlite-vec,文本存入 FTS5,元数据存入 SQLite 表。所有数据均保存在本地。
  4. 查询:系统会对你的自然语言查询进行嵌入,并通过向量相似度和 BM25 同时进行搜索。
  5. 融合:系统使用 Reciprocal Rank Fusion 融合结果,然后根据符号名称匹配、编辑器上下文(当前活动文件、已打开的标签页)和 git 新近度进行加权。
  6. 重新排序(可选):专用重排序器会对排名靠前的候选项重新评分,以提高精度。
  7. 图扩展:系统沿代码图扩展排名靠前的结果——同时附带调用方、被调用方和引用的定义,让大模型获得完整上下文。

如果你的平台无法加载 sqlite-vec 扩展,步骤 2 和步骤 4 中的向量处理部分会自动跳过,搜索引擎将以**纯关键词模式(BM25)**运行——查找概念匹配会更慢,但所有功能仍可正常使用,并且 getStatus() / CLI / 扩展都会显示当前模式。

📏 衡量检索质量

oce eval 会根据带标签的查询集为引擎评分——因此,排名变化有据可依,而非凭空猜测:

# Score the engine against the bundled gold set for this repo
oce eval --cases eval/oce.eval.json

# Save a baseline, change a ranking knob, then compare
oce eval --cases eval/oce.eval.json --out baseline.json
# ...tweak weights / expansion / reranker...
oce eval --cases eval/oce.eval.json --baseline baseline.json

# Measure what symbol/graph expansion contributes
oce eval --cases eval/oce.eval.json --no-expand --baseline baseline.json

报告 recall@k、MRR、nDCG@k、hit-rate 和每个查询的延迟,以及相对于已保存基线的每个案例变化(提升 / 退步)。指标以文件为粒度:当目标文件在返回的前 k 个不重复文件中排名时,该案例即通过。

当前数据是在此仓库已提交的 44 个案例黄金集(eval/oce.eval.json)和外部的 27 个案例 Flask 集(eval/external/flask.eval.json)上重新测得的;基线与它们一同提交:

黄金集仅关键词(BM25)混合(voyage-code-3)混合(本地 MiniLM,自适应融合)
此仓库 — recall@10 / MRR / nDCG@100.886 / 0.676 / 0.7160.943 / 0.759 / 0.7920.932 / 0.691 / 0.743
Flask 3.1.2(外部)— recall@10 / MRR / nDCG@100.926 / 0.605 / 0.6850.889 / 0.604 / 0.6760.926 / 0.641 / 0.711

有两点客观结论,两者都很重要:

  • 查询改述意图时,混合检索更有优势——在此仓库的集合中,召回率提升了 6 个百分点,而且 Agent 实际运行的正是这种模式。
  • 自适应融合弥补了定义类查询的差距。 过去,等权 RRF 会将 BM25 的高置信度命中排在向量偏好的文档 / 测试之后(MiniLM 混合检索在 Flask 上得分为 0.852,低于仅关键词检索的 0.926)。现在会根据查询形式进行分类——标识符拼写、带引号的代码和文件路径倾向于 BM25;改述倾向于语义检索(src/core/query-profile.ts)——本地 MiniLM 混合检索在 Flask 集上达到 与仅关键词检索持平(0.926),同时保留混合检索在改述查询上的优势。Voyage 列的数据早于自适应融合(仅改变查询时行为;已提交的基线仍为等权参考值)。你可以自行重新运行:oce eval --no-adaptive-fusion 可对比新旧行为。

本节过去引用的 6 月基线(混合检索 0.977)无法在当前引擎上复现(0.943)——现在每次运行都会捕捉到这种偏差,而不是让它悄无声息地进入发布版本。

报告会记录生成报告时所用的搜索模式(hybrid 与 keyword-only),比较基线时若模式不匹配,也会发出明确警告。

跨仓库验证: 随附的集合只能证明检索在此仓库上的效果。eval/external/ 中包含 OCE 从未处理过的代码库黄金集——首先是 Flask 3.1.2(Python,27 个案例,关键词检索的 recall@10 为 0.926)——并提供已提交的基线和添加更多集合的工作流。在 eval/oce.eval.json 上表现更好的排名变更,在被视为进展前,也应在这些集合上重新运行。

案例文件是一个 JSON 数组(或 { cases: [...] }):

{ "id": "rrf-fusion", "query": "where is reciprocal rank fusion implemented", "expectedPaths": ["src/core/retriever.ts"] }

请在 .contextignore 中列出评估集目录,避免将其纳入索引——黄金集会将查询映射到答案,因此将其编入索引会污染它所衡量的排名。

📦 要求

  • Node.js 22 或更高版本(22 和 24 LTS 无需编译器即可安装;Node 20 已结束生命周期,SQLite 绑定不再为其提供预构建二进制文件)
  • 一个聊天模型——oce setup 会列出免费选项(本地运行 Ollama,或使用 Google、Groq、Cerebras 或 OpenRouter 的免费层密钥)
  • 嵌入模型为可选项:不使用时,搜索仅运行关键词检索(BM25)。如需语义排序,可使用 Ollama(nomic-embed-text,免费且本地运行)、可选的 @huggingface/transformers 包(--provider local),或 Voyage / OpenAI 密钥
  • 不支持构建 sqlite-vec 的平台(例如 win32-arm64、Alpine)也仅运行关键词检索

📄 许可证

MIT © Gain


专为希望 AI 真正理解其代码的开发者打造。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。