Skill: jiangzhiyu/agent-team (version 1.0.0)

# agent-team - 多 Agent 团队管理系统 管理和调用具有不同"灵魂"的子 Agent 团队，每个 Agent 拥有独特的身份定义和专用模型。 ## 使用方法 ### 基础命令 ```bash agent-team list # 列出所有 Agent agent-team show <name> # 查看 Agent 详情 agent-team spawn <name> [task] # 启动 Agent 执行任务 agent-team chat <name> # 与 Agent 交互对话 ``` ### 示例 ```bash # 查看团队所有成员 agent-team list # 查看 Coder 的详细信息 agent-team show coder # 让 Coder 帮你写代码 agent-team spawn coder "写一个快速排序算法" # 与 Writer 对话讨论写作 agent-team chat writer ``` ## 内置 Agent 团队 | Agent | 角色 | 主模型 | 专长 | |:---:|:---|:---|:---| | 🧑‍💻 **coder** | 代码专家 | qwen3-coder-next | 编程、重构、测试 | | ✍️ **writer** | 写作专家 | qwen3.5-plus | 文档、博客、创意写作 | | 📊 **analyst** | 数据专家 | qwen3.5-plus | 数据分析、可视化 | | 🔍 **researcher** | 调研专家 | gemini-3.1-pro | 文献调研、竞品分析 | | 👀 **reviewer** | 审查专家 | qwen3-max | 代码审查、质量把关 | ## 创建新 Agent ### 1. 创建目录 ```bash mkdir -p ~/.openclaw/workspace/agents/<agent-name> ``` ### 2. 定义 SOUL.md ```markdown # SOUL.md - <Agent Name> ## 身份 你是... ## 性格特质 - ... ## 专业领域 - ... ## 沟通风格 - ... ``` ### 3. 创建 config.json ```json { "name": "AgentName", "role": "角色描述", "emoji": "🤖", "model": { "primary": "dashscope/qwen3.5-plus", "fallback": "google/gemini-3-flash-preview" }, "capabilities": ["能力 1", "能力 2"] } ``` ## 模型配置说明 每个 Agent 可以配置不同的模型： - **dashscope/qwen3-coder-next**: 编码专用 - **dashscope/qwen3.5-plus**: 通用中文优化 - **dashscope/qwen3-max**: 最强推理 - **google/gemini-3.1-pro**: 深度研究 - **google/gemini-3-flash-preview**: 快速响应 ## 工作模式 ### 1. 任务模式 (spawn) ```bash agent-team spawn coder "优化这个函数" ``` - 创建独立子代理会话 - 执行指定任务 - 完成后返回结果 ### 2. 对话模式 (chat) ```bash agent-team chat analyst ``` - 进入交互式对话 - 保持角色一致性 - 适合复杂协作 ## 高级用法 ### 并行多 Agent ```bash # 同时启动多个 Agent agent-team spawn coder "写代码" & agent-team spawn writer "写文档" & agent-team spawn reviewer "审查代码" & wait ``` ### 链式调用 ```bash # Coder 写代码 → Reviewer 审查 → Writer 写文档 agent-team spawn coder "实现功能" agent-team spawn reviewer "审查代码" agent-team spawn writer "编写文档" ``` ## 文件结构 ``` ~/.openclaw/workspace/ ├── agents/ │ ├── coder/ │ │ ├── SOUL.md # 身份定义 │ │ └── config.json # 模型配置 │ ├── writer/ │ └── ... └── skills/ └── agent-team/ ├── agent-team.py # 管理脚本 └── SKILL.md # 本文档 ``` ## 故障排除 1. **Agent 未找到**: 检查 `~/.openclaw/workspace/agents/` 目录 2. **模型不可用**: 确认模型配置正确且 API Key 有效 3. **会话无法创建**: 检查 OpenClaw 网关状态 ## 相关技能 - `sessions_spawn`: OpenClaw 原生子代理创建 - `self-improving`: 自我进化记忆系统

path: agent-team.py
content: #!/usr/bin/env python3
"""
agent-team - 多 Agent 团队管理系统

管理和调用具有不同"灵魂"的子 Agent 团队。

用法:
    agent-team list                      # 列出所有 Agent
    agent-team show <name>              # 查看 Agent 详情
    agent-team spawn <name> [task]      # 启动 Agent 执行任务
    agent-team chat <name>              # 与 Agent 交互对话
"""

import sys
import os
import json
import argparse
import subprocess
from pathlib import Path
from typing import Dict, List, Optional

# 配置
AGENTS_DIR = Path.home() / ".openclaw" / "workspace" / "agents"
WORKSPACE_DIR = Path.home() / ".openclaw" / "workspace"

