Skill: mars82311111/feishu-agent-team (version 1.0.0)

--- name: feishu-agent-team description: 在 OpenClaw 中构建多 Agent 团队协作系统。Coordinator（调度中心）接收 Feishu 群聊 @mention，自动路由任务到专业 Agent，支持自定义 Agent 角色和数量。适用于：(1) 需要 AI 团队处理多类型任务 (2) 希望用单一入口调度专家 Agent (3) 构建自动化工作流团队。 metadata: { "openclaw": { "requires": { "commands": ["python3"] }, "install": [], }, } --- # Feishu Agent Team - 多 Agent 团队协作系统 ## 概念 将多个 AI Agent 组织成"团队"： - **1 个 Coordinator** - 调度中心，接收所有消息并分发 - **N 个 Specialist** - 专家 Agent，各司其职 ``` ┌─→ Specialist-A (商分) │ User @Coordinator ──┼─→ Specialist-B (市场) │ │ │ └─→ Specialist-C (开发) │ └──→ [State] ←──┘ ``` ## 核心功能 - **智能路由**：关键词匹配 → 自动分发到对应专家 - **Feishu 集成**：群 @mention 触发调度，支持多群配置 - **跨 Agent 通信**：MQ 消息队列异步协作 - **状态持久化**：LangGraph Checkpoint 支持断点恢复 - **可扩展**：添加任意数量的专家 Agent ## 安装 ```bash # 进入 OpenClaw workspace cd ~/.openclaw/workspace # 克隆项目 git clone <repo-url> feishu-agent-team # 安装依赖 pip install langgraph langchain-openai feishu-oapi # 初始化 python team.py init ``` ## 快速配置 ### 1. 定义团队角色 编辑 `config/team.yaml`: ```yaml coordinator: name: "Coordinator" # 调度中心名称 mention_name: "coordinator" # 群里的 @ 名称 specialists: - name: "Analyst" # 专家1 specialty: "商业分析" keywords: ["分析", "市场", "投资", "趋势", "商分"] - name: "Developer" # 专家2 specialty: "技术开发" keywords: ["代码", "开发", "bug", "技术", "架构"] - name: "Marketer" # 专家3 specialty: "市场推广" keywords: ["推广", "增长", "内容", "运营"] ``` ### 2. 配置 OpenClaw 绑定 ```json { "bindings": [ { "agentId": "coordinator", "match": { "channel": "feishu", "accountId": "coordinator" } }, { "agentId": "analyst", "match": { "channel": "feishu", "accountId": "analyst" } }, { "agentId": "developer", "match": { "channel": "feishu", "accountId": "developer" } }, { "agentId": "marketer", "match": { "channel": "feishu", "accountId": "marketer" } } ] } ``` ### 3. 配置 Feishu App ```json { "channels": { "feishu": { "accounts": { "coordinator": { "appId": "cli_xxx", "appSecret": "xxx", "groupPolicy": "open", "groups": { "YOUR_GROUP_ID": { "enabled": true, "requireMention": true, "groupSessionScope": "group_sender" } } }, "analyst": { "appId": "cli_yyy", "appSecret": "yyy" }, "developer": { "appId": "cli_zzz", "appSecret": "zzz" }, "marketer": { "appId": "cli_aaa", "appSecret": "aaa" } } } } } ``` ### 4. 启动 Agent 监听 ```bash # 每个 Specialist Agent 运行一个监听进程 python listeners/specialist_listener.py --agent analyst & python listeners/specialist_listener.py --agent developer & python listeners/specialist_listener.py --agent marketer & ``` ## 使用方式 ### 群里 @ Coordinator 发任务 ``` @Coordinator 分析一下当前AI市场的投资趋势 ``` Coordinator 自动识别 → 分发给 Analyst → Analyst 在群里回复。 ### 支持多类型任务 ``` @Coordinator 开发一个用户登录模块 @Coordinator 推广我们的新产品 @Coordinator 分析竞品情况 ``` ### CLI 方式 ```bash # 测试任务路由 python team.py route "我想推广新产品" # → Marketer # 运行任务 python team.py run "分析竞争对手" # 查看团队状态 python team.py info ``` ### Python API ```python from src.api import TeamGraphAPI api = TeamGraphAPI() # 执行任务 result = api.process("市场调研报告", team_config="config/team.yaml") print(result["specialist"]) # 自动路由到对应专家 ``` ## 自定义指南 ### 添加新的专家 Agent 1. 在 `config/team.yaml` 添加: ```yaml specialists: - name: "Designer" specialty: "UI设计" keywords: ["设计", "界面", "UI", "UX", "图标", "海报"] ``` 2. 创建监听器: ```python # listeners/designer_listener.py from src.listeners.base import SpecialistListener class DesignerListener(SpecialistListener): name = "designer" specialty = "UI设计" if __name__ == "__main__": DesignerListener().start() ``` 3. 添加 OpenClaw 绑定和 Feishu 账号 4. 启动监听: `python listeners/designer_listener.py &` ### 修改路由逻辑 编辑 `src/graph.py` 中的路由函数: ```python def route_to_specialist(state: TeamState) -> str: task = state["task"].lower() # 自定义路由规则 if any(kw in task for kw in ["分析", "研究", "报告"]): return "analyst" elif any(kw in task for kw in ["开发", "代码", "bug"]): return "developer" # ... 更多规则 return "coordinator" # 默认保留给调度者处理 ``` ### 多群支持 配置多个群组 ID: ```json { "channels": { "feishu": { "accounts": { "coordinator": { "groups": { "GROUP_ID_1": { "enabled": true, "requireMention": true }, "GROUP_ID_2": { "enabled": true, "requireMention": true }, "GROUP_ID_3": { "enabled": true, "requireMention": true } } } } } } } ``` ## 工作原理 ``` 1. 用户在 Feishu 群 @Coordinator 发送任务 ↓ 2. Coordinator 接收消息，提取任务内容 ↓ 3. 任务路由函数分析关键词，匹配专家 ↓ 4. 通过 MQ 消息队列分发任务给对应专家 ↓ 5. Specialist Agent 接收任务，在群里回复 ``` ## 技术栈 - **状态机**: LangGraph - **持久化**: SQLite Checkpoint - **消息队列**: 轻量级 MQ 实现 - **飞书集成**: feishu-oapi ## 项目结构 ``` feishu-agent-team/ ├── SKILL.md ├── README.md ├── config/ │ └── team.yaml # 团队配置（角色、关键词） ├── src/ │ ├── __init__.py │ ├── api.py # Python API │ ├── graph.py # LangGraph 图定义 │ ├── nodes.py # 节点逻辑 │ ├── state.py # 状态定义 │ ├── routing.py # 路由逻辑 │ ├── feishu_group.py # Feishu 群操作 │ └── persistence/ # Checkpoint 持久化 ├── listeners/ │ ├── base.py # 监听器基类 │ ├── analyst_listener.py │ ├── developer_listener.py │ └── marketer_listener.py ├── team.py # CLI 入口 └── tests/ ``` ## 常见问题 **Q: 需要多少个 Feishu App？** A: 最少 2 个（1 个 Coordinator + 1 个 Specialist），最多 N+1 个。 **Q: 如何添加更多专家？** A: 见"自定义指南 - 添加新的专家 Agent"。 **Q: 任务失败怎么办？** A: Coordinator 会保留任务状态，可通过 `python team.py retry <task_id>` 重试。 ## 许可证 MIT License - 免费使用 ## 支持 遇到问题提交 Issue

