☰
agent-core-java 旧版控制器兼容任务模型 Task:字段语义、依赖关系与执行流转全解析
2026/10/13 1:56:48 网站建设 项目流程
  • 人工智能
  • AI Agent
  • Agent 框架
  • 工具调用
  • Agent 工作流
  • RAG
  • MCP Clients
  • 强化学习

【免费下载链接】agent-core-java

openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。

项目地址:https://gitcode.com/openJiuwen/agent-core-java
点击查看免费下载

本文围绕 openJiuwen agent-core-java(com.openjiuwen.core.controller.legacy.task.Task)旧版控制器兼容任务模型展开:它既是旧版意图检测控制器(IntentDetectionController)与 reasoner/planner 协作的载体,也是理解旧版控制器如何描述"执行什么、依赖什么、执行到哪一步"的核心数据对象。读完本文,你将掌握Task的 13 个字段的语义与默认值、TaskStatus/TaskType/DependencyType三类枚举的取值与序列化规则、TaskInput/TaskResult/TaskDependency三个嵌套类型的设计,以及Task在"新建任务→执行→中断→恢复→取消"整条流转链路中的真实用法。

一、Task 在旧版控制器中的定位

Task是旧版(legacy)控制器体系的兼容任务模型,用于记录任务的标识、状态、输入输出与依赖关系。它在源码中位于 core/src/main/java/com/openjiuwen/core/controller/legacy/task/Task.java,与TaskStatus、TaskInput、TaskResult、TaskDependency、DependencyType同属com.openjiuwen.core.controller.legacy.task包。

根据 controller/legacy.README.md 的说明,com.openjiuwen.core.controller.legacy保留了早期 Controller 体系的兼容 API,包括基于内存消息队列的控制器基类、意图检测控制器、旧版 reasoner、事件模型、任务模型和工具函数。该子树主要用于兼容旧代码路径,新控制器能力应优先参考com.openjiuwen.core.controller、modules和schema包。

从源码结构看,Task类注释明确声明它是对 Python 版本openjiuwen/core/controller/legacy/task/task.py中Task的镜像(Mirrors),因此在 Java 端负责承载与 Python 旧版控制器相同的任务语义,保证跨语言行为一致性。

类声明本身非常简洁:

@Data @NoArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) public class Task { // 13 个业务字段,见下文 }
  • @Data:Lombok 生成 getter、setter、equals/hashCode/toString,这与文档中"依赖 Lombok 生成访问器"的描述一致;
  • @NoArgsConstructor:提供无参构造,便于反序列化与默认创建;
  • @JsonInclude(JsonInclude.Include.NON_NULL):Jackson 序列化时跳过null字段,避免空字段污染检查点或消息体。

值得注意的细节是:虽然文档提及"使用 Lombok builder 管理任务标识、状态、输入输出和依赖关系",但当前Task类实际只标注了@Data与@NoArgsConstructor,并未标注@Builder;真正提供显式构造的是嵌套类型TaskDependency(提供TaskDependency(String dependencyId)与全参构造)和TaskInput(提供TaskInput(String targetId, String targetName, Object arguments))、TaskResult(提供TaskResult(TaskStatus, Object, String, Map))。Task自身主要依赖无参构造加 setter 完成组装,这一点从DefaultPlanner与测试代码中new Task()加逐字段 setter 的用法可以得到印证。

二、核心字段表:语义、类型与默认值

原文档的字段表是理解Task的入口。结合源码,各字段的完整语义如下:

字段类型默认值说明
agentIdStringnull任务所属 agent,序列化字段名为agent_id
taskIdString""(空字符串)任务 ID,序列化字段名为task_id
taskTypeTaskTypeTaskType.UNDEFINED任务类型,序列化字段名为task_type
descriptionStringnull任务描述
statusTaskStatusTaskStatus.PENDING任务当前状态
metadataMap<String, Object>空LinkedHashMap附加元数据
inputTaskInput新TaskInput实例任务输入
resultTaskResultnull任务结果
dependenciesList<TaskDependency>空ArrayList该任务的依赖列表
dependentsSet<String>空LinkedHashSet依赖本任务的哪些任务
parentTaskIdStringnull父任务 ID,序列化字段名为parent_task_id
childTaskIdsSet<String>空LinkedHashSet子任务 ID 集合,序列化字段名为child_task_ids
groupIdStringnull所属 group,序列化字段名为group_id
levelint0层级深度

与原文档字段表相比,源码补充了三个关键信息:

  1. JSON 字段名:agentId、taskId、taskType、parentTaskId、childTaskIds、groupId均通过@JsonProperty映射为下划线风格的 wire 名(agent_id、task_id、task_type、parent_task_id、child_task_ids、group_id),而description、status、metadata、input、result、dependencies、dependents、level未加注解,序列化时直接使用字段名。这与 Python 端任务模型的 JSON 表示保持一致。

  2. 集合默认值:metadata、dependencies、dependents、childTaskIds分别初始化为LinkedHashMap/ArrayList/LinkedHashSet,保证无参构造后即可安全遍历,避免 NPE。

  3. setter 空值归一化:Task重写了setAgentId、setMetadata、setInput、setDependencies、setDependents、setChildTaskIds这几个 setter,将传入的null统一替换为对应的空集合/新实例。例如传入null的input会被重置为new TaskInput(),传入null的dependencies会被替换为空ArrayList。这意味着调用方"先置空再赋值"也能得到健壮的任务对象。

level字段用于标记任务在分解树中的层级深度(默认0,表示顶层任务),配合parentTaskId/childTaskIds可以还原出任务分解(decomposition)的树状结构;groupId则用于把一组相关任务归入同一个执行组,便于批量管理与编排。

三、任务分类:TaskType 枚举

taskType字段的类型是com.openjiuwen.core.common.constants.TaskType(见 core/src/main/java/com/openjiuwen/core/common/constants/TaskType.java),它定义了任务的执行形态:

枚举值wire 值含义
PLUGINplugin插件类任务
WORKFLOWworkflow工作流任务
MCPmcpMCP 工具类任务
UNDEFINEDundefined未定义类型(默认值)

TaskType.fromValue(String)采用宽容解析:能匹配到对应 wire 值就返回该类型,否则统一回退为UNDEFINED,不会抛异常。测试 core/src/test/java/com/openjiuwen/core/application/workflow_agent/WorkflowControllerTest.java 中,意图检测识别到工作流后生成的Task其taskType即被设置为TaskType.WORKFLOW(见singleWorkflowCreatesNewTaskWithFilteredInputs用例),说明taskType是控制器选择执行路径的依据之一。

四、任务状态机:TaskStatus 枚举

status字段使用TaskStatus枚举(core/src/main/java/com/openjiuwen/core/controller/legacy/task/TaskStatus.java),它是任务生命周期状态机:

枚举值wire 值含义
PENDINGpending待执行(默认值)
RUNNINGrunning运行中
SUCCESSsuccess成功
FAILEDfailed失败
CANCELLEDcancelled已取消
INTERRUPTEDinterrupted已中断(等待用户补充输入)
INPUT_REQUIREDinput-required需要输入补充

原文档描述"覆盖待执行、运行中、成功、失败、已取消和已中断",源码在此基础上还增加了INPUT_REQUIRED,用于显式表达"任务等待用户输入"的中间态。

两个与序列化直接相关的实现细节:

  • @JsonValue:枚举序列化时输出的是 wire 小写字符串(如"pending"),而非 Java 枚举名;
  • @JsonCreator fromValue(String):反序列化时同时接受wire 值与枚举名(status.value.equals(value) || status.name().equals(value)),因此从检查点(checkpoint)或 JSON 中恢复状态时,无论存的是"running"还是"RUNNING"都能正确解析;对于空白或未知字符串,则安全回退为PENDING,避免旧数据损坏后直接抛异常。

五、任务输入与输出:TaskInput 与 TaskResult

5.1 TaskInput:描述"执行什么"

TaskInput(core/src/main/java/com/openjiuwen/core/controller/legacy/task/TaskInput.java)描述任务的目标与参数:

字段类型默认值说明
targetIdString""目标标识(如工作流weather_1.0),序列化字段名target_id
targetNameString""目标名称,序列化字段名target_name
argumentsObject空LinkedHashMap任务参数(实际往往为Map<String, Object>)

targetId通常形如<workflow>_<version>。测试中生成的Task其input.targetId为"weather_1.0",arguments为经过筛选后的参数字典(例如只保留工作流 schema 中声明的city、unit,丢弃无关的ignored扩展字段),说明TaskInput承担了"把用户查询转成结构化目标调用参数"的职责。setArguments同样做了 null 归一化,传入null会重置为空LinkedHashMap。

5.2 TaskResult:描述"执行得怎样"

TaskResult(core/src/main/java/com/openjiuwen/core/controller/legacy/task/TaskResult.java)描述任务执行结果:

字段类型默认值说明
statusTaskStatusnull结果状态
outputObjectnull任务输出
errorStringnull错误信息
metadataMap<String, Object>空LinkedHashMap结果元数据

output使用Object类型,可以承载字符串、结构化 Map 或任意业务对象;error记录失败原因;metadata可附加执行统计等辅助信息。setMetadata同样把null归一化为空映射。

六、任务依赖模型:TaskDependency 与 DependencyType

6.1 依赖关系四分类

DependencyType(core/src/main/java/com/openjiuwen/core/controller/legacy/task/DependencyType.java)定义任务间的依赖关系类型,原文档概括为"顺序、并行、条件和数据依赖":

枚举值wire 值含义
SEQUENTIALsequential顺序依赖:前序任务完成后才能执行
PARALLELparallel并行依赖:可与依赖任务并行执行
CONDITIONALconditional条件依赖:满足condition才触发
DATAdata数据依赖:需要依赖任务的数据产出

与TaskStatus不同,DependencyType.fromValue(String)是严格解析:未知值会抛出IllegalArgumentException("Unknown dependency type: ..."),null则返回null。这说明依赖类型一旦写入持久化数据就应当保持合法值,容错性低于状态字段。

6.2 单条依赖的描述:TaskDependency

TaskDependency(core/src/main/java/com/openjiuwen/core/controller/legacy/task/TaskDependency.java)描述"依赖哪个任务、怎么依赖、何时触发、数据如何流转":

字段类型默认值说明
dependencyIdStringnull被依赖任务的 ID,序列化字段名dependency_id
dependencyTypeDependencyTypeSEQUENTIAL依赖类型,序列化字段名dependency_type
conditionStringnull触发条件(条件依赖时使用)
dataMappingMap<String, String>空LinkedHashMap数据映射(上游输出字段 → 本任务输入字段),序列化字段名data_mapping
requiredbooleantrue该依赖是否必需

TaskDependency提供两个构造器:TaskDependency(String dependencyId)便捷构造,以及包含全部字段的全参构造;setDependencyType与setDataMapping同样做 null 归一化(分别回退到SEQUENTIAL与空映射)。

6.3 正向依赖与反向依赖

Task通过两组字段双向表达任务图:

  • 正向:dependencies(List<TaskDependency>)——本任务依赖谁,携带依赖类型、条件与数据映射;
  • 反向:dependents(Set<String>)——谁依赖本任务(被依赖者视角的任务 ID 集合)。

配合parentTaskId(父任务 ID)与childTaskIds(子任务 ID 集合),可以同时还原"任务分解树"(父-子)与"任务依赖图"(依赖-被依赖)两层结构。level字段则标记任务在分解树中的深度。

七、Task 在 IntentDetectionController 中的执行流转

原文档明确指出:"IntentDetectionController和旧版 reasoner/planner 主要围绕这一任务模型协作"。以 core/src/main/java/com/openjiuwen/core/controller/legacy/IntentDetectionController.java 为参照,Task是意图检测结果(Intent)与任务执行之间的"交接单":

Intent类(IntentDetectionController.Intent)持有Task task字段,并由IntentType决定后续动作:

IntentTypewire 值对 Task 的处理
EXEC_NEW_TASKexec_new_taskhandleNewTask:取intent.getTask(),置status = PENDING后调用execTask执行
RESUME_TASKresume_taskhandleResume:校验任务为INTERRUPTED状态,从会话状态workflow_controller.interrupted_tasks中还原被中断的组件,把用户输入重映射进task.getInput().setArguments(...)后重新execTask
CANCEL_TASKcancel_taskhandleCancel:置status = CANCELLED,返回取消结果
DEFAULT_RESPONSEdefault_response走默认回复,不触碰任务
UNKNOWNunknown走未知意图兜底

关键源码片段(handleNewTask):

protected Map<String, Object> handleNewTask(Event event, Intent intent, Object session) { Task task = intent.getTask(); if (task == null) { return Map.of("status", "error", "message", "Task not found in intent"); } task.setStatus(TaskStatus.PENDING); LOG.info("Handling new task: task_id={}", task.getTaskId()); return execTask(event == null ? null : event.getContent(), task, session); }

handleResume的细节值得展开:当任务因人机交互中断后,会话状态中保存了interrupted_tasks,键为workflowId.replace('.', '_')(如flow_1_2),值包含task与component_id。恢复时控制器会从会话状态读出被中断的组件 ID,将用户输入映射到该组件所需的InteractiveInput,再写回task.input.arguments并重新执行——这正是Task承担"可中断、可恢复"状态载体的体现。status从INTERRUPTED恢复为执行态,贯穿整个生命周期。

此外,控制器内维护了TaskQueue(含RunningTaskInfo,记录task、Future<?>、targetId、startTime),通过registerTask(conversationId, task, future, targetId)把运行中的任务与异步执行句柄关联起来,为并发任务跟踪提供支撑。

八、旧版 reasoner/planner 与 Task 的协作

旧版 reasoner 体系由IntentDetector(意图检测)与Planner(任务规划)组合而成(见 core/src/main/java/com/openjiuwen/core/controller/legacy/reasoner/AgentReasoner.java),两者都以Task为产出物:

  • AgentReasoner.detect(Event, AgentSessionApi)通过intentDetector.processMessage(event)检测意图;
  • AgentReasoner.plan(Intent, AgentSessionApi)通过planner.processMessage(...)产出List<Task>。

DefaultPlanner(core/src/main/java/com/openjiuwen/core/controller/legacy/reasoner/DefaultPlanner.java)展示了最基础的任务创建范式——createDefaultTask用new Task()无参构造后逐字段 setter 组装:

Map<String, Object> meta = new LinkedHashMap<>(); meta.put("original_message_id", event.getEventId()); meta.put("task_source", "planner"); Task task = new Task(); task.setTaskType(TaskType.UNDEFINED); task.setDescription(desc); task.setStatus(TaskStatus.PENDING); task.setMetadata(meta);

可以看到:新建任务显式置PENDING状态、在metadata中记录消息来源与原始消息 ID,为后续执行与追踪提供线索。这印证了metadata字段在旧版链路中用于携带任务溯源信息。

九、测试验证与新旧模型对照

9.1 测试对 Task 行为的验证

测试 core/src/test/java/com/openjiuwen/core/application/workflow_agent/WorkflowControllerTest.java 直接覆盖了Task的关键行为:

  • singleWorkflowCreatesNewTaskWithFilteredInputs:验证意图检测后生成的Task——taskId为"workflow_EVT"、taskType为TaskType.WORKFLOW、status为TaskStatus.PENDING、input.targetId为"weather_1.0"、arguments仅含 schema 声明字段;
  • interruptedStructuredValueReturnsInterruptionAgain:通过会话状态预置interrupted_tasks(包含task与component_id)验证中断任务的恢复路径;
  • 其余用例验证了未配置工作流时意图检测抛IllegalArgumentException、多工作流回退默认回复等行为。

这些测试同时可作为Task组装与状态流转的"可运行示例"参考。

9.2 与 schema 版 Task 的区别

仓库中还存在新控制器体系的任务模型 controller/schema/Task.md(源码位于com.openjiuwen.core.controller.schema),两者定位不同:

维度legacyTaskschemaTask
定位旧版控制器兼容任务模型,配合意图检测与 reasoner/planner控制器内部任务模型,配合TaskManager执行管理
状态TaskStatus(PENDING/RUNNING/SUCCESS/FAILED/CANCELLED/INTERRUPTED/INPUT_REQUIRED)TaskStatus(含 SUBMITTED/COMPLETED/TIMEOUT 等,见 core/src/test/java/com/openjiuwen/core/common/task_manager/TaskStatusTest.java)
输入单个TaskInput(targetId/targetName/arguments)List<Object> inputs输入对象列表
输出单个TaskResultList<ControllerOutputChunk> outputs输出块列表
特有能力依赖模型(dependencies/dependents+DependencyType)、level层级优先级priority、validate()校验、copy()深拷贝、toMap()/fromMap()持久化

简言之:legacyTask面向"意图→规划→执行"的旧版协作链路,schemaTask面向新控制器的执行管理与持久化。选型时新项目应优先使用 schema 体系,legacyTask仅用于兼容旧代码路径。

十、总结

com.openjiuwen.core.controller.legacy.task.Task是旧版控制器兼容体系中"任务即数据"的集中体现:

  • 标识与归属:taskId/taskType/agentId/groupId/level定义了任务的身份、分类与层级;
  • 生命周期:TaskStatus状态机(含INPUT_REQUIRED)配合TaskInput/TaskResult记录任务从待执行到成功/失败/取消/中断的全过程;
  • 编排结构:dependencies/dependents/parentTaskId/childTaskIds双向描述任务分解树与依赖图,TaskDependency+DependencyType表达顺序、并行、条件与数据四类关系;
  • 协作链路:IntentDetectionController负责按IntentType驱动任务流转,reasoner/planner 负责产出任务,metadata承担溯源与附加信息。

它保留了 Python 端任务模型的字段与 JSON 语义(snake_case wire 名、宽容的状态反序列化、严格的依赖类型解析),是理解旧版控制器架构、迁移遗留代码、以及对照 schema 版任务模型时必读的类型。相关源码与测试可进一步参阅 legacy/task 包、IntentDetectionController.java 与 WorkflowControllerTest.java。

  • 人工智能
  • AI Agent
  • Agent 框架
  • 工具调用
  • Agent 工作流
  • RAG
  • MCP Clients
  • 强化学习

【免费下载链接】agent-core-java

openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。

项目地址:https://gitcode.com/openJiuwen/agent-core-java
点击查看免费下载

相关推荐

上一篇:Artipie是什么?免费开源的二进制制品管理平台,Artifactory最佳替代方案
下一篇:lark-cli 妙搭应用本地开发全流程:从 `+init` 拉取源码到 git 提交与 `+release-create` 发布上线

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询