关于 contextweaver
ContextWeaver 是面向编码 Agent 的代码检索引擎,结合向量与全文搜索、结构化上下文扩展和令牌预算整理代码片段。它可通过 MCP 提供检索、符号查询与索引统计。
主要功能
- 01向量与全文混合检索
- 02Tree-sitter AST 语义分块
- 03邻近、结构与导入扩展
- 04令牌预算上下文打包
- 05文件监视与增量索引
- 06符号查询和索引统计
适用场景
- 01为编码 Agent 查找相关代码
- 02追踪同文件及跨文件上下文
- 03按符号定位定义与引用
- 04监控代码库变更并更新索引
MCP 相关
ContextWeaver 以 MCP 服务模式提供代码检索、文件列表、符号定义、引用查询和统计工具。首次查询可触发自动索引,后续更新可增量进行。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
6收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mode | enum | 否 | 可选的检索配置。quick 可降低成本,balanced 使用默认设置,deep 可提高召回率并扩大搜索范围。quick | balanced | deep |
| language | array | 否 | 检索后应用的可选语言允许列表。 |
| max_files | number | 否 | 打包后返回的可选最大文件数。 |
| repo_path | string | 是 | 代码库根目录的绝对文件系统路径。 |
| return_debug | boolean | 否 | 为 true 时,包含每次调用的调试元数据。 |
| exclude_globs | array | 否 | 检索后应用的可选文件 glob 拒绝列表。 |
| include_globs | array | 否 | 检索后应用的可选文件 glob 允许列表。 |
| output_format | enum | 否 | 响应格式。为保持向后兼容,默认使用 markdown。markdown | json | both |
| max_total_chars | number | 否 | 每次调用的可选输出字符数预算。 |
| technical_terms | array | 否 | 硬性筛选条件。可选的精确已知标识符列表(类/函数名、常量),这些标识符必须出现在代码中。仅使用 100% 确定存在的词条。探索时留空。 |
| information_request | string | 是 | 语义目标。用完整的自然语言句子描述要查找的功能、逻辑或行为。重点描述“如何运作”,而非确切名称。(例如,“追踪登录流程的执行过程”) |
| max_segments_per_file | number | 否 | 每个文件可返回的可选非连续片段数上限。 |
| low_confidence_behavior | enum | 否 | 控制 top rerank score 低于 SmartTopK floor 时的 MCP 行为。return_top1 | return_empty | return_with_warning |
详细介绍
ContextWeaver
🧵 为 AI Agent 精心编织的代码库上下文引擎
面向 AI Agent 的语义代码检索 — 混合搜索 • 图扩展 • 感知 Token 的打包
English · 简体中文
ContextWeaver 是一款专为 AI 编码助手打造的语义检索引擎。它结合混合搜索(向量 + 词法)、智能上下文扩展和感知 Token 的打包,为大模型提供精准、相关且上下文完整的代码片段。
✨ 核心功能
🔍 混合检索引擎
- 向量检索:通过相似度实现深层语义理解
- 词法检索(FTS):精确匹配函数名、类名及其他技术术语
- RRF 融合(倒数排名融合):智能合并多个召回通道
🧠 AST 语义分块
- Tree-sitter 解析:支持 TypeScript、JavaScript、Python、Go、Java、Rust、C、C++、C# 等
- 双文本策略:使用
displayCode进行展示,使用vectorText生成嵌入 - 感知间隙合并:智能处理代码间隙,同时保留语义完整性
- 注入面包屑路径:向量文本携带分层路径,以提升召回效果
- UTF-16 字符域归一化:写入元数据前,通过
SourceAdapter.toCharOffset统一偏移量,避免多字节字符切片错误(v1.4.0+)
📊 三阶段上下文扩展
- E1 邻近扩展:扩展同一文件中的相邻代码块,保留代码块完整性
- E2 面包屑补全:补充同一类/函数下的同级方法,便于理解结构
- E3 导入解析:追踪跨文件依赖(可配置开关)
🎯 智能 TopK 截断
- 锚点与下限:动态阈值与绝对下限双重保障
- Delta 保护机制:避免在 Top1 异常值场景中产生误判
- 安全区:前 N 个结果仅检查下限,确保基础召回效果
🔌 原生 MCP 支持
- MCP 服务模式:通过一条命令启动 Model Context Protocol 服务
- 多工具粒度(v1.5.0+):除核心语义检索外,还提供用于结构浏览、符号引用、符号定义和统计的专用工具
- 意图与术语分离:面向大模型的 API 设计
- 自动索引:首次查询会自动触发索引;增量更新透明完成
⚡ 查询缓存与文件监视(v1.5.0+)
- 查询缓存(QueryCache):按项目划分的进程内 LRU 缓存(默认 50 个条目);命中时会跳过整个向量召回、重排和扩展流程
- 自动缓存失效:缓存键由
normalized query + projectId + index version + search-config fingerprint组成,因此索引更新或配置变更后会自动失效,不会返回过时结果 - 监视模式:
contextweaver watch会监视文件系统并自动触发增量索引,支持防抖(默认 500ms)和扫描去重(不会并发扫描)
📈 统计与可观测性(v1.5.0+)
- 三类指标:索引过程、搜索质量/行为、健康状态/一致性
- 双入口:
contextweaver stats命令行(支持--json)以及 MCPstats工具 - 一致性诊断:自动检测异常迁移状态、
pending_marks积压、缺失的向量行等,并提供建议的修复方法
🛡️ 防崩溃数据架构(v1.4.0+)
- 内容的唯一事实来源:LanceDB 仅存储向量和定位元数据;内容从
files.content读取,从而将索引大小缩减 30–50% - 跨存储事务补偿:分三个阶段写入 LanceDB → FTS+outbox → SQLite 标记;发生任何故障时自动回滚或重放
- 迁移状态机:持久化
pending/done/aborted状态,并在崩溃恢复时自动重建 - 跨进程互斥:建议锁可防止 MCP 服务和命令行同时触发 LanceDB 迁移
- chunk_id 去重:写入前先删除,避免重试时产生重复行
📦 快速开始
环境要求
- Node.js >= 20
- pnpm(推荐)或 npm
安装
# Global install
npm install -g @chiway/contextweaver
# Or with pnpm
pnpm add -g @chiway/contextweaver
初始化配置
# Create the config file (~/.contextweaver/.env)
contextweaver init
# Or the short alias
cw init
编辑 ~/.contextweaver/.env 并填写 API 密钥:
# Embedding API config (required)
EMBEDDINGS_API_KEY=your-api-key-here
EMBEDDINGS_BASE_URL=https://api.siliconflow.cn/v1/embeddings
EMBEDDINGS_MODEL=BAAI/bge-m3
EMBEDDINGS_MAX_CONCURRENCY=10
EMBEDDINGS_DIMENSIONS=1024
# Reranker config (required)
RERANK_API_KEY=your-api-key-here
RERANK_BASE_URL=https://api.siliconflow.cn/v1/rerank
RERANK_MODEL=BAAI/bge-reranker-v2-m3
RERANK_TOP_N=20
# Search parameters (optional, override built-in defaults)
CW_SEARCH_WVEC=0.6
CW_SEARCH_WLEX=0.4
CW_SEARCH_RERANK_TOP_N=10
CW_SEARCH_MAX_TOTAL_CHARS=48000
CW_SEARCH_VECTOR_TOP_K=80
CW_SEARCH_SMART_MAX_K=8
CW_SEARCH_IMPORT_FILES_PER_SEED=3
# Ignore patterns (optional, comma-separated)
# IGNORE_PATTERNS=.venv,node_modules
为代码库建立索引
# Run from the codebase root
contextweaver index
# Specify a path
contextweaver index /path/to/your/project
# Force a full re-index
contextweaver index --force
监视模式(v1.5.0+)
# Watch for file changes and auto-index incrementally (Ctrl+C to stop)
contextweaver watch
# Specify a path and debounce window (ms)
contextweaver watch /path/to/project --debounce 800
watch 启动时会运行一次完整的增量扫描,然后监听文件系统事件;变更会在防抖时间窗口内触发一次去重后的扫描,被忽略规则排除的路径不会触发扫描。
本地搜索
# Semantic search
cw search --information-request "How is the user authentication flow implemented?"
# With exact terms
cw search --information-request "Database connection logic" --technical-terms "DatabasePool,Connection"
结构浏览与符号查找(v1.5.0+)
以下命令是 MCP 工具的命令行对应版本,不会产生 Embedding API 费用:
# List indexed files (supports glob / language / count filters)
contextweaver list-files --glob "src/**/*.ts" --language typescript --max-results 100
# Look up a symbol definition
contextweaver definition SearchService --hint-path src/search
# Look up symbol references
contextweaver references handleStats --exclude-definition
统计(v1.5.0+)
# Human-readable stats report
contextweaver stats
# JSON output (for scripting)
contextweaver stats --json
# Specify a project path
contextweaver stats --path /path/to/project
启动 MCP 服务
# Launch the MCP server (for use by Claude and other AI assistants)
contextweaver mcp
索引管理(v1.4.0+)
# Show LanceDB migration state
contextweaver migrate
# Clear the aborted state: wipe LanceDB and trigger a full rebuild
# Triggered when: the Indexer refuses to write after sampling validation fails;
# run this, then index again.
contextweaver migrate --reset
# Specify a project path
contextweaver migrate --path /path/to/project
🔧 MCP 集成
Claude Desktop 配置
将以下内容添加到 Claude Desktop 配置文件中:
{
"mcpServers": {
"contextweaver": {
"command": "contextweaver",
"args": ["mcp"]
}
}
}
MCP 工具概览(v1.5.0+)
ContextWeaver 提供 5 个 MCP 工具,采用“语义检索优先,结构浏览其次”的分层设计:
| 工具 | 用途 | Embedding 费用 |
|---|---|---|
codebase-retrieval | 主要工具:混合语义与精确匹配检索 | 是 |
list-files | 列出已建立索引的文件结构(路径/语言/大小) | 否 |
find-references | 查找符号的启发式文本引用 | 否 |
get-symbol-definition | 查找符号可能对应的定义块 | 否 |
stats | 索引/搜索/健康状态统计 | 否 |
codebase-retrieval 参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
repo_path | string | ✅ | 仓库根目录的绝对路径 |
information_request | string | ✅ | 用自然语言描述的语义意图 |
technical_terms | string[] | ❌ | 精确的技术术语(类名、函数名等) |
mode | string | ❌ | 检索配置:quick、balanced 或 deep |
include_globs | string[] | ❌ | 检索后应用的文件 glob 允许列表 |
exclude_globs | string[] | ❌ | 检索后应用的文件 glob 拒绝列表 |
language | string[] | ❌ | 检索后应用的语言允许列表 |
max_total_chars | number | ❌ | 每次调用的输出字符数预算 |
max_files | number | ❌ | 打包后返回的最大文件数 |
max_segments_per_file | number | ❌ | 每个文件的最大非连续片段数 |
return_debug | boolean | ❌ | 在结构化输出中包含调试元数据 |
low_confidence_behavior | string | ❌ | 低置信度处理方式:return_top1、return_empty 或 return_with_warning |
output_format | string | ❌ | 响应格式:markdown、json 或 both |
list-files 参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
repo_path | string | ✅ | 仓库根目录的绝对路径 |
glob | string | ❌ | 用于筛选路径的 glob 模式 |
language | string | ❌ | 语言筛选器(与 files.language 匹配) |
max_results | number | ❌ | 返回的最大文件数(默认值为 200) |
find-references 参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
repo_path | string | ✅ | 仓库根目录的绝对路径 |
symbol | string | ✅ | 精确的符号名称 |
exclude_definition | boolean | ❌ | 排除面包屑末尾与符号名称匹配的代码块 |
max_results | number | ❌ | 返回的最大引用数(默认值为 50) |
get-symbol-definition 参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
repo_path | string | ✅ | 仓库根目录的绝对路径 |
symbol | string | ✅ | 要解析的精确符号名称 |
hint_path | string | ❌ | 用于区分同名定义的首选路径 |
max_results | number | ❌ | 返回的最大定义数(默认值为 3) |
注意:
find-references和get-symbol-definition是对已索引代码块进行的启发式文本查找,并非编译器级别的导航。若要进行穷尽式原始文本匹配,请在 MCP 之外使用grep。
设计理念
- 意图与术语分离:
information_request描述“要做什么”,technical_terms筛选“它叫什么” - 优先提供同文件上下文:默认提供同文件上下文;跨文件探索由 Agent 发起
- 回归 Agent 的直觉:工具只负责定位;按需由 Agent 触发跨文件探索
🏗️ 架构
flowchart TB
subgraph Interface["CLI / MCP Interface"]
CLI[contextweaver CLI]
MCP[MCP Server]
end
subgraph Search["SearchService"]
QC[QueryCache<br/>LRU]
VR[Vector Retrieval]
LR[Lexical Retrieval]
RRF[RRF Fusion + Rerank]
QC -.cache hit.-> CP
VR --> RRF
LR --> RRF
end
subgraph Expand["Context Expansion"]
GE[GraphExpander]
CP[ContextPacker]
GE --> CP
end
subgraph Storage["Storage Layer"]
VS[(VectorStore<br/>LanceDB)]
DB[(SQLite<br/>FTS5)]
end
subgraph Index["Indexing Pipeline"]
CR[Crawler<br/>fdir] --> SS[SemanticSplitter<br/>Tree-sitter] --> IX[Indexer<br/>Batch Embedding]
end
Interface --> Search
RRF --> GE
Search <--> Storage
Expand <--> Storage
Index --> Storage
核心模块
| 模块 | 职责 |
|---|---|
| SearchService | 混合搜索核心:协调向量/词法召回、RRF 融合和重排;集成 QueryCache |
| QueryCache | 按项目划分的进程内 LRU 缓存(v1.5.0+);命中时跳过整个检索流水线 |
| GraphExpander | 上下文扩展器:运行 E1/E2/E3 三阶段扩展策略 |
| ContextPacker | 上下文打包器:合并片段并控制令牌预算 |
| ChunkContentLoader | 按 (path, start_index, end_index) 切分 files.content(v1.4.0+) |
| VectorStore | LanceDB 适配器;仅提供纯向量操作 |
| Database (SQLite) | 元数据存储 + FTS5 全文索引 + 统计计数器,schema_version=3 |
| Bootstrap | 跨存储初始化协调器:重放 pending_marks + LanceDB 架构迁移(v1.4.0+) |
| SemanticSplitter | AST 语义分块器(Tree-sitter);写入时将偏移量标准化为 UTF-16 字符域 |
| Watcher | 文件监视协调器(v1.5.0+):防抖 + 扫描去重 + 忽略规则过滤 |
| Stats | 统计聚合层(v1.5.0+):汇总索引/搜索/健康指标 |
数据架构(v1.4.0+)
~/.contextweaver/<projectId>/
├── index.db # SQLite
│ ├── files # File metadata + full content (content column, the only source for text slicing)
│ ├── files_fts # External-content table, inverted index pointing to files
│ ├── chunks_fts # Chunk-level inverted index, per-file wholesale replacement
│ ├── metadata # schema_version / lancedb_migration_state / lock
│ ├── stats # Cumulative index/search counters (v1.5.0+)
│ └── pending_marks # Outbox: replayed when a vector_index_hash mark failed
└── vectors.lance/ # LanceDB chunks table (vectors + locating metadata only, no content)
关键不变量:
- 内容的唯一事实来源是
files.content;ChunkContentLoader通过start_index/end_index切分(与displayCode使用相同来源) - 所有 LanceDB 偏移字段都位于 UTF-16 字符域;多字节文件绝不会被错误切分
- 跨存储写入顺序:LanceDB →(FTS + outbox 单一事务)→ SQLite 标记 + 清除 outbox
- LanceDB 迁移状态
pending/done/aborted会持久化,并通过咨询锁实现跨进程互斥 - 查询缓存键与索引版本和搜索配置指纹绑定;任何索引或配置变更都会使其失效
📁 项目结构
contextweaver/
├── src/
│ ├── index.ts # CLI entry (init / index / watch / search / mcp / migrate / stats)
│ ├── config.ts # Config management (environment variables)
│ ├── defaultEnv.ts # Default .env template
│ ├── cli/
│ │ └── mirrorCommands.ts # CLI mirrors of MCP tools (list-files / definition / references)
│ ├── api/ # External API wrappers
│ │ ├── embedding.ts # Embedding API
│ │ └── reranker.ts # Reranker API
│ ├── chunking/ # Semantic chunking
│ │ ├── SemanticSplitter.ts # AST semantic chunker
│ │ ├── SourceAdapter.ts # Source adapter (UTF-16/UTF-8 domain normalization)
│ │ ├── LanguageSpec.ts # Language spec definitions
│ │ ├── ParserPool.ts # Tree-sitter parser pool
│ │ └── types.ts # Chunking type definitions
│ ├── scanner/ # File scanning
│ │ ├── index.ts # Scan orchestration
│ │ ├── crawler.ts # Filesystem traversal
│ │ ├── processor.ts # File processing
│ │ ├── watcher.ts # File-watch coordinator (v1.5.0+)
│ │ ├── filter.ts # Filter rules
│ │ ├── hash.ts # File hash
│ │ └── language.ts # Language detection
│ ├── indexer/ # Indexer
│ │ └── index.ts # Three-stage transaction (LanceDB → FTS+outbox → SQLite mark)
│ ├── vectorStore/ # Vector storage
│ │ └── index.ts # LanceDB adapter (pure vector operations)
│ ├── db/ # Database
│ │ ├── index.ts # SQLite + FTS5 + pending_marks + migration state machine + stats counters
│ │ └── bootstrap.ts # Cross-store init coordinator (v1.4.0+)
│ ├── search/ # Search service
│ │ ├── SearchService.ts # Core search service (cache-integrated)
│ │ ├── QueryCache.ts # Per-project LRU query cache (v1.5.0+)
│ │ ├── GraphExpander.ts # Context expander
│ │ ├── ContextPacker.ts # Context packer
│ │ ├── ChunkContentLoader.ts # Slices by (path, start_index, end_index) (v1.4.0+)
│ │ ├── fts.ts # Full-text search (per-file wholesale replacement)
│ │ ├── config.ts # Search default config + value bounds
│ │ ├── loadConfig.ts # Env-var overrides + config fingerprint (v1.5.0+)
│ │ ├── types.ts # Type definitions
│ │ ├── utils.ts # Token-overlap scoring
│ │ └── resolvers/ # Multi-language import resolvers
│ │ ├── JsTsResolver.ts
│ │ ├── PythonResolver.ts
│ │ ├── GoResolver.ts
│ │ ├── JavaResolver.ts
│ │ ├── RustResolver.ts
│ │ ├── CppResolver.ts
│ │ └── CSharpResolver.ts
│ ├── stats/ # Statistics aggregation layer (v1.5.0+)
│ │ └── index.ts # Aggregates and renders index/search/health metrics
│ ├── mcp/ # MCP server
│ │ ├── server.ts # MCP server implementation (registers 5 tools)
│ │ ├── main.ts # MCP entry
│ │ └── tools/
│ │ ├── index.ts # Tool registry
│ │ ├── shared.ts # Shared tool logic
│ │ ├── codebaseRetrieval.ts # Code retrieval tool
│ │ ├── listFiles.ts # File structure browsing (v1.5.0+)
│ │ ├── findReferences.ts # Symbol reference lookup (v1.5.0+)
│ │ ├── getSymbolDefinition.ts # Symbol definition lookup (v1.5.0+)
│ │ └── stats.ts # Statistics tool (v1.5.0+)
│ └── utils/ # Utilities
│ ├── logger.ts # Logging system
│ ├── encoding.ts # Encoding detection
│ └── lock.ts # File lock
├── tests/ # Unit + integration tests (28 test files, 156 test cases)
│ ├── chunking/ # SourceAdapter / chunking
│ ├── cli/ # mirrorCommands
│ ├── db/ # migration, outbox, advisory lock, index-version
│ ├── indexer/ # transaction compensation, GC, aborted guard
│ ├── integration/ # real LanceDB end-to-end
│ ├── mcp/ # list-files / find-references / get-symbol-definition / shared / tool registry
│ ├── scanner/ # watcher / index-version
│ ├── search/ # FTS, ChunkContentLoader, Packer, cache, loadConfig
│ ├── stats/ # statistics aggregation
│ └── vectorStore/ # chunk_id de-duplication, sampling validation
├── package.json
└── tsconfig.json
⚙️ 配置参考
环境变量
| 变量 | 必填 | 默认值 | 描述 |
|---|---|---|---|
EMBEDDINGS_API_KEY | ✅ | - | Embedding API 密钥 |
EMBEDDINGS_BASE_URL | ✅ | - | Embedding API URL |
EMBEDDINGS_MODEL | ✅ | - | Embedding 模型名称 |
EMBEDDINGS_MAX_CONCURRENCY | ❌ | 10 | Embedding 并发数 |
EMBEDDINGS_DIMENSIONS | ❌ | 1024 | 向量维度 |
RERANK_API_KEY | ✅ | - | 重排器 API 密钥 |
RERANK_BASE_URL | ✅ | - | 重排器 API URL |
RERANK_MODEL | ✅ | - | 重排器模型名称 |
RERANK_TOP_N | ❌ | 20 | 重排返回数量 |
IGNORE_PATTERNS | ❌ | - | 额外忽略规则 |
搜索参数环境变量覆盖(v1.5.0+)
以下环境变量会覆盖内置默认值;超出范围的值会自动限制在有效区间内。如果只设置了 wVec/wLex 中的一个,另一个会自动设为 1 - x。
| 变量 | 默认值 | 范围 | 描述 |
|---|---|---|---|
CW_SEARCH_WVEC | 0.6 | 0–1 | 向量权重(融合阶段) |
CW_SEARCH_WLEX | 0.4 | 0–1 | 词法权重(与 wVec 互补) |
CW_SEARCH_RERANK_TOP_N | 10 | 5–20 | 重排后保留的结果数 |
CW_SEARCH_MAX_TOTAL_CHARS | 48000 | 20000–80000 | 令牌预算(按字符计,约 12k 个令牌) |
CW_SEARCH_VECTOR_TOP_K | 80 | 40–200 | 向量召回候选数 |
CW_SEARCH_SMART_MAX_K | 8 | 5–15 | Smart TopK 硬性上限 |
CW_SEARCH_IMPORT_FILES_PER_SEED | 3 | 0–5 | 每个种子在 E3 中解析的导入文件数(0 表示禁用跨文件扩展) |
搜索配置参数(内置默认值)
interface SearchConfig {
// === Recall ===
vectorTopK: number; // Vector recall candidates (default 80)
vectorTopM: number; // Vectors kept after dedup (default 60)
ftsTopKFiles: number; // FTS recall file count (default 20)
lexChunksPerFile: number; // Lexical chunks per file (default 2)
lexTotalChunks: number; // Total lexical chunks (default 40)
// === Fusion ===
rrfK0: number; // RRF smoothing constant (default 20)
wVec: number; // Vector weight (default 0.6)
wLex: number; // Lexical weight (default 0.4)
fusedTopM: number; // Candidates fed into rerank after fusion (default 60)
// === Rerank ===
rerankTopN: number; // Results kept after rerank (default 10)
maxRerankChars: number; // Max chars per chunk sent to reranker (default 1000)
maxBreadcrumbChars: number;// Max chars for breadcrumb context (default 250)
headRatio: number; // Head/tail ratio when truncating (default 0.67)
// === Expansion ===
neighborHops: number; // E1 neighbor hops (default 2)
breadcrumbExpandLimit: number; // E2 breadcrumb completions (default 3)
importFilesPerSeed: number; // E3 import files per seed (default 3)
chunksPerImportFile: number; // E3 chunks per import file (default 3)
// === ContextPacker ===
maxSegmentsPerFile: number; // Max non-contiguous segments per file (default 3)
maxTotalChars: number; // Token budget (chars, default 48000)
// === Smart TopK ===
enableSmartTopK: boolean; // Enable smart cutoff (default true)
smartTopScoreRatio: number; // Dynamic threshold ratio (default 0.5)
smartTopScoreDeltaAbs: number; // Max absolute drop from Top1 (default 0.25)
smartMinScore: number; // Absolute floor (default 0.25)
smartMinK: number; // Safe Harbor count (default 2)
smartMaxK: number; // Hard upper bound (default 8)
}
🌍 多语言支持
ContextWeaver 通过 Tree-sitter 原生支持以下语言的 AST 解析:
| 语言 | AST 解析 | 导入解析 | 扩展名 |
|---|---|---|---|
| TypeScript | ✅ | ✅ | .ts、.tsx |
| JavaScript | ✅ | ✅ | .js、.jsx、.mjs、.cjs |
| Python | ✅ | ✅ | .py |
| Go | ✅ | ✅ | .go |
| Java | ✅ | ✅ | .java |
| Rust | ✅ | ✅ | .rs |
| C | ✅ | ✅ | .c、.h |
| C++ | ✅ | ✅ | .cpp、.cc、.cxx、.hpp |
| C# | ✅ | ✅ | .cs |
其他语言会回退到基于行的分块方式,仍可正常建立索引和搜索。
🔄 工作流
索引流程
0. Bootstrap → pending_marks replay + LanceDB schema migration (first launch)
1. Crawler → traverse the filesystem, filter ignored items
2. Processor → read file content, compute hash
3. Splitter → AST parse, semantic chunking (offsets normalized to UTF-16 char domain)
4. Indexer → batch embedding
5. Stages 4-6 pseudo-transaction:
├─ LanceDB write (pre-delete (path, hash) to avoid duplicates → add → clear old versions)
├─ FTS + outbox single SQLite transaction (rolls back LanceDB on failure)
└─ SQLite mark + clear outbox single transaction (outbox kept on failure, replayed next launch)
6. Trailing GC → clean up LanceDB orphan chunks (time budget 5s)
搜索流程
1. Query Parse → parse the query, separate semantics from terms
2. Cache Lookup → return immediately on hit (v1.5.0+, key includes index version + config fingerprint)
3. Hybrid Recall → dual-channel vector + lexical recall
4. RRF Fusion → Reciprocal Rank Fusion
5. Rerank → cross-encoder reranking
6. Smart Cutoff → intelligent score cutoff
7. Graph Expand → neighbor/breadcrumb/import expansion
8. Context Pack → segment merging, token budget
9. Cache Store → write to cache (v1.5.0+)
10. Format Output → format and return to the LLM
📊 性能特性
- 查询缓存:重复查询会命中 LRU 缓存,跳过整个召回/重排/扩展流程(v1.5.0+)
- 增量索引:仅处理已更改的文件;重新建立索引的速度提升 10 倍以上
- 批量嵌入:自适应批次大小,并控制并发
- 速率限制恢复:遇到 429 错误时自动退避,并逐步恢复
- 连接池复用:复用池化的 Tree-sitter 解析器
- 文件索引缓存:GraphExpander 中的文件路径索引按需加载
- 零成本元数据工具:
list-files/find-references/get-symbol-definition不会调用 Embedding API(v1.5.0+)
📈 统计与可观测性(v1.5.0+)
contextweaver stats 会输出三个部分:
- 索引过程:累计索引运行次数、上次索引时间、上次运行快照(新增/修改/删除/未更改/跳过/错误 + 向量索引详情)
- 搜索质量/行为:累计查询次数、缓存命中率、实际计算运行次数,以及各阶段的平均延迟(检索/重排/扩展/打包)和平均召回种子数量
- 健康状态/一致性:文件数量和内容总大小、LanceDB 向量行数、嵌入维度、索引版本、迁移状态、
pending_marks、语言分布
检测到异常迁移状态、pending_marks 积压或缺少向量行时,报告会附上相应的诊断警告和修复命令。--json 输出映射到 StatsReport,供脚本和监控系统使用。
🐛 日志与调试
日志文件位置:~/.contextweaver/logs/app.YYYY-MM-DD.log
设置日志级别:
# Enable debug logging
LOG_LEVEL=debug contextweaver search --information-request "..."
🚨 故障排除(v1.4.0+)
LanceDB 迁移卡住(aborted 状态)
症状:contextweaver index 报错:"LanceDB is in the aborted state, refusing to write to prevent schema pollution."
原因:升级到 v1.4.0 时,旧 LanceDB 索引中的 display_code 与当前 files.content 在抽样时相差超过 1%(通常出现在分块偏移量使用 UTF-8 字节域的旧索引中)。
修复:
contextweaver migrate --reset # Clear the LanceDB chunks table + reset state to done
contextweaver index # Full rebuild (new schema)
你也可以先运行 contextweaver stats,查看诊断警告并确认当前迁移状态和 pending_marks 积压情况。
跨进程迁移竞争
如果 MCP 服务长时间运行,而另一个终端运行 contextweaver index,两个进程会争用迁移。v1.4.0 引入了一个建议锁,并设置 10 分钟的僵尸阈值;迁移期间会自动允许其中一个进程跳过迁移,让另一个进程完成迁移。
如果锁卡住(例如在 kill -9 后),请手动清除:
sqlite3 ~/.contextweaver/<projectId>/index.db \
"DELETE FROM metadata WHERE key = 'lancedb_migration_lock';"
浪费重复嵌入
v1.4.0 通过 pending_marks 发件箱解决了此问题:如果 FTS 写入成功,但 vector_index_hash 标记写入失败,下次启动时会自动重放,避免重复嵌入。
搜索结果未反映最近更改
确认已运行增量索引(或启用 contextweaver watch 以自动执行增量索引)。查询缓存键与索引版本绑定,因此索引更新后旧缓存条目会自动失效,无需手动清除。
📄 许可证
本项目采用 MIT License 许可。
🙏 Acknowledgements
- Tree-sitter - high-performance syntax parsing
- LanceDB - embedded vector database
- MCP - Model Context Protocol
- Source - Source repository
Made with ❤️ for AI-assisted coding
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。