path: README.md
content: # Feishu Agent Team

在 OpenClaw 中构建多 Agent 团队协作系统。

## 概念

将多个 AI Agent 组织成"团队"：
- **1 个 Coordinator** - 调度中心，接收所有消息并分发
- **N 个 Specialist** - 专家 Agent，各司其职

## 快速开始

### 1. 克隆项目

```bash
cd ~/.openclaw/projects
git clone <repo-url> feishu-agent-team
cd feishu-agent-team
```

### 2. 安装依赖

```bash
pip install pyyaml
```

### 3. 配置团队

编辑 `config/team.yaml` 自定义团队角色和关键词。

### 4. 测试路由

```bash
python team.py route "分析AI市场趋势"
# → Analyst
```

### 5. 查看团队

```bash
python team.py info
```

## 配置说明

编辑 `config/team.yaml`:

```yaml
coordinator:
  name: "Coordinator"
  mention_name: "coordinator"  # Feishu 群里的 @ 名称

specialists:
  - name: "Analyst"
    keywords: ["分析", "市场", "投资", ...]
    session_key: "agent:analyst:main"
```

## 工作原理

1. 用户在 Feishu 群 @Coordinator 发送任务
2. Coordinator 接收消息，提取任务内容
3. 路由函数分析关键词，匹配专家
4. 任务分发到对应专家 Agent
5. Specialist 回复到群里

