☰
openJiuwen agent-core-java 临时团队生命周期:shutdown_member 与 clean_team 收尾机制深度解析
2026/10/12 14:18:35 网站建设 项目流程
  • 人工智能
  • 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 中 Agent Teams 的**临时团队(temporary)**生命周期收尾机制展开,剖析内置 Leader 提示词模板lifecycle_temporary.md的语义、shutdown_member与clean_team两个收尾工具的底层实现,以及配套的状态机与完成判定逻辑。读完本文,你将掌握临时团队从任务完成、成果汇总到成员关闭、团队解散的完整收尾链路,并能在自己的多智能体应用中正确、高效地编排团队生命周期。

什么是临时团队:一次任务、一次生命周期

在 openJiuwen agent-core-java 的com.openjiuwen.agentteams包中,团队的生命周期模式由TeamAgentSpec.lifecycle字段声明,默认值即为temporary(见 TeamAgentSpec.java)。也就是说,不加显式声明创建的团队,天然是"一次性"团队:它围绕某次具体任务临时组建,任务完成后就地解散,不长期驻留。

与它相对的是persistent(长期团队)——完成任务后保持运行、进入待命状态等待新指令,不关闭成员也不解散团队(见 lifecycle_persistent.md)。两者在 Leader 的系统提示词中占据同一位置、由同一套装配逻辑按lifecycle值二选一注入,但收尾语义截然相反。

这一设计对应到真实场景:一个"分析财报 → 输出报告"的投资分析任务,结束后团队没有继续存在的意义,应立即回收资源;而一个持续服务用户的智能助手团队,则应当长期存活。临时团队的价值正是按需组建、用完即毁,避免成员进程、KV Cache、共享工作空间等资源长期空转。

收尾提示词模板:临时团队的"行为契约"

lifecycle_temporary.md是专门注入给 Leader 角色的系统提示词片段,全文如下(原文位于 lifecycle_temporary.md,英文版见 en/lifecycle_temporary.md):

## 团队性质:临时团队 本团队为临时团队,在所有任务完成后应解散。完成所有任务后: 1. 汇总工作成果 2. 用 shutdown_member 关闭所有成员 3. 用 clean_team 解散团队 **收尾要高效**:用 `send_message(to="*")` 一次性广播总结与解散通知后立即执行关闭流程,不要逐个成员告别,也不要回复成员的致谢/确认消息,避免无意义的来回寒暄。

这段模板定义了临时团队的三条收尾铁律:

  1. 先汇总、后关闭、再解散:成果汇总在成员存活时完成,顺序不可颠倒;
  2. 收尾手段固定:关闭成员用shutdown_member,解散团队用clean_team,两个工具都仅 Leader 可调用(参见 AgentTeams.md 团队工具集 中 Leader 专属工具清单);
  3. 收尾要高效:send_message(to="*")一次性广播总结与解散通知,随后立即执行关闭流程——禁止逐个成员告别、禁止回复致谢。

第三条是刻意设计的协作礼仪约束:Agent 团队中每多一轮"谢谢/不客气"式的寒暄,就多一次无意义的 LLM 推理开销。而to="*"广播则保证全员在同一时刻收到统一信息,同时把通信次数压缩到一次。

模板如何被注入 Leader 提示词

该模板并不是"写了就算数"的普通文档,而是被运行时真实装配进 Leader 系统提示词的动态章节。装配入口是TeamRail.buildTeamLifecycleSection(...)(见 TeamRail.java),其关键逻辑:

  • 仅 Leader 注入:role != TeamRole.LEADER时直接返回空 section,teammate 永远不会看到收尾指令;
  • 按 lifecycle 二选一:"persistent".equals(lifecycle)加载lifecycle_persistent,否则加载lifecycle_temporary;
  • 作为独立 PromptSection 存在:section 名称为team_lifecycle(TeamRail.LIFECYCLE常量),与角色策略、工作流程、团队信息等章节按优先级拼接成 Leader 的完整提示词。

