当前位置: 首页 > news >正文

从零构建 DeepClassify:一个本地代码工程智能管理 Agent

从零构建 DeepClassify:一个本地代码工程智能管理 Agent

拖入代码工程 → 自动扫描 → AI 分类 → 生成文档 → RAG 语义搜索。
全程本地运行,无需联网,你的代码不离开你的机器。


github链接:https://github.com/lsy511640489/DeepClassify
演示视频链接:https://www.bilibili.com/video/BV1SVjm6oE4b/

缘起:为什么我需要这个工具

作为一个同时在维护 30+ 个代码仓库的开发者,我面临一个普遍的困境:

  • 接手同事的项目,看不懂这是干什么的
  • 三个月前自己从github上拉的代码忘记这是做啥的
  • 硬盘里散落着各种嵌入式工程、Web 项目、AI 实验,根本分不清

现有的方案要么是云端的(代码上传到第三方),要么是纯手动的(写 README 靠自觉)。我想要的很简单:

把代码文件夹拖进去,自动告诉我是干什么的,然后能随时搜索找到。

于是有了 DeepClassify。


设计哲学:三个核心决策

1. 本地优先,不是口号

所有数据 —— SQLite 数据库、ChromaDB 向量索引、生成的 Markdown 文档 —— 全部存在你的硬盘上。LLM 通过调用本地的 Ollama 或你自己的 DeepSeek API Key 完成,代码工程一行都不会上传到第三方服务器

这意味着:

  • 内网环境也能用
  • 没有 API 费用(用 Ollama 本地模型时)
  • 工程代码绝对隐私

2. AI 主导分类,规则兜底

传统的代码分类工具依赖正则匹配:检测到.ioc文件 → STM32 工程,检测到package.json→ 前端项目。

这有两个致命问题:

  • 覆盖盲区:新框架、自研框架、混合工程无法识别
  • 误判:一个引用了 STM32 HAL 库的 PC 仿真器会被误判为嵌入式工程

我的做法是反过来:

┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Stage 1 │────▶│ Stage 2 │────▶│ Stage 3 │ │ 规则预筛选 │ │ ★ AI 分类 │ │ 规则校验 │ │ 提取硬信号 │ │ LLM 读源码 │ │ 交叉验证 │ │ 供 AI 参考 │ │ 自主判断 │ │ 矛盾降置信度 │ └──────────────┘ └──────────────┘ └──────────────┘

让 AI 读完关键源文件后自己决定 “这个工程是什么”,规则只在 AI 不可用时兜底,以及在 AI 给出结果后做一致性验证。

3. 事件驱动的管道架构

整个处理流程被建模为一条 7 步管道:

拖入工程 → 创建记录 → 扫描指纹 → AI分类 → 生成摘要 → 渲染文档 → 向量索引 │ │ └────────── 每一步通过 EventBus 发出事件 → WebSocket 实时推送 ───────┘

前端能实时看到进度:“正在扫描文件结构…” → “AI 正在分析工程类型…” → “正在生成文档…” → “完成!”


技术全景

整体架构

┌──────────────────────┐ ┌──────────────────────┐ │ Desktop UI │ │ Web UI │ │ Avalonia .NET 10 │ │ React 19 + Vite 8 │ │ MVVM + Fluent │ │ Tailwind 4 + Zustand│ └──────────┬───────────┘ └──────────┬───────────┘ │ HTTP REST │ │ 127.0.0.1:8765/api/v1 │ └──────────┬───────────────┘ │ ┌──────────▼───────────┐ │ FastAPI Backend │ │ Python 3.12+ │ │ │ │ ┌────────────────┐ │ │ │ EventBus │ │ │ └───────┬────────┘ │ │ │ │ │ ┌───────▼────────┐ │ │ │ Pipeline │ │ │ │ Scan→Classify │ │ │ │ →Doc→Index │ │ │ └───────┬────────┘ │ │ │ │ │ ┌───────▼────────┐ │ │ │ RAG Engine │ │ │ │ Hybrid Search │ │ │ └────────────────┘ │ └──────────┬───────────┘ │ ┌──────────▼───────────┐ │ Data Layer │ │ SQLite + ChromaDB │ │ + File System │ └──────────────────────┘