## 许可证

MIT License


path: config/team.yaml
content: # Feishu Agent Team 配置
# ========================
# 修改此文件来自定义你的 AI 团队

coordinator:
  name: "Coordinator"
  description: "调度中心，接收所有消息并智能分发"
  # 在 Feishu 群里 @ 此名称触发
  mention_name: "coordinator"

specialists:
  - name: "Analyst"
    description: "商业分析专家"
    keywords:
      - "分析"
      - "市场"
      - "投资"
      - "趋势"
      - "研究"
      - "报告"
      - "数据"
      - "竞品"
    session_key: "agent:analyst:main"
    
  - name: "Developer"
    description: "技术开发专家"
    keywords:
      - "代码"
      - "开发"
      - "bug"
      - "技术"
      - "架构"
      - "API"
      - "数据库"
      - "部署"
    session_key: "agent:developer:main"
    
  - name: "Marketer"
    description: "市场推广专家"
    keywords:
      - "推广"
      - "增长"
      - "内容"
      - "运营"
      - "社交媒体"
      - "粉丝"
      - "广告"
    session_key: "agent:marketer:main"

# 可添加更多专家...
#  - name: "Designer"
#    description: "UI设计专家"
#    keywords:
#      - "设计"
#      - "界面"
#      - "UI"
#      - "海报"
#    session_key: "agent:designer:main"


path: listeners/__init__.py
content: """
监听器模块 - Specialist Agent 监听并处理任务
"""

import os
import sys
import time
import json
import threading
from typing import Optional, Dict, Any

# 添加 src 目录到 path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from src.routing import TeamRouter


class BaseListener:
    """监听器基类"""
    
    def __init__(self, agent_name: str, config_path: Optional[str] = None):
        self.agent_name = agent_name
        self.router = TeamRouter(config_path)
        self.running = False
        
    def get_mq_messages(self, agent: str, timeout: int = 5) -> list:
        """
        从 MQ 获取消息
        
        Args:
            agent: 目标 agent 名称
            timeout: 超时时间（秒）
            
        Returns:
            消息列表
        """
        # TODO: 实现真实的 MQ 读取
        # 目前是占位符，需要接入实际的 MQ 系统
        return []
    
    def process_message(self, message: Dict[str, Any]) -> str:
        """
        处理单条消息
        
        Args:
            message: 消息内容
            
        Returns:
            处理结果
        """
        task = message.get('task', '')
        return f"[{self.agent_name}] 处理任务: {task}"
    
    def send_to_group(self, message: str, chat_id: str) -> bool:
        """
        发送消息到群里
        
        Args:
            message: 消息内容
            chat_id: 群 ID
            
        Returns:
            是否发送成功
        """
        # TODO: 实现真实的 Feishu API 调用
        print(f"[{self.agent_name}] 发送到群 {chat_id}: {message[:50]}...")
        return True
    
    def start(self):
        """启动监听"""
        self.running = True
        print(f"[{self.agent_name}] 监听器已启动")
        
        while self.running:
            messages = self.get_mq_messages(self.agent_name)
            for msg in messages:
                result = self.process_message(msg)
                # 发送到群里
                chat_id = msg.get('chat_id')
                if chat_id:
                    self.send_to_group(result, chat_id)
            
            time.sleep(1)
    
    def stop(self):
        """停止监听"""
        self.running = False
        print(f"[{self.agent_name}] 监听器已停止")


def main():
    """命令行入口"""
    import argparse
    
    parser = argparse.ArgumentParser(description='Agent 监听器')
    parser.add_argument('--agent', required=True, help='Agent 名称')
    parser.add_argument('--config', help='配置文件路径')
    
    args = parser.parse_args()
    
    listener = BaseListener(args.agent, args.config)
    
    try:
        listener.start()
    except KeyboardInterrupt:
        listener.stop()


if __name__ == "__main__":
    main()


path: src/__init__.py
content: """
Feishu Agent Team - 多 Agent 团队协作系统
"""

__version__ = "1.0.0"


path: src/routing.py
content: """
路由模块 - 基于配置文件智能分发任务
"""

