从"工具闲置"到"智能分配":OpenCode 多 Agent 工具管理方案实践

0 阅读7分钟

一场始于"这些工具都装好了吗"的自我追问,最终演变成一个自动化工具分配系统的设计与实现。


背景

作为 AI Agent 深度用户,我习惯给 OpenCode 安装各种 MCP 和 Skill——看到好的工具就装,久而久之,工具数量越来越多:

  • 8 个 MCP:playwright、lark、memory、one-search、supabase、clerk、neon、chrome-cdp
  • 34 个 Skills:frontend-design、lark-* 系列、vercel-* 系列、summarize-pro、persistent-memory……

某天我突然意识到一个问题:这些工具真的被用起来了吗?


Plan:问题定义与目标设定

现状分析

我检查了 opencode.json 中的 Agent 配置,发现有 4 个协作 Agent:

{
  "agent": {
    "AIBA": { "description": "需求分析师" },
    "AIUIUX": { "description": "UI/UX设计师" },
    "AITA": { "description": "技术架构师" },
    "AICA": { "description": "编码工程师" }
  }
}

问题是:每个 Agent 的配置文件里,工具清单是手写的、静态的。当安装新工具后,我需要手动更新每个 Agent 的 MD 文件。更糟糕的是,工具分配完全凭直觉——"感觉这个工具应该给谁"。

核心痛点

  1. 工具闲置:装了 40+ 工具,但 Agent 可能只用了其中 10%
  2. 分配主观:没有客观依据,凭感觉分配
  3. 维护困难:每次装新工具都要手动更新配置
  4. 不可扩展:换了 Agent 名称或新增角色,规则全部失效

目标设定

构建一个自动化的工具分配系统,让工具根据 Agent 的实际职能自动分配。

具体目标:

  • ✅ 自动发现所有已安装的工具(MCP + Skills)
  • ✅ 自动分析 Agent 职能(不依赖名称硬匹配)
  • ✅ 生成合理的工具分配方案
  • ✅ 自动同步到 Agent 配置文件

Do:方案设计与实现

第一版:关键词匹配

最初的想法很简单——从 Agent 名称推断职能

const ROLE_KEYWORDS = {
  'coder': ['coder', 'coding', 'code', '程序员'],
  'designer': ['designer', '设计', '设计师'],
  'architect': ['architect', '架构师'],
  'analyst': ['analyst', '分析师', '需求']
};

这样 AIBA 能被识别为 analyst,AIUIUX 能被识别为 designer

效果:勉强能用,但问题很快暴露——

如果有人给 Coder Agent 取名叫 "Steve" 或 "小码" 呢?系统直接失效。

第二版:描述字段 + 名称双重匹配

吸取教训,我增加了 opencode.jsondescription 字段的分析:

function extractAgentRoles(agent) {
  const description = (agent.description || '').toLowerCase();
  const name = (agent.name || '').toLowerCase();
  // 检查名称 + 描述中的关键词
}

效果:好了一点,但仍然不够。

描述里写"编码工程师,生成生产代码"——能识别出"工程师",但识别不出这是 Coder 角色还是 Fullstack 角色。

第三版:多维度综合分析(最终方案)

痛定思痛,我决定从多个维度综合判断 Agent 职能:

维度 1:MD 文件内容分析(权重最高)

读取 Agent 的 MD 配置文件,分析:

分析内容说明权重
已有工具清单配置了 playwright → QA/Coder10
关键词代码、设计、架构、需求等5
动词生成(代码)、设计(界面)、分析(需求)等8
交付物描述需求文档、设计规范、架构方案等6
function analyzeAgentMdFile(agentName, agentDir) {
  const content = fs.readFileSync(mdPath, 'utf-8');
  
  // 检查已有工具(最可靠的信号)
  if (/playwright|chrom[e]?[- ]?cdp/i.test(content)) {
    roles.add('qa');
  }
  
  // 检查动词
  if (/生成|编写|实现/.test(content)) {
    roles.add('coder');
  }
}

维度 2:权限链分析

如果 Agent 能调用 AICA,说明是上游的 AITA:

if (calledAgents.includes('AICA')) {
  roles.add('architect'); // 能调用 coder 的,可能是 architect
}

维度 3:描述字段分析

分析 description 中的输出物描述:

const outputPatterns = [
  { pattern: /输出需求文档|产出需求/i, role: 'ba' },
  { pattern: /输出设计规范|产出设计/i, role: 'designer' },
  { pattern: /输出架构方案|产出架构/i, role: 'architect' },
  { pattern: /生成代码|产出代码/i, role: 'coder' }
];

维度 4:名称分析(兜底)

检查名称中的角色关键词:

for (const [role, keywords] of Object.entries(ROLE_KEYWORDS)) {
  if (nameLower.includes(keyword)) {
    roles.add(role);
  }
}

核心算法:加权得分

每个 Agent 的最终角色由加权得分决定:

function extractAgentRoles(agent, agentDir, allAgents) {
  const evidence = [];
  
  // 四个维度收集证据...
  
  // 计算每个角色的加权得分
  const roleScores = {};
  for (const ev of evidence) {
    roleScores[ev.role] = (roleScores[ev.role] || 0) + ev.weight;
  }
  
  // 按得分排序,取前 4 个
  return Object.entries(roleScores)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 4);
}