技术栈速览

技术选型理由
Desktop UIAvalonia 12 + .NET 10 + CommunityToolkit.Mvvm跨平台桌面框架,MVVM 源码生成器消除样板代码
Web UIReact 19 + TypeScript 6 + Tailwind 4 + Zustand轻量、类型安全、原子化 CSS
BackendFastAPI + SQLAlchemy + aiosqlite + ChromaDB异步 Python、本地向量存储
Embeddingsentence-transformers (all-MiniLM-L6-v2)384 维,仅 80MB,离线运行
LLMDeepSeek / Ollama / Claude 三 Provider 可切换灵活适配不同场景
PackagingPyInstaller + .NET Publish后端打包为单一 exe,桌面端自包含发布

核心模块拆解

1. 工程指纹扫描器 — 不只是数文件

扫描器 (src/scanner/) 生成一个包含 15 个字段的ProjectFingerprint

fingerprint: file_count: 142 total_size_mb: 3.2 languages: { C: 65%, Python: 20%, CMake: 10%, Assembly: 5% } frameworks: [STM32 HAL, FreeRTOS, CMSIS-DSP] build_systems: [CMake, Makefile] dependencies: [arm-none-eabi-gcc, stm32cube-f4] key_files: [main.c, stm32f4xx_it.c, motor_control.c] key_dirs: [Core/, Drivers/, Middleware/] readme_summary: "基于STM32F407的无刷直流电机FOC控制..." source_samples: { motor_control.c: "void FOC_Clark(...){...}", ... }

关键在于不只是匹配文件名——它会解析CMakeLists.txt中的target_link_librariespackage.jsondependencies、甚至 STM32 CubeMX 的.ioc文件,从中提取出有意义的框架和依赖信息。framework_detector.py内置了 35+ 种框架的签名数据库。

2. 三级分类器 — AI 为核心,规则为安全网

Stage 1 — 预筛选(rule_prefilter.py):

快速提取硬信号(文件模式、依赖名称、框架签名),生成结构化线索:

{"clues":{"embedded_signals":["STM32 HAL","FreeRTOS","CMSIS-DSP"],"likely_l1":"embedded","hard_evidence":[".ioc文件存在","startup_stm32f407xx.s 存在"]}}

这些线索不直接决定分类,而是作为 AI 的参考上下文。

Stage 2 — AI 分类(llm_classifier.py):

构建一个包含指纹数据、预筛选线索和关键源码样本的 Prompt,让 LLM 输出:

{"l1":"embedded","l2":"stm32","l3":"motor-control","confidence":0.92,"reasoning":"该工程包含STM32F407的FOC算法实现,使用CMSIS-DSP库进行Clarke/Park变换,判断为STM32电机控制工程"}

LLM 可以自由创建taxonomy.yaml中不存在的新子类别——分类树是开放的。

Stage 3 — 校验(rule_validator.py):

将 AI 的分类结果与硬信号交叉比对。比如 AI 返回l1: "web"但工程里有.ioc文件和startup_stm32.s,校验器会将置信度从 0.85 降到 0.3 —— 显然是误判。

降级路径:当 LLM 不可用时(离线 / 配额耗尽),系统自动切换到纯规则模式——25+ 条优先级规则逐条尝试,最终UnknownRule兜底。

3. RAG 混合检索引擎 — 语义 + 关键词

只用向量搜索的问题是:搜 “FOC 电机控制” 可能漏掉标题就是foc_motor.c但描述用词不同的文档。只用关键词搜索的问题是:搜 “无刷直流电机控制” 找不到只写了 “BLDC Control” 的文档。

所以用了混合检索 + RRF 融合

