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

32 KiB
Raw Blame History

深度技术评估报告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精确定位函数体内的第一个字符串表达式
    # 改进后的提取逻辑
    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未更新导致元数据不准确。

影响程度🔴 高(可能误导用户)

改进建议

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 数据结构:

@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格式和位置不同单一提取器无法通用。

影响程度🟡 中(影响多语言支持)

改进建议:语言特定提取器:

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设计层级关系存储
  • 基础的MicroChunkerfor/while/if/try块提取

需要原型验证的部分

  • 🔬 层级化检索权重search_hierarchical中的level_weights={1:1.0, 2:0.8}较主观

    • 验证方法:构建测试集,对比不同权重策略的搜索结果相关性
    • 实验参数
      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行跳过向量化可能遗漏重要的简短逻辑。

影响程度🟡 中(影响搜索覆盖率)

改进建议:智能选择策略

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模板

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)

文档中的实现严重低估了难度

# 文档中的简化实现
def resolve_call_target(self, call_edge, caller_context):
    # 策略1: 本地调用
    # 策略2: 方法调用
    # 策略3: 导入的函数TODO

真实世界的复杂性

# 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__返回值类型

技术债务评估

  • 完整实现需要一个接近 pyrightmypy 级别的类型推断引擎
  • 这些工具历经多年开发,代码量数十万行
  • 不现实在12-15周内从零实现

建议的务实路径

  1. 集成现有工具:调研 jedipyright 的API是否可用
  2. 限定范围V1只处理简单的本地调用和直接导入
  3. 明确边界:对无法解析的调用,标记为"动态"并降低置信度

3.3 性能与效果预测

前提假设名称解析能达到70%+的准确率

指标 预测值 说明
搜索维度 全新维度 支持"影响分析"、"调用链追踪"
开发时间 24-30周 原估算12-15周过于乐观
索引时间增加 +300% 全量静态分析 + 图构建
存储空间 +200-500% 图数据庞大
查询速度 <100ms 简单调用关系查询
影响分析 数秒 全代码库范围的图遍历

名称解析准确率影响

如果准确率只有50%
- 调用图充满噪音和缺失边
- 影响分析结果不可信
- 整个图谱价值大打折扣

如果准确率达到85%+
- 可以支撑实用的影响分析
- 结合LLM语义能回答复杂问题
- 成为代码理解的核心基础设施

3.4 关键设计盲点

盲点1动态语言的静态分析极限

问题描述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增量更新的复杂性

问题描述:当一个核心函数签名改变时,图中所有调用它的边都需要更新。

影响程度🟡 中(影响可用性)

改进建议:变更传播队列

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优先级)

# 原型验证目标
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 - 立即启动Q1Docstring与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混合策略开发

# 创建开发分支
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:建立评估基准

# 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周内

调研1NameResolver技术选型

目标:评估集成现有工具的可行性

方案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周

原型1NameResolver验证原型

# prototypes/name_resolver_validation/

测试项目选择一个中等复杂度的开源项目
  - requests库 (约10k行30+文件) 
  - flask库 (约15k行50+文件)

验证步骤
1. 手动标注100个函数调用关系ground truth
2. 运行原型提取调用图
3. 对比结果计算准确率/召回率

成功标准
- 准确率 > 70%
- 召回率 > 60%
- 假阳性率 < 20%

失败后续
- 如果< 50%准确率暂停图谱项目调研集成方案
- 如果50-70%调整范围只做高置信度的简单调用
- 如果> 70%继续但投入更多资源优化

原型2:层级化检索权重实验

# 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 建议复审周期: 每个阶段结束后进行复盘和调整