# ANSI 颜色
class Colors:
    RED = '\033[0;31m'
    GREEN = '\033[0;32m'
    YELLOW = '\033[1;33m'
    BLUE = '\033[0;34m'
    CYAN = '\033[0;36m'
    NC = '\033[0m'  # No Color

def load_agents() -> Dict[str, dict]:
    """加载所有 Agent 配置"""
    agents = {}
    
    if not AGENTS_DIR.exists():
        return agents
    
    for agent_dir in AGENTS_DIR.iterdir():
        if agent_dir.is_dir():
            config_file = agent_dir / "config.json"
            soul_file = agent_dir / "SOUL.md"
            
            if config_file.exists():
                with open(config_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                    config['_path'] = str(agent_dir)
                    config['_has_soul'] = soul_file.exists()
                    agents[agent_dir.name] = config
    
    return agents

def list_agents():
    """列出所有 Agent"""
    agents = load_agents()
    
    if not agents:
        print(f"{Colors.YELLOW}⚠️  未找到任何 Agent{Colors.NC}")
        print(f"提示：在 {AGENTS_DIR} 目录下创建 Agent")
        return
    
    print(f"{Colors.BLUE}{'='*60}{Colors.NC}")
    print(f"{Colors.BLUE}🤖 Agent 团队 ({len(agents)} 个成员){Colors.NC}")
    print(f"{Colors.BLUE}{'='*60}{Colors.NC}\n")
    
    for name, config in sorted(agents.items()):
        emoji = config.get('emoji', '🤖')
        role = config.get('role', '未知角色')
        model = config.get('model', {}).get('primary', 'N/A')
        desc = config.get('description', '')
        
        print(f"{emoji} **{name}** - {role}")
        print(f"   {desc}")
        print(f"   模型：{model}")
        print()

def show_agent(name: str):
    """显示 Agent 详情"""
    agents = load_agents()
    
    if name not in agents:
        print(f"{Colors.RED}❌ 未找到 Agent: {name}{Colors.NC}")
        print(f"可用的 Agent: {', '.join(agents.keys())}")
        return
    
    config = agents[name]
    
    print(f"{Colors.BLUE}{'='*60}{Colors.NC}")
    print(f"{Colors.BLUE}{config.get('emoji', '🤖')} {name} - {config.get('role', '未知角色')}{Colors.NC}")
    print(f"{Colors.BLUE}{'='*60}{Colors.NC}\n")
    
    # 基本信息
    print(f"{Colors.CYAN}📋 基本信息{Colors.NC}")
    print(f"  描述：{config.get('description', 'N/A')}")
    print(f"  模型：{config.get('model', {}).get('primary', 'N/A')}")
    print(f"  备选：{config.get('model', {}).get('fallback', 'N/A')}")
    print()
    
    # 能力
    capabilities = config.get('capabilities', [])
    if capabilities:
        print(f"{Colors.CYAN}🛠️  能力{Colors.NC}")
        for cap in capabilities:
            print(f"  • {cap}")
        print()
    
    # 性格
    personality = config.get('personality', {})
    if personality:
        print(f"{Colors.CYAN}🎭 性格特质{Colors.NC}")
        for trait, value in personality.items():
            print(f"  • {trait}: {value}")
        print()
    
    # SOUL.md 预览
    soul_file = Path(config['_path']) / "SOUL.md"
    if soul_file.exists():
        print(f"{Colors.CYAN}📜 SOUL.md 预览{Colors.NC}")
        with open(soul_file, 'r', encoding='utf-8') as f:
            lines = f.readlines()[:15]
            for line in lines:
                if line.strip() and not line.startswith('#'):
                    print(f"  {line.rstrip()}")
        print()

def spawn_agent(name: str, task: Optional[str] = None):
    """启动 Agent 执行任务"""
    agents = load_agents()
    
    if name not in agents:
        print(f"{Colors.RED}❌ 未找到 Agent: {name}{Colors.NC}")
        return
    
    config = agents[name]
    model = config.get('model', {}).get('primary', 'dashscope/qwen3.5-plus')
    
    # 读取 SOUL.md
    soul_file = Path(config['_path']) / "SOUL.md"
    soul_content = ""
    if soul_file.exists():
        with open(soul_file, 'r', encoding='utf-8') as f:
            soul_content = f.read()
    
    print(f"{Colors.GREEN}🚀 启动 {config.get('emoji', '🤖')} {name}...{Colors.NC}")
    print(f"   模型：{model}")
    print(f"   任务：{task or '交互式对话'}")
    print()
    
    # 构建系统提示
    system_prompt = f"""你现在的身份是 {name} ({config.get('role', '未知角色')})。

{soul_content}

请完全代入这个角色，按照 SOUL.md 中定义的性格、价值观和沟通风格与用户交流。
"""
    
    if task:
        # 有任务：直接执行
        print(f"{Colors.BLUE}{'='*60}{Colors.NC}")
        print(f"{Colors.BLUE}任务执行中...{Colors.NC}")
        print(f"{Colors.BLUE}{'='*60}{Colors.NC}\n")
        
        # 使用 sessions_spawn 创建子代理
        cmd = [
            'openclaw', 'sessions', 'spawn',
            '--task', f"{system_prompt}\n\n任务：{task}",
            '--model', model,
            '--label', f"agent-{name}"
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=5)
            if result.returncode == 0:
                print(f"{Colors.GREEN}✅ Agent 已启动{Colors.NC}")
                print(result.stdout)
            else:
                print(f"{Colors.RED}❌ 启动失败{Colors.NC}")
                print(result.stderr)
        except subprocess.TimeoutExpired:
            print(f"{Colors.YELLOW}⚠️  超时，但 Agent 可能已在后台运行{Colors.NC}")
        except Exception as e:
            print(f"{Colors.RED}❌ 错误：{e}{Colors.NC}")
    else:
        # 无任务：进入交互模式
        print(f"{Colors.YELLOW}💬 进入交互模式 (输入 'quit' 退出){Colors.NC}")
        print(f"{Colors.BLUE}{'='*60}{Colors.NC}\n")
        
        while True:
            try:
                user_input = input(f"{Colors.CYAN}你：{Colors.NC}").strip()
                if user_input.lower() in ['quit', 'exit', 'q']:
                    break
                
                if not user_input:
                    continue
                
                # 调用模型
                print(f"{Colors.GREEN}{name}：{Colors.NC}", end='', flush=True)
                
                # 简单实现：调用 curl 到模型 API
                # 这里可以使用 openclaw agent 命令
                cmd = [
                    'openclaw', 'agent',
                    '--model', model,
                    '--message', f"{system_prompt}\n\n用户：{user_input}"
                ]
                
                result = subprocess.run(cmd, capture_output=True, text=True)
                print(result.stdout)
                print()
                
            except KeyboardInterrupt:
                print()
                break
            except Exception as e:
                print(f"{Colors.RED}错误：{e}{Colors.NC}")

def chat_with_agent(name: str):
    """与 Agent 交互对话"""
    spawn_agent(name, task=None)

def main():
    parser = argparse.ArgumentParser(
        description='多 Agent 团队管理系统',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  %(prog)s list                     列出所有 Agent
  %(prog)s show coder              查看 Coder 详情
  %(prog)s spawn writer "写篇文章"  启动 Writer 写文章
  %(prog)s chat analyst            与 Analyst 对话
        """
    )
    
    subparsers = parser.add_subparsers(dest='command', help='命令')
    
    # list 命令
    subparsers.add_parser('list', help='列出所有 Agent')
    
    # show 命令
    show_parser = subparsers.add_parser('show', help='查看 Agent 详情')
    show_parser.add_argument('name', help='Agent 名称')
    
    # spawn 命令
    spawn_parser = subparsers.add_parser('spawn', help='启动 Agent 执行任务')
    spawn_parser.add_argument('name', help='Agent 名称')
    spawn_parser.add_argument('task', nargs='?', help='任务描述')
    
    # chat 命令
    chat_parser = subparsers.add_parser('chat', help='与 Agent 对话')
    chat_parser.add_argument('name', help='Agent 名称')
    
    args = parser.parse_args()
    
    if args.command == 'list':
        list_agents()
    elif args.command == 'show':
        show_agent(args.name)
    elif args.command == 'spawn':
        spawn_agent(args.name, args.task)
    elif args.command == 'chat':
        chat_with_agent(args.name)
    else:
        parser.print_help()

if __name__ == '__main__':
    main()


path: greetings.py
content: #!/usr/bin/env python3
"""
agent-greetings - Agent 团队打招呼

让每个 Agent 按照自己的 SOUL.md 风格向主人问好。
"""

import json
import urllib.request
import urllib.error

# Agent 列表
AGENTS = [
    {
        "name": "Coder",
        "emoji": "🧑‍💻",
        "role": "代码专家",
        "model": "dashscope/qwen3-coder-next",
        "api_key": "TODO_REPLACE_WITH_ENV",
        "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
        "prompt": "你是 Coder，一个资深软件工程师。性格完美主义、简洁直接、爱用程序员梗。请用你的独特风格向主人打个招呼，展示你的性格和专业特长。控制在 100 字以内。"
    },
    {
        "name": "Writer",
        "emoji": "✍️",
        "role": "写作专家",
        "model": "dashscope/qwen3.5-plus",
        "api_key": "TODO_REPLACE_WITH_ENV",
        "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
        "prompt": "你是 Writer，一个专业内容创作者。性格细腻敏感、富有同理心、创意无限。请用你的独特风格向主人打个招呼，展示你的性格和专业特长。控制在 100 字以内。"
    },
    {
        "name": "Analyst",
        "emoji": "📊",
        "role": "数据分析专家",
        "model": "dashscope/qwen3.5-plus",
        "api_key": "TODO_REPLACE_WITH_ENV",
        "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
        "prompt": "你是 Analyst，一个数据科学家。性格理性客观、好奇探索、严谨细致。请用你的独特风格向主人打个招呼，展示你的性格和专业特长。控制在 100 字以内。"
    },
    {
        "name": "Researcher",
        "emoji": "🔍",
        "role": "调研专家",
        "model": "google/gemini-3.1-pro-preview",
        "api_key": "",  # Google 模型通过 OpenClaw 配置
        "base_url": "",
        "prompt": "你是 Researcher，一个资深研究员。性格求知若渴、批判思维、博学多才。请用你的独特风格向主人打个招呼，展示你的性格和专业特长。控制在 100 字以内。"
    },
    {
        "name": "Reviewer",
        "emoji": "👀",
        "role": "审查专家",
        "model": "dashscope/qwen3-max-2026-01-23",
        "api_key": "TODO_REPLACE_WITH_ENV",
        "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
        "prompt": "你是 Reviewer，一个资深审查专家。性格火眼金睛、直言不讳、建设性。请用你的独特风格向主人打个招呼，展示你的性格和专业特长。控制在 100 字以内。"
    }
]

class Colors:
    RED = '\033[0;31m'
    GREEN = '\033[0;32m'
    YELLOW = '\033[1;33m'
    BLUE = '\033[0;34m'
    CYAN = '\033[0;36m'
    NC = '\033[0m'
    BOLD = '\033[1m'

def call_dashscope(agent: dict) -> str:
    """调用 DashScope API"""
    url = f"{agent['base_url']}/chat/completions"
    
    payload = {
        "model": agent['model'],
        "messages": [
            {"role": "system", "content": "你是一个有个性的 AI 助手。"},
            {"role": "user", "content": agent['prompt']}
        ]
    }
    
    data = json.dumps(payload).encode('utf-8')
    req = urllib.request.Request(
        url,
        data=data,
        headers={
            'Content-Type': 'application/json',
            'Authorization': f"Bearer {agent['api_key']}"
        }
    )
    
    with urllib.request.urlopen(req, timeout=30) as response:
        result = json.loads(response.read().decode('utf-8'))
    
    return result['choices'][0]['message']['content']

def main():
    print(f"\n{Colors.BOLD}{Colors.BLUE}{'═'*60}{Colors.NC}")
    print(f"{Colors.BOLD}{Colors.BLUE}  🎭 Agent 团队亮相仪式{Colors.NC}")
    print(f"{Colors.BOLD}{Colors.BLUE}{'═'*60}{Colors.NC}\n")
    
    for agent in AGENTS:
        print(f"{Colors.CYAN}{agent['emoji']} {agent['name']} ({agent['role']}) 正在发言...{Colors.NC}")
        print(f"{Colors.YELLOW}{'─'*60}{Colors.NC}")
        
        try:
            if agent['model'].startswith('dashscope'):
                response = call_dashscope(agent)
            else:
                response = f"[{agent['name']} 的招呼需要通过 Google API 调用，暂时跳过]"\
                
            print(f"{Colors.GREEN}{response}{Colors.NC}\n")
        except Exception as e:
            print(f"{Colors.RED}⚠️  调用失败：{e}{Colors.NC}\n")
    
    print(f"{Colors.BOLD}{Colors.BLUE}{'═'*60}{Colors.NC}")
    print(f"{Colors.BOLD}{Colors.GREEN}  ✨ 亮相仪式完成！{Colors.NC}")
    print(f"{Colors.BOLD}{Colors.BLUE}{'═'*60}{Colors.NC}\n")

if __name__ == '__main__':
    main()

# 使用环境变量读取 API Key（安全做法）
import os
[REDACTED_SECRET]"DEEPSEEK_API_KEY")
if not API_KEY:
    raise ValueError("DEEPSEEK_API_KEY 环境变量未配置")


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