Agensh 的任务分配为什么总偏向同一个智能体——先看角色描述和选择规则

文章导读
Agensh 里任务总落到同一个智能体,通常是两件事叠在一起:角色描述彼此覆盖,按描述匹配时打分拉不开差距;或者分配规则本身是顺序优先、先匹配先停,列表里排在前面的智能体反复截走任务。先分清是哪一层导致偏斜,再改描述或改规则,否则只改一边很容易看起来没变化。
📋 目录
  1. A 统计每个智能体实际接到的任务数
  2. B 对比角色描述,找出高度重叠的表述
  3. C 把职责差异写成可判断的适用条件
  4. D 确认分配规则是顺序、轮询还是按描述匹配
  5. E 改完再跑同一批任务,看分布是否变均匀
A A

Agensh 里任务总落到同一个智能体,通常是两件事叠在一起:角色描述彼此覆盖,按描述匹配时打分拉不开差距;或者分配规则本身是顺序优先、先匹配先停,列表里排在前面的智能体反复截走任务。先分清是哪一层导致偏斜,再改描述或改规则,否则只改一边很容易看起来没变化。

先把现象量化:按统一口径统计一段时间内每个智能体实际接到的任务条数和子任务数,确认是全部任务都集中还是某类输入集中。再并排对比角色描述,去掉名字后第三方仍无法判断归属的,视为描述重叠。然后确认分配规则类型——顺序、轮询还是按描述匹配,三类规则表现不同,识别方法也不同。修改后必须用同一批任务复跑对比,注意任务本身分布偏斜时不应强求均匀。

统计每个智能体实际接到的任务数

先不要改配置,先拿到分布。统计口径要写清楚:按任务条数算还是按子任务数算。一个父任务被拆成多个子任务分派时,按条数统计会放大拆分多的智能体,按子任务数统计才反映实际工作量。建议两个口径都出,任务条数看入口归属,子任务数看执行归属,两者差异大的地方往往就是路由层把任务全塞给了一个入口智能体。

记录方式建议直接从调度记录里导出,而不是靠页面手动数。下面是一段通用骨架,表名和字段名需按你的实际结构替换,时间窗口用参数传入,不要写死。

-- 按任务条数统计
SELECT agent_id,
       COUNT(*) AS task_count,
       COUNT(DISTINCT task_type) AS type_count,
       MIN(created_at) AS first_seen,
       MAX(created_at) AS last_seen
FROM task_dispatch
WHERE created_at >= :window_start
  AND created_at <  :window_end
GROUP BY agent_id
ORDER BY task_count DESC;

-- 按子任务数统计
SELECT agent_id,
       COUNT(DISTINCT parent_task_id) AS parent_tasks,
       COUNT(*) AS subtasks
FROM task_dispatch
WHERE created_at >= :window_start
  AND created_at <  :window_end
GROUP BY agent_id
ORDER BY subtasks DESC;

看结果时区分两种形态:所有任务类型都集中到一个智能体,方向更偏向分配规则或描述无差异;只有某一类输入集中,方向更偏向输入特征命中了某个描述里的宽泛关键词。同时记录未被分配的兜底数量,兜底比例异常高说明匹配阈值过严,任务被迫落到默认智能体,这是另一种形式的偏斜。

对比角色描述,找出高度重叠的表述

把每个智能体的描述并排放在一张表里逐项对照,不要只读文字感觉“不太一样”。判断标准很实用:遮住智能体名字,把一条真实任务摆出来,一个不了解系统的人能否只凭描述判断该由谁接。判断不了,就是描述层面无法区分,按描述匹配时得分自然接近,排在前面的赢。

对照项智能体 A智能体 B能否区分
职责一句话负责回答用户问题负责处理用户请求否
能力清单问答、总结、信息整理问答、归纳、资料整理否
适用输入特征未写未写否
排除条件未写未写否
兜底或交接对象未写未写否

