Files

1 line
38 KiB
JSON
Raw Permalink 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.
{"repo": "chengannnn/codemind-agent", "files": {"README.md": {"5dcb619e2f34d967c2b3752e0405b8cd033e50ef": {"t": 1785747286.978339, "n": 10532, "h": "d242ac5e8dcd6767", "c": "# CodeMind Agent — 基于 LangGraph 的自动化代码审查与修复多智能体系统\n\n> 一个具备**自我进化记忆能力**的多智能体代码审查引擎,通过严格的状态机路由、三层记忆架构与向量语义匹配,实现从「接收代码 → 智能分发 → 审查诊断 → 自动修复 → 经验沉淀」的完整自动化闭环。\n\n---\n\n## 📑 目录\n\n- [项目简介](#-项目简介)\n- [核心特性](#-核心特性)\n- [系统架构与运行流程](#-系统架构与运行流程)\n- [项目结构与模块说明](#-项目结构与模块说明)\n- [快速开始](#-快速开始)\n- [技术栈](#-技术栈)\n- [架构设计理念](#-架构设计理念)\n\n---\n\n## 📖 项目简介\n\n**CodeMind Agent** 是一个基于 **LangGraph** 构建的 Multi-Agent 代码审查与修复系统。传统代码审查工具往往只做静态分析或单次 LLM 调用,而本系统将大语言模型的推理能力与**有状态图工作流**深度结合,带来了以下差异化价值:\n\n| 维度 | 传统方案 | CodeMind Agent |\n|:---|:---|:---|\n| 审查深度 | 单轮 LLM 调用 | Manager 规划 → Reviewer 审查 → Fixer 修复,多轮迭代 |\n| 经验复用 | 无 | ChromaDB 向量检索,历史相似 Bug 的修复方案可被直接复用 |\n| 持续对话 | 每次独立 | 摘要压缩 + 状态隔离,支持多轮连续审查任务 |\n| 流程控制 | 线性或无 | 严格 SOP 状态机路由,避免无限循环与资源浪费 |\n\n系统的核心理念是:**审查一个 Bug 的经验,应该成为修复下一个 Bug 的资产**。通过向量化的长期记忆,系统能够在遇到相似问题时\"秒级响应\",真正实现越用越聪明的自我进化能力。\n\n---\n\n## ✨ 核心特性\n\n### 🔄 状态机路由架构 (State Machine Routing)\n\n系统摒弃了 LLM 自由发散的调用模式,采用 **MECE(Mutually Exclusive, Collectively Exhaustive)** 原则设计的严格 SOP 路由策略。Manager 节点根据当前执行阶段(`execution_history`)和长期记忆匹配状态(`match_status`)进行确定性的下一跳决策:\n\n- **状态 A — 流程收敛**:已有 Fixer 输出 → 判定任务完成,流转至 `FINISH`\n- **状态 B — 先审后修**:已有 Reviewer 输出但无 Fixer 输出 → 派发至 `fixer`\n- **状态 C — 冷启动**:根据 `match_status` 决策\n - `IDENTICAL` → 直接 `FINISH`,历史方案即为答案\n - `SIMILAR` → 派发 `fixer`,参照历史经验直接修复\n - `NONE` → 派发 `reviewer`,从零开始完整审查\n\n这种设计确保了**每个节点只执行一次**,杜绝了 LangGraph 工作流中常见的无限循环问题。\n\n### 🧠 三层记忆机制 (Three-Tier Memory)\n\n| 层级 | 载体 | 容量策略 | 作用 |\n|:---|:---|:---|:---|\n| **短期记忆** | `state[\"messages\"]` (add_messages Reducer) | LangGraph 原生消息队列 | 承载当前审查任务的完整对话上下文 |\n| **中期记忆** | `state[\"summary\"]` (LLM 摘要) | 消息 > 6 条时触发压缩 | 防止上下文膨胀,保留任务关键信息 |\n| **长期记忆** | ChromaDB 向量库 (`chroma_db/`) | 持久化磁盘存储 | 跨任务复用历史 Bug 的审查结论与修复方案 |\n\n### 🎯 向量查重与捷径匹配 (Vector Matching & Short-circuit)\n\n长期记忆检索不是简单的\"相关与否\"二分判断,而是通过 **代码精确比对 + 向量距离阈值** 实现三态匹配:\n\n```\n用户输入代码 ──► ChromaDB similarity_search_with_score(k=1)\n │\n ├── 完全匹配 (page_content.strip() == input.strip())\n │ └──► IDENTICAL ──► 历史修复方案即为答案,直接秒杀\n │\n ├── L2 距离 < 0.2\n │ └──► SIMILAR ──► 存在高度相似的修复经验,模仿修复\n │\n └── 其余情况\n └──► NONE ──► 全新问题,启动完整审查流程\n```\n\n- **IDENTICAL(完全一致)**:代码去重命中,直接输出历史修复方案,**跳过 Reviewer 和 Fixer**,零 LLM 调用消耗\n- **SIMILAR(高度相似)**:向量距离 `< 0.2`,检索到的历史修复方案作为 Few-shot 提示注入 Fixer,实现**经验迁移**\n- **NONE(全新问题)**:无相关历史,启动标准的 Reviewer → Fixer 完整链路,并在任务结束后将新经验入库\n\n### ♻️ 优雅的内存回收 (Graceful Garbage Collection)\n\nLangGraph 的 `add_messages` Reducer 天然支持消息累加,但在多轮连续对话场景下会导致:\n\n- 上一个任务的审查意见\"泄漏\"到下一个任务\n- `current_code` 等状态字段残留,造成逻辑混乱\n- 消息队列无限膨胀,上下文窗口快速耗尽\n\n`clear` 节点通过双重清理机制解决此问题:\n\n1. **消息级清理**:遍历所有 `messages`,为每条消息构造 `RemoveMessage(id=m.id)`,利用 Reducer 的反向语义删除旧消息\n2. **状态级清理**:将所有业务字段(`current_code`、`summary`、`plan` 等)重置为初始值\n\n清理完成后,系统通过 `continue_router` 与用户交互,选择继续下一个任务或安全退出,形成 **CLI 闭环**。\n\n---\n\n## 🏗️ 系统架构与运行流程\n\n### 整体数据流图\n\n![CodeMind 流程图](codemind_liuchengtu.png)\n\n### 单轮任务执行详解\n\n**1. `user_input` 接收代码**\n\n用户以多行形式粘贴待审查代码,输入 `EOF` 终止。节点将代码同时写入 `current_code`(工作副本)和 `user_input_code`(原始快照,防止后续被修改导致记忆污染)。\n\n**2. `retrieve_memory` 向量检索**\n\n将 `current_code` 通过 BAAI/bge-m3 模型编码为向量,在 ChromaDB 的 `historical_bug_fixes` 集合中检索最相似的 1 条记录。根据代码精确匹配度和 L2 距离,产出 `match_status` 标签(`IDENTICAL` / `SIMILAR` / `NONE`)。\n\n**3. `manager` 大脑决策**\n\n读取当前 `messages` 中的执行历史,判断 Reviewer/Fixer 是否已执行。结合 `match_status` 标签,通过 LLM + Pydantic 结构化输出,产出:\n- `plan`:审查/修复步骤列表\n- `next_worker`:下一个执行节点(`reviewer` / `fixer` / `FINISH`)\n\n**4. `reviewer` 审查 / `fixer` 修复**\n\n- **Reviewer**:基于 Manager 的审查计划,对 `current_code` 进行深度代码审查,输出结构化审查报告\n- **Fixer**:基于历史经验 + 近期审查意见 + 原始代码,使用 Pydantic `FixResult` 模型输出修复后的代码和说明,**物理更新** `state[\"current_code\"]`\n\n**5. `save_experience` 经验沉淀**\n\n从消息历史中提取 Fixer 的修复结果。通过**代码去重拦截**检查:相同代码不重复入库。将 `<代码, 修复方案>` 作为 Document 持久化至 ChromaDB。\n\n**6. `summarize` 摘要压缩**\n\n当 `messages` 数量超过 6 条时,触发 LLM 摘要压缩。将旧消息浓缩为 `summary` 字段,同时用 `RemoveMessage` 删除原始消息。\n\n**7. `clear` 状态清零**\n\n彻底清空所有状态字段,为下一轮任务提供\"白纸\"状态。\n\n**8. `continue_router` 闭环交互**\n\n询问用户是否继续输入下一个待审查代码。`y` → 回到 `user_input` 开始新一轮;`n` → 系统安全退出。\n\n---\n\n## 📁 项目结构与模块说明\n\n```\ncode_reviewer_agent/\n├── main.py # 入口文件 & LangGraph StateGraph 编排\n├── state.py # 全局状态定义 (TypedDict)\n├── requirements.txt # Python 依赖清单\n├── .gitignore # Git 忽略规则\n├── .env # 环境变量配置 (API Keys, 不提交至 Git)\n├── agents/ # 智能体模块 (Worker Nodes)\n│ ├── manager.py # Manager 大脑:规划 + SOP 路由决策\n│ ├── reviewer.py # Reviewer 审查员:代码审查报告\n│ └── fixer.py # Fixer 修复专家:代码修复 + 结构化输出\n├── memory/ # 三层记忆模块\n│ ├── short_term.py # 短期记忆:滑动窗口工具类 (独立组件)\n│ ├── mid_term.py # 中期记忆:对话摘要压缩节点\n│ └── long_term.py # 长期记忆:ChromaDB 向量读写核心\n├── nodes/ # 工作流节点\n│ ├── user_input.py # 用户输入接收节点\n│ └── clear.py # 状态清理与 GC 节点\n├── utils/ # 工具类\n│ └── config.py # 环境变量加载与校验\n├── chroma_db/ # ChromaDB 持久化存储目录 (已忽略)\n│ └── chroma.sqlite3 # 向量数据库文件 (运行时自动生成)\n└── __pycache__/ # Python 字节码缓存 (已忽略)\n```\n\n### 模块详细说明\n\n#### `state.py` — 全局状态定义\n\n定义 LangGraph 工作流的共享状态,采用 `TypedDict` 声明:\n\n| 字段 | 类型 | 说明 |\n|:---|:---|:---|\n| `messages` | `Annotated[Sequence[BaseMessage], add_messages]` | 短期记忆消息队列,LangGraph 原生 Reducer 自动管理追加/删除 |\n| `summary` | `str` | 中期记忆:对话摘要,由 `summarize` 节点维护 |\n| `long_term_context` | `str` | 从 ChromaDB 检索到的历史经验,注入给 Manager 和 Fixer |\n| `current_code` | `str` | 当前正在处理的代码副本,Fixer 会物理修改此字段 |\n| `user_input_code` | `str` | 用户原始输入快照,**永不修改**,用于 `save_experience` 时保证存入的是原始代码 |\n| `plan` | `list[str]` | Manager 生成的审查/修复步骤列表 |\n| `next_worker` | `str` | Manager 决策的下一跳节点名 |\n| `match_status` | `str` | 长期记忆匹配状态:`IDENTICAL` / `SIMILAR` / `NONE` |\n\n> **设计亮点**:`user_input_code` 与 `current_code` 的分离是关键设计。Fixer 节点会覆盖 `current_code`,但经验沉淀必须使用原始代码作为索引键——如果存入修复后的代码,下次相似问题时将无法正确匹配。\n\n---\n\n#### `main.py` — 工作流编排核心\n\n- 定义 LangGraph `StateGraph`,注册所有节点和边\n- **条件边 (Conditional Edges)** 实现动态路由:\n - `manager → router` 决定派发至 `reviewer`、`fixer` 或 `save_experience`\n - `clear → continue_router` 决定循环或退出\n- 使用 `app.stream()` 以流式方式执行工作流,实时打印每个节点的输出\n\n---\n\n#### `agents/manager.py` — 大脑节点\n\nManager 是整个系统的决策中枢,职责包括:\n\n1. **上下文聚合**:从 `state[\"messages\"]` 中提取执行历史,识别 Reviewer/Fixer 的执行状态\n2. **LLM 规划**:通过 `ChatPromptTemplate` 构建 SOP 提示词,驱动 LLM 输出 `TaskPlan`(Pydantic 结构化输出)\n3. **路由决策**:基于执行历史和匹配状态的笛卡尔组合确定 `next_worker`\n\n**SOP 路由规则 (MECE)**:\n\n```\nIF fixer 已执行过:\n → FINISH (流程终结)\nELIF reviewer 已执行过:\n → fixer (先审后修)\nELSE:\n IF match_status == \"IDENTICAL\":\n → FINISH (历史方案直接输出)\n ELIF match_status == \"SIMILAR\":\n → fixer (参照历史经验修复)\n ELSE:\n → reviewer (从零开始完整审查)\n```\n\n---\n\n#### `agents/reviewer.py` — 审查节点\n\n- 接收 Manager 制定的 `plan` 和 `current_code`\n- 以 `temperature=0.3` 的 LLM 进行深度代码审查\n- 输出格式化的审查报告,以 `AIMessage` 形式追加至消息队列\n- 审查意见会包含在后续 Fixer 的上下文中,形成 **Review → Fix 的信息传递链**\n\n---\n\n#### `agents/fixer.py` — 修复节点\n\n- 接收三重上下文:长期记忆经验 + 近期审查意见 + 原始代码\n- 使用 **Pydantic `FixResult` 模型**约束 LLM 输出结构:`fixed_code`(修复后的完整代码)+ `explanation`(修改说明)\n- 通过 `PydanticOutputParser` 实现结构化解析,避免 LLM 自由文本导致的解析失败\n- **物理更新** `state[\"current_code\"]`,确保最终输出的是修复后的代码\n\n---\n\n#### `memory/long_term.py` — 长期记忆核心\n\n整个系统\"自我进化\"能力的技术底座:\n\n- **向量存储**:ChromaDB 持久化于 `chroma_db/` 目录,集合名 `historical_bug_fixes`\n- **Embedding 模型**:通过 SiliconFlow API 调用 `BAAI/bge-m3`(支持多语言、高质量语义表征)\n- **写入流程**:先执行相似度查重 → 精确匹配则跳过入库(代码去重拦截) → 否则以 `<代码内容, 修复方案元数据>` 格式入库\n- **检索流程**:对输入代码进行 Top-K 向量检索 → 三态判定(IDENTICAL / SIMILAR / NONE) → 返回格式化的上下文字符串 + 状态标签\n\n---\n\n#### `memory/mid_term.py` — 中期记忆节点\n\n- **触发条件**:`messages` 数量 > 6 条时激活\n- **压缩策略**:将历史消息(排除最近 2 条,保留近期上下文)送入 LLM 进行摘要融合\n- **清理策略**:生成新摘要后,用 `RemoveMessage` 删除已被压缩的原始消息,释放上下文窗口\n\n---\n\n#### `memory/short_term.py` — 短期记忆工具类\n\n- 基于 `collections.deque` 的滑动窗口实现\n- 当前工作流中未直接调用,`state[\"messages\"]` 的 `add_messages` Reducer 天然实现了短期记忆功能\n- 作为独立组件保留,可在需要更精细窗口控制的场景中替换原生 Reducer\n\n---\n\n#### `nodes/user_input.py` — 用户输入节点\n\n- 采用循环 `input()` 接收多行代码,以 `EOF` 作为终止标记\n- 将代码同时写入 `user_input_code`(原始快照)和 `current_code`(工作副本)\n- 附加标准化的用户需求提示词\n\n---\n\n#### `nodes/clear.py` — 状态清理节点\n\n解决 LangGraph 多轮对话的核心痛点:\n\n- **消息清理**:为所有消息构造 `RemoveMessage`,利用 `add_messages` Reducer 的反向语义彻底清空队列\n- **状态重置**:将所有业务字段归零,确保下一个任务从\"白纸\"状态开始\n- **脏状态隔离**:防止上一个任务的审查意见和代码污染下一个任务\n\n---\n\n#### `utils/config.py` — 配置管理\n\n- 统一加载 `.env` 文件中的环境变量\n- 提供 `get_env_var()` 校验函数,缺失变量时抛出明确异常\n- 导出全局常量:`DEEPSEEK_API_KEY`、`DEEPSEEK_BASE_URL`、`EMBEDDING_API_KEY`、`EMBEDDING_BASE_URL`\n\n---\n\n## 🚀 快速开始\n\n### 环境要求\n\n- Python >= 3.9\n- 有效的 API Key(见下方环境变量配置)\n\n### 1. 安装依赖\n\n```bash\npip install -r requirements.txt\n```\n\n### 2. 配置环境变量\n\n在项目根目录创建 `.env` 文件,填入以下配置:\n\n```env\n# DeepSeek LLM (用于 Manager / Reviewer / Fixer 的推理)\nDEEPSEEK_API_KEY=your_deepseek_api_key_here\nDEEPSEEK_BASE_URL=https://api.deepseek.com\n\n# SiliconFlow Embedding API (用于 BAAI/bge-m3 向量编码)\nEMBEDDING_API_KEY=your_siliconflow_api_key_here\nEMBEDDING_BASE_URL=https://api.siliconflow.cn/v1\n```\n\n> **说明**:向量 Embedding 服务通过 SiliconFlow 平台调用 `BAAI/bge-m3` 模型,需单独申请 API Key。\n\n### 3. 运行系统\n\n```bash\npython main.py\n```\n\n系统启动后,按提示粘贴待审查的代码,以 `EOF` 结束输入即可开始自动化审查与修复流程。\n\n### 使用示例\n\n```\n==================================================\n\n🚀 系统开始运行...\n\n==================================================\n(请在此粘贴你的代码,最后一行输入 EOF)\n\ndef cal_average(numbers):\n total = 0\n for n in numbers:\n total = total + n\n result = total / len(numbers)\n return result\nEOF\n\n--- [retrieve_memory执行完毕] ---\n--- [manager执行完毕] ---\n--- [reviewer执行完毕] ---\n => ## 代码审查报告\n 1. ZeroDivisionError: 当 numbers 为空列表时...\n 2. ...\n--- [manager执行完毕] ---\n--- [fixer执行完毕] ---\n => 修复说明: 添加了空列表校验和类型注解...\n\n 是否需要继续输入下一个待修改代码?(y/n):\n```\n\n---\n\n## 🛠️ 技术栈\n\n| 组件 | 技术选型 | 作用 |\n|:---|:---|:---|\n| **编排框架** | [LangGraph](https://github.com/langchain-ai/langgraph) | 有状态图工作流、条件边、Reducer 状态管理 |\n| **LLM 推理** | [LangChain](https://github.com/langchain-ai/langchain) | Prompt 模板、输出解析器、消息管理 |\n| **大语言模型** | DeepSeek (`deepseek-chat`) | Manager 规划、Reviewer 审查、Fixer 修复、摘要压缩 |\n| **向量数据库** | [ChromaDB](https://github.com/chroma-core/chroma) | 长期记忆的持久化向量存储,支持相似度检索 |\n| **Embedding 模型** | BAAI/bge-m3 (via SiliconFlow) | 多语言代码语义向量化,L2 距离相似度计算 |\n| **数据校验** | [Pydantic](https://github.com/pydantic/pydantic) | LLM 结构化输出 (`TaskPlan`, `FixResult`) |\n| **环境管理** | python-dotenv | `.env` 文件加载与变量注入 |\n\n---\n\n> *Built with LangGraph & DeepSeek — Making Code Review Intelligent, Memory-Driven, and Self-Evolving.*\n"}, "3f1e4cfe8b85514c4d456b245bfa5b5fbd99bc8b": {"t": 1785772156.3224697, "n": 12414, "h": "a74af6e1ea6d2573", "c": "# CodeMind Agent — 基于 LangGraph 的自动化代码审查与修复多智能体系统\n\n> 一个具备**自我进化记忆能力**的多智能体代码审查引擎,通过严格的状态机路由、三层记忆架构与向量语义匹配,实现从「接收代码 → 智能分发 → 审查诊断 → 自动修复 → 经验沉淀」的完整自动化闭环。\n\n---\n\n## 📑 目录\n\n- [项目简介](#-项目简介)\n- [核心特性](#-核心特性)\n- [系统架构与运行流程](#-系统架构与运行流程)\n- [项目结构与模块说明](#-项目结构与模块说明)\n- [快速开始](#-快速开始)\n- [技术栈](#-技术栈)\n- [架构设计理念](#-架构设计理念)\n\n---\n\n## 📖 项目简介\n\n**CodeMind Agent** 是一个基于 **LangGraph** 构建的 Multi-Agent 代码审查与修复系统。传统代码审查工具往往只做静态分析或单次 LLM 调用,而本系统将大语言模型的推理能力与**有状态图工作流**深度结合,带来了以下差异化价值:\n\n| 维度 | 传统方案 | CodeMind Agent |\n|:---|:---|:---|\n| 审查深度 | 单轮 LLM 调用 | Manager 规划 → Reviewer 审查 → Fixer 修复,多轮迭代 |\n| 经验复用 | 无 | ChromaDB 向量检索,历史相似 Bug 的修复方案可被直接复用 |\n| 持续对话 | 每次独立 | 摘要压缩 + 状态隔离,支持多轮连续审查任务 |\n| 流程控制 | 线性或无 | 严格 SOP 状态机路由,避免无限循环与资源浪费 |\n\n系统的核心理念是:**审查一个 Bug 的经验,应该成为修复下一个 Bug 的资产**。通过向量化的长期记忆,系统能够在遇到相似问题时\"秒级响应\",真正实现越用越聪明的自我进化能力。\n\n---\n\n## ✨ 核心特性\n\n### 🔄 状态机路由架构 (State Machine Routing)\n\n系统摒弃了 LLM 自由发散的调用模式,采用 **MECE(Mutually Exclusive, Collectively Exhaustive)** 原则设计的严格 SOP 路由策略。Manager 节点根据当前执行阶段(`execution_history`)和长期记忆匹配状态(`match_status`)进行确定性的下一跳决策:\n\n- **状态 A — 流程收敛**:已有 Fixer 输出 → 判定任务完成,流转至 `FINISH`\n- **状态 B — 先审后修**:已有 Reviewer 输出但无 Fixer 输出 → 派发至 `fixer`\n- **状态 C — 冷启动**:根据 `match_status` 决策\n - `IDENTICAL` → 直接 `FINISH`,历史方案即为答案\n - `SIMILAR` → 派发 `fixer`,参照历史经验直接修复\n - `NONE` → 派发 `reviewer`,从零开始完整审查\n\n这种设计确保了**每个节点只执行一次**,杜绝了 LangGraph 工作流中常见的无限循环问题。\n\n### 🧠 三层记忆机制 (Three-Tier Memory)\n\n| 层级 | 载体 | 容量策略 | 作用 |\n|:---|:---|:---|:---|\n| **短期记忆** | `state[\"messages\"]` (add_messages Reducer) | LangGraph 原生消息队列 | 承载当前审查任务的完整对话上下文 |\n| **中期记忆** | `state[\"summary\"]` (LLM 摘要) | 消息 > 6 条时触发压缩 | 防止上下文膨胀,保留任务关键信息 |\n| **长期记忆** | ChromaDB 向量库 (`chroma_db/`) | 持久化磁盘存储 | 跨任务复用历史 Bug 的审查结论与修复方案 |\n\n### 🎯 向量查重与捷径匹配 (Vector Matching & Short-circuit)\n\n长期记忆检索不是简单的\"相关与否\"二分判断,而是通过 **代码精确比对 + 向量距离阈值** 实现三态匹配:\n\n```\n用户输入代码 ──► ChromaDB similarity_search_with_score(k=1)\n │\n ├── 完全匹配 (page_content.strip() == input.strip())\n │ └──► IDENTICAL ──► 历史修复方案即为答案,直接秒杀\n │\n ├── L2 距离 < 0.2\n │ └──► SIMILAR ──► 存在高度相似的修复经验,模仿修复\n │\n └── 其余情况\n └──► NONE ──► 全新问题,启动完整审查流程\n```\n\n- **IDENTICAL(完全一致)**:代码去重命中,直接输出历史修复方案,**跳过 Reviewer 和 Fixer**,零 LLM 调用消耗\n- **SIMILAR(高度相似)**:向量距离 `< 0.2`,检索到的历史修复方案作为 Few-shot 提示注入 Fixer,实现**经验迁移**\n- **NONE(全新问题)**:无相关历史,启动标准的 Reviewer → Fixer 完整链路,并在任务结束后将新经验入库\n\n### ♻️ 优雅的内存回收 (Graceful Garbage Collection)\n\nLangGraph 的 `add_messages` Reducer 天然支持消息累加,但在多轮连续对话场景下会导致:\n\n- 上一个任务的审查意见\"泄漏\"到下一个任务\n- `current_code` 等状态字段残留,造成逻辑混乱\n- 消息队列无限膨胀,上下文窗口快速耗尽\n\n`clear` 节点通过双重清理机制解决此问题:\n\n1. **消息级清理**:遍历所有 `messages`,为每条消息构造 `RemoveMessage(id=m.id)`,利用 Reducer 的反向语义删除旧消息\n2. **状态级清理**:将所有业务字段(`current_code`、`summary`、`plan` 等)重置为初始值\n\n清理完成后,系统通过 `continue_router` 与用户交互,选择继续下一个任务或安全退出,形成 **CLI 闭环**。\n\n---\n\n## 🏗️ 系统架构与运行流程\n\n### 整体数据流图\n\n```\n ┌──────────────┐\n │ user_input │ ◄── 用户输入带 Bug 的代码 (EOF 终止)\n └──────┬───────┘\n │\n ┌──────▼──────────────┐\n │ retrieve_memory │ ◄── ChromaDB 向量检索,打上 match_status 标签\n │ (IDENTICAL/SIMILAR │ (三种状态决定后续路由走向)\n │ /NONE) │\n └──────┬─────────────┘\n │\n ┌──────▼──────────────┐\n │ manager │ ◄── 大脑节点:生成审查计划 + 决策下一跳\n │ (Plan-Act + SOP) │ 基于 match_status + execution_history\n └──────┬──────────────┘\n │\n ┌────────────┼────────────────┐\n ▼ ▼ ▼\n ┌──────────┐ ┌──────────┐ ┌──────────────┐\n │ reviewer │ │ fixer │ │save_experience│\n │ (审查) │ │ (修复) │ │ (经验入库) │\n └────┬─────┘ └────┬─────┘ └──────┬───────┘\n │ │ │\n └────────────┘ │\n │ │\n 回传 manager │\n │ │\n └────────────────────────┘\n │\n ┌──────▼───────┐\n │ summarize │ ◄── 对话摘要压缩 (消息 > 6 时触发)\n │ (mid-term) │\n └──────┬───────┘\n │\n ┌──────▼───────┐\n │ clear │ ◄── 状态清零,隔离脏数据\n │ (GC 清理) │\n └──────┬───────┘\n │\n ┌──────▼───────┐\n │continue_router│ ◄── 询问用户是否继续\n │ (y → loop) │\n │ (n → END) │\n └──────────────┘\n```\n\n### 单轮任务执行详解\n\n**1. `user_input` 接收代码**\n\n用户以多行形式粘贴待审查代码,输入 `EOF` 终止。节点将代码同时写入 `current_code`(工作副本)和 `user_input_code`(原始快照,防止后续被修改导致记忆污染)。\n\n**2. `retrieve_memory` 向量检索**\n\n将 `current_code` 通过 BAAI/bge-m3 模型编码为向量,在 ChromaDB 的 `historical_bug_fixes` 集合中检索最相似的 1 条记录。根据代码精确匹配度和 L2 距离,产出 `match_status` 标签(`IDENTICAL` / `SIMILAR` / `NONE`)。\n\n**3. `manager` 大脑决策**\n\n读取当前 `messages` 中的执行历史,判断 Reviewer/Fixer 是否已执行。结合 `match_status` 标签,通过 LLM + Pydantic 结构化输出,产出:\n- `plan`:审查/修复步骤列表\n- `next_worker`:下一个执行节点(`reviewer` / `fixer` / `FINISH`)\n\n**4. `reviewer` 审查 / `fixer` 修复**\n\n- **Reviewer**:基于 Manager 的审查计划,对 `current_code` 进行深度代码审查,输出结构化审查报告\n- **Fixer**:基于历史经验 + 近期审查意见 + 原始代码,使用 Pydantic `FixResult` 模型输出修复后的代码和说明,**物理更新** `state[\"current_code\"]`\n\n**5. `save_experience` 经验沉淀**\n\n从消息历史中提取 Fixer 的修复结果。通过**代码去重拦截**检查:相同代码不重复入库。将 `<代码, 修复方案>` 作为 Document 持久化至 ChromaDB。\n\n**6. `summarize` 摘要压缩**\n\n当 `messages` 数量超过 6 条时,触发 LLM 摘要压缩。将旧消息浓缩为 `summary` 字段,同时用 `RemoveMessage` 删除原始消息。\n\n**7. `clear` 状态清零**\n\n彻底清空所有状态字段,为下一轮任务提供\"白纸\"状态。\n\n**8. `continue_router` 闭环交互**\n\n询问用户是否继续输入下一个待审查代码。`y` → 回到 `user_input` 开始新一轮;`n` → 系统安全退出。\n\n---\n\n## 📁 项目结构与模块说明\n\n```\ncode_reviewer_agent/\n├── main.py # 入口文件 & LangGraph StateGraph 编排\n├── state.py # 全局状态定义 (TypedDict)\n├── requirements.txt # Python 依赖清单\n├── .gitignore # Git 忽略规则\n├── .env # 环境变量配置 (API Keys, 不提交至 Git)\n├── agents/ # 智能体模块 (Worker Nodes)\n│ ├── manager.py # Manager 大脑:规划 + SOP 路由决策\n│ ├── reviewer.py # Reviewer 审查员:代码审查报告\n│ └── fixer.py # Fixer 修复专家:代码修复 + 结构化输出\n├── memory/ # 三层记忆模块\n│ ├── short_term.py # 短期记忆:滑动窗口工具类 (独立组件)\n│ ├── mid_term.py # 中期记忆:对话摘要压缩节点\n│ └── long_term.py # 长期记忆:ChromaDB 向量读写核心\n├── nodes/ # 工作流节点\n│ ├── user_input.py # 用户输入接收节点\n│ └── clear.py # 状态清理与 GC 节点\n├── utils/ # 工具类\n│ └── config.py # 环境变量加载与校验\n├── chroma_db/ # ChromaDB 持久化存储目录 (已忽略)\n│ └── chroma.sqlite3 # 向量数据库文件 (运行时自动生成)\n└── __pycache__/ # Python 字节码缓存 (已忽略)\n```\n\n### 模块详细说明\n\n#### `state.py` — 全局状态定义\n\n定义 LangGraph 工作流的共享状态,采用 `TypedDict` 声明:\n\n| 字段 | 类型 | 说明 |\n|:---|:---|:---|\n| `messages` | `Annotated[Sequence[BaseMessage], add_messages]` | 短期记忆消息队列,LangGraph 原生 Reducer 自动管理追加/删除 |\n| `summary` | `str` | 中期记忆:对话摘要,由 `summarize` 节点维护 |\n| `long_term_context` | `str` | 从 ChromaDB 检索到的历史经验,注入给 Manager 和 Fixer |\n| `current_code` | `str` | 当前正在处理的代码副本,Fixer 会物理修改此字段 |\n| `user_input_code` | `str` | 用户原始输入快照,**永不修改**,用于 `save_experience` 时保证存入的是原始代码 |\n| `plan` | `list[str]` | Manager 生成的审查/修复步骤列表 |\n| `next_worker` | `str` | Manager 决策的下一跳节点名 |\n| `match_status` | `str` | 长期记忆匹配状态:`IDENTICAL` / `SIMILAR` / `NONE` |\n\n> **设计亮点**:`user_input_code` 与 `current_code` 的分离是关键设计。Fixer 节点会覆盖 `current_code`,但经验沉淀必须使用原始代码作为索引键——如果存入修复后的代码,下次相似问题时将无法正确匹配。\n\n---\n\n#### `main.py` — 工作流编排核心\n\n- 定义 LangGraph `StateGraph`,注册所有节点和边\n- **条件边 (Conditional Edges)** 实现动态路由:\n - `manager → router` 决定派发至 `reviewer`、`fixer` 或 `save_experience`\n - `clear → continue_router` 决定循环或退出\n- 使用 `app.stream()` 以流式方式执行工作流,实时打印每个节点的输出\n\n---\n\n#### `agents/manager.py` — 大脑节点\n\nManager 是整个系统的决策中枢,职责包括:\n\n1. **上下文聚合**:从 `state[\"messages\"]` 中提取执行历史,识别 Reviewer/Fixer 的执行状态\n2. **LLM 规划**:通过 `ChatPromptTemplate` 构建 SOP 提示词,驱动 LLM 输出 `TaskPlan`(Pydantic 结构化输出)\n3. **路由决策**:基于执行历史和匹配状态的笛卡尔组合确定 `next_worker`\n\n**SOP 路由规则 (MECE)**:\n\n```\nIF fixer 已执行过:\n → FINISH (流程终结)\nELIF reviewer 已执行过:\n → fixer (先审后修)\nELSE:\n IF match_status == \"IDENTICAL\":\n → FINISH (历史方案直接输出)\n ELIF match_status == \"SIMILAR\":\n → fixer (参照历史经验修复)\n ELSE:\n → reviewer (从零开始完整审查)\n```\n\n---\n\n#### `agents/reviewer.py` — 审查节点\n\n- 接收 Manager 制定的 `plan` 和 `current_code`\n- 以 `temperature=0.3` 的 LLM 进行深度代码审查\n- 输出格式化的审查报告,以 `AIMessage` 形式追加至消息队列\n- 审查意见会包含在后续 Fixer 的上下文中,形成 **Review → Fix 的信息传递链**\n\n---\n\n#### `agents/fixer.py` — 修复节点\n\n- 接收三重上下文:长期记忆经验 + 近期审查意见 + 原始代码\n- 使用 **Pydantic `FixResult` 模型**约束 LLM 输出结构:`fixed_code`(修复后的完整代码)+ `explanation`(修改说明)\n- 通过 `PydanticOutputParser` 实现结构化解析,避免 LLM 自由文本导致的解析失败\n- **物理更新** `state[\"current_code\"]`,确保最终输出的是修复后的代码\n\n---\n\n#### `memory/long_term.py` — 长期记忆核心\n\n整个系统\"自我进化\"能力的技术底座:\n\n- **向量存储**:ChromaDB 持久化于 `chroma_db/` 目录,集合名 `historical_bug_fixes`\n- **Embedding 模型**:通过 SiliconFlow API 调用 `BAAI/bge-m3`(支持多语言、高质量语义表征)\n- **写入流程**:先执行相似度查重 → 精确匹配则跳过入库(代码去重拦截) → 否则以 `<代码内容, 修复方案元数据>` 格式入库\n- **检索流程**:对输入代码进行 Top-K 向量检索 → 三态判定(IDENTICAL / SIMILAR / NONE) → 返回格式化的上下文字符串 + 状态标签\n\n---\n\n#### `memory/mid_term.py` — 中期记忆节点\n\n- **触发条件**:`messages` 数量 > 6 条时激活\n- **压缩策略**:将历史消息(排除最近 2 条,保留近期上下文)送入 LLM 进行摘要融合\n- **清理策略**:生成新摘要后,用 `RemoveMessage` 删除已被压缩的原始消息,释放上下文窗口\n\n---\n\n#### `memory/short_term.py` — 短期记忆工具类\n\n- 基于 `collections.deque` 的滑动窗口实现\n- 当前工作流中未直接调用,`state[\"messages\"]` 的 `add_messages` Reducer 天然实现了短期记忆功能\n- 作为独立组件保留,可在需要更精细窗口控制的场景中替换原生 Reducer\n\n---\n\n#### `nodes/user_input.py` — 用户输入节点\n\n- 采用循环 `input()` 接收多行代码,以 `EOF` 作为终止标记\n- 将代码同时写入 `user_input_code`(原始快照)和 `current_code`(工作副本)\n- 附加标准化的用户需求提示词\n\n---\n\n#### `nodes/clear.py` — 状态清理节点\n\n解决 LangGraph 多轮对话的核心痛点:\n\n- **消息清理**:为所有消息构造 `RemoveMessage`,利用 `add_messages` Reducer 的反向语义彻底清空队列\n- **状态重置**:将所有业务字段归零,确保下一个任务从\"白纸\"状态开始\n- **脏状态隔离**:防止上一个任务的审查意见和代码污染下一个任务\n\n---\n\n#### `utils/config.py` — 配置管理\n\n- 统一加载 `.env` 文件中的环境变量\n- 提供 `get_env_var()` 校验函数,缺失变量时抛出明确异常\n- 导出全局常量:`DEEPSEEK_API_KEY`、`DEEPSEEK_BASE_URL`、`EMBEDDING_API_KEY`、`EMBEDDING_BASE_URL`\n\n---\n\n## 🚀 快速开始\n\n### 环境要求\n\n- Python >= 3.9\n- 有效的 API Key(见下方环境变量配置)\n\n### 1. 安装依赖\n\n```bash\npip install -r requirements.txt\n```\n\n### 2. 配置环境变量\n\n在项目根目录创建 `.env` 文件,填入以下配置:\n\n```env\n# DeepSeek LLM (用于 Manager / Reviewer / Fixer 的推理)\nDEEPSEEK_API_KEY=your_deepseek_api_key_here\nDEEPSEEK_BASE_URL=https://api.deepseek.com\n\n# SiliconFlow Embedding API (用于 BAAI/bge-m3 向量编码)\nEMBEDDING_API_KEY=your_siliconflow_api_key_here\nEMBEDDING_BASE_URL=https://api.siliconflow.cn/v1\n```\n\n> **说明**:向量 Embedding 服务通过 SiliconFlow 平台调用 `BAAI/bge-m3` 模型,需单独申请 API Key。\n\n### 3. 运行系统\n\n```bash\npython main.py\n```\n\n系统启动后,按提示粘贴待审查的代码,以 `EOF` 结束输入即可开始自动化审查与修复流程。\n\n### 使用示例\n\n```\n==================================================\n\n🚀 系统开始运行...\n\n==================================================\n(请在此粘贴你的代码,最后一行输入 EOF)\n\ndef cal_average(numbers):\n total = 0\n for n in numbers:\n total = total + n\n result = total / len(numbers)\n return result\nEOF\n\n--- [retrieve_memory执行完毕] ---\n--- [manager执行完毕] ---\n--- [reviewer执行完毕] ---\n => ## 代码审查报告\n 1. ZeroDivisionError: 当 numbers 为空列表时...\n 2. ...\n--- [manager执行完毕] ---\n--- [fixer执行完毕] ---\n => 修复说明: 添加了空列表校验和类型注解...\n\n 是否需要继续输入下一个待修改代码?(y/n):\n```\n\n---\n\n## 🛠️ 技术栈\n\n| 组件 | 技术选型 | 作用 |\n|:---|:---|:---|\n| **编排框架** | [LangGraph](https://github.com/langchain-ai/langgraph) | 有状态图工作流、条件边、Reducer 状态管理 |\n| **LLM 推理** | [LangChain](https://github.com/langchain-ai/langchain) | Prompt 模板、输出解析器、消息管理 |\n| **大语言模型** | DeepSeek (`deepseek-chat`) | Manager 规划、Reviewer 审查、Fixer 修复、摘要压缩 |\n| **向量数据库** | [ChromaDB](https://github.com/chroma-core/chroma) | 长期记忆的持久化向量存储,支持相似度检索 |\n| **Embedding 模型** | BAAI/bge-m3 (via SiliconFlow) | 多语言代码语义向量化,L2 距离相似度计算 |\n| **数据校验** | [Pydantic](https://github.com/pydantic/pydantic) | LLM 结构化输出 (`TaskPlan`, `FixResult`) |\n| **环境管理** | python-dotenv | `.env` 文件加载与变量注入 |\n\n---\n\n> *Built with LangGraph & DeepSeek — Making Code Review Intelligent, Memory-Driven, and Self-Evolving.*\n"}}}}