从源码结构看,模板正文与装配逻辑解耦——CLAUDE.md 明确说明"Markdown 模板是团队 Agent 的行为契约……改提示词不需要动装配代码",新增语言只需在cn/、en/下成对添加翻译文件。

收尾第一步:汇总工作成果

在调用任何关闭工具之前,Leader 必须先把本轮协作的成果汇聚成一份可交付的总结。这与团队协作模式的产物约定一致:

  • 在默认(default)团队模式下,teammate 完成任务后通过send_message向 Leader 发送完成摘要与产物文件路径(典型如.team/reports/T*.md),Leader 在收尾前把这些信息归并进最终总结;
  • 广播语法为send_message(to="*"),一次调用送达全员,同时作为解散前的正式通知。

需要注意的是,总结必须在shutdown_member之前完成。一旦成员进入关闭流程,其 ReAct 循环终止、流关闭,不会再处理新消息,此时再索要成果为时已晚。

收尾第二步:shutdown_member 有序关闭成员

shutdown_member是临时团队收尾的核心工具,其语义定义在工具描述文件 shutdown_member.md 中:

参数用法
member_name要请求关闭的成员 member_name,应指向当前团队中的有效成员
force是否强制关闭。仅在成员卡死、长期无响应或无法正常收尾时作为兜底使用

适用场景:成员已完成负责的工作需要有序退出;团队收尾需逐个关闭成员后再clean_team;成员长时间卡住、无法恢复时可考虑force=true。

关键语义:发起请求,而非同步关闭

工具描述明确强调:"这不是'立即完成关闭'的同步操作,而是发起关闭请求"。调用后应等待成员真正进入SHUTDOWN,再执行clean_team或依赖其已退出的后续操作。force=true仅用于异常兜底,可能中断未完成工作,不应作为常规路径。

从实现看,TeamBackend.shutdownMember(...) 的调用链为:

  1. 校验成员存在且当前状态允许迁移(依赖MemberStatus.canTransitionTo状态机);
  2. 把成员持久化状态置为SHUTDOWN_REQUESTED;
  3. 通过messageManager.sendMessage(...)向该成员发送"Shutdown requested by team leader."消息;
  4. 发布MEMBER_SHUTDOWN团队事件,驱动成员侧的shutdownSelf()。

而成员侧收到事件后(见 TeamAgent.shutdownSelf()),会依次:取消 agent → 关闭流 → 将自身状态更新为SHUTDOWN→ 释放会话 KV Cache → 关闭资源。这一收尾动作在成员自然轮次结束点落定(finalizeStreamingRound中执行),确保成员完成当前推理后再退出,而非被粗暴打断。

状态机视角:SHUTDOWN_REQUESTED → SHUTDOWN

MemberStatus 定义了成员全量状态,其中与收尾直接相关的是:

  • READY / BUSY / PAUSED / STOPPED→ 允许迁入SHUTDOWN_REQUESTED;
  • SHUTDOWN_REQUESTED→ 只允许迁入SHUTDOWN或ERROR(终态前的"最后一站")。

也就是说,SHUTDOWN_REQUESTED是一个中间态——它标记"Leader 已请求关闭,成员正在完成收尾"。TeamBackend.isAnyMemberShuttingDown()专门检测这一窗口(见 TeamBackend.java):当存在SHUTDOWN_REQUESTED成员时,StreamController会跳过POLL_MAILBOX派发,避免 Leader 在关闭窗口期内被自身事件反复唤醒、空耗 LLM token。

内置保护:不关"仍有任务在身"的成员

TeamTools.ShutdownMemberTool 在调用后端前有一道守卫:若该成员名下仍存在非终态任务(非 completed/cancelled),默认拒绝关闭,并提示"Complete, reassign, or cancel them first; or pass force=true"。原因是关闭一个仍持有 in-flight 任务的成员会使这些任务成为孤儿,拖垮整个团队任务 DAG。只有force=true才能绕过,作为管理员的最后手段。

收尾第三步:clean_team 解散团队

