Files
Claude-Code-Workflow/codex-lens/docs/DESIGN_EVALUATION_REPORT.md
catlog22 3ffb907a6f feat: add semantic graph design for static code analysis
- Introduced a comprehensive design document for a Code Semantic Graph aimed at enhancing static analysis capabilities.
- Defined the architecture, core components, and implementation steps for analyzing function calls, data flow, and dependencies.
- Included detailed specifications for nodes and edges in the graph, along with database schema for storage.
- Outlined phases for implementation, technical challenges, success metrics, and application scenarios.
2025-12-15 09:47:18 +08:00

1011 lines
32 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 深度技术评估报告Codex-Lens 改进方案
**评估工具**: Gemini 2.5 Pro
**评估日期**: 2025-12-15
**评估范围**: 多层次分词器、静态分析语义图谱、Docstring与LLM混合策略
---
## 执行摘要
三个方案目标清晰,层层递进,从优化现有功能(混合策略)到改进核心机制(分词器),再到引入全新能力(语义图谱),共同构成了一个宏伟但可行的代码理解增强蓝图。
### 核心评分
| 方案 | 完善性评分 | 可行性 | ROI | 技术风险 | 建议优先级 |
|------|-----------|--------|-----|----------|-----------|
| Docstring与LLM混合 | 8.0/10 | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 极高 | ⭐⭐ 低 | **P0 (立即启动)** |
| 多层次分词器 | 8.0/10 | ⭐⭐⭐⭐ 中高 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中 | **P1 (Q2启动)** |
| 静态分析语义图谱 | 6.0/10 | ⭐⭐ 低 | ⭐⭐⭐⭐⭐ 极高* | ⭐⭐⭐⭐⭐ 极高 | **P2 (需原型验证)** |
*注图谱的ROI极高但前提是技术挑战得以克服
---
## 1. Docstring与LLM混合策略评估
### 1.1 完善性评分
| 维度 | 评分 | 说明 |
|------|------|------|
| 架构设计 | 9/10 | 流程清晰,分层策略合理 |
| 实现细节 | 8/10 | 代码示例完整,但提取逻辑可优化 |
| 测试覆盖 | 8/10 | 单元测试和集成测试设计充分 |
| 风险控制 | 7/10 | 识别了主要风险,但降级策略可加强 |
| **平均分** | **8.0/10** | 设计文档非常完整 |
### 1.2 技术可行性:⭐⭐⭐⭐⭐ 高
**可以直接实施的部分**
-`DocstringQuality` 枚举和评分逻辑(基于长度和结构)
-`HybridEnhancer` 的三种策略分支
- ✅ 成本统计和监控模块
- ✅ Python docstring解析Google/NumPy风格
**需要优化的部分**
- ⚠️ **Docstring提取** (`_extract_from_code`):当前基于行号搜索较脆弱
- **改进建议**使用tree-sitter AST精确定位函数体内的第一个字符串表达式
```python
# 改进后的提取逻辑
body_node = func_node.child_by_field_name('body')
if body_node and len(body_node.children) > 0:
first_stmt = body_node.children[0]
if first_stmt.type == 'expression_statement':
expr = first_stmt.children[0]
if expr.type in ['string', 'string_literal']:
return extract_string_content(expr)
```
**需要原型验证的模块**
- 🔬 **质量评估器准确性**在3-5个真实项目上验证评估准确率
- 目标与人工标注对比准确率达到85%+
- 方法收集100个docstring样本人工标注质量等级调整阈值
### 1.3 性能与效果预测
| 指标 | 预测值 | 依据 |
|------|--------|------|
| 搜索质量提升 | +15-25% | docstring保留作者意图准确性接近100% |
| 成本降低 | 40-60% | 高质量docstring占比越高节省越多 |
| 索引速度提升 | +30-50% | 跳过完整LLM生成步骤 |
| 元数据准确率 | 95%+ | 使用docstring的符号达到近完美准确性 |
**成本计算示例**1000个函数
```
假设docstring分布High 30% | Medium 40% | Low 30%
纯LLM模式1000 × 100% = 1000 units
混合模式300×20% + 400×60% + 300×100% = 600 units
节省40%
如果High质量达到50%
混合模式500×20% + 300×60% + 200×100% = 480 units
节省52%
```
### 1.4 关键设计盲点
#### 盲点1Docstring与代码不同步
**问题描述**代码已修改docstring未更新导致元数据不准确。
**影响程度**:🔴 高(可能误导用户)
**改进建议**
```python
class DocstringFreshnessChecker:
def check_parameter_consistency(self, signature, docstring_params):
"""检查参数列表是否匹配"""
actual_params = extract_params_from_signature(signature)
documented_params = set(docstring_params.keys())
missing = actual_params - documented_params
extra = documented_params - actual_params
if missing or extra:
return QualityDowngrade(
from_level='HIGH',
to_level='MEDIUM',
reason=f'Parameter mismatch: missing={missing}, extra={extra}'
)
def check_return_type_consistency(self, signature, docstring_returns):
"""检查返回值类型注解是否与docstring匹配"""
if has_return_annotation(signature) and docstring_returns:
annotation = get_return_annotation(signature)
# 简单的字符串匹配检查
if annotation.lower() not in docstring_returns.lower():
return QualityWarning('Return type mismatch')
```
#### 盲点2结构化信息丢失
**问题描述**`_use_docstring_with_llm_keywords` 只使用了summary丢失了参数、返回值、示例等信息。
**影响程度**:🟡 中(影响搜索结果展示的丰富性)
**改进建议**:扩展 `SemanticMetadata` 数据结构:
```python
@dataclass
class EnhancedSemanticMetadata(SemanticMetadata):
"""扩展的语义元数据"""
parameters: Optional[Dict[str, str]] = None # {param_name: description}
returns: Optional[str] = None
raises: Optional[List[str]] = None
examples: Optional[str] = None
# 搜索结果展示时可以显示更丰富的信息
```
#### 盲点3多语言docstring提取差异
**问题描述**不同语言的docstring格式和位置不同单一提取器无法通用。
**影响程度**:🟡 中(影响多语言支持)
**改进建议**:语言特定提取器:
```python
class LanguageSpecificExtractor:
EXTRACTORS = {
'python': PythonDocstringExtractor,
'javascript': JSDocExtractor,
'typescript': TSDocExtractor,
'java': JavadocExtractor,
}
def extract(self, language, code, symbol):
extractor_class = self.EXTRACTORS.get(language, GenericExtractor)
return extractor_class().extract(code, symbol)
class JSDocExtractor:
"""JavaScript/TypeScript JSDoc在函数定义之前"""
def extract(self, code, symbol):
lines = code.splitlines()
start_line = symbol.range[0] - 1
# 向上查找 /** ... */
for i in range(start_line - 1, max(0, start_line - 20), -1):
if '*/' in lines[i]:
return self._extract_jsdoc_block(lines, i)
```
### 1.5 时间估算校准
**原估算**6-8周
**校准后**:✅ 6-8周合理
**分阶段时间表**
- Week 1-2: 核心`DocstringExtractor` + `QualityEvaluator`
- Week 3-4: `HybridEnhancer` + 三种策略
- Week 5-6: 真实项目测试 + 评估器调优
- Week 7-8: 多语言支持 + CLI集成
---
## 2. 多层次分词器评估
### 2.1 完善性评分
| 维度 | 评分 | 说明 |
|------|------|------|
| 架构设计 | 9/10 | 分层思想清晰,数据结构设计合理 |
| 实现细节 | 8/10 | AST遍历逻辑详细但边界情况处理可加强 |
| 测试覆盖 | 7/10 | 单元测试设计充分,缺少大规模集成测试 |
| 风险控制 | 8/10 | 提出了降级策略和性能优化方案 |
| **平均分** | **8.0/10** | 技术方案完整且可行 |
### 2.2 技术可行性:⭐⭐⭐⭐ 中高
**可以直接实施的部分**
- ✅ `MacroChunker`(符号级分词)- 复用现有`code_extractor`
- ✅ 数据库schema设计层级关系存储
- ✅ 基础的`MicroChunker`for/while/if/try块提取
**需要原型验证的部分**
- 🔬 **层级化检索权重**`search_hierarchical`中的`level_weights={1:1.0, 2:0.8}`较主观
- **验证方法**:构建测试集,对比不同权重策略的搜索结果相关性
- **实验参数**
```python
weight_strategies = [
{'macro': 1.0, 'micro': 0.5}, # 强调宏观
{'macro': 1.0, 'micro': 0.8}, # 原设计
{'macro': 1.0, 'micro': 1.0}, # 平等对待
{'macro': 0.8, 'micro': 1.0}, # 强调细节
]
```
- 🔬 **逻辑块粒度控制**:何时需要二次划分?当前阈值`max_lines=50`需验证
- **数据收集**:统计真实项目中函数长度分布
- **A/B测试**对比阈值30/50/100的搜索效果
**技术挑战**
1. **上下文冗余问题**父chunk和子chunk的摘要如何避免重复
- **解决方案**子chunk的LLM prompt应强调**角色定位**
```
# Bad Prompt
"Summarize this for loop"
# Good Prompt
"This for loop is part of function authenticate_user().
Describe its specific role in the authentication process."
```
2. **结果聚合与展示**搜索同时匹配父子chunk时如何展示
- **UI设计建议**
```
[Match 1] ▼ function authenticate_user() - Score: 0.92
├─ Line 45-52: Password validation loop - Score: 0.88
└─ Line 67-75: Token generation block - Score: 0.85
[Match 2] function login_handler() - Score: 0.81
```
### 2.3 性能与效果预测
| 指标 | 预测值 | 说明 |
|------|--------|------|
| 搜索质量提升 | +30-40% | 大函数中精确定位逻辑块 |
| 索引时间增加 | +50-100% | AST深度遍历 + 更多LLM调用 |
| 存储空间增加 | +40-80% | 取决于micro-chunk数量 |
| 检索速度 | ±5% | 精确目标可能更快 |
**存储空间计算**
```
假设平均每个文件10个函数
每个函数生成1个macro chunk + 平均3个micro chunks
总chunk数10 × (1 + 3) = 40 chunks/文件
相比现有10 chunks/文件增长4倍
但使用选择性向量化只对50%的micro chunks生成向量
向量索引增长10 × (1 + 1.5) = 2.5倍
```
### 2.4 关键设计盲点
#### 盲点1选择性向量化的风险
**问题描述**:基于行数(<5行跳过向量化可能遗漏重要的简短逻辑。
**影响程度**:🟡 中(影响搜索覆盖率)
**改进建议**:智能选择策略
```python
class IntelligentVectorizationSelector:
def should_vectorize(self, chunk: HierarchicalChunk) -> bool:
# 规则1: Level 1总是向量化
if chunk.metadata.level == 1:
return True
# 规则2: 复杂度判断(圈复杂度)
complexity = calculate_cyclomatic_complexity(chunk.content)
if complexity >= 3: # 有多个分支
return True
# 规则3: 关键词判断
critical_keywords = ['critical', 'security', 'auth', 'payment']
if any(kw in chunk.content.lower() for kw in critical_keywords):
return True
# 规则4: LLM快速判断重要性
if chunk.metadata.level == 2 and len(chunk.content) < 5:
importance = quick_llm_importance_check(chunk)
return importance > 0.7
return False
```
#### 盲点2LLM增强的上下文设计不足
**问题描述**文档中micro chunk的prompt未充分利用父chunk信息。
**影响程度**:🟡 中(影响元数据质量)
**改进建议**上下文感知的prompt模板
```python
MICRO_CHUNK_PROMPT = """
PARENT CONTEXT:
- Function: {parent_symbol_name}
- Purpose: {parent_purpose}
- Summary: {parent_summary}
THIS CODE BLOCK ({chunk_type} at lines {start_line}-{end_line}):
```{language}
{chunk_content}
```
TASK: Describe this block's SPECIFIC ROLE in the parent function.
Focus on:
- What does it do within the larger logic flow?
- What intermediate result does it produce?
- How does it contribute to the parent function's goal?
OUTPUT: 1 sentence describing its role + 3-5 keywords
"""
```
#### 盲点3增量更新的复杂性
**问题描述**:文件修改后,如何高效地重新索引?
**影响程度**:🟡 中(影响实用性)
**改进建议**:智能增量更新
```python
class IncrementalHierarchicalIndexer:
def update_file(self, file_path: Path):
new_content = file_path.read_text()
new_hash = hashlib.sha256(new_content.encode()).hexdigest()
# 检查文件级别的变化
old_hash = self.get_file_hash(file_path)
if new_hash == old_hash:
return # 文件未变化
# 提取新的chunks
new_chunks = self.chunker.chunk_file(new_content, file_path)
# 与旧chunks对比基于内容hash
old_chunks = self.get_chunks_by_file(file_path)
for new_chunk in new_chunks:
new_chunk_hash = hash_chunk_content(new_chunk)
matching_old = find_by_hash(old_chunks, new_chunk_hash)
if matching_old:
# chunk内容未变保留旧的embedding和metadata
new_chunk.embedding = matching_old.embedding
new_chunk.metadata = matching_old.metadata
else:
# 新chunk或内容已变需要重新处理
self.process_new_chunk(new_chunk)
# 删除不再存在的旧chunks
self.delete_obsolete_chunks(old_chunks, new_chunks)
```
### 2.5 时间估算校准
**原估算**7-10周
**校准后**:✅ 7-10周合理
**关键里程碑**
- Week 3: 完成数据库迁移和基础chunker
- Week 6: 完成层级化检索逻辑
- Week 8: 完成LLM增强集成
- Week 10: 性能优化和发布
---
## 3. 静态分析语义图谱评估
### 3.1 完善性评分
| 维度 | 评分 | 说明 |
|------|------|------|
| 架构设计 | 8/10 | 图模型设计合理,但实现路径模糊 |
| 实现细节 | 6/10 | 核心难点(名称解析)实现过于简化 |
| 测试覆盖 | 5/10 | 测试策略不足,缺少复杂场景覆盖 |
| 风险控制 | 5/10 | 对动态语言的限制和性能瓶颈认识不足 |
| **平均分** | **6.0/10** | 愿景宏大但技术风险极高 |
### 3.2 技术可行性:⭐⭐ 低(短期完全实现)
**阿喀琉斯之踵:名称解析 (`NameResolver`)**
文档中的实现**严重低估了难度**
```python
# 文档中的简化实现
def resolve_call_target(self, call_edge, caller_context):
# 策略1: 本地调用
# 策略2: 方法调用
# 策略3: 导入的函数TODO
```
**真实世界的复杂性**
```python
# Case 1: 复杂导入
from package.submodule import func as f
from package import * # 星号导入
import package.module # 模块导入
result = f(x) # 需要解析f -> package.submodule.func
# Case 2: 动态调用
handler = getattr(module, 'process_' + request_type)
handler() # 静态分析无法确定目标
# Case 3: 装饰器包装
@cache
@retry(max_attempts=3)
def expensive_operation():
pass
# 调用时需要解析到原始函数,而非装饰器
# Case 4: 类型变量
processor: Callable = get_processor(config)
processor() # 需要类型推断
# Case 5: 上下文管理器
with get_connection() as conn:
conn.execute(...) # 需要理解__enter__返回值类型
```
**技术债务评估**
- 完整实现需要一个接近 `pyright` 或 `mypy` 级别的类型推断引擎
- 这些工具历经多年开发,代码量数十万行
- 不现实在12-15周内从零实现
**建议的务实路径**
1. **集成现有工具**:调研 `jedi` 或 `pyright` 的API是否可用
2. **限定范围**V1只处理简单的本地调用和直接导入
3. **明确边界**:对无法解析的调用,标记为"动态"并降低置信度
### 3.3 性能与效果预测
**前提假设**名称解析能达到70%+的准确率
| 指标 | 预测值 | 说明 |
|------|--------|------|
| 搜索维度 | 全新维度 | 支持"影响分析"、"调用链追踪" |
| 开发时间 | **24-30周** | 原估算12-15周过于乐观 |
| 索引时间增加 | +300% | 全量静态分析 + 图构建 |
| 存储空间 | +200-500% | 图数据庞大 |
| 查询速度 | <100ms | 简单调用关系查询 |
| 影响分析 | 数秒 | 全代码库范围的图遍历 |
**名称解析准确率影响**
```
如果准确率只有50%
- 调用图充满噪音和缺失边
- 影响分析结果不可信
- 整个图谱价值大打折扣
如果准确率达到85%+
- 可以支撑实用的影响分析
- 结合LLM语义能回答复杂问题
- 成为代码理解的核心基础设施
```
### 3.4 关键设计盲点
#### 盲点1动态语言的静态分析极限
**问题描述**Python高度动态大量调用关系在运行时才确定。
**影响程度**:🔴 极高(根本性限制)
**改进建议**:混合静态+运行时分析
```python
class HybridCallGraphBuilder:
def build_graph(self, codebase):
# 阶段1: 静态分析(确定性的调用)
static_graph = self.static_analyzer.build_call_graph(codebase)
# 阶段2: 运行时数据补充(可选)
if self.config.enable_runtime_profiling:
runtime_data = self.collect_runtime_traces()
static_graph.merge(runtime_data, confidence=0.7)
# 阶段3: LLM推断低置信度
for dynamic_call in static_graph.get_unresolved_calls():
possible_targets = self.llm_infer_call_target(dynamic_call)
static_graph.add_edges(dynamic_call, possible_targets, confidence=0.5)
return static_graph
```
**运行时数据来源**
- 集成现有APM工具如Sentry, DataDog
- 代码覆盖率报告如coverage.py
- 自定义的轻量级tracer
#### 盲点2跨语言支持的工程量
**问题描述**:文档轻描淡写"支持JS/Java",实际上需要为每种语言重写整个分析引擎。
**影响程度**:🔴 极高(时间成本巨大)
**改进建议**:分阶段语言支持
```
V1 (6个月): 只支持Python
- 专注于将Python分析做到80%+准确率
- 建立完整的图存储、查询、LLM增强基础设施
V2 (再6个月): 添加JavaScript/TypeScript
- 复用图基础设施
- 开发JS特定的AST分析器
V3 (再6个月): 添加Java
- Java的静态类型使分析更容易
- 但生态复杂Maven, Gradle, Spring框架
```
#### 盲点3增量更新的复杂性
**问题描述**:当一个核心函数签名改变时,图中所有调用它的边都需要更新。
**影响程度**:🟡 中(影响可用性)
**改进建议**:变更传播队列
```python
class GraphIncrementalUpdater:
def update_function(self, function_id: str, new_code: str):
old_signature = self.graph.get_node(function_id).signature
new_signature = extract_signature(new_code)
if old_signature != new_signature:
# 签名变化,需要级联更新
affected_edges = self.graph.get_edges_targeting(function_id)
for edge in affected_edges:
# 标记为待更新
self.update_queue.add(UpdateTask(
edge_id=edge.edge_id,
reason='target_signature_changed',
priority='high'
))
# 重新分析函数内部的调用
new_callees = self.analyzer.extract_calls(new_code)
self.graph.update_edges_from(function_id, new_callees)
# 后台任务LLM重新生成语义
self.llm_queue.add(LLMTask(node_id=function_id))
```
### 3.5 时间估算校准
**原估算**12-15周
**校准后**:🔴 **24-30周到达可用的V1**
**现实的里程碑**
```
Phase 0: 前置验证 (4-6周)
- NameResolver原型开发和测试
- 决策点:如果准确率<70%,暂停项目或调整范围
Phase 1: 基础图构建 (8周)
- 简单的调用图提取(本地调用+直接导入)
- SQLite图存储和基础查询
Phase 2: LLM语义增强 (4周)
- 为节点和边生成语义描述
- 批量处理优化
Phase 3: 高级查询 (6周)
- 影响分析
- 调用链追踪
- 数据流基础支持
Phase 4: 优化与稳定 (6周)
- 性能优化
- 增量更新
- 大规模测试
```
### 3.6 必须的前置验证
**NameResolver原型验证 (P0优先级)**
```python
# 原型验证目标
class NameResolverPrototype:
"""
目标在一个真实的中等复杂度Python项目~10k行代码20-30个文件上测试
成功标准:
1. 本地函数调用解析准确率 > 95%
2. 跨文件导入解析准确率 > 80%
3. 类方法调用解析准确率 > 75%
4. 整体准确率 > 70%
如果失败:
- 调研集成jedi/pyright的可行性
- 或调整图谱范围(只做本地调用图)
- 或推迟项目,投入更多资源
"""
def validate(self, test_project_path: Path):
# 手动标注ground truth
ground_truth = self.load_manual_annotations(test_project_path)
# 运行原型
resolved_calls = self.resolve_all_calls(test_project_path)
# 计算准确率
metrics = self.calculate_metrics(resolved_calls, ground_truth)
return ValidationReport(
accuracy=metrics.accuracy,
precision=metrics.precision,
recall=metrics.recall,
false_positives=metrics.fp_examples,
false_negatives=metrics.fn_examples,
)
```
---
## 4. 方案间协同分析
### 4.1 依赖关系图
```
Docstring混合策略 ──(提供高质量元数据)──> 语义图谱
│ │
│ │
(共享docstring (共享AST分析)
解析能力) │
│ │
v v
多层次分词器 ────(提供细粒度节点)────> 语义图谱
```
**关键依赖**
1. **图谱依赖混合策略**高质量的节点摘要和purpose标签来自混合策略
2. **图谱和分词器共享AST能力**:可以开发一个统一的`ASTAnalyzer`模块
3. **分词器增强图谱**micro chunks可以作为图谱的更细粒度节点
### 4.2 协同效应1+1+1 > 3
**场景1精确代码导航**
```
用户查询: "Find the password hashing logic in authentication"
Step 1: 向量搜索(分词器)
-> 定位到 authenticate_user() 函数的 micro chunk (lines 45-52)
Step 2: 图谱上下文
-> 显示该函数的所有调用者login_api(), register_api()
-> 追踪数据流password变量的传递路径
Step 3: 语义元数据(混合策略)
-> 展示函数的docstring"使用bcrypt进行密码哈希salt轮数为12"
-> 关联的security标签和注意事项
```
**场景2影响分析**
```
用户问题: "If I change User.email validation, what breaks?"
Step 1: 图谱查询
-> 找到所有调用 User.email setter的函数
-> 构建影响树validate_email() -> update_profile() -> profile_api()
Step 2: 分词器展示
-> 对每个受影响的函数展示具体的调用位置micro chunk
-> 用户可以快速review每个调用点的上下文
Step 3: 混合策略提供摘要
-> 每个函数的docstring说明其业务意图
-> LLM生成的"此函数在email验证中的角色"描述
```
### 4.3 组合实施的量化效果预测
**假设场景**一个10万行的Python代码库
| 指标 | 当前 | +混合策略 | +分词器 | +图谱(全部) |
|------|------|----------|---------|------------|
| 搜索准确率 | 70% | 80% (+10%) | 92% (+12%) | 95% (+3%) |
| 索引时间 | 10min | 7min (-30%) | 12min (+20%) | 50min (+300%) |
| 存储空间 | 1GB | 0.8GB (-20%) | 2GB (+100%) | 6GB (+200%) |
| 查询延迟 | 50ms | 50ms | 60ms (+20%) | 100ms (+100%) |
| 能力维度 | 搜索 | 搜索 | 搜索 | 搜索+理解+分析 |
**关键洞察**
- 混合策略是"降本增效",提升质量同时降低成本
- 分词器是"增效",显著提升搜索精度,但有成本
- 图谱是"开新维度",不只是优化,而是全新能力
---
## 5. 优先级重排与实施路线图
### 5.1 重排后的优先级
**P0 - 立即启动Q1**Docstring与LLM混合策略
- ✅ ROI最高成本-40%,质量+15%
- ✅ 风险最低
- ✅ 6-8周可见效
- ✅ 为后续方案铺路(提供高质量元数据)
**P1 - Q2启动**:多层次分词器
- ✅ 投入产出比高
- ✅ 技术可行性已验证
- ✅ 7-10周实现核心功能
- ⚠️ 依赖P0完成后的稳定基础
**P2 - 需原型验证后决定**:静态分析语义图谱
- 🔬 **前置条件**NameResolver原型验证通过4-6周
- ⚠️ 如果验证失败,调整范围或推迟
- ✅ 如果验证成功Q3-Q4启动正式开发24-30周
### 5.2 详细实施路线图
```
Q1 2024 (Week 1-13)
├─ Week 1-8: 实施Docstring混合策略
│ ├─ Week 1-2: DocstringExtractor + QualityEvaluator
│ ├─ Week 3-4: HybridEnhancer核心逻辑
│ ├─ Week 5-6: 真实项目测试 + 调优
│ └─ Week 7-8: 多语言支持 + 发布
├─ Week 4-10: (并行) NameResolver原型验证
│ ├─ Week 4-6: 原型开发
│ ├─ Week 7-8: 在3个真实项目上测试
│ ├─ Week 9-10: 评估报告 + 决策
│ └─ 决策点:图谱项目是否继续?
└─ Week 9-13: 分词器Phase 0 (准备工作)
├─ 数据库设计和迁移脚本
├─ 基础AST分析模块
└─ 测试环境搭建
Q2 2024 (Week 14-26)
├─ Week 14-23: 实施多层次分词器
│ ├─ Week 14-16: MacroChunker + MicroChunker
│ ├─ Week 17-19: HierarchicalVectorStore
│ ├─ Week 20-21: LLM分层增强集成
│ └─ Week 22-23: 性能优化 + 发布
└─ Week 24-26: 评估和规划
├─ 收集用户反馈
├─ 调整图谱计划(如果原型通过)
└─ 制定Q3-Q4详细计划
Q3-Q4 2024 (Week 27-52) - 条件性启动图谱
├─ 如果NameResolver原型通过:
│ ├─ Week 27-34: 基础调用图构建
│ ├─ Week 35-38: LLM语义增强
│ ├─ Week 39-44: 高级查询功能
│ └─ Week 45-52: 优化与稳定
└─ 如果原型失败:
├─ 调研集成现有工具jedi/pyright
├─ 或调整范围(只做本地调用图)
└─ 或推迟到2025投入更多资源
```
---
## 6. 具体行动建议
### 6.1 立即可执行(本周)
**行动1**启动Docstring混合策略开发
```bash
# 创建开发分支
git checkout -b feature/docstring-hybrid-strategy
# 目录结构
src/codexlens/semantic/
├── docstring_extractor.py # NEW
├── quality_evaluator.py # NEW
├── hybrid_enhancer.py # NEW (替代llm_enhancer.py)
└── llm_enhancer.py # 保留作为后端
# 第一周任务
- [ ] 实现PythonDocstringExtractor (基于tree-sitter)
- [ ] 实现DocstringQuality评估器
- [ ] 编写单元测试(覆盖率>80%
```
**行动2**:建立评估基准
```python
# scripts/evaluate_docstring_quality.py
"""
在3个真实项目上评估docstring质量分布
目标项目:
1. 内部项目A (高质量docstring, Google style)
2. 开源项目B (中等质量docstring, NumPy style)
3. 遗留代码C (低质量或无docstring)
输出:
- 质量分布统计HIGH/MEDIUM/LOW/MISSING百分比
- 评估器准确率vs 人工标注)
- 潜在节省成本估算
"""
```
### 6.2 需要调研2周内
**调研1**NameResolver技术选型
```
目标:评估集成现有工具的可行性
方案A集成jedi
- API文档https://jedi.readthedocs.io/
- 评估点:能否获取函数调用的目标定义?
- 实验写一个100行的测试脚本调用jedi API
方案B集成pyright (通过CLI)
- pyright --verifytypes可以输出类型信息
- 评估点:能否解析其输出构建调用图?
- 实验在测试项目上运行pyright分析输出
方案C自研退路
- 只处理简单场景(本地调用+直接导入)
- 明确标注"不支持复杂导入"
```
**调研2**:图数据库选型
```
目标对比SQLite vs Neo4j vs NetworkX
测试场景:
- 1000个节点5000条边的调用图
- 查询1: 找到函数A的所有调用者广度优先深度3
- 查询2: 找到函数A和函数B之间的最短路径
- 查询3: 找到所有孤立的节点(未被调用的函数)
评估指标:
- 查询性能(<100ms?
- 存储空间
- 维护复杂度
- 是否支持事务
```
### 6.3 必须做的原型验证4-6周
**原型1**NameResolver验证原型
```python
# prototypes/name_resolver_validation/
测试项目:选择一个中等复杂度的开源项目
- requests库 (约10k行30+文件) 或
- flask库 (约15k行50+文件)
验证步骤:
1. 手动标注100个函数调用关系ground truth
2. 运行原型,提取调用图
3. 对比结果,计算准确率/召回率
成功标准:
- 准确率 > 70%
- 召回率 > 60%
- 假阳性率 < 20%
失败后续:
- 如果< 50%准确率:暂停图谱项目,调研集成方案
- 如果50-70%:调整范围,只做高置信度的简单调用
- 如果> 70%:继续,但投入更多资源优化
```
**原型2**:层级化检索权重实验
```python
# prototypes/hierarchical_search_weights/
实验设计:
1. 手动构建一个包含10个函数的测试代码库
2. 为每个函数创建macro chunk + micro chunks
3. 准备20个搜索查询人工标注期望结果
4. 测试不同的权重策略:
- Strategy 1: {macro: 1.0, micro: 0.5}
- Strategy 2: {macro: 1.0, micro: 0.8}
- Strategy 3: {macro: 1.0, micro: 1.0}
- Strategy 4: {macro: 0.8, micro: 1.0}
评估指标:
- NDCG@10 (Normalized Discounted Cumulative Gain)
- MRR (Mean Reciprocal Rank)
- User preference survey (if possible)
输出:
- 最佳权重策略
- 权重参数的敏感性分析
```
---
## 7. 风险评估与缓解
### 7.1 高风险项
| 风险 | 方案 | 影响 | 概率 | 缓解措施 |
|------|------|------|------|----------|
| NameResolver准确率<50% | 图谱 | 🔴 极高 | 40% | 前置原型验证准备集成jedi的备选方案 |
| 分词器micro chunks过多 | 分词器 | 🟡 中 | 30% | 自适应阈值;选择性向量化 |
| LLM成本超预算 | 全部 | 🟡 中 | 25% | 混合策略优先;批量处理优化 |
| 图谱增量更新复杂度 | 图谱 | 🟡 中 | 50% | V1不支持增量全量重建V2再优化 |
### 7.2 缓解策略矩阵
**对于NameResolver风险**
```
Plan A (理想): 自研达到70%+准确率
- 投入: 1名高级工程师 × 6周
- 成功率: 40%
Plan B (务实): 集成jedi或pyright
- 投入: 2周调研 + 4周集成
- 成功率: 70%
- 限制: 依赖外部工具,可能有版本兼容问题
Plan C (保底): 限定范围(只做本地调用图)
- 投入: 4周
- 成功率: 95%
- 限制: 功能大幅缩水,但仍有价值
```
**对于成本控制风险**
```
成本监控dashboard:
- 实时显示LLM调用次数和费用
- 按策略分类full-gen / refine / keywords-only
- 告警阈值:日费用>$50 或 月费用>$1000
成本优化开关:
- 在配置中设置每日预算上限
- 超过后自动降级跳过micro chunks的LLM增强
- 批量处理大小动态调整
```
---
## 8. 总结与最终建议
### 8.1 核心结论
1. **Docstring混合策略**:✅ **立即启动**
- 完善性最高8.0/10
- 技术风险最低
- ROI最高成本-40%,质量+15%
- 6-8周可见效
2. **多层次分词器**:✅ **Q2启动**
- 完善性高8.0/10
- 技术可行性已验证
- 搜索质量提升30%+
- 需在P0完成后启动
3. **静态分析语义图谱**:⚠️ **需原型验证**
- 完善性中等6.0/10
- 技术风险极高(名称解析难度)
- 潜力巨大(全新能力维度)
- **必须先验证NameResolver可行性**
### 8.2 最终建议的实施顺序
```
Stage 1 (立即): Docstring混合策略 (6-8周)
├─ 快速降低成本
├─ 提升元数据质量
└─ 为后续打基础
Stage 2 (并行): NameResolver原型 (4-6周)
├─ 决定图谱项目的命运
├─ 如果失败,调整或推迟
└─ 如果成功Q3正式启动
Stage 3 (Q2): 多层次分词器 (7-10周)
├─ 显著提升搜索精度
├─ 为图谱提供细粒度节点
└─ 用户体验质的飞跃
Stage 4 (Q3-Q4, 条件性): 静态分析图谱 (24-30周)
├─ 如果Stage 2成功则启动
├─ 从简单做起(本地调用图)
└─ 逐步增强跨文件、LLM语义
```
### 8.3 成功的关键
1. **风险前置**:不要盲目启动图谱,必须先验证核心技术假设
2. **迭代交付**:每个方案都要尽早发布可用版本,收集反馈
3. **成本控制**实时监控LLM费用设置预算上限和降级机制
4. **数据驱动**:用真实项目数据验证假设,不要依赖理论推导
5. **务实落地**完美是优秀的敌人先做到70分可用再优化到90分
### 8.4 量化预期(全部实施后)
**假设**:所有三个方案都成功实施
| 指标 | 当前基线 | 预期目标 | 提升幅度 |
|------|---------|---------|---------|
| 搜索准确率 | 70% | **95%** | +25% |
| 搜索覆盖率 | 80% | **98%** | +18% |
| 元数据质量 | 75% | **92%** | +17% |
| LLM成本 | $1000/月 | **$600/月** | -40% |
| 索引速度 | 10min | **15min** | +50% (可接受) |
| 新能力 | 搜索 | **搜索+理解+分析** | 质的飞跃 |
---
**报告完成时间**: 81.2秒
**评估工具**: Gemini 2.5 Pro
**建议复审周期**: 每个阶段结束后进行复盘和调整