Loading...
正在加载...
请稍候

JManus 分析

✨步子哥 (steper) 2025年11月08日 16:45

项目概览

  • 项目定位: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)、计划模板、配置与工具编排。
  • 执行内核planningruntimeagenttoolrecorder 等包构成执行链路,从计划解析、Agent 分发、工具调用到执行记录。
  • 数据与配置层:基于 Spring Data JPA 与 Config/Recorder 等实体包实现持久化,config 包提供动态配置、启动加载与属性映射。
  • 外部集成层llm 负责与 LLM 服务交互,mcp 引入 MCP 服务与工具,adapter 提供 OpenAI 协议兼容层,deploy 目录封装容器化部署脚本。
  • 事件与任务调度event 包提供领域事件总线,cron 包装 Spring Scheduling,实现计划的定时执行与监控。

后端架构

核心分层与入口

  • 启动入口OpenManusSpringBootApplication 统一启用 Scheduling、JPA、Component 扫描,并提供 Playwright 初始化脚本开关。
		else {
			SpringApplication.run(OpenManusSpringBootApplication.class, args);
		}
  • 分层结构
    • controller:暴露 REST API,处理任务提交、计划模板、配置与工具操作。
    • service:封装业务流程(计划生成、工具注册、执行协调、配置同步等)。
    • entity/vo:对应数据库表与前端展示模型,支持计划树、执行记录、配置项等。
    • repository:Spring Data JPA 仓储接口。
    • runtimeplanning:执行内核,负责解析计划、分配 Agent、调度工具与记录执行。
    • tool:工具插件集合,采用 ToolCallBiFunctionDef 标准封装工具元数据、输入参数与执行逻辑。

计划执行链路

  • 计划装配与工具注册PlanningFactory 聚合浏览器、数据库、Cron 等工具的回调注册,并按 MCP 服务动态扩展工具列表。
		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
	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 实现分层线程池调度。
	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 对话记忆。
	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 管理连接。
    • 文件与存储TextFileServiceUnifiedDirectoryManager、OCR 转 Markdown(MarkdownConverterTool)等处理文件。
    • Cron 工具CronTool 将计划注册到 CronService,形成计划级定时任务。
    • 并行执行ParallelExecutionTool 触发子计划并发。
  • 扩展机制
    • tool/howToCreateNewTool.md 指导自定义工具实现。
    • MCP 工具通过 McpService 动态加载远端能力。

配置与启动

  • config 包含:
    • 属性映射ManusPropertiesCoordinatorPropertiesMemoryConfig 等映射 application.yml
    • 动态配置管理ConfigController + ConfigService + ConfigEntity 支持 REST 修改配置。
    • 启动监听AppStartupListenerConfigAppStartupListener 导入默认配置、迁移数据库。
    • CORS/JSON/PlaywrightCorsConfigJacksonConfigPlaywrightConfig
  • 多环境配置:src/main/resources 下提供 application-{profile}.ymlMakefiledeploy/Dockerfile 支持本地与容器化构建。

事件与调度

  • event 包定义 JmanusEventPlanExceptionEventJmanusListenerRegister,在计划异常时被 ManusController 缓存并反馈给 API 调用方。
  • cron 包含计划实体、枚举、调度器与 REST API,实现周期性执行与 Cron 工具的持久化。
  • runtime/service/TaskInterruptionManager 与数据库表 RootTaskManagerEntity 协同,实现执行中断与状态查询。

数据持久化与审计

  • 计划执行轨迹存储在 recorder 包,NewRepoPlanExecutionRecorder 写入执行记录(Plan、Agent、Think-Act 层级)。
  • runtime/entity/recorder/entity 结构化定义执行日志、工具调用、内嵌上下文,支持 UI 上的执行树展示。
  • 配置信息由 ConfigRepository、工具目录由 CoordinatorToolRepository 管理;命名空间、用户等业务实体独立在 namespaceuser 包内。
  • 日志体系基于 logback-spring.xml,同时支持 ManusProperties 中的 debug 细节开关。

前端架构

技术栈与工程化

  • 框架组合:Vue 3(Composition API)+ TypeScript + Vite + Pinia + Vue Router + Ant Design Vue,辅以 vue3-colorpickernprogress 等增强组件。
  • 构建与部署:开发态 pnpm run dev,生产态 pnpm run build 并将 ui-vue3/dist 复制到后端 static/uivite.config.ts 配置静态资源路径与代理(可与后端同域)。
  • 国际化与主题base/i18n 目录整合多语言文案,支持按路由/组件切换;Ant Design 的 reset.css 引导统一 UI 基线。

状态管理与交互模式

  • stores 下多个 Pinia Store 管理全局状态:
    • task:负责任务提交流程、运行状态、停止操作、表单预填。
    • sidebarmemorynamespace:分别维护侧边栏折叠、对话记忆、命名空间上下文。
  • Store 通过浏览器事件(window.dispatchEvent)、localStorage(记录引导完成)与 API 调用交织,保证任务跨界面同步。
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 列表获取,避免异常情况下抛出错误导致轮询中断。
  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 展示。

用户输入与中断

  • 表单等待:当工具请求用户输入时,UserInputServiceRootTaskManagerEntity 中标记等待状态,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 包含 DynamicAgentConfigurableDynaAgent 与注解 DynamicAgentDefinition,可在运行时装配不同 Agent 流程。
  • subplan 模块允许计划执行过程中动态生成子计划,通过 SubplanToolService 注册子计划工具,形成树状执行。
  • PlanExecutorFactory 可按计划类型(Function 模式、动态工具模式等)选择不同执行器,实现差异化控制策略。

部署与运维

  • 构建链路Makefiletools/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 APIruntime/controller/ManusControllerplanning/controllerconfig/ConfigControllercoordinator/controller/CoordinatorToolController
  • 执行核心planning/PlanningFactoryruntime/service/PlanningCoordinatorruntime/executor/*agent/BaseAgent
  • 工具体系tool/*tool/browsetool/databasetool/convertToMarkdowntool/mapreduce
  • 持久化recorder/service/PlanExecutionRecorderruntime/entityconfig/entity/ConfigEntitycoordinator/entity/po/CoordinatorToolEntity
  • 前端入口ui-vue3/src/main.tsui-vue3/src/routerui-vue3/src/storesui-vue3/src/views
  • 部署脚本Makefiledeploy/Dockerfiletools/make/*.mktools/scripts/*

通过上述架构设计,JManus 形成了“前端编排 → 后端计划执行内核 → 工具与外部服务 → 执行记录与可视化反馈”的闭环。开发者可在保持核心执行链路稳定的前提下,按需扩展工具能力、定制计划模板或替换 LLM 服务,以适配不同业务场景。

讨论回复

加载中...
正在加载回复...

正在加载回复...

推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录