当所有非 Leader 成员都进入SHUTDOWN后,Leader 调用clean_team正式解散团队。工具语义见 clean_team.md:

解散团队并删除所有资源(团队记录、成员、任务——级联删除)。仅 Leader 可用。重要:如果任何成员未处于 SHUTDOWN 状态,clean_team 将失败。请先用 shutdown_member 关闭所有成员,再调用 clean_team。

对应实现 TeamBackend.cleanTeam() 的流程是:

  1. 校验所有非 Leader 成员均为SHUTDOWN:任一成员不是SHUTDOWN,直接返回失败——这就是为什么必须先shutdown_member再clean_team;
  2. 级联删除团队记录(db.team.deleteTeam,成员、任务、依赖关系随之删除);
  3. 触发onTeamCleaned回调,让宿主TeamAgent把StreamController标记为终止并关闭流(见 TeamAgent.handleTeamCleaned());
  4. 清理团队共享工作空间、成员工作空间等资源;
  5. 发布CLEANED团队事件。

clean_team 的三个拒绝分支

CleanTeamTool(见 TeamTools.java)在调用后端前还有两道任务层面的守卫:

  • 存在非终态任务(非 completed/cancelled):拒绝清理,要求先完成任务;
  • 存在被取消的任务(cancelled):拒绝清理,要求 Leader 处理(cancelled 在任务侧虽然是终态,但在团队收尾语境下被视为"悬而未决",需要 Leader 完成或确认);
  • 后端返回失败但无活跃成员:提示"团队可能已被清理或删除,已处于终态"。

这三道防线共同保证:不会带着未结任务解散团队,也不会对不存在的团队做无意义的清理。

完成判定的底层支撑:TEAM_COMPLETED 事件

临时团队的收尾不是 Leader 拍脑袋决定的,而是建立在框架的"团队完成判定"之上。TeamCompletionHandler(leader-only,见 AgentTeams.md)在 Leader idle 时周期性调用TeamBackend.isTeamCompleted()(见 TeamBackend.java),该方法三条件同时满足才返回完成快照:

  1. 任务全部终态:所有 task 处于completed/cancelled(即GraphUtils.TASK_TERMINAL_STATUSES);
  2. 成员全部 settled:所有成员(含 Leader)处于READY / PAUSED / STOPPED / SHUTDOWN(MEMBER_SETTLED_STATUSES)——SHUTDOWN_REQUESTED、RESTARTING、BUSY、ERROR都会阻止完成判定;
  3. 无未读消息:全团队无未读消息(含广播)。

三条件满足后,handler 上升沿发布一次TEAM_COMPLETED事件到team:<name>主题。temporary团队此时由 Leader 自己按提示词指引走shutdown_member+clean_team(这正是lifecycle_temporary.md生效的时机);而persistent团队则由TeamLifecycleController自动关闭 Leader 流、驱动 finalize → pause,进入待命。这一差异在 AgentTeams.md 中有明确记载。

值得一提的是,clean_team成功后团队 DB 行被删除,isTeamCompleted()会返回一个"终态快照",保证TEAM_COMPLETED只发一次、Leader 流正常关闭,不会因级联删除导致 Leader 在过期 dispatch prompt 上空转。

实战:一条完整的临时团队收尾链路

结合 Leader 工作流模板 与上述机制,一个临时团队从组建到解散的完整生命周期如下:

  1. 建队:build_team组建团队,lifecycle缺省即temporary;
  2. 建任务:create_task创建任务 DAG(依赖任务初始为blocked,依赖满足后自动转pending);
  3. 拉人:spawn_member按领域创建专业成员(预定义团队模式下此步被禁用);
  4. 启动:send_message(to="*")广播启动指令,系统自动拉起未启动成员;
  5. 协作:成员claim_task领取、执行、update_task(status=completed)标记完成;Leader 审批计划(仅 plan_mode)、裁决冲突;
  6. 完成判定:全部任务终态 + 全员 settled + 无未读消息 → 框架发TEAM_COMPLETED;
  7. Leader 收尾(本主题核心):
    • 汇总各成员通过send_message上报的成果,形成最终总结;
    • send_message(to="*")广播总结与解散通知;
    • 对每个成员调用shutdown_member(member_name=...),等待其从SHUTDOWN_REQUESTED进入SHUTDOWN;
    • 全部关闭后调用clean_team,级联删除团队记录、成员、任务及工作空间资源;
  8. 框架确认:onTeamCleaned回调终止 Leader 流,isTeamCompleted()返回终态快照,整个团队生命周期结束。

