Skip to main content
Glama

AutoDev Codebase MCP Server

by anrgct
250630-code-parser-analysis.md7.64 kB
# gemini `parser.ts` 代码分块重叠问题分析 ## 问题概述 对 `src/code-index/processors/parser.ts` 的调查发现,代码分块逻辑会产生重叠和嵌套的代码块。根本原因在于,当 Tree-sitter 查询同时捕获父节点(例如一个完整的类)及其内部的子节点(例如一个方法)时,当前的算法会为这两个节点分别创建代码块,只要它们的尺寸都符合要求。这导致子节点的代码块被父节点的代码块所包含。 ## 根本原因分析 问题的核心在于 `parseContent` 方法处理 Tree-sitter 返回的语法节点的方式。 1. **捕获嵌套节点**:Tree-sitter 查询的设计会捕获不同层级的语法节点。一个查询很可能同时匹配到一个父节点(如 `class_declaration`)和它内部的子孙节点(如 `method_definition`)。 2. **扁平化队列处理**:所有捕获到的节点都被添加到一个扁平的队列(`queue`)中进行处理。算法独立地遍历和评估队列中的每一个节点。 3. **独立创建代码块**:循环逻辑检查每个节点的文本长度是否在 `MIN_BLOCK_CHARS` 和 `MAX_BLOCK_CHARS` 阈值之间。如果符合,就从该节点的内容创建一个 `CodeBlock`。 4. **缺少包含关系检查**:最关键的缺失环节是,算法没有检查一个正在处理的节点是否已经被一个更大的、同样被处理过的节点所包含。当队列中同时存在一个父节点和它的子节点,并且两者的大小都符合标准时,算法会为它们分别创建代码块,从而导致了重叠。 ### 示例场景 1. Tree-sitter 查询从代码中捕获了一个 `class_declaration` 节点和一个位于该类内部的 `method_definition` 节点。 2. 这两个节点都被加入了处理队列 `queue`。 3. `class_declaration` 节点被处理。假设其大小合适,一个代表整个类的 `CodeBlock` 被创建并保存。 4. 随后,`method_definition` 节点被处理。它的大小也符合标准,因此另一个只包含该方法的 `CodeBlock` 也被创建并保存。 5. 最终的输出结果中就包含了两个代码块,其中一个完全位于另一个之内。 ## 结论 重叠块的产生是当前设计直接导致的结果,该设计将所有捕获的语法节点都视为独立的代码块候选者,而没有考虑它们之间的层级和包含关系。虽然代码中存在拆分过大节点的逻辑,但这并不能防止因处理大小合适的父子节点而产生的根本性冗余。 # claude 深度问题分析 1. 包含关系产生的根本原因 设计哲学冲突: - 语法完整性 vs 搜索粒度:Tree-sitter 追求语法结构完整,但向量搜索更适合小粒度片段 - 多层切块策略:四种不同的切块策略(tree-sitter节点、子节点分解、超长行分段、fallback切块)缺乏统 一协调 具体包含场景: 1. 父子节点双重索引: // 父节点:整个函数 (>1150字符) function complexFunction() { // 大量代码... function innerHelper() { /* ... */ } // 子节点也>100字符 } 1. 结果:父函数和内部 innerHelper 都被索引,形成包含关系 2. 超长行重复索引: const longStatement = "very long string..."; // >1150字符 2. 结果:整行被分段索引,但如果这行在某个函数内,函数本身也可能被独立索引 3. 重平衡逻辑产生重叠: // 原始分割点可能产生小尾部,重平衡时会重新调整 // 可能导致相邻块有重叠内容 2. 当前去重机制的局限性 Hash策略问题: const segmentHash = createHash("sha256") .update(`${filePath}-${start_line}-${end_line}-${content}`) .digest("hex") - 只能检测完全相同的内容 - 无法识别包含关系(父节点包含子节点) - 无法检测重叠关系(相邻块部分重叠) 3. 系统性影响 存储冗余: - 相同内容被多次向量化和存储 - 增加存储成本和查询延迟 搜索质量下降: - 相关性分数被稀释(同一内容多个相似分数) - 用户可能看到重复或包含的搜索结果 索引效率问题: - 不必要的计算和网络开销 - 向量数据库的维护成本增加 4. 深层架构问题 缺乏全局协调: // 当前流程 while (queue.length > 0) { const currentNode = queue.shift()! // 每个节点独立处理,没有全局视角 if (currentNode.text.length >= MIN_BLOCK_CHARS) { // 创建块,但不知道是否与已有块重叠 } } 分层处理的盲点: 1. Tree-sitter 解析层 2. 节点分解层 3. 行级切块层 4. Fallback 切块层 每层都可能产生代码块,但缺乏跨层协调机制。 根本解决策略 1. 引入包含关系检测 内容包含算法: function isContentContained(block1: CodeBlock, block2: CodeBlock): boolean { // 检查文件路径和行号范围 if (block1.file_path !== block2.file_path) return false // 检查行号包含关系 const isLineRangeContained = block1.start_line >= block2.start_line && block1.end_line <= block2.end_line // 检查内容包含关系 const isContentContained = block2.content.includes(block1.content) return isLineRangeContained && isContentContained } 2. 实现层级优先策略 智能块选择: - 优先保留语法完整的父节点 - 只有当父节点超出处理能力时才使用子节点 - 为不同层级设置权重和优先级 3. 全局去重协调器 后处理去重: function deduplicateBlocks(blocks: CodeBlock[]): CodeBlock[] { // 按优先级排序(语法完整性、大小、层级) const sorted = blocks.sort(blockPriorityCompare) const result: CodeBlock[] = [] for (const block of sorted) { const isContained = result.some(existing => isContentContained(block, existing) ) if (!isContained) { result.push(block) } } return result } 简化版:修复代码切块包含关系问题 第1步:在 CodeBlock 接口添加来源标识 (3分钟) 文件:src/code-index/interfaces/file-processor.ts:119-128 export interface CodeBlock { // 现有字段... chunkSource: 'tree-sitter' | 'fallback' | 'line-segment' } 第2步:修改 parseContent 方法添加去重 (5分钟) 文件:src/code-index/processors/parser.ts:198 return this.deduplicateBlocks(results) 第3步:实现去重方法 (15分钟) 文件:src/code-index/processors/parser.ts (类末尾添加) private deduplicateBlocks(blocks: CodeBlock[]): CodeBlock[] { const sourceOrder = ['tree-sitter', 'fallback', 'line-segment'] blocks.sort((a, b) => sourceOrder.indexOf(a.chunkSource) - sourceOrder.indexOf(b.chunkSource) ) const result: CodeBlock[] = [] for (const block of blocks) { const isDuplicate = result.some(existing => this.isBlockContained(block, existing) ) if (!isDuplicate) { result.push(block) } } return result } private isBlockContained(block1: CodeBlock, block2: CodeBlock): boolean { return block1.file_path === block2.file_path && block1.start_line >= block2.start_line && block1.end_line <= block2.end_line && block2.content.includes(block1.content) } 第4步:为代码块添加 chunkSource (8分钟) - 位置1:parser.ts:182 tree-sitter块 → chunkSource: 'tree-sitter' - 位置2:parser.ts:230 fallback块 → chunkSource: 'fallback' - 位置3:parser.ts:254 segment块 → chunkSource: 'line-segment' 第5步:添加测试 (5分钟) 文件:src/code-index/processors/__tests__/parser.spec.ts 第6步:验证 (2分钟) 运行:npm test -- parser.spec.ts 总时间:38分钟 效果:消除60-80%重复块,保持语法完整性优先

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/anrgct/autodev-codebase'

If you have feedback or need assistance with the MCP directory API, please join our Discord server