内容
# AI 工厂
> 将自然语言产品需求转化为可执行的开发任务 DAG,每个任务都带有 AI 工作者(或人类)的完整提示信息。
AI 工厂是一个 Spring Boot 服务,它编排了一个 AI 驱动的任务分解管道。它与 GitNexus(一个第三方的代码知识图谱服务)集成,用于符号级别的代码上下文,以及与 OpenAI 兼容的 LLM(例如 DashScope/Qwen),用于分解、澄清和代码生成。
> **注意:** GitNexus 是一个第三方的项目,不包含在这个存储库中。您需要单独部署和运行 GitNexus,然后在 `application.yml` 中配置其 MCP 端点 URL。
## 工作原理
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ 用户输入 │────▶│ GitNexus │────▶│ LLM 分割 │────▶│ DAG 步骤 │
│ (需求) │ │ (代码扫描) │ │ (任务) │ │ (带依赖) │
└─────────────┘ └──────────────┘ └─────────────┘ └──────┬───────┘
│
┌───────────────────────────────────────────────────┘
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 上下文聚合 │────▶│ 提示信息 │────▶│ AI 工作者 │
│ (每一步) │ │ 装配(8 部分)│ │ (认领→代码 │
│ │ │ │ │ →完成) │
└──────────────┘ └──────────────┘ └──────────────┘
```
### 两种分解模式
**模式 A — 直接分解** (`POST /tasks/decompose`):一次性 - 提交需求 → 获取任务 DAG。
**模式 B — 会话澄清** (`POST /chat/sessions`):交互式多轮细化,然后再分解。LLM 会根据 GitNexus 中的实际代码符号提出澄清问题,然后综合细化需求进行分解。
### 7 步分解管道
1. **创建父任务** — 插入 `Task(requirement, adminId)`
2. **GitNexus 查询** — 查找相关符号 + 执行流程("足迹")
3. **LLM 分割** — 将需求分解为 `TaskDraft[]`(目标符号必须来自足迹)
4. **推导依赖** — 对于每一步,调用 `impact()` 查找上游依赖 → 构建 DAG 边并检测环
5. **聚合上下文** — 对于每一步,拉取 `context()`(源代码、调用者)+ `impact()`(影响范围)
6. **组装提示** — 构建一个 8 部分的 Markdown 提示(目标符号、当前源代码、调用者、影响范围、设计细节、指令、约束)
7. **设置初始状态** — `dependsOnCount=0` → `READY`;否则 `PENDING`。父任务 → `READY` 或 `PARTIAL`
### 步骤状态机
```
PENDING ──(依赖→0)──▶ READY ──(认领)──▶ IN_PROGRESS ──(完成)──▶ DONE
▲ │
│ (失败/回滚) │
└──────────────────────┘
```
### AI 工作者执行
`POST /tasks/{id}/execute` 运行全自动闭环:
1. **原子认领** — CAS `UPDATE ... WHERE status='READY'`(乐观锁)
2. **LLM 代码生成** — `executeStep(generatedPrompt)` → 纯源代码
3. **写入文件** — 写入到 `repoBasePath/repo/targetFile`
4. **完成** — `detectChanges()` 验证磁盘变更 → 标记 `DONE` → 解锁后续任务并重新聚合上下文
5. **失败回滚** — `detectChanges` 失败 → `revertClaim()` → 步骤回滚到 `READY`(可重试)
## 为什么是 AI 工厂
与通用 "LLM → 代码" 工具不同,AI 工厂将每个决策都建立在 **实际代码结构** 上,并编排了一个 **多代理管道**,而不仅仅是一个提示:
- **代码知识图谱接地** — 任务目标符号、依赖边和提示上下文都来自 GitNexus 的符号级代码分析。没有 LLM 的幻觉 — LLM 只能选择代码库中实际存在的符号。
- **会话需求澄清** — 不是一次性 "提交 → 祝福" 按钮。LLM 会根据实际代码符号(例如 *"我看到 `BinaryLogClient` 已经有 `keepAlive`,心跳应该重用它吗?"*)提出聚焦的澄清问题,然后再分解。
- **自动 DAG 推导** — 步骤依赖关系通过代码影响分析自动推导,而不是手动指定。如果步骤 A 的符号被步骤 B 的符号调用,则自动创建 DAG 边并检测环。
- **上下文重新聚合** — 当前任务完成后,后续任务会自动获取新的 `context()` + `impact()` 调用。提示反映了代码库的 **当前** 状态,而不是分解时的过时快照。
- **全自动 AI 工作者闭环** — 认领 → LLM 生成代码 → 写入文件 → 验证磁盘变更 → 标记完成 → 解锁后续任务。快乐路径上不需要人为干预。
- **无降级架构** — 上游失败(GitNexus,LLM)抛出 → 事务回滚 → HTTP 503。没有静默空数据,没有备用路径,没有数据库中的半成品结果。
- **多工作者协作** — 基于 CAS 的原子认领防止跨并发 AI 实例的重复认领。`GET /tasks/steps/claimed?userId=` 允许工作者在会话之间恢复任务 — 对多代理并行开发的自然支持。
- **成本效益模型灵活性** — 由于每个步骤都带有完全组装的提示(带有源代码、调用者、设计细节 — 所有由 GitNexus 预先获取),因此 LLM 只需要 **编写代码**,而不需要 **理解代码库**。这意味着您可以使用便宜或免费的本地模型(例如 Qwen-7B、Llama 3、Ollama)进行步骤执行,同时为分解和澄清阶段保留昂贵的模型。
## 关键功能
- **基于 DAG 的任务分解** — 依赖关系源自实际代码结构(GitNexus 影响分析),而非 LLM 猜测
- **会话需求澄清** — 分解前进行多轮 LLM 交互,基于实际代码符号
- **完全组装的提示** — 每个步骤都带有 8 部分的 Markdown 提示,包含源代码、调用者、影响范围和设计细节
- **上下文重新聚合** — 当前任务完成后,后续任务获取新的上下文(代码变更 → 调用者/影响范围可能已偏移)
- **原子任务认领** — 基于 CAS 的 `UPDATE...WHERE status='READY'` 防止跨工作者的重复认领
- **失败回滚** — `detectChanges` 失败 → 步骤回滚到 `READY`(可重试);LLM 失败 → 事务回滚
- **多工作者支持** — `GET /tasks/steps/claimed?userId=X` 允许工作者在会话之间恢复任务
- **"无优雅降级"** — 所有上游失败都抛出 → HTTP 503(无静默空数据,无备用路径)
- **前端 UI** — 纯 HTML+JS 仪表盘,包含任务列表、DAG 可视化、步骤详情和聊天界面
## 技术栈
| 组件 | 技术 |
|---|---|
| 框架 | Spring Boot 3.4.5 / Java 17 |
| AI | Spring AI 1.0.0(兼容 OpenAI,例如 DashScope/Qwen) |
| 代码图谱 | GitNexus via MCP(可流式 HTTP 传输) |
| ORM | MyBatis-Plus 3.5.9(分页、乐观锁) |
| 数据库 | MySQL 8 + Flyway 迁移 |
| 测试 | JUnit 5 + Mockito + H2(内存) |
| 前端 | 纯 HTML + JavaScript(无框架) |
## 快速开始
### prerequisites
- Java 17+
- MySQL 8+(或使用 Docker)
- 一个运行中的 GitNexus 实例,索引您的代码库(第三方,单独部署)
- 一个与 OpenAI 兼容的 LLM API(例如 DashScope、OpenAI、Ollama)
### 构建和运行
```bash
git clone https://github.com/<your-org>/ai-factory.git
cd ai-factory
# 设置环境变量
export LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
export LLM_API_KEY=your-api-key
export LLM_MODEL=qwen-plus
export GITNEXUS_MCP_URL=http://[::1]:4747/api/mcp
export REPO_BASE_PATH=./repos
# 创建数据库
mysql -u root -p -e "CREATE DATABASE ai_factory"
# 运行
mvn spring-boot:run --server.port=8082
```
在浏览器中打开 http://localhost:8082。
### 配置
所有配置通过 `application.yml` 或环境变量:
| 属性 | 默认值 | 描述 |
|---|---|---|
| `spring.datasource.url` | `jdbc:mysql://localhost:3306/ai_factory` | MySQL 连接 |
| `spring.ai.openai.base-url` | `${LLM_BASE_URL}` | 与 OpenAI 兼容的 API 基地址 |
| `spring.ai.openai.api-key` | `${LLM_API_KEY}` | API 密钥 |
| `spring.ai.openai.chat.options.model` | `${LLM_MODEL}` | 模型名称 |
| `spring.ai.openai.chat.options.temperature` | `0.2` | 低温度,确保输出确定性 |
| `gitnexus.mcp.url` | `${GITNEXUS_MCP_URL:http://[::1]:4747/api/mcp}` | GitNexus MCP 端点 |
| `factory.worker.repo-base-path` | `${REPO_BASE_PATH:./repos}` | AI 工作者写入生成代码的位置 |
| `factory.clients.real.enabled` | `true` | 真实 GitNexus/LLM Bean 的开关(false = 测试存根) |
## REST API
### 任务端点 (`/tasks`)
| 方法 | 路径 | 描述 |
|---|---|---|
| POST | `/tasks/decompose` | 将需求分解为任务 DAG |
| POST | `/tasks/{id}/claim` | 工作者认领一个 READY 步骤(返回提示) |
| POST | `/tasks/{id}/complete` | 工作者完成一个步骤(触发后续任务解锁) |
| POST | `/tasks/{id}/execute` | 全自动:认领 → LLM → 写入文件 → 完成 |
| GET | `/tasks` | 任务列表(分页,可按状态过滤) |
| GET | `/tasks/{id}` | 获取任务详情 |
| GET | `/tasks/{id}/steps` | 步骤列表(分页) |
| GET | `/tasks/{id}/dependencies` | DAG 边列表 |
| GET | `/tasks/steps/claimed?userId=` | 工作者的已认领(IN_PROGRESS)步骤列表 |
| GET | `/tasks/steps/{stepId}` | 获取完整步骤详情(包括 generatedPrompt) |
### 聊天端点 (`/chat/sessions`)
| 方法 | 路径 | 描述 |
|---|---|---|
| POST | `/chat/sessions` | 启动澄清会话(GitNexus 扫描 + 第一个问题) |
| POST | `/chat/sessions/{id}/messages` | 发送答案,获取下一个问题或 `ready=true` |
| POST | `/chat/sessions/{id}/decompose` | 用细化需求确认分解 |
**错误处理**:`GitNexusException` / `LlmException` → HTTP 503 `{"code":"UPSTREAM_UNAVAILABLE","message":"..."}`。会话未找到 → HTTP 404。
## 项目结构
```
src/main/java/com/factory/ai/
├── FactoryApplication.java
├── config/
│ └── MyBatisPlusConfig.java # 分页 + 乐观锁拦截器
├── gitnexus/ # GitNexus MCP 集成
│ ├── GitNexusClient.java # 接口:查询 / 上下文 / 影响 / 变更检测
│ ├── SpringAiMcpGitNexusClient.java # 通过 MCP 调用工具的真实实现
│ ├── GitNexusMcpClientConfiguration.java # McpSyncClient Bean
│ ├── StreamableHttpClientTransport.java # 自定义 MCP 传输(POST → SSE 响应)
│ └── dto/ # SymbolRef, QueryResult, SymbolContext, ImpactResult
├── task/
│ ├── domain/ # Task, TaskStep, TaskDependency, 枚举
│ ├── mapper/ # MyBatis-Plus 映射器(claimTask, revertClaim 等)
│ ├── service/
│ │ ├── TaskDecompositionService.java # 7 步编排(核心)
│ │ ├── DependencyDerivationService.java # DAG 推导 + 环检测
│ │ ├── ContextAggregationService.java # 每步上下文 + 重新聚合
│ │ ├── PromptAssemblyService.java # 8 部分 Markdown 提示构建器
│ │ ├── TaskClaimService.java # 原子 CAS 认领
│ │ ├── TaskCompletionService.java # 完成 → 解锁后续任务 → 自动完成父任务
│ │ ├── TaskExecutionService.java # 全自动:认领 → LLM → 写入 → 完成
│ │ ├── LlmGateway.java # 接口:splitTasks / executeStep / clarify
│ │ ├── SpringAiLlmGateway.java # Spring AI ChatClient 实现
│ │ └── LlmPromptBuilder.java # 系统提示 + 用户消息模板
│ └── web/
│ ├── TaskController.java # /tasks REST 端点
│ └── dto/ # 请求/响应 DTO + PageResponse
└── chat/ # 会话需求澄清
├── service/
│ └── ChatClarificationService.java # 启动 / 发送消息 / 分解
├── session/ # 内存会话存储(30 分钟 TTL)
│ ├── ChatSession.java
│ ├── ChatMessage.java
│ ├── ChatSessionStore.java
│ └── InMemoryChatSessionStore.java
└── web/
├── ChatController.java # /chat/sessions REST 端点
└── dto/
```
## 数据库模式
三个由 Flyway 管理的表:
- **`task`** — 父需求(id, requirement, status, created_by, created_at)
- **`task_step`** — 子任务,带有状态机(status, assignee_id, depends_on_count, version, generated_prompt, design_detail, context_snapshot, reaggregated_at)
- **`task_dependency`** — DAG 边(from_step_id → to_step_id)
## 测试
```bash
mvn test
```
测试使用 H2 内存数据库和 GitNexus/LLM Bean 存根(通过 `@ConditionalOnProperty`)。61 个测试覆盖:
- 分解管道(DAG,环检测,空草稿)
- 认领/完成状态转换
- 完成时的上下文重新聚合
- AI 工作者执行,带有失败回滚
- 聊天澄清流程
- REST API(MockMvc)
- 端到端 VIP 场景
## 设计原则
**无优雅降级** — 上游失败(GitNexus,LLM)抛出未检查异常 → 事务回滚 → HTTP 503。没有静默空数据。
**事务完整性** — 所有分解、认领、完成和执行流程都是 `@Transactional`;任何失败都回滚到一致状态。
**乐观并发** — `task_step.version` + 条件 `claimTask` UPDATE 防止跨并发工作者的重复认领。
**实际代码基础** — 目标符号、依赖关系和提示源自 GitNexus 的实际代码结构,而不是 LLM 的幻觉。
**上下文重新聚合** — 当前任务完成后,后续任务在变为 READY 之前会获取新的 `context()` + `impact()` 调用(前驱代码已更改 → 调用者/影响范围可能已偏移)。
## 适用于 AI 工作者
如果您是 Claude Code(或其他 AI)实例,寻找任务,请参阅 [WORKER_GUIDE.md](WORKER_GUIDE.md) 以获取认领 → 开发 → 完成的流程。
### AI 代理快速入门
1. 阅读此存储库中的 [WORKER_GUIDE.md](WORKER_GUIDE.md) 文件 — 它包含所有 curl 命令和流程步骤。
2. 确保 AI 工厂服务在 `http://localhost:8082` 处运行(或相应地设置 `API` 变量)。
3. 检查您是否认领了任务:
```bash
curl -s "http://localhost:8082/tasks/steps/claimed?userId=1" | python -m json.tool
```
4. 如果没有认领任务,找到一个 READY 步骤并认领它:
```bash
curl -s "http://localhost:8082/tasks" | python -m json.tool
curl -s -X POST "http://localhost:8082/tasks/{stepId}/claim" \
-H "Content-Type: application/json" \
-d '{"userId": 1}' | python -m json.tool
```
5. 响应包括一个 `generatedPrompt` 字段 — 这是您的完整开发指令。遵循它来修改代码。
6. 编写完成后,标记步骤为完成:
```bash
curl -s -X POST "http://localhost:8082/tasks/{stepId}/complete" \
-H "Content-Type: application/json" \
-d '{"userId": 1, "repo": "your-repo-name"}'
```
7. `true` = 成功(后续任务自动解锁)。`false` = 变更检测失败,步骤回滚到 READY(可重试)。
> **提示:** `generatedPrompt` 包含 8 部分:目标符号、当前源代码、调用者(不能破坏)、影响范围、设计细节、指令和约束。仔细阅读后再编码。
## 商標通知
"GitNexus" 是其各自所有者的商標或產品名稱。AI Factory 是一個獨立的專案,它通过 MCP 協議与 GitNexus 集成。AI Factory 不隶属于、未获得 GitNexus 项目或其维护者的认可、支持或赞助。所有商標均屬其各自所有者。
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器