import os
import yaml
from typing import Optional, Dict, Any

DEFAULT_CONFIG_PATH = os.path.join(
    os.path.dirname(os.path.dirname(__file__)), 
    "config", 
    "team.yaml"
)


class TeamRouter:
    """团队路由基类"""
    
    def __init__(self, config_path: str = DEFAULT_CONFIG_PATH):
        self.config_path = config_path
        self.config = self._load_config()
        
    def _load_config(self) -> Dict[str, Any]:
        """加载团队配置"""
        if not os.path.exists(self.config_path):
            raise FileNotFoundError(f"配置文件不存在: {self.config_path}")
        
        with open(self.config_path, 'r', encoding='utf-8') as f:
            return yaml.safe_load(f)
    
    def reload(self):
        """重新加载配置"""
        self.config = self._load_config()
    
    def route_task(self, task: str) -> Optional[str]:
        """
        根据任务内容路由到对应专家
        
        Args:
            task: 任务文本
            
        Returns:
            专家名称，未匹配返回 None
        """
        task_lower = task.lower()
        
        for specialist in self.config.get('specialists', []):
            keywords = specialist.get('keywords', [])
            for kw in keywords:
                if kw.lower() in task_lower:
                    return specialist['name']
        
        return None
    
    def get_specialist_info(self, name: str) -> Optional[Dict[str, Any]]:
        """获取专家信息"""
        for specialist in self.config.get('specialists', []):
            if specialist['name'] == name:
                return specialist
        return None
    
    def get_all_specialists(self) -> list:
        """获取所有专家列表"""
        return self.config.get('specialists', [])
    
    def get_coordinator_info(self) -> Dict[str, Any]:
        """获取调度中心信息"""
        return self.config.get('coordinator', {})


def route_task(task: str, config_path: str = DEFAULT_CONFIG_PATH) -> Optional[str]:
    """快捷路由函数"""
    router = TeamRouter(config_path)
    return router.route_task(task)


if __name__ == "__main__":
    # 测试路由
    router = TeamRouter()
    
    test_tasks = [
        "分析一下AI市场趋势",
        "写一个用户登录功能",
        "推广新产品",
        "研究竞品情况"
    ]
    
    print("路由测试:")
    for task in test_tasks:
        specialist = router.route_task(task)
        print(f"  '{task}' → {specialist}")


path: team.py
content: #!/usr/bin/env python3
"""
Feishu Agent Team - CLI 入口
"""

import os
import sys
import argparse

# 添加 src 目录到 path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from src.routing import TeamRouter, route_task


def cmd_route(args):
    """测试路由"""
    router = TeamRouter(args.config)
    specialist = router.route_task(args.task)
    print(f"任务 '{args.task}' → {specialist or 'Coordinator（默认）'}")
    return 0


def cmd_info(args):
    """显示团队信息"""
    router = TeamRouter(args.config)
    
    coord = router.get_coordinator_info()
    print("=" * 50)
    print("调度中心:", coord.get('name', 'N/A'))
    print("描述:", coord.get('description', 'N/A'))
    print("-" * 50)
    print("专家团队:")
    for spec in router.get_all_specialists():
        print(f"  [{spec['name']}] {spec['description']}")
        print(f"    关键词: {', '.join(spec['keywords'][:5])}...")
    print("=" * 50)
    return 0


def cmd_init(args):
    """初始化项目"""
    print("Feishu Agent Team 初始化完成")
    print("请编辑 config/team.yaml 自定义团队")
    return 0


def main():
    parser = argparse.ArgumentParser(description='Feishu Agent Team CLI')
    parser.add_argument('--config', help='配置文件路径')
    subparsers = parser.add_subparsers(dest='cmd', help='子命令')
    
    # route 子命令
    p_route = subparsers.add_parser('route', help='测试任务路由')
    p_route.add_argument('task', help='任务文本')
    p_route.set_defaults(func=cmd_route)
    
    # info 子命令
    p_info = subparsers.add_parser('info', help='显示团队信息')
    p_info.set_defaults(func=cmd_info)
    
    # init 子命令
    p_init = subparsers.add_parser('init', help='初始化')
    p_init.set_defaults(func=cmd_init)
    
    args = parser.parse_args()
    
    if not args.cmd:
        parser.print_help()
        return 1
    
    return args.func(args)


if __name__ == "__main__":
    sys.exit(main() or 0)


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)