关于 open-context-engine
open-context-engine 是面向开发者和编码 Agent 的本地优先代码检索引擎。它结合 AST 感知索引与语义、关键词混合搜索,并通过 MCP 提供代码检索,无需将代码发送到云端。
主要功能
- 01基于 AST 的代码分块
- 02向量与 BM25 混合搜索
- 03本地 SQLite 向量索引
- 04符号与代码图扩展
- 05可选结果重排序
- 06监视变更并更新索引
适用场景
- 01为编码 Agent 的回答提供代码依据
- 02用自然语言查询代码
- 03向 MCP 客户端提供实时代码上下文
MCP 相关
通过 stdio 或 Streamable HTTP 提供检索、文件和符号工具。服务启动时会索引工作区,也可监视变更以保持索引更新。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Open Context Engine
本地。语义化。即时。
将任何代码库变成可供 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) │
└─────────────────────────────────────────────────────────────┘
⚙️ 配置
嵌入模型
| 提供商 | 模型 | 维度 | 最适用于 |
|---|---|---|---|
| Voyage | voyage-code-3 | 1024 | ⭐ 代码检索(推荐) |
| OpenAI | text-embedding-3-large | 3072 | 通用用途 |
| OpenAI | text-embedding-3-small | 1536 | 速度与成本 |
| Ollama | nomic-embed-text | 768 | 通过 Ollama 服务实现 100% 本地运行 |
| Local | jina-embeddings-v2-base-code | 768 | 100% 本地运行、进程内执行、针对代码调优——无需密钥或服务 |
| Local | all-MiniLM-L6-v2 | 384 | 100% 本地运行、进程内执行、体积最小/速度最快 |
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)
🧪 搜索原理
- 分块:Tree-sitter 会将你的代码解析为语义单元(函数、类、方法)。不受支持的文件会回退到按边界感知的行分块。
- 嵌入:每个块都会使用你选择的提供方进行嵌入。Voyage Code-3 针对代码进行了优化,可提供最佳检索质量。
- 索引:向量存入
sqlite-vec,文本存入 FTS5,元数据存入 SQLite 表。所有数据均保存在本地。 - 查询:系统会对你的自然语言查询进行嵌入,并通过向量相似度和 BM25 同时进行搜索。
- 融合:系统使用 Reciprocal Rank Fusion 融合结果,然后根据符号名称匹配、编辑器上下文(当前活动文件、已打开的标签页)和 git 新近度进行加权。
- 重新排序(可选):专用重排序器会对排名靠前的候选项重新评分,以提高精度。
- 图扩展:系统沿代码图扩展排名靠前的结果——同时附带调用方、被调用方和引用的定义,让大模型获得完整上下文。
如果你的平台无法加载 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@10 | 0.886 / 0.676 / 0.716 | 0.943 / 0.759 / 0.792 | 0.932 / 0.691 / 0.743 |
| Flask 3.1.2(外部)— recall@10 / MRR / nDCG@10 | 0.926 / 0.605 / 0.685 | 0.889 / 0.604 / 0.676 | 0.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 真正理解其代码的开发者打造。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。