DeepSeek Harness Agent Teams 冲突:list_agents 同名与子代理停不掉

故障排查发布于 2026-10-17作者: DeepSeek Plugin 插件市场
DeepSeek HarnessAgent Teamssubagentinterrupt_agentlist_agentswait_agentprofile patch
DeepSeek Harness 挂上 Agent Teams 后,直接委派会与 Team 版工具撞名,同一作用域出现两个 list_agents;而且 Team 版按 roster 名寻址,父 Agent 派出的匿名子代理不在名册里,控制类工具便找不到它。本文给出判据、机制与三种处置。

DeepSeek Harness(DSH)的 Agent Teams 是一套「换寻址方式」的实验能力:它会把原生的子代理控制类工具替换成按名册名寻址的版本(tool-subagent-control、tool-subagent-list-agents、tool-subagent、tool-subagent-fork 都被替换)。于是挂上 Team 之后,你在会话里用 subagent 直接派出的匿名子代理就落进了一个盲区——它不在名册里,interrupt_agent 与 send_message 会报 active teammate "<id>" not found、list_agents 只返回 lead,跑飞的子代理收不回来。 更麻烦的是第二种形态:Team 的补丁按 id 只作用于根层,而各个 preset 在嵌套的 plugins: 段里各自声明了同名 id 的副本,补丁够不到它们,于是同一个作用域里同时存在两个 list_agents、wait_agent 永远返回 noProgress: no-active-peer(#9764、#9523)。

DeepSeek Harness 父 Agent 停不掉自己派出的子代理

一句话结论:不是工具坏了,而是「寻址体系换了」——控制类工具改由 Team 版提供,Team 版按名册名寻址,而你直接委派产生的匿名子代理从来不在名册里,所以按会话 id 找不到它。 症状三连(#9764):

  1. interrupt_agent 报 active teammate "<id>" not found;
  2. send_message 报同一句;
  3. list_agents 只返回 lead,没有你刚派出的那个子代理。

DeepSeek Harness 判据:用参数名对照,不必读源码

最省事的自证方式是看参数名约定。 两套实现的目标寻址参数不同——一套用 agent_id,另一套用 target(名册名)。据社区源码核对,这个差异来自 patch 的四行改动与团队版对参数名的重新约定,报错出处是团队模块的 roster.ts(#9764)。

  1. 做一次调用对照:按文档里的参数名调用 interrupt_agent,若被判定为「缺少必需参数」或「目标不存在」,换另一套参数名再试一次。
  2. 看返回的目标形态:Team 版期望的是名册里的名字,而不是会话/代理 id;如果你手里只有 id,基本可以判断当前挂的是 Team 版(#9764)。
  3. 确认 subagent 工具描述是否失真:讨论里指出,在 Team profile 下 subagent 工具的说明文字与实际行为不一致——它仍然声称返回的 id 可用于 send_message,但实测不成立(#9764)。

DeepSeek Harness 三条处置

  1. 统一改用 Team 玩法(推荐,改动最小):
spawn_teammate  →  建立成员进名册
list_agents     →  拿到名册里的名字
interrupt_agent(target: <名册名>)  →  终止指定成员

关键点是全程用名册名寻址,不要混用 id(#9764)。

  1. 不挂 agent-team-profile:如果团队玩法不是你的刚需,去掉它可以立刻恢复原生委派的寻址方式(#9764)。
  2. 给委派加提示词约束:在派发提示里要求子代理「先把结论写盘再结束」,这样即便它一时收不回来,成果也不会丢——这条在「子代理异常终止读不回输出」时同样有效(#9764)。 子代理「收不回来、输出读不回」本身还有一族可开的诊断与生命周期排查,见 DeepSeek Harness 子代理排查:codex 只报 product-error、条目删不掉与结算崩溃。

DeepSeek Harness list_agents 同名冲突:根层 patch 够不到 preset 层

一句话结论:Team 的补丁按 id 只作用于根层,而各 preset 在嵌套的 plugins: 段里各自声明了同名 id 的副本;补丁在结构上够不到 preset 层,于是根层那份被替换、preset 层那份仍在,同作用域同时出现两个 list_agents,wait_agent 无从判断「谁在运行」。 症状是 wait_agent 永远返回 noProgress: no-active-peer(讨论中单会话实测空转 59 次)(#9523)。

DeepSeek Harness 机制:寻址只在自己组内递归

据报告者与社区互相确认:补丁的 id 寻址实现只递归同级 group,而 preset 把配置声明在更深一层的 plugins: 里,于是根层的替换命中的是另一行;更隐蔽的是——这种缺失是静默的,没有任何「补丁未命中」的报错(#9523)。

DeepSeek Harness 四步确认与处置

  1. 确认判据:wait_agent 反复返回 noProgress: no-active-peer,而 list_agents 的结果看起来「有两套」(名字重复或行为不一致)(#9523)。
  2. 处置一(临时、运行时):装社区插件 @argszero/cordis-plugin-team-delegation-guard,在委派前做一层守卫(#9523):
bash
npm i @argszero/cordis-plugin-team-delegation-guard
  1. 处置二(结构性,三选一):讨论中给了三个补丁分支方向——A 按行加 teams 条件(只在需要时替换);B 改名解耦(让两套工具用不同名字,彻底避开同名);C 只改文案(把工具说明写准,至少不误导)#9523。
  2. 验证:处理后确认同作用域只有一个 list_agents,且 wait_agent 能观察到同伴(不再永远 no-active-peer)(#9523)。

DSH插件 排查注意事项

这一族的排查主线只有一条:先确认「现在生效的是哪一套工具」,再决定怎么寻址——这比读源码快得多。 七条要点:

  1. 参数名就是身份标识:agent_id 与 target 的差异能立刻告诉你挂的是哪一套(#9764)。
  2. list_agents 只返回 lead 是强信号:说明匿名子代理不在名册里(#9764)。
  3. 别信工具描述的自我声称:Team profile 下 subagent 的说明与行为不一致(#9764)。
  4. 删掉 Team profile 是最快的确定性解法,如果不刚需团队玩法(#9764)。
  5. 补丁未命中是静默的:no-active-peer 这类症状背后常常是「补丁打到了另一行」,而不是逻辑 bug(#9523)。
  6. 同名工具会互相遮蔽行为:两套实现共存时,参数约定与返回结构都可能不一致,排查时必须以「实际生效的那套」为准(#9523)。
  7. 修复状态如实:寻址方式替换与 patch 够不到 preset 层在讨论所指版本(0.2.0-rc.2)里都未修;社区插件是运行时守卫,不会替你改 profile 结构,官方也没有宣布修复。

Agent Teams 这类「换工具、换寻址」的能力,排查时最需要的是「当前到底挂了哪些插件与配置行」的清楚视图。与其在各处手敲命令推断,不如用 DSH Plugin Hub 这类可视化插件市场:已安装列表带来源标记、装卸历史与系统日志集中在一个面板里,先把「环境里到底挂了什么」看准。

已安装插件列表

来源:Discussion #9764、Discussion #9523。

常见问题

DeepSeek Harness 里用 subagent 工具派出的子代理,为什么 interrupt_agent 和 send_message 都报 active teammate not found?

在 DeepSeek Harness 里,这条报错说明寻址体系变了:挂上 Agent Teams 的 profile 之后,控制类工具改由 Team 版提供,而 Team 版是按团队名册(roster)里的名字寻址的,你在会话里直接派出的匿名子代理从来不在名册里,所以按它的会话 id 找不到任何东西。判据是 list_agents 只返回 lead 而没有你刚派出的那个子代理。

DeepSeek Harness 启用 Agent Teams 后,同一会话里出现两个 list_agents、wait_agent 一直说 no-active-peer,是配置写错了吗?

这多半不是 DeepSeek Harness 的配置写法问题,而是补丁打不到该打的位置。Team 的补丁按 id 只作用于根层,而各个 preset 在嵌套的 plugins 段里各自声明了同名 id 的副本,补丁在结构上够不到 preset 层,于是根层那份被替换了、preset 层那份还在,两个同名工具同时存在。识别特征就是 wait_agent 反复返回 noProgress: no-active-peer。

在 DeepSeek Harness 里,怎么用参数名快速区分某个工具是 Agent Teams 的 Team 版还是原生委派的普通版?

在 DeepSeek Harness 里看参数名最直接:两套实现的参数约定不同,例如寻址目标一个用 agent_id、另一个用 target(名册名)。如果你按文档里的参数名传参却被判无效,或者反过来文档里的名字根本不存在,就说明当前挂载的是另一套实现。这个对照不需要读源码,试一次调用就能看出来。

在 DeepSeek Harness 里,不想动 profile 结构,能不能让 Agent Teams 与直接用 subagent 委派和平共存?

在 DeepSeek Harness 里可以:不挂 Agent Teams 的 profile,只用原生子代理工具;或者按 Team 的方式统一改用名册寻址,即先用 spawn_teammate 建成员、再用 list_agents 拿名字、最后用带 target 参数的 interrupt_agent 终止。运行时还有社区插件可以在委派前做一层守卫,但它只做提示与拦截,不会帮你改 profile 结构。

在 DeepSeek Harness 挂上 Agent Teams 后,父 Agent 为什么拿不回自己派出去的跑飞子代理?

在 DeepSeek Harness 里,父代理拿不回这类子代理有两个原因叠在一起:一是控制类工具被替换成按名册寻址的版本,匿名子代理不在名册里;二是团队视角下父代理并非每个子代理的管理者,它只认识名册成员。所以「跑飞的子代理无法回收」在这套组合下是结构性的,规避方式是先统一委派方式,再考虑挂不挂 Team。

相关术语

Agent Teams
Agent Teams 是 DeepSeek Harness 的一组实验性能力与配套 profile,用「团队」的方式组织多个代理:成员先被创建进名册,之后通过名册名互相寻址与协作。它替换了原生子代理的控制类工具,因此寻址方式与原生委派不同。— https://github.com/deepseek-ai/deepseek-harness/discussions/9764
roster(名册)
roster 是 Agent Teams 里记录团队成员的名单,成员按名册名被寻址。直接委派产生的匿名子代理不会被写进名册,因此在按名册寻址的工具里找不到它们,这是「父代理停不掉自己派出的子代理」的直接原因。— https://github.com/deepseek-ai/deepseek-harness/discussions/9764
profile patch 的 id 寻址
profile patch 通过 id 定位要替换的配置行,但它只在自己的组内递归查找。由于 preset 在嵌套的 plugins 段里声明了同名 id 的副本,根层 patch 在结构上够不到 preset 层,于是会出现「看起来打上了、实际只替换了一份」的情况。— https://github.com/deepseek-ai/deepseek-harness/discussions/9523
wait_agent
wait_agent 是等待某个协作代理结束或产生进展的工具,按名册或代理标识查找目标。当同作用域存在两套实现、且目标并未登记进名册时,它会一直返回 noProgress: no-active-peer,看起来像「没有任何活跃同伴」。— https://github.com/deepseek-ai/deepseek-harness/discussions/9523

来源