用户查询: "FOC 矢量控制" │ ├──▶ ChromaDB 语义搜索 ──▶ [doc1:0.89, doc3:0.78, doc5:0.72] │ ├──▶ SQLite FTS5 全文搜索 ──▶ [doc3:0.91, doc2:0.85, doc1:0.60] │ └──▶ RRF 融合 ──▶ [doc3, doc1, doc2, doc5] (重排序)

RRF (Reciprocal Rank Fusion) 公式:score = Σ 1/(k + rank_i)k=60。简单但有效——不依赖分数归一化,对语义和关键词搜索的分数尺度差异不敏感。

4. 文档生成器 — 按分类定制模板

不同领域的工程需要不同的文档结构。用 Jinja2 模板 + 按一级分类路由:

src/documentor/templates/ ├── base.md.j2 ← 基础布局(所有文档共用) ├── embedded.md.j2 ← 嵌入 MCU 信息、外设配置、引脚分配 ├── ai_ml.md.j2 ← 模型架构、训练数据、评估指标 ├── web.md.j2 ← 前后端分离、API 接口、部署方式 └── default.md.j2 ← 兜底模板

每个模板注入三个信息来源:

  1. README 概述(从工程原始 README 提取)
  2. LLM 摘要(2–4 句中文功能描述)
  3. 规则概述(从指纹数据自动生成的技术栈清单)

5. 事件总线 — 解耦的秘密武器

整个系统通过一个不到 100 行的EventBus实现模块间通信:

# 发布者:管道发出进度事件awaitevent_bus.emit("project.scan_done",{"project_id":id,"fingerprint":fp})# 订阅者 1:WebSocket 广播给前端@event_bus.subscribe("project.scan_done")asyncdefws_broadcast(event):forwsinconnected_clients:awaitws.send_json(event)# 订阅者 2:任何模块都可以监听@event_bus.subscribe("project.ready")asyncdefon_project_ready(event):# 比如:发送桌面通知、触发 CI 流水线...pass

这带来的好处是:添加新功能不需要修改现有代码。想做桌面通知?订阅project.ready事件即可。想做自动备份?订阅project.ready事件即可。Pipeline、WebSocket、未来的任何模块完全解耦。


双向 UI:Desktop + Web

DeepClassify 有两套 UI,共用同一套后端 API:

Desktop UI (Avalonia)

面向日常桌面使用的用户。特点:

  • 原生 Windows 窗口,启动快,内存占用低
  • 内置 AI 聊天(SSE 流式),可以直接用自然语言问 “有哪些做电机控制的 STM32 工程?”
  • 知识图谱可视化— Canvas 手绘节点,力模拟布局,拖拽旋转交互
  • 粉色模式(🌸 少女粉模式)—— 一点小趣味

MVVM 架构使用 CommunityToolkit.Mvvm 的源码生成器:

publicpartialclassSearchViewModel:ObservableObject{[ObservableProperty]privatestring_query="";[RelayCommand]privateasyncTaskSearchAsync(){Results=await_api.SearchAsync(Query);}}// [ObservableProperty] 自动生成 Query 属性 + PropertyChanged// [RelayCommand] 自动生成 SearchCommand

Web UI (React)

面向浏览器访问的场景(比如 NAS 上部署、局域网共享)。特点:

  • SVG 力导向知识图谱— 600 次迭代物理模拟,拖拽缩放
  • 项目卡片仪表盘+ recharts 饼图
  • Tailwind 暗色模式,保护深夜工作的眼睛
  • 可拖拽侧边栏,宽度持久化到 localStorage

数据流全景

让我用一个完整的例子串联所有模块:

