## 项目概览
- **项目定位**:JManus 是 Spring Boot 驱动的多智能体计划执行平台,目标是在企业环境中提供强确定性、可审计的 AI 工作流编排能力。前端采用 Vue3 + Ant Design Vue,提供图形化的计划编排、运行与监控界面。
- **总体形态**:单体式 Spring Boot 应用承载全部业务 API、计划执行内核、工具体系与持久化层,并通过静态资源方式托管 Vue 前端;同时兼容 Docker 与 Native Image(GraalVM)场景。
- **核心能力**:Plan-Act 模式的计划生成与调度、工具调用(数据库、浏览器、Bash、OCR 等)、执行轨迹记录、对话上下文记忆、MCP(Model Context Protocol)扩展、开放的 HTTP API 以及 Cron 定时。
- **运行依赖**:Java 17+、默认 H2 内嵌数据库(可切换 MySQL/PostgreSQL)、外部 LLM 服务(DashScope 等)、可选 Playwright/ChromeDriver。
## 总体架构蓝图
- **界面层**:`ui-vue3` 子仓负责所有交互式 UI,打包后进入 `src/main/resources/static` 并由 Spring Boot 静态资源端点提供。
- **服务层**:Spring Boot 暴露 `/api/*` REST API;高层 API 聚焦计划执行(`ManusController`)、计划模板、配置与工具编排。
- **执行内核**:`planning`、`runtime`、`agent`、`tool`、`recorder` 等包构成执行链路,从计划解析、Agent 分发、工具调用到执行记录。
- **数据与配置层**:基于 Spring Data JPA 与 `Config`/`Recorder` 等实体包实现持久化,`config` 包提供动态配置、启动加载与属性映射。
- **外部集成层**:`llm` 负责与 LLM 服务交互,`mcp` 引入 MCP 服务与工具,`adapter` 提供 OpenAI 协议兼容层,`deploy` 目录封装容器化部署脚本。
- **事件与任务调度**:`event` 包提供领域事件总线,`cron` 包装 Spring Scheduling,实现计划的定时执行与监控。
## 后端架构
### 核心分层与入口
- **启动入口**:`OpenManusSpringBootApplication` 统一启用 Scheduling、JPA、Component 扫描,并提供 Playwright 初始化脚本开关。
```36:44:src/main/java/com/alibaba/cloud/ai/manus/OpenManusSpringBootApplication.java
else {
SpringApplication.run(OpenManusSpringBootApplication.class, args);
}
```
- **分层结构**:
- `controller`:暴露 REST API,处理任务提交、计划模板、配置与工具操作。
- `service`:封装业务流程(计划生成、工具注册、执行协调、配置同步等)。
- `entity`/`vo`:对应数据库表与前端展示模型,支持计划树、执行记录、配置项等。
- `repository`:Spring Data JPA 仓储接口。
- `runtime` 与 `planning`:执行内核,负责解析计划、分配 Agent、调度工具与记录执行。
- `tool`:工具插件集合,采用 `ToolCallBiFunctionDef` 标准封装工具元数据、输入参数与执行逻辑。
### 计划执行链路
- **计划装配与工具注册**:`PlanningFactory` 聚合浏览器、数据库、Cron 等工具的回调注册,并按 MCP 服务动态扩展工具列表。
```207:306:src/main/java/com/alibaba/cloud/ai/manus/planning/PlanningFactory.java
List<McpServiceEntity> functionCallbacks = mcpService.getFunctionCallbacks(planId);
for (McpServiceEntity toolCallback : functionCallbacks) {
String serviceGroup = toolCallback.getServiceGroup();
ToolCallback[] tCallbacks = toolCallback.getAsyncMcpToolCallbackProvider().getToolCallbacks();
for (ToolCallback tCallback : tCallbacks) {
toolDefinitions.add(new McpTool(tCallback, serviceGroup, planId, innerStorageService, objectMapper));
}
}
// Create FunctionToolCallback for each tool
for (ToolCallBiFunctionDef<?> toolDefinition : toolDefinitions) {
```
- **执行协调**:`PlanningCoordinator` 将计划转换为 `ExecutionContext`,交由 `PlanExecutorFactory` 选择具体执行器,并在执行完成后进入 `PlanFinalizer`。
```69:131:src/main/java/com/alibaba/cloud/ai/manus/runtime/service/PlanningCoordinator.java
public CompletableFuture<PlanExecutionResult> executeByPlan(PlanInterface plan, String rootPlanId,
String parentPlanId, String currentPlanId, String toolcallId, boolean isVueRequest, String uploadKey,
int planDepth) {
try {
// ...
PlanExecutorInterface executor = planExecutorFactory.createExecutor(plan);
CompletableFuture<PlanExecutionResult> executionFuture = executor.executeAllStepsAsync(context);
return executionFuture.thenCompose(result -> {
try {
PlanExecutionResult processedResult = planFinalizer.handlePostExecution(context, result);
return CompletableFuture.completedFuture(processedResult);
```
- **执行器设计**:`AbstractPlanExecutor` 控制步骤循环、Agent 执行、上传文件同步、步骤结果记录与中断处理,通过 `LevelBasedExecutorPool` 实现分层线程池调度。
```215:299:src/main/java/com/alibaba/cloud/ai/manus/runtime/executor/AbstractPlanExecutor.java
public CompletableFuture<PlanExecutionResult> executeAllStepsAsync(ExecutionContext context) {
int planDepth = context.getPlanDepth();
ExecutorService executor = levelBasedExecutorPool.getExecutorForLevel(planDepth);
return CompletableFuture.supplyAsync(() -> {
PlanExecutionResult result = new PlanExecutionResult();
PlanInterface plan = context.getPlan();
plan.setCurrentPlanId(context.getCurrentPlanId());
plan.updateStepIndices();
try {
syncUploadedFilesToPlan(context);
List<ExecutionStep> steps = plan.getAllSteps();
recorder.recordPlanExecutionStart(context.getCurrentPlanId(), context.getPlan().getTitle(),
context.getUserRequest(), steps, context.getParentPlanId(), context.getRootPlanId(),
```
- **后置处理**:`PlanFinalizer` 根据上下文决定生成执行摘要、直接响应或中断提示,同时写入执行记录并交互 LLM 对话记忆。
```180:221:src/main/java/com/alibaba/cloud/ai/manus/planning/service/PlanFinalizer.java
public PlanExecutionResult handlePostExecution(ExecutionContext context, PlanExecutionResult result) {
if (context == null || result == null) {
return result;
}
try {
if (isTaskInterrupted(context, result)) {
handleInterruptedTask(context, result);
return result;
}
if (context.isNeedSummary()) {
generateSummary(context, result);
return result;
}
else if (context.getPlan() != null && context.getPlan().isDirectResponse()) {
generateDirectResponse(context, result);
```
### 工具体系
- **工具抽象**:所有工具实现 `ToolCallBiFunctionDef` 接口,统一提供名称、描述、输入 Schema 与执行回调,可贴合 Model Function Calling。
- **内置工具族群**:
- **浏览器自动化**:`BrowserUseTool` 借助 `ChromeDriverService` 与 Playwright,实现页面抓取与交互。
- **数据库工具**:`DatabaseReadTool`/`DatabaseWriteTool`/`DatabaseMetadataTool` 封装查询与元数据访问,通过 `DataSourceService` 管理连接。
- **文件与存储**:`TextFileService`、`UnifiedDirectoryManager`、OCR 转 Markdown(`MarkdownConverterTool`)等处理文件。
- **Cron 工具**:`CronTool` 将计划注册到 `CronService`,形成计划级定时任务。
- **并行执行**:`ParallelExecutionTool` 触发子计划并发。
- **扩展机制**:
- `tool/howToCreateNewTool.md` 指导自定义工具实现。
- MCP 工具通过 `McpService` 动态加载远端能力。
### 配置与启动
- `config` 包含:
- **属性映射**:`ManusProperties`、`CoordinatorProperties`、`MemoryConfig` 等映射 `application.yml`。
- **动态配置管理**:`ConfigController` + `ConfigService` + `ConfigEntity` 支持 REST 修改配置。
- **启动监听**:`AppStartupListener`、`ConfigAppStartupListener` 导入默认配置、迁移数据库。
- **CORS/JSON/Playwright**:`CorsConfig`、`JacksonConfig`、`PlaywrightConfig`。
- 多环境配置:`src/main/resources` 下提供 `application-{profile}.yml`,`Makefile` 与 `deploy/Dockerfile` 支持本地与容器化构建。
### 事件与调度
- `event` 包定义 `JmanusEvent`、`PlanExceptionEvent`、`JmanusListenerRegister`,在计划异常时被 `ManusController` 缓存并反馈给 API 调用方。
- `cron` 包含计划实体、枚举、调度器与 REST API,实现周期性执行与 Cron 工具的持久化。
- `runtime/service/TaskInterruptionManager` 与数据库表 `RootTaskManagerEntity` 协同,实现执行中断与状态查询。
### 数据持久化与审计
- 计划执行轨迹存储在 `recorder` 包,`NewRepoPlanExecutionRecorder` 写入执行记录(Plan、Agent、Think-Act 层级)。
- `runtime/entity`/`recorder/entity` 结构化定义执行日志、工具调用、内嵌上下文,支持 UI 上的执行树展示。
- 配置信息由 `ConfigRepository`、工具目录由 `CoordinatorToolRepository` 管理;命名空间、用户等业务实体独立在 `namespace`、`user` 包内。
- 日志体系基于 `logback-spring.xml`,同时支持 `ManusProperties` 中的 debug 细节开关。
## 前端架构
### 技术栈与工程化
- **框架组合**:Vue 3(Composition API)+ TypeScript + Vite + Pinia + Vue Router + Ant Design Vue,辅以 `vue3-colorpicker`、`nprogress` 等增强组件。
- **构建与部署**:开发态 `pnpm run dev`,生产态 `pnpm run build` 并将 `ui-vue3/dist` 复制到后端 `static/ui`。`vite.config.ts` 配置静态资源路径与代理(可与后端同域)。
- **国际化与主题**:`base/i18n` 目录整合多语言文案,支持按路由/组件切换;Ant Design 的 `reset.css` 引导统一 UI 基线。
### 状态管理与交互模式
- `stores` 下多个 Pinia Store 管理全局状态:
- `task`:负责任务提交流程、运行状态、停止操作、表单预填。
- `sidebar`、`memory`、`namespace`:分别维护侧边栏折叠、对话记忆、命名空间上下文。
- Store 通过浏览器事件(`window.dispatchEvent`)、`localStorage`(记录引导完成)与 API 调用交织,保证任务跨界面同步。
```28:192:ui-vue3/src/stores/task.ts
export const useTaskStore = defineStore('task', () => {
const currentTask = ref<TaskPayload | null>(null)
const taskToInput = ref<string>('')
const hasVisitedHome = ref(false)
const setTask = (prompt: string) => {
if (!prompt.trim()) {
return
}
const newTask = {
prompt,
timestamp: Date.now(),
processed: false,
}
currentTask.value = newTask
}
// ...
const stopCurrentTask = async () => {
if (currentTask.value && currentTask.value.isRunning && currentTask.value.planId) {
const { DirectApiService } = await import('@/api/direct-api-service')
await DirectApiService.stopTask(currentTask.value.planId)
currentTask.value.isRunning = false
return true
```
### API 协议与数据流
- API 层集中在 `src/api`,以 `fetch` 封装 REST 调用,约定 `/api/executor` 等后端路径,统一处理错误与 JSON 解析。
- `CommonApiService` 负责计划详情轮询、Form 表单提交、Prompt 列表获取,避免异常情况下抛出错误导致轮询中断。
```22:74:ui-vue3/src/api/common-api-service.ts
public static async getDetails(planId: string): Promise<PlanExecutionRecordResponse> {
try {
const response = await fetch(`${this.BASE_URL}/details/${planId}`)
if (response.status === 404) {
return null
}
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Failed to get detailed information: ${response.status} - ${errorText}`)
}
const rawText = await response.text()
const data = JSON.parse(rawText)
if (data && typeof data === 'object' && !data.currentPlanId) {
data.currentPlanId = planId
}
return data
} catch (error: unknown) {
console.error('[CommonApiService] Failed to get plan details:', error)
return null
}
```
- 计划执行流程:前端提交任务 → 获取 `planId` → 使用 Pinia Store 记录状态 → 轮询 `/api/executor/details/{planId}` 获取执行树 → 若待用户输入,通过 `/submit-input/{planId}` 填写表单。
- 任务中断:`stopCurrentTask` 调用 `/api/executor/stopTask/{planId}`,并更新 Store 状态。
## 服务交互与关键流程
### 计划创建到执行
- **入口**:`ManusController.executeByToolNameAsync` 支持工具名称或模板 ID 调用,自动写入对话记忆、同步上传文件,并触发 `PlanningCoordinator`。
- **计划模板**:`PlanTemplateService` 读取最新版本 JSON,通过 `IPlanParameterMappingService` 进行参数替换(支持 `<<param>>` 占位符)。
- **执行记录**:`PlanExecutionRecorder` 全程记录计划 → 步骤 → Think-Act → 工具调用,并在 API 层对接详情查询。
- **结果生成**:`PlanFinalizer` 决定是否基于 LLM 生成摘要或直接回应;对 Vue 请求默认生成摘要文本,满足 UI 展示。
### 用户输入与中断
- **表单等待**:当工具请求用户输入时,`UserInputService` 在 `RootTaskManagerEntity` 中标记等待状态,`ManusController` 在详情 API 中合并 `UserInputWaitState` 返回 UI。
- **用户提交**:`/api/executor/submit-input/{planId}` 接收 JSON 表单,写回等待队列并唤醒执行器。
- **中断确认**:`TaskInterruptionManager` 通过数据库状态控制执行线程,在 `AbstractPlanExecutor` 的循环与 `PlanFinalizer` 后置处理中判定并返回中断消息。
## 扩展性与定制化
### 工具扩展
- 开发者可参考 `tool/howToCreateNewTool.md`,继承 `ToolCallBiFunctionDef` 并注册到 Spring 容器或 MCP 服务。
- `PlanningFactory` 在启动时根据 `agent.init` 配置决定是否注册全量工具,支持按环境裁剪。
### MCP 与外部服务
- `mcp` 包对接外部 MCP 服务目录与工具注册,`McpService` 负责缓存、鉴权与动态生成 `McpTool`,让计划执行时透明调用远程能力。
- LLM 集成通过 `LlmService` 适配 Spring AI,支持多厂商模型、流式响应与对话记忆策略。
### 动态 Agent 与子计划
- `agent` 包含 `DynamicAgent`、`ConfigurableDynaAgent` 与注解 `DynamicAgentDefinition`,可在运行时装配不同 Agent 流程。
- `subplan` 模块允许计划执行过程中动态生成子计划,通过 `SubplanToolService` 注册子计划工具,形成树状执行。
- `PlanExecutorFactory` 可按计划类型(Function 模式、动态工具模式等)选择不同执行器,实现差异化控制策略。
## 部署与运维
- **构建链路**:`Makefile` 与 `tools/make` 模块封装 Maven、前端构建、Docker 镜像制作、CI 检查(codespell、markdownlint、yamllint)。
- **容器化**:`deploy/Dockerfile` 基于 JDK17,复制后端 Jar 与构建后的前端静态文件,`deploy/start.sh` 提供启动脚本。
- **配置管理**:通过 `/api/config` 对外提供动态配置接口;`ConfigAppStartupListener` 支持启动时加载默认配置模板。
- **日志与调试**:`logback-spring.xml` 控制日志级别;`ManusProperties.debugDetail` 可打开 LLM 调试信息;`PlanExecutionRecorder` 的持久化记录方便线下排错。
- **Playwright/Chrome 驱动**:`OpenManusSpringBootApplication` 启动参数 `playwright-init` 可预下载浏览器内核,避免首次运行延迟。
## 附录:关键类索引
- **HTTP API**:`runtime/controller/ManusController`、`planning/controller`、`config/ConfigController`、`coordinator/controller/CoordinatorToolController`。
- **执行核心**:`planning/PlanningFactory`、`runtime/service/PlanningCoordinator`、`runtime/executor/*`、`agent/BaseAgent`。
- **工具体系**:`tool/*`、`tool/browse`、`tool/database`、`tool/convertToMarkdown`、`tool/mapreduce`。
- **持久化**:`recorder/service/PlanExecutionRecorder`、`runtime/entity`、`config/entity/ConfigEntity`、`coordinator/entity/po/CoordinatorToolEntity`。
- **前端入口**:`ui-vue3/src/main.ts`、`ui-vue3/src/router`、`ui-vue3/src/stores`、`ui-vue3/src/views`。
- **部署脚本**:`Makefile`、`deploy/Dockerfile`、`tools/make/*.mk`、`tools/scripts/*`。
通过上述架构设计,JManus 形成了“前端编排 → 后端计划执行内核 → 工具与外部服务 → 执行记录与可视化反馈”的闭环。开发者可在保持核心执行链路稳定的前提下,按需扩展工具能力、定制计划模板或替换 LLM 服务,以适配不同业务场景。
登录后可参与表态
讨论回复
11 条回复
✨步子哥 (steper)
#1
11-08 16:58
登录后可参与表态
✨步子哥 (steper)
#2
11-08 17:13
登录后可参与表态
✨步子哥 (steper)
#3
11-08 17:16
登录后可参与表态
✨步子哥 (steper)
#4
11-08 22:46
登录后可参与表态
✨步子哥 (steper)
#5
11-13 06:59
登录后可参与表态
✨步子哥 (steper)
#6
11-13 07:04
登录后可参与表态
✨步子哥 (steper)
#7
11-13 07:06
登录后可参与表态
✨步子哥 (steper)
#8
11-13 07:10
登录后可参与表态
✨步子哥 (steper)
#9
11-13 07:16
登录后可参与表态
✨步子哥 (steper)
#10
11-13 07:22
登录后可参与表态
✨步子哥 (steper)
#11
11-13 07:44
登录后可参与表态