工具匹配策略

根据工具能力标签,匹配到合适的 Agent:

const CAPABILITY_TO_AGENT = {
  // 前端/设计 → 主要 designer
  'frontend': ['designer', 'frontend'],
  'design': ['designer'],
  
  // 测试/调试 → 主要 QA
  'testing': ['qa', 'coder'],
  'browser': ['qa', 'frontend'],
  
  // 飞书业务工具 → 主要 BA
  'calendar': ['ba'],
  'task': ['ba'],
  'meeting': ['ba'],
  
  // 全局 → 所有人
  'memory': ['*'],
  'search': ['*']
};

系统架构

┌─────────────────────────────────────────────────────────┐
│  1. 发现工具                                             │
│     扫描 ~/.config/opencode/skills/                     │
│     扫描 ~/.agents/skills/                              │
│     读取 opencode.json 中的 MCP 配置                    │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  2. 多维度角色分析                                       │
│     读取每个 AgentMD 文件                           │
│     分析已有工具、关键词、动词、交付物                    │
│     分析权限链、描述字段、Agent 名称                     │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  3. 智能匹配                                             │
│     工具能力标签 ↔ Agent 职能得分                       │
│     加权计算,生成分配推荐                               │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  4. 同步配置                                             │
│     更新 Agent 配置文件                                  │
│     更新全局记忆文件                                     │
│     输出分配报告                                         │
└─────────────────────────────────────────────────────────┘

Check:验证结果

角色识别效果

运行 tool-allocator sync 后:

🔍 Agent 角色多维度分析:
​
📌 AIBA
   识别角色: designer, ba, coder, analyst
   证据来源:
     - designer (得分:38) <- MD文件:已有工具, MD文件:关键词:design, MD文件:动词:设计
     - ba (得分:37) <- MD文件:关键词:ba, MD文件:交付物, 描述:需求分析师
​
📌 AIUIUX
   识别角色: designer, coder, qa, ui
   证据来源:
     - designer (得分:69) <- MD文件:关键词:design, MD文件:动词:设计, 描述:设计师
​
📌 AITA
   识别角色: architect, designer, coder, qa
   证据来源:
     - architect (得分:53) <- MD文件:关键词:architecture, MD文件:动词:架构设计
​
📌 AICA
   识别角色: coder, designer, qa, architect
   证据来源:
     - coder (得分:43) <- MD文件:关键词:coding, 描述:编码, 描述:生成

工具分配结果

工具类型分配给
lark-* 业务工具AIBA(BA 角色)
supabase / clerkAITA, AICA(后端/架构)
playwright / chrome-cdpAIUIUX, AITA, AICA(测试)
vercel-* 前端工具AIBA, AIUIUX, AITA(前端能力)
frontend-designAIBA, AIUIUX, AITA, AICA(全局设计)
memory / one-search所有人(全局)

无闲置工具

✅ 正在使用:
   - chrome-cdp ← AIUIUX, AITA, AICA
   - summarize-pro ← AIBA
   - ui-ux-pro-max ← AIUIUX, AIBA, AITA
   - playwright ← AIUIUX, AITA, AICA
   - supabase ← AITA, AICA
   ……
​
⚠️ 可能闲置:0 个工具

Act:标准化与持续改进

成果固化

  1. 封装为 Skill:将工具命名为 tool-allocator,上传到 GitHub

  2. 标准化使用流程

    # 安装
    /cocoloop install tool-allocator
    ​
    # 同步分配
    /tool-allocator sync# 检查闲置
    /tool-allocator check
    
  3. 文档完善:编写 SKILL.md 和 README.md,记录使用方法和配置选项

经验总结

教训收获
不能仅靠名称推断职能必须多维度综合分析
主观分配容易出错用证据和得分量化决策
工具越多越容易闲置自动化发现 + 智能匹配
硬编码规则不可扩展基于能力的自适应匹配

未来改进方向

  1. 机器学习优化:根据工具实际使用情况自动调整权重
  2. 可视化配置:提供 Web 界面查看分配矩阵
  3. 冲突检测:检测两个工具功能重复,建议移除
  4. 使用率统计:追踪每个 Agent 实际使用了哪些工具

结语

这个项目源自我对"工具是否真的被用起来"的追问。最初的方案很简单,但随着问题深入,解决方案也越来越完善。

核心洞察:AI Agent 的工具分配不能依赖名称或描述的字面匹配,必须从 Agent 的实际行为(已有工具、动词使用、交付物描述)来推断其职能。

正如 PDCA 的精髓——持续改进。第一版方案虽然粗糙,但它指明了方向;第二版改进了描述分析;第三版才真正解决了问题。每一次迭代都让系统更接近"智能分配"的理想状态。

如果你也在管理多个 Agent 和大量工具,不妨试试这个方案。相信我,工具装得多不是问题,不知道怎么用才是


项目地址github.com/1624318455/…

关键词:OpenCode、Multi-Agent、MCP、Skill、工具管理、自动化配置