1. 用户将 "foc_motor_ctrl/" 文件夹拖入 data/inbox/ 2. WatchService (watchdog) └─ 检测到新目录 → 去抖 10s → 验证是否为有效代码工程 └─ emit("project.detected", {path: "data/inbox/foc_motor_ctrl"}) 3. Pipeline.process_project() ├─ Step 1: 在 SQLite 创建 Project 记录 (status: "detected") ├─ Step 2: Scanner 扫描 │ └─ 遍历 142 个文件 → 发现 .ioc + startup_stm32f407.s + FreeRTOSConfig.h │ └─ 解析 CMakeLists.txt → 提取 arm-none-eabi-gcc, CMSIS-DSP │ └─ 生成 ProjectFingerprint → emit("project.scan_done") ├─ Step 3: Classifier 分类 │ └─ PreFilter → clues: {likely_l1: "embedded", signals: ["STM32", "FreeRTOS"]} │ └─ LLM 读取 main.c + motor_control.c → "这是 STM32F407 的 FOC 电机控制" │ └─ Validator → 交叉验证通过 → emit("project.classify_done") ├─ Step 4: LLM 摘要 │ └─ "基于STM32F407的FOC矢量控制工程,使用FreeRTOS多任务架构..." ├─ Step 5: Documentor → Jinja2 渲染 embedded.md.j2 │ └─ 输出到 data/projects/embedded/stm32/foc_motor_ctrl.md ├─ Step 6: RAG Indexer │ └─ Chunker 按 ## 标题分割 → 每个chunk嵌入为384维向量 │ └─ 写入 ChromaDB + SQLite FTS5 → emit("project.ready") └─ 完成! status: "ready" 4. 用户搜索 "FOC 矢量控制" └─ Retriever 混合搜索 → ChromaDB 语义 + FTS5 关键词 → RRF 融合 └─ 返回: [foc_motor_ctrl (score: 0.94), bldc_driver (score: 0.78), ...] 5. 用户在 AI Chat 中问 "foc_motor_ctrl 用了哪些外设?" └─ Chat API → RAG 检索相关文档块 → 拼接 Prompt → LLM 回答

一些有意思的实现细节

去抖 (Debounce) 不只是前端的事

文件监听器面临的问题:用户拖入一个 500MB 的工程文件夹,操作系统需要几秒甚至十几秒才能完成复制。如果每检测到一个新文件就触发处理,会变成灾难。

解决方案:每路径异步去抖——在该路径上 10 秒没有新事件后才触发处理。

ChromaDB 的 PyInstaller 兼容

ChromaDB 依赖onnxruntimepypika,这两个包在 PyInstaller 打包时需要显式声明 hidden-import。否则打包后的 exe 跑不起来。BUILD.md 里专门有一节 troubleshooting 记录踩过的坑。

嵌入模型的离线缓存

sentence-transformers默认从 HuggingFace Hub 下载模型。在国内网络环境下,这可能需要数次重试。系统做了两件事:

  1. 模型缓存到data/model_cache/,二次启动秒加载
  2. 支持HF_ENDPOINT=https://hf-mirror.com镜像加速

知识图谱的简易物理引擎

KnowledgeGraph.tsx没有引入 D3 或任何图布局库,而是手写了 600 次迭代的力模拟:

for i in 0..600: cooling = exp(-i / 200) # 指数衰减 for each node pair: dx = node2.x - node1.x dist = max(|dx|, 1) force = REPULSION / dist² # Coulomb 斥力 node1.x -= force * dx * cooling node2.x += force * dx * cooling for nodes in same category: # 同类节点轻微吸引 attract_towards_centroid()

简单但效果不错——几百个节点也能在几百毫秒内完成布局。


项目结构一览

deepClassify/ ├── desktop_ui/ # Desktop UI (Avalonia .NET) │ └── DeepClassify.App/ │ ├── Views/ # .axaml 页面 (6个) │ ├── ViewModels/ # MVVM ViewModel (8个) │ ├── Services/ # ApiClient + ThemeService │ └── Models/ # DTO 记录类型 │ ├── web_ui/ # Web UI (React + Vite) │ └── src/ │ ├── pages/ # 5个路由页面 │ ├── components/ # Layout / Sidebar / KnowledgeGraph │ └── stores/ # Zustand 状态 │ ├── src/ # Python 后端 │ ├── api/ # FastAPI (18个REST端点 + WebSocket) │ ├── pipeline.py # 核心管道 │ ├── scanner/ # 指纹扫描 (50+语言, 35+框架) │ ├── classifier/ # 三级分类 (AI主导 + 25条规则) │ ├── documentor/ # Jinja2文档生成 (5套模板) │ ├── rag_engine/ # 混合检索 (ChromaDB + FTS5 + RRF) │ ├── storage/ # SQLAlchemy + SQLite │ └── watch_service/ # 文件系统监听 │ ├── taxonomy.yaml # 分类体系 (9大类, 50+子类) ├── design-assets/ # ★ 设计资产 & 复用指南 │ ├── README.md # 设计资产复用文档 │ └── BLOG.md # 本篇博客 └── docs/ # 架构 + RAG + 嵌入模型 文档

适用场景 & 局限

适合

  • 管理大量散落的代码工程(嵌入式 / AI / Web / FPGA 混合场景尤其受益)
  • 团队知识管理 —— 新人来了能快速了解每个工程是干什么的
  • 个人开发者整理多年的代码积累
  • 对代码隐私有严格要求的环境

不适合

  • 单个巨型 monorepo 的分类(扫描器针对独立工程目录设计)
  • 需要协作编辑的场景(文档生成是单向的)
  • 动态语言的精确分类(Python/JS 工程的框架检测不如 C/C++ 工程精确)

写在最后

这个项目的核心思路很简单:让 AI 读你的代码,帮你理解你的代码

http://www.jsqmd.com/news/1078701/

相关文章:

  • 机器学习新手实操地图:5种可解释算法从入门到运行
  • TscanCode深度解析:高性能多语言静态代码分析引擎架构与优化策略
  • 3dsmax更换背景的详细操作
  • 关于算法稳定性与数据分布的内在联系研究的技术8
  • [智能体-517]:AI 软件工程全流程工具(完整 SDLC 生命周期,2026 最新)
  • 使用subagent组建WPF视觉开发团队,全自动开发
  • 时间序列回归实战:滞后特征与滑动窗口工程指南
  • Java国密SM2算法实战:从Bouncy Castle集成到Spring Boot应用
  • 展筑沪上势能:2026上海靠谱展厅设计搭建公司深度实测梳理
  • 第三视觉理解徐玉生与他的商业活动(3)
  • 关于图染色问题的NP完全性与启发式求解的技术8
  • 决策树分类:可解释AI的透明逻辑与工业级落地
  • 多智能体(Multi-Agent)协同:从Workflow失控到Orchestration编排
  • 你会亲手构建什么
  • 如何从Search Agent 方向,切入到 Coding Agent?
  • Elasticsearch介绍
  • IntelliJ IDEA离线安装全攻略(含JetBrains Toolbox替代方案):无网络环境下的3种纯净部署路径,企业IT管理员已批量验证
  • AI 大模型 API 调用报错怎么查?先从错误码看起
  • 最新用 AI 学量化表达,别脱离 Python 和 API 流程
  • RAG的另类思考
  • 计算机岗位100篇___大模型应用开发工程师
  • Leader 考核实习生:“你怎么配置 Claude Code?” 我挠头:“多写 Skills?” 她摇头:“明天别来了!”
  • HIP 编译器优化详解,ROCm 7.x 如何提升大模型推理效率
  • 最新量化开发提效,AI 先检查代码逻辑和流程缺口
  • API 接口可达性检测指南:Postman 能通、全国用户不通的真相
  • AI会成为跟编辑器一样新的一个中间层
  • aeneas:音频和文字自动对齐,支持38种语言
  • Redis 缓存穿透与雪崩问题解决方案
  • 【设计文档+源码+数据集】基于YOLOv8+Flask的罂粟识别系统
  • 小chunk和大段落,SproutRAG用注意力组起来了