官方 E2E 示例 AgentTeamE2eExample.java 印证了这一链路:示例在finally块只做leader.close()和Runner.stop(),不显式调用clean_team——因为 lifecycle 是temporary,Leader 会在收到TEAM_COMPLETED后按提示词指引自行完成shutdown_member+clean_team(参见 AgentTeams.md 的 Demo 收尾说明)。

测试佐证:生命周期语义的可验证性

仓库测试 TeamLifecycleCompatibilityTest.java 对生命周期语义做了直接验证:

  • temporaryTeam_defaultLifecycle:未显式声明 lifecycle 的 spec,默认即为"temporary";
  • persistentTeam_lifecycleIsCreatedBeforeStart:persistent团队 build 后团队级生命周期为CREATED,start 后转RUNNING;
  • persistentTeam_memberReadyToReadyIsValid:READY→READY自迁移在 persistent 模式下合法(长期团队保持 READY 待命的基础)。

而 TeamRailCompatibilityTest.java 则验证了提示词装配规则:teammate 只能收到ROLE / PERSONA / EXTRA三个静态章节,workflow 与 lifecycle 章节对非 Leader 一律不注入。

常见问题与最佳实践

Q1:clean_team报"Active members remain"怎么办?说明仍有成员未处于SHUTDOWN。逐个核对成员状态:shutdown_requested表示已发起关闭但成员尚未完成收尾,应等待其自然进入SHUTDOWN;若成员卡死(长期停留在SHUTDOWN_REQUESTED或无法收尾),可对其实例重试shutdown_member(force=true)——TeamBackend对已处于SHUTDOWN_REQUESTED的成员以 force 重试时会重新发布MEMBER_SHUTDOWN事件,再次驱动shutdownSelf(见 TeamBackend.java 注释),从而解锁clean_team。

Q2:为什么收尾要"高效"?每一轮寒暄都是一次完整 LLM 推理往返。send_message(to="*")把总结+通知压缩为一次通信,成员收到后即进入关闭流程;Leader 不回复致谢,避免制造新的未读消息——别忘了"无未读消息"是完成判定的条件之一,寒暄反而可能拖住收尾。

Q3:shutdown_member与clean_team的时序要求?严格有序:先全部shutdown_member,全部进入SHUTDOWN后再clean_team。两者之间是"请求 → 确认"的关系,clean_team会强制校验所有非 Leader 成员状态。

Q4:临时团队与持久团队如何选择?单次任务、用完即回收的场景选temporary(默认);需要长期驻留、等待多轮用户指令的场景选persistent。二者共享同一套协调内核,仅收尾语义不同——前者由 Leader 主动关闭+解散,后者完成任务后自动 pause 待命(concludeCompletedRound关闭 Leader 流,见 TeamAgent.java)。

最佳实践清单:

  • 成果汇总(含产物路径)必须在shutdown_member之前完成并广播;
  • 逐个shutdown_member后,用list_members或事件确认全员SHUTDOWN,再调clean_team;
  • force=true仅在成员卡死时使用,正常路径绝不启用;
  • 若团队需要复用,改用lifecycle=persistent,不要对临时团队做"半解散式"保留。

通过本文的剖析可以看到,lifecycle_temporary.md虽是一段不足十行的提示词,背后却串联着工具集过滤、成员状态机、完成判定、事件驱动与资源回收的完整机制。理解它,是正确驾驭 openJiuwen Agent Teams 生命周期管理的关键一步。

  • 人工智能
  • 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
点击查看免费下载

相关推荐

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

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

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

立即咨询