常见的重叠信号有三类:一是能力词高度同义,只是换了近义词;二是所有描述都写“通用、日常、协助”,没有任何领域限定;三是只有正向能力描述,没有写不接什么、什么情况下转交。第三种最容易被忽略,因为匹配时只看正向相似度,两个都能接的智能体之间没有排除机制,顺序在前的就一直赢。

把职责差异写成可判断的适用条件

让分配有依据,描述里要出现可判定的输入特征,而不是形容词。写法建议三段式:在什么输入特征下由谁接、什么条件下明确不接、都不匹配时交给谁。下面是一段结构示例,字段名按你的配置格式替换,关键词列表要按实际业务补充,不要直接照抄。

Agensh 的任务分配为什么总偏向同一个智能体——先看角色描述和选择规则
agents:
  - name: code_agent
    accept_when:
      - input_contains: ['报错栈', 'Traceback', '编译失败', '单元测试']
      - input_type: code_snippet
    reject_when:
      - input_contains: ['发票', '报销', '对账']

  - name: finance_agent
    accept_when:
      - input_contains: ['发票', '报销', '对账', '金额']
    reject_when:
      - input_type: code_snippet

  - name: router_agent
    role: fallback
    accept_when:
      - no_match: true

两个注意点。其一,关键词要挑判别力强的,像“问题、帮忙、处理”这类词几乎每条输入都有,写进去等于没写。其二,排除条件比正向条件更能拉开差距,明确写“遇到代码片段不接”,匹配分数才会真正分化。改完后可以直接用几条典型输入手动跑一遍匹配,看各自命中的智能体是否和预期一致,这一步不需要等全量复跑。

确认分配规则是顺序、轮询还是按描述匹配

描述改完仍然偏斜,就要确认规则类型。三类规则的识别方法和表现特征不一样,用同一批输入重复提交几次就能看出端倪:轮询会在多个可用智能体之间来回切换,顺序和匹配不会;顺序规则对列表顺序敏感,把两个智能体在配置里对调位置,结果跟着变,这说明是按顺序取第一个可用;按描述匹配通常会在调度日志里留下相似度或命中理由字段,日志里没有这类字段,基本可以排除按描述匹配。

规则类型识别方法典型表现
顺序优先调换配置里智能体的排列顺序,重跑同一输入结果跟着顺序走,排第一的持续接单
轮询同一输入连续提交多次,看归属是否轮换任务数接近均分,单条任务无差别轮转
按描述匹配查调度日志是否有相似度、命中理由等字段结果稳定,分数接近时固定落到某一个

还有一种混合情况:先按描述匹配,分数并列时按列表顺序取第一个。这种配置在描述重叠时表现和纯顺序规则几乎一样,需要通过日志里的分数字段区分——如果每次都是同分且总落到同一个,问题在描述而不是规则。判断清楚之后再决定改描述还是改规则,避免两边同时大改导致无法归因。

改完再跑同一批任务,看分布是否变均匀

验证要固定输入。把之前统计窗口内的一批任务导出成任务清单文件,去掉时间戳影响,标注一个批次号,按相同顺序重新提交,再用同一段统计骨架按批次号筛选,得到修改后的分布。两次结果放在一起对比三项:每个智能体的任务条数、任务类型命中情况、兜底数量占比。

# 结构示例,命令名和参数按你的实际工具替换
agensh dispatch `--batch-file` tasks_sample.jsonl \
                `--batch-id` retest_01 \
                `--dry-run`

结论判断不要盯着“是否绝对均匀”。合理的状态是:每个智能体在自己声明的适用条件下都有任务进来,兜底占比回到正常水平,原本被一个智能体垄断的任务类型出现分流。如果任务本身分布就偏斜,比如绝大多数输入确实属于同一领域,那么分布仍不均匀是正常的,反而说明分流没有错配。需要警惕的是另一种情况:分布均匀了,但抽查几条任务发现归属明显不对,这通常是关键词写得过宽,把不该分的任务强行分走了,此时应回退关键词而不是继续调规则。所有调整建议先在测试批次上复跑确认,再考虑应用到正式调度,配置改动要留版本记录,方便回滚对比。