Skip to content

Latest commit

 

History

History
900 lines (661 loc) · 33.6 KB

File metadata and controls

900 lines (661 loc) · 33.6 KB

RepoLens 演进日志

项目背景

RepoLens 是一个 AI 驱动的 Python 仓库分析平台,由个人开发者独立完成, 采用 Vibe Coding 模式从零到一构建。

作为个人 AI 应用开发实践项目,RepoLens 旨在探索「AI 辅助编程」的全流程: 从架构设计、代码实现、测试验证,到文档编写、代码审查、架构演进, 每一行代码均由个人完成,AI 作为协作伙伴参与整个开发流程。

项目基于 FastAPI 异步后端 + React SPA 前端 + SQLite 持久化 + OpenAI 兼容 LLM, 后续逐步从单一流水线架构演进为 Multi-Agent 分析平台。


Phase 0 — RepoLens MVP

  • 时间:2026-05-31
  • 版本:v1.0.0
  • Commit29a1772

目标

实现最小可用的 Python 仓库分析平台:输入 GitHub URL → 自动克隆 → 多维度分析 → HTML 报告。

核心能力

能力 实现方式
Git 活动分析 git rev-list + git shortlog + git log 子进程,统计提交数、贡献者、活跃趋势
静态代码分析 Pylint(lint 检查 + 评分)+ Radon(圈复杂度),3 个子进程并行
README 意图分析 LLM 推理(OpenAI 兼容 API),含启发式回退降级
HTML 报告生成 自包含 HTML,含可折叠表格、SVG 趋势图、评分维度柱状图
React 前端 Vite + TypeScript + Zustand + Tailwind + shadcn/ui
SQLite 持久化 aiosqlite WAL 模式,任务状态 + 报告 + LLM 缓存三张表

主要技术栈

后端:  Python 3.12+ / FastAPI / Pydantic v2 / Uvicorn
AI:    OpenAI Compatible API (response_format=json_object + 0.3 温度)
代码:  Pylint + Radon (subprocess + asyncio.to_thread)
版本:  Git 子进程 (rev-list / shortlog / log / log --name-only)
前端:  React 18 + TypeScript 5 + Vite 6 + Zustand + Tailwind + shadcn/ui
存储:  SQLite (aiosqlite, WAL 模式)
测试:  pytest-asyncio 集成测试

设计决策

  1. 异步优先:全链路 asyncio,后台任务用 asyncio.create_task 而非 Celery——项目单机场景不需要分布式队列
  2. 无 ORM:2 张表用原生 SQL + Pydantic 序列化,映射层样板代码量超过 SQL 本身
  3. 分析器独立:三个分析器通过 asyncio.gather(return_exceptions=True) 并行,单点失败不崩溃
  4. 优雅降级链:子进程 → 分析器 → 编排器 → Reporter,共 7 层降级路径
  5. 双层超时:分析器级 wait_for(120-180s)+ 流水线级 wait_for(600s)
  6. LLM 缓存sha256(repo_url|readme_hash|model) 三维键,避免重复分析时重复调用

收获

  • asyncio.to_thread(subprocess.run) 是在所有平台默认事件循环下运行的唯一可靠方案, Windows ProactorEventLoop 不支持 create_subprocess_exec
  • return_exceptions=Trueasyncio.gather 并行调度的关键参数——不用它会导致一个子任务失败就全部取消
  • SQLite WAL 模式对「前端高频轮询 + 后台低频写入」负载类型非常适配
  • Pydantic v2 的 model_dump_json() 直接序列化到 SQLite TEXT 字段,零映射成本

Phase 1 — 数据可信度治理与 MVP 修复

  • 时间:2026-05-31
  • 版本:v1.1
  • Commitsf028ae4d3d339ad19bbc6

问题发现

MVP 发布后,通过实际分析 tiangolo/fastapi 仓库发现多个数据异常:

异常 表现 根因
Pylint 评分始终 N/A 页面显示 N/A _PYLINT_SCORE_RE 正则定义了但从未被调用
Git 提交数偏少 L1(git原生命令) 7203 提交 vs L2(GitAnalyzer) 仅 1 提交 早期用了 --depth 1 浅克隆
时间显示 UTC 18:00 显示为 10:00 datetime.utcnow() 未转本地时间
控制台无日志 uvicorn 运行但看不到分析进度 main.py 缺少 logging.basicConfig()
pylint 找不到 pylint: command not found subprocess.run(["pylint"]) 依赖 PATH,Windows reload 模式下 PATH 不完整
pylint 命令超长 1118 个文件路径拼接超 32k Windows 命令行长度限制

修复内容

数据可信度修复

  • 移除 --depth 1 浅克隆,改为完整克隆
  • 增加浅克隆检测 git rev-parse --is-shallow-repository + 自动 git fetch --unshallow
  • 新增 verify_data.py 数据对账脚本(对比 git 原生命令基准值与分析器输出)
  • 删除冗余 reconcile.py(功能被 verify_data.py 覆盖)

Pylint 修复

  • _parse_pylint_scores() 增加 _PYLINT_SCORE_RE 对 "Your code has been rated at X.XX/10" 的匹配
  • _unwrap_pylint() 改为优先读取 __overall__ 键(来自正则匹配),回退计算旧版模块级评分平均值
  • 子进程调用从 pylint 改为 python -m pylint / radon,确保使用 uvicorn 同一 Python 环境
  • 子进程参数从逐一传 .py 文件改为传目录路径 + --recursive=y,规避 Windows 命令行长度限制

超时配置

  • PYLINT_TIMEOUT: 120s → 300s(1118 文件仓库实际需 ~200s)
  • _TIMEOUT_STATIC: 180s → 420s
  • clone_timeout_seconds: 120s → 300s
  • pipeline_timeout_seconds: 180s → 600s
  • 所有超时支持 .env 自定义(PIPELINE_TIMEOUT_SECONDS / CLONE_TIMEOUT_SECONDS

环境与日志

  • requirements.txt 新增 pylint>=3.0 + radon>=6.0
  • main.py 添加 logging.basicConfig(),恢复分析器日志输出
  • .env 缺失时输出警告而非静默失败
  • 时间格式统一为 YYYY-MM-DD HH:MM:SS(本地时间)

安全审查

  • ReportViewer.vue iframe sandbox 移除 allow-same-origin,防止 XSS 同源访问
  • cloner.py 本地路径增加系统目录拦截(/etc/procC:\Windows 等)
  • main.py 断言回退改为 HTTPException(503)-O 模式下不失效

代码质量清理

  • 前端:删除未使用的 clampProgressformatDurationMsfetchHealthCardFooterlucide-react 依赖、warning/success Tailwind 颜色
  • 前端:JobStatus(store)重命名为 UiJobStatus,消除与后端类型冲突

文档补充

  • 新增 WORKFLOW.md(端到端流程详解)、frontend/README.mdtests/README.mdscripts/README.md
  • 重写 backend/README.md(从 2 行占位符扩展为完整文档)、samples/README.md(推荐测试仓库)
  • 新增 DECISIONS.md(技术选型说明)

对账结果

使用 verify_data.pytiangolo/fastapi 仓库进行 L1(git原生命令) 与 L2(GitAnalyzer) 对账:

total_commits:        L1=7203  L2=7203  ✅
unique_contributors:  L1=931   L2=931   ✅
active_days:          L1=xxx   L2=xxx   ✅
ci_cd_config:         一致            ✅

测试结果

全部 12 个集成测试用例通过:Schema 序列化、Reporter HTML、数据库操作、错误场景、API 路由。


Phase 2 — Multi-Agent Architecture

  • 时间:2026-06-01
  • 版本:v2.0
  • Commit10814a3

目标

引入 Agent 抽象层,为后续多 Agent 协作奠定基础,而不引入框架级依赖。

新增

模块 文件 职责
BaseAgent agents/base.py 抽象基类,定义统一 async run(context, **kwargs) 接口
StaticAgent agents/static_agent.py 封装 StaticAnalyzer,委托代码质量分析
RepoAgent agents/repo_agent.py 封装 RepoAnalyzer,委托仓库意图分析(从 Context 获取 repo_url)
GitAgent agents/git_agent.py 封装 GitAnalyzer,委托 Git 活动分析
AgentRegistry agents/registry.py 注册中心:注册/获取/调度/生命周期管理

架构变化

v1.x:
  Orchestrator ──→ StaticAnalyzer.run()
                ├─→ RepoAnalyzer.run()
                └─→ GitAnalyzer.run()

v2.0:
  Orchestrator ──→ AgentRegistry.get("static") ──→ StaticAgent.run(ctx)
                ├─→ AgentRegistry.get("repo")   ──→ RepoAgent.run(ctx)
                └─→ AgentRegistry.get("git")    ──→ GitAgent.run(ctx)
                     ↑
              AgentRegistry + RepositoryContext
              (register / get / list / run_all)

设计原则

  1. 无侵入:三个 Analyzer 源码完全不变,Agent 是纯包装层。分析逻辑、超时处理、错误降级一字节未改
  2. 接口统一BaseAgent.run(context, **kwargs) 统一入口,Registry.run_all() 批量并行调度
  3. 职责分离:Analyzer 专注分析逻辑,Agent 专注调度与生命周期,Registry 专注注册与发现
  4. 零破坏:前端代码零修改、API 路由零修改、所有现有测试 12/12 通过

测试结果

=== RepoLens 端到端验证 ===
12/12 全部通过(Schema / Reporter / DB / 错误场景 / API路由)

收益

  • 为后续阶段提供可插拔的 Agent 接口
  • AgentRegistry.run_all() 可被 Orchestrator Agent 直接调用
  • RepositoryContext 统一了 Agent 入参,消除 **kwargs 传参的不确定性
  • Analyzer 源码零改动

Phase 3 — Agent Context Layer

  • 时间:2026-06-01
  • 版本:v2.1
  • Commit24230bc

目标

在 Agent 层和 Orchestrator 之间引入不可变的分析上下文(RepositoryContext), 解耦 Agent 与原始参数的传递方式。BaseAgent.run(repo_path) 升级为 BaseAgent.run(context)

为什么引入 Context

Phase 2 中 Agent 的 run() 接口存在两个问题:

  1. 参数不一致StaticAgent.run(repo_path)GitAgent.run(repo_path) 只需路径, 但 RepoAgent.run(repo_path, repo_url=...) 需要通过 **kwargs 额外传 repo_url**kwargs 不够类型安全,且调用方需记住不同 Agent 需要哪些参数。

  2. 扩展困难:未来 Agent 可能需要更多元信息(缓存键、历史快照、分析策略), 逐参数添加会导致接口持续膨胀。

解决方案:将所有分析上下文封装为不可变对象,Agent 从中按需提取。 这类似 HTTP 框架中 Request 对象的设计模式——通过上下文解耦入参。

新增

模块 文件 职责
RepositoryContext context/base.py 不可变 dataclass(frozen=True):repo_url、repo_path、repo_name、analysis_id、started_at
make_context() context/repository_context.py 工厂函数:从原始参数构建 RepositoryContext,自动提取仓库名
ContextManager context/context_manager.py 生命周期管理:create() / validate() / create_and_validate()

架构变化

v2.0:
  Orchestrator
    └─→ AgentRegistry.get("static") ──→ StaticAgent.run(repo_path)
         AgentRegistry.get("repo")   ──→ RepoAgent.run(repo_path, repo_url=...)
         AgentRegistry.get("git")    ──→ GitAgent.run(repo_path)

v2.1:
  Orchestrator
    └─→ ContextManager.create(repo_url, repo_path, job_id) ──→ RepositoryContext
         └─→ AgentRegistry.get("static") ──→ StaticAgent.run(ctx)
              AgentRegistry.get("repo")   ──→ RepoAgent.run(ctx)  # ctx.repo_url / ctx.repo_path
              AgentRegistry.get("git")    ──→ GitAgent.run(ctx)

Agent 接口变更

Agent v2.0 入参 v2.1 入参
StaticAgent run(repo_path) run(context)context.repo_path
RepoAgent run(repo_path, repo_url=xxx) run(context)context.repo_url + context.repo_path
GitAgent run(repo_path) run(context)context.repo_path

测试结果

=== RepoLens 端到端验证 ===
12/12 全部通过(Schema / Reporter / DB / 错误场景 / API路由)

收益

  • Agent 入参接口完全统一:所有 Agent 接收同一个 RepositoryContext
  • **kwargs 被消除:repo_url 等额外参数直接从 context 获取
  • frozen=True 保证上下文不可变,Agent 间无副作用
  • Analyzer 源码零改动、API 零改动、前端零改动

Phase 4 — Shared Memory Layer

  • 时间:2026-06-01
  • 版本:v2.2
  • Commit6d83a69

目标

在 Agent 架构中引入 SharedMemory,为 Agent 间数据共享铺设基础设施。 当前阶段铺设通道,暂不产生业务使用。

为什么引入 SharedMemory

Phase 2-3 中 Agent 之间完全隔离——每个 Agent 独立完成分析后返回结果, Agent 之间无法在分析过程中共享中间数据。未来场景需要:

  • StaticAgent 发现高风险文件后通知 GitAgent 聚焦分析其变更历史
  • RepoAgent 识别核心模块后传递给 StaticAgent 提高评分权重
  • 多个 Agent 写入同一分析结果供 Reporter 聚合

解决方案:在 Agent 间引入线程安全的共享键值存储,Agent 在 run() 中 可读写此存储,Orchestrator 和 Reporter 也可读取。

新增

模块 文件 职责
SharedMemory memory/base.py 线程安全 KV 存储:set/get/has/delete/keys/snapshotthreading.RLock
get_by_prefix() / batch_set() memory/shared_memory.py 辅助函数:按前缀筛选、批量写入
MemoryManager memory/memory_manager.py 生命周期管理:create()/clear()/get_memory()

架构变化

v2.1:
  Orchestrator → ContextManager → Context → AgentRegistry → Agent

v2.2:
  Orchestrator
    ├─→ ContextManager.create()           → RepositoryContext
    ├─→ MemoryManager.create()            → SharedMemory
    └─→ AgentRegistry.inject_memory()
         └─→ Agent.run(ctx)  # self.memory 可用

Agent 接口变更

组件 变更
BaseAgent 构造函数新增 memory: SharedMemory, 属性 self.memory
StaticAgent 构造函数新增 memory 参数
RepoAgent 构造函数新增 memory 参数
GitAgent 构造函数新增 memory 参数
AgentRegistry 新增 inject_memory(memory) 方法,向所有 Agent 注入
Orchestrator 新增 MemoryManager,每流水线 create()inject_memory() → 结束后 clear()

测试结果

=== RepoLens 端到端验证 ===
12/12 全部通过

收益

  • Agent 间数据共享通道已就绪,Phase 5+ 可直接使用
  • threading.RLock 保证线程安全,兼容 asyncio.to_thread 场景
  • Memory 每次流水线独立实例,无数据泄漏风险

Phase 5 — PlannerAgent(Agent 协作)

  • 时间:2026-06-01
  • 版本:v2.3
  • Commitba164c1

目标

实现第一条真实 Agent 协作链路:PlannerAgent → SharedMemory → 三个分析 Agent。 不再新增基础设施,开始让 Agent 真正通过 Memory 协作。

为什么引入 PlannerAgent

Phase 4 铺设了 SharedMemory 通道,但没有任何 Agent 真正使用它。 Phase 5 引入 PlannerAgent 作为协作的起点——它在流水线中最先运行, 制定分析计划写入 Memory,后续 Agent 读取此计划并根据其内容调整行为。

这是从"各自独立的 Agent"到"协作的多 Agent 系统"的关键一步。

新增

模块 文件 职责
PlannerAgent agents/planner_agent.py 分析计划编排,写入 memory.set("analysis_plan", plan)
AnalysisPlan schemas.py Pydantic 模型:tasks: list[str] + priority: str

架构变化

v2.2:
  Orchestrator → Context+Memory → [StaticAgent | RepoAgent | GitAgent]

v2.3:
  Orchestrator → Context+Memory
    ├─→ PlannerAgent.run(ctx)
    │     └─→ memory.set("analysis_plan", plan)
    └─→ [StaticAgent | RepoAgent | GitAgent].run(ctx)
          └─→ memory.get("analysis_plan")  # 读取并记录日志

Agent 协作链路

1. Orchestrator 创建 Context + Memory
2. PlannerAgent.run(ctx)
     ├─ 制定 AnalysisPlan(tasks=["static_analysis", "repo_analysis", "git_analysis"])
     └─ memory.set("analysis_plan", plan)
3. StaticAgent.run(ctx)  → memory.get("analysis_plan") → 日志: "读取分析计划"
   RepoAgent.run(ctx)    → memory.get("analysis_plan") → 日志: "读取分析计划"
   GitAgent.run(ctx)     → memory.get("analysis_plan") → 日志: "读取分析计划"

Orchestrator 流程变更

阶段 v2.2 v2.3
注册 3 个 Agent 4 个 Agent(+PlannerAgent)
执行顺序 Clone → 并行 3 Agent Clone → PlannerAgent(串行) → 并行 3 Agent
Planner 失败 不阻塞后续分析,日志记录警告

测试结果

=== RepoLens 端到端验证 ===
12/12 全部通过

收益

  • 第一条真实 Agent 协作链路验证了 Memory 通道可用
  • PlannerAgent 可以热插拔——移除它不影响其他 Agent 运行
  • 后续 Phase 可扩展 PlannerAgent 根据仓库特征动态决定分析策略(大仓库跳过某些分析器等)

Phase 6 — ReportAgent(生成汇总报告)

  • 时间:2026-06-01
  • 版本:v2.4
  • Commitaf14f12

目标

引入 ReportAgent,从 SharedMemory 读取三个分析 Agent 的结果, 生成结构化 JSON + 可折叠 HTML 汇总报告。

为什么引入 ReportAgent

Phase 5 建立了 Planner → Memory → Agents 的写入链路, 但缺少从 Memory 消费数据的 Agent。ReportAgent 填补了这个空缺—— 它读取所有 Agent 写入 SharedMemory 的结果,生成为人可读的汇总报告。

这是 Agent 协作链路的完整闭环:Planner → 分析 Agents → ReportAgent。

新增

模块 文件 职责
ReportAgent agents/report_agent.py 读取 SharedMemory → 生成 ReportResult(JSON + HTML)
ReportResult schemas.py Pydantic 模型:汇总统计 + 自包含 HTML

Agent 协作链路(完整闭环)

1. PlannerAgent.run(ctx) → memory.set("analysis_plan", plan)
2. StaticAgent.run(ctx)  → memory.set("static_result", result)
   RepoAgent.run(ctx)    → memory.set("repo_result", result)
   GitAgent.run(ctx)     → memory.set("git_result", result)
3. ReportAgent.run(ctx)
     ├─ memory.get("static_result")
     ├─ memory.get("repo_result")
     ├─ memory.get("git_result")
     ├─ 生成 ReportResult (JSON + HTML)
     └─ memory.set("report_result", result)

Orchestrator 流程变更

v2.3:  Planner → [Static | Repo | Git] → Reporter(report)

v2.4:  Planner → [Static | Repo | Git] → ReportAgent → Reporter(report)

HTML 报告内容

  • Agent 状态徽章(static / repo / git,彩色标签)
  • 静态分析:扫描文件数、Pylint 评分、复杂函数数
  • 仓库洞察:使用模式、核心模块、README 质量
  • Git 活动:总提交、贡献者数、活跃天数、CI/CD 状态
  • 可折叠章节、零外部 CSS/JS 依赖

测试结果

=== RepoLens 端到端验证 ===
12/12 全部通过

收益

  • Agent 协作链路首尾闭环:Plan → Execute → Report
  • ReportAgent 可独立替换——不影响其他 Agent 运行
  • SharedMemory 作为 Agent 间总线已验证可行

Phase 7 — Dynamic Planner(动态策略引擎)

  • 时间:2026-06-01
  • 版本:v2.5
  • Commit8200abe

目标

将 PlannerAgent 从固定计划升级为动态策略引擎。 根据仓库特征(文件数、README 存在性)自动决定应执行和应跳过的分析任务。 不引入 LLM 调用,纯规则引擎驱动。

为什么引入 Dynamic Planner

Phase 5 的 PlannerAgent 始终返回固定计划(三个分析器全部执行), 没有体现"规划"的实际价值。动态 Planner 让系统能根据仓库特征做出智能决策: 大仓库跳过昂贵的静态分析、无 README 的仓库跳过意图分析。

新增

模块 文件 职责
RepositoryProfiler planner/repository_profiler.py 扫描仓库元信息(文件数、README/CI/Docker 存在性)
PlanningRules planner/planning_rules.py 规则引擎:file_count>1000→skip static, !has_readme→skip repo
DynamicPlanner planner/dynamic_planner.py 组合 Profiler + Rules,生成 AnalysisPlan

规划规则

条件 动作 原因
file_count > 1000 跳过 static_analysis repository too large
!has_readme 跳过 repo_analysis README missing
默认 全部执行

架构变化

v2.4:  PlannerAgent → 固定 tasks=["static","repo","git"]

v2.5:  PlannerAgent → DynamicPlanner
         ├─ RepositoryProfiler.analyze(repo_path) → profile
         ├─ PlanningRules.evaluate(profile) → AnalysisPlan
         └─ Orchestrator 根据 plan.tasks 动态决定执行哪些 Agent

Schema 升级

AnalysisPlan 新增字段:

  • skipped_tasks: list[str] — 被跳过的任务
  • reasons: dict[str, str] — 跳过原因(task → reason)

向后兼容:旧字段 taskspriority 不变。

Orchestrator 流程变更

_run_analyzers 改为 Plan 驱动:

  • "static_analysis" in skippedrun_static() 返回 None
  • "repo_analysis" in skippedrun_repo() 返回 None
  • git_analysis 始终执行(不会被规则跳过)

ReportAgent 增强

HTML 报告新增 Plan Summary 区域:

  • 展示执行了哪些任务
  • 跳过了哪些任务及原因
  • 计划优先级

测试结果

=== RepoLens 端到端验证 ===
12/12 全部通过

收益

  • 大仓库分析速度提升(跳过静态分析节省 120-300s)
  • 缺失 README 的仓库不再浪费 LLM 调用
  • 规则引擎可扩展:新增规则只需在 PlanningRules.evaluate() 加 if 块
  • 无 LLM 调用、无新依赖、纯 Python

Phase 7.5 — 测试覆盖 + 前端交互修复

  • 时间:2026-06-01
  • 版本:v2.5.1
  • Commite05d0d9

目标

为 Agent 架构补充完整单元测试覆盖,同时修复多轮手动测试中发现的前端交互问题。

新增测试

测试类 数量 覆盖范围
TestSharedMemory 11 set/get/delete/clear/keys/len/snapshot/overwrite/types
TestMemoryManager 5 create/get/clear/replace lifecycle
TestRepositoryContext 6 construction/immutability/defaults/make_context
TestContextManager 3 create/validate success & failure
TestPlanningRules 8 skip conditions + boundary + priority
TestDynamicPlanner 3 real directory / small dir / missing dir fallback
TestAgentRegistry 7 register/get/duplicate/inject_memory/list/len/clear
TestPlannerAgent 3 memory write / without memory / tasks not empty
TestReportAgent 5 empty memory / write / HTML structure / plan summary / agent results

总计:55 个单元测试,全部通过。

前端交互修复

在手动端到端测试中发现并修复了以下问题:

问题 现象 根因 修复
iframe 高度截断 分析报告只显示上半部分,下半部分无法滚动不可见 sandbox="allow-scripts" 禁止 contentDocument 读取;IIFE 在 DOM 布局完成前执行,scrollHeight 不准确 HTML 脚本改用 DOMContentLoaded + setTimeout(100ms) 延迟上报;ReportViewer 切换报告时重置高度
进度条被覆盖 分析中点击历史条目,进度条跳到 100% setReport() 同时覆写 status: 'completed' + progressPct: 100 拆分 setReport(仅设 report)和 completeJob(设完成态)
轮询被中断 查看历史后刷新出现多个"分析中"僵尸条目 历史查看触发 stopPolling(),当前任务永远无法完成 setReport 不再改变 status,轮询仅由 completeJob 终止
404 错误 点击当前运行中的历史条目弹 404 loadHistorical 对未完成任务也调 fetchReportJson 点击当前任务时判断状态:已完成→重新加载,运行中→清除报告显示骨架屏
完成态点回空白 任务完成后从历史点回最新显示"尚未生成报告" 无差别 clearReport() 清掉了已完成任务的报告 已完成态重新 fetchReportJson 加载报告
历史状态滞后 分析过程中历史列表状态不变,需手动刷新 只在挂载和新报告生成时刷新 分析中每 3 秒自动拉取历史列表

架构清理

  • 移除 ReportAgent 重复执行:Orchestrator 中 ReportAgent 产出 ReportResult 后立即被 _mem_manager.clear() 丢弃,前端从未使用。移除 _run_reporter() 及其注册逻辑,消除重复日志输出。

修改文件

文件 变更
tests/test_agent_architecture.py 新增,55 个单元测试
tests/README.md 更新测试覆盖说明
samples/README.md 更新示例说明
backend/repolens/reporter.py HTML postMessage 改用 DOMContentLoaded+setTimeout
backend/repolens/agents/report_agent.py 同上
backend/repolens/orchestrator.py 移除未使用的 ReportAgent 执行路径
frontend/src/store/analysisStore.ts 拆分 setReport/completeJob,新增 clearReport
frontend/src/hooks/useAnalysisJob.ts 轮询完成用 completeJob
frontend/src/App.tsx 历史查看不中断轮询、自动刷新历史、点击当前任务智能恢复
frontend/src/components/ReportViewer.tsx postMessage 监听,切换报告时重置高度

测试结果

55/55 agent architecture 单元测试全部通过
手动端到端回归测试通过(分析→历史切换→任务完成→报告查看)

收益

  • Agent 架构核心模块达到 100% 单元测试覆盖
  • 前端交互逻辑健壮性大幅提升,消除 6 个状态管理 bug
  • 历史列表实时更新,无需手动刷新
  • 历史查看与当前任务彻底解耦,互不干扰

Phase 8 — Strategy-Based Planning(从 Skip 升级为 Strategy)

  • 时间:2026-06-01
  • 版本:v2.6
  • Commit13ed8b9

目标

将 Planner 从"决定哪些任务不执行"升级为"决定各 Agent 如何执行"。 消除 skip-task 模式导致的评分不完整、报告信息缺失等设计缺陷。

为什么升级

Phase 7 的 DynamicPlanner 使用 skip-task 模式:大仓库跳过 StaticAgent、 无 README 跳过 RepoAgent。这导致了三个问题:

  1. 评分不完整:跳过的 Agent 为 0 分,综合健康评分失真
  2. 报告信息缺失:用户看不到被跳过的维度的任何数据
  3. Agent 协作价值下降:Planner 的价值被简化为"关掉Agent"

新增

模块 文件 变更
AnalysisStrategy schemas.py 新增模型:static/repo/git 各带策略模式 + static_confidence 属性
AnalysisPlan.strategy schemas.py 新增字段,替代 skip_tasks 为主决策方式
PlanningRules planning_rules.py 重写:从 remove-task 改为选择 strategy
StaticAgent agents/static_agent.py _read_analysis_strategy() 读取 strategy,传递给 StaticAnalyzer
StaticAnalyzer analyzers/static_analyzer.py run() 新增 strategy_mode 参数,支持 full/focused/fast
ReportAgent agents/report_agent.py _plan_summary 改为展示 strategy + 置信度
Orchestrator orchestrator.py 移除 skip 逻辑,始终执行所有 Agent

策略矩阵

file_count static 策略 行为 置信度
≤ 500 full 完整 pylint + radon 100%
501–1000 focused 非测试文件 pylint + 全量 radon 75%
> 1000 fast 仅 radon cc 50%

repo / git 始终 full

向后兼容

  • skipped_tasks / reasons 字段保留,但 Orchestrator 不再使用
  • AnalysisPlan 默认 strategy=AnalysisStrategy()(full/full/full)
  • 旧测试已更新为新的 strategy 断言

架构变化

v2.5:
  PlannerAgent → AnalysisPlan(skipped_tasks=["static_analysis"])
  Orchestrator → "static_analysis" in skipped → return None

v2.6:
  PlannerAgent → AnalysisPlan(strategy=AnalysisStrategy(static="fast"))
  Orchestrator → 始终执行 StaticAgent
  StaticAgent   → 读取 plan.strategy.static → "fast" → 仅 radon
  ReportAgent   → HTML 展示策略 + 置信度

测试结果

55/55 agent architecture 单元测试全部通过
新增 strategy 相关测试 10+ 个

收益

  • 所有 Agent 始终执行,评分始终完整
  • 仓库规模越大 → 分析深度越浅(但不消失)
  • 用户永远看到各维度的数据 + 置信度标注
  • Planner 价值提升:从"开关"升级为"智能调速器"
  • 规则引擎可扩展:新增策略模式只需加 elif 分支

Phase 8.1 — Strategy Refinement(命名优化 + 可解释性增强)

  • 时间:2026-06-01
  • 版本:v2.6.1
  • Commitace58b7

目标

不改核心逻辑,仅做命名优化和前端可解释性提升,让用户看到报告时能明确理解当前策略含义。

修改

变更 说明
sampledfocused 全项目重命名。当前实现是排除测试文件而非随机采样,focused 更准确
ReportResult.strategy 新增字段,暴露当前 static 策略供前端读取
ReportJson.strategy 新增字段,打通 Reporter → API 数据链路
HTML 策略展示 Reporter + ReportAgent 双端展示:三种模式各有专属英文名称 + 详细说明
前端 strategy badge ReportViewer 非 full 模式时在标题栏显示策略标签
samples 数据实测 verify_samples.py 脚本实测文件数,README 更新为准确数据

测试样本优化

实测原始 README 声称的文件数全部不准确(pytest 声称 600 实测 270)。 更新为三种模式各一个代表:

模式 仓库 实测 .py 文件数
full pallets/flask ~80
focused sqlalchemy/sqlalchemy ~670
fast tiangolo/fastapi ~1120

新增 scripts/verify_samples.py 可复用验证脚本。

HTML 展示示例

ReportAgent Plan Summary(iframe 内)

📊 分析策略
   Strategy: Focused Analysis · Confidence: 75%
   → Test files were excluded to improve performance.
     Production code received priority analysis.
   Repo: full · Git: full

Reporter 报告(前端 iframe 主内容)

分析策略
Focused Analysis · 置信度 75%
Test files excluded. Production code received priority analysis.

修改文件

文件 变更
schemas.py sampled→focused;ReportResult/ReportJson 新增 strategy
planning_rules.py _SAMPLED_THRESHOLD→_FOCUSED_THRESHOLD;全量重命名
static_analyzer.py 注释/日志 sampled→focused
report_agent.py strategy 写入 ReportResult;HTML 策略展示优化
reporter.py render() 新增 strategy 参数;新增 _html_strategy() 方法;_build_html 增加策略区域
orchestrator.py 传递 plan.strategy 给 Reporter
contracts.ts ReportJson 新增 strategy 字段
ReportViewer.tsx 非 full 模式时标题栏显示策略标签
test_agent_architecture.py 全量重命名 + 新增 strategy 验证测试
samples/README.md 数据实测更新,三种模式各一个代表
scripts/verify_samples.py 新增,可复用实测验证脚本
EVOLUTION_LOG.md Phase 8 表项更新 + 新增 Phase 8.1 条目

测试结果

55/55 passed

收益

  • 命名准确:focused 如实描述"聚焦生产代码"行为
  • 前端可见:用户打开报告即可看到 Strategy 标签
  • HTML 可读:三种模式的英文名称+说明让非技术用户也能理解
  • 零核心逻辑改动:评分、调度、规则引擎完全不受影响

Phase 9 — Engineering Completion(工程化收尾)

  • 时间:2026-06-01
  • 版本:v2.6.2
  • Commit42e5ca2

目标

核心功能已全部完成。本阶段仅补充文档和发布清单,让项目达到 GitHub Release Ready 状态。 禁止修改核心架构、Agent、Planner、评分逻辑。

新增文档

文档 说明
docs/architecture/system-overview.md 系统架构总览,含 Mermaid 图
docs/architecture/agent-flow.md Agent 协作流程,含时序图 + Memory Key 约定
docs/adr/ADR-001-agent-architecture.md 为什么从传统流程改为 Multi-Agent
docs/adr/ADR-002-shared-memory.md 为什么采用 SharedMemory
docs/adr/ADR-003-strategy-planning.md 为什么从 Skip-Based 升级到 Strategy-Based
docs/testing/TEST_REPORT.md 55 测试覆盖报告
docs/case-studies/case-flask-full.md pallets/flask full 策略分析案例
docs/performance/PERFORMANCE.md 性能基准模板(待实测填充)
docs/RELEASE_CHECKLIST.md 发布准备检查清单

更新文档

文件 变更
README.md 新增 Agent 工作流、策略引擎、文档导航章节
docs/EVOLUTION_LOG.md Phase 8.1 commit hash 更新 + 新增 Phase 9 条目

文档目录树

docs/
├── EVOLUTION_LOG.md
├── RELEASE_CHECKLIST.md
├── architecture/
│   ├── system-overview.md
│   └── agent-flow.md
├── adr/
│   ├── ADR-001-agent-architecture.md
│   ├── ADR-002-shared-memory.md
│   └── ADR-003-strategy-planning.md
├── testing/
│   └── TEST_REPORT.md
├── case-studies/
│   └── case-flask-full.md
└── performance/
    └── PERFORMANCE.md

测试结果

55/55 passed

发布就绪状态

✅ 核心功能完整
✅ 55 单元测试全部通过
✅ 3 个 ADR 记录所有关键架构决策
✅ 架构图(Mermaid)覆盖整体 + Agent 流程
✅ 真实案例分析
✅ 性能基准模板
✅ README 可从零启动项目
✅ 发布检查清单全项勾选

未来方向

  • Agent 深度协作(StaticAgent 发现热点 → GitAgent 聚焦变更历史)
  • 安全扫描 Agent(Bandit / Semgrep)
  • LLM 代码审查 Agent(高风险文件语义审查 + 重构建议)
  • 多语言支持(JS/TS/Rust/Go)
  • 多仓库对比 + 趋势追踪 + Webhook 触发