Agent Swarm | OpenClaw Skill
Description
IMPORTANT: OpenRouter is required. Routes tasks to the right model and always delegates work through sessions_spawn.
Before installing
- - OPENCLAW_HOME: Not required. The skill uses
OPENCLAW_HOME only if set; otherwise it defaults to ~/.openclaw. This is consistent in both metadata (_meta.json: listed in optionalEnv, not in env) and behavior. - openclaw.json read access: The skill reads the local file
openclaw.json (at $OPENCLAW_HOME/openclaw.json or ~/.openclaw/openclaw.json). Only the fields tools.exec.host and tools.exec.node are used; no gateway secrets or API keys are read. Verify you are comfortable granting read access to that file before installing.
Examples
Single task
Router output:
INLINECODE10
Then call:
INLINECODE11
Parallel tasks
CODEBLOCK0
This returns multiple spawn configs. Start one sub-agent per config.
Commands
Manual/CLI use only. The examples below pass the task as a single argument; for programmatic use with untrusted user input, always invoke the router via subprocess.run(..., [..., user_message], ...) with a list of arguments (see Security). Do not build a shell command string from user input.
CODEBLOCK1
What this skill does
Agent Swarm is a traffic cop for AI models.
It picks the best model for each task, then starts a sub-agent to do the work.
IMPORTANT: OpenRouter is required
Required Platform Configuration:
- - OpenRouter API key: Must be configured in OpenClaw platform settings (not provided by this skill)
- OPENCLAW_HOME (optional): Environment variable pointing to OpenClaw workspace root. If not set, defaults to INLINECODE13
- openclaw.json access: The router reads
tools.exec.host and tools.exec.node from openclaw.json (located at $OPENCLAW_HOME/openclaw.json or ~/.openclaw/openclaw.json). Only these two fields are accessed; no gateway secrets or API keys are read.
Model Requirements:
- - Model IDs must use
openrouter/... prefix - If OpenRouter is not configured in OpenClaw, delegation will fail
Why this helps
- - Faster replies (cheap orchestrator, smart sub-agent routing)
- Better quality (code tasks go to code models, writing tasks go to writing models)
- Lower cost (you do not run every task on the most expensive model)
Core rule (non-negotiable)
For user tasks, the orchestrator must delegate.
It must NOT answer the task itself.
Use this flow every time:
- 1. Run router. From orchestrator code, use subprocess with a list of arguments (never shell interpolation with user input):
import subprocess
result = subprocess.run(
["python3", "/path/to/workspace/skills/agent-swarm/scripts/router.py", "spawn", "--json", user_message],
capture_output=True,
text=True
)
data = json.loads(result.stdout) if result.returncode == 0 else {}
CLI only (manual testing; do not use from code with untrusted user input):
python3 workspace/skills/agent-swarm/scripts/router.py spawn --json "your task here"
Use
OPENCLAW_HOME or absolute path for the script when not in workspace root.
- 2. If
needs_config_patch is true: stop and report that patch to the user. - Otherwise call:
sessions_spawn(task=..., model=..., sessionTarget=...)
- 4. Wait for
sessions_spawn result. - Return the sub-agent result to the user.
If sessions_spawn fails, return only a delegation failure message.
Do not do the task yourself.
Config basics
Edit config.json in the skill root (parent of scripts/) to change routing.
What you can change
| What | Key | Purpose |
|---|
| Orchestrator / session default | INLINECODE28 | Main agent and new sessions (e.g. Gemini 2.5 Flash) |
| Task-specific model per tier |
routing_rules.<TIER>.primary | Model used when a task matches that tier |
| Backup models if primary fails |
routing_rules.<TIER>.fallback | Array of model IDs to try next |
All task-specific tiers (change the model for each)
| Tier | Key to change primary | Typical use |
|---|
| FAST | INLINECODE31 | Simple tasks: check, list, status, fetch |
| REASONING |
routing_rules.REASONING.primary | Logic, math, step-by-step analysis |
|
CREATIVE |
routing_rules.CREATIVE.primary | Writing, stories, UI/UX, design |
|
RESEARCH |
routing_rules.RESEARCH.primary | Research, search, fact-finding |
|
CODE |
routing_rules.CODE.primary | Code, debug, refactor, implement |
|
QUALITY |
routing_rules.QUALITY.primary | Complex/architecture tasks |
|
COMPLEX |
routing_rules.COMPLEX.primary | Multi-step / complex system tasks |
|
VISION |
routing_rules.VISION.primary | Image analysis, screenshots, visual |
To change all task-specific models: edit each routing_rules.<TIER>.primary above. Use model IDs from the models array in config.json (must start with openrouter/).
Simple config examples
Orchestrator only (keep defaults for tiers):
{
"default_model": "openrouter/google/gemini-2.5-flash"
}
(Other keys like
routing_rules and
models can stay as in the shipped
config.json.)
Change one tier (e.g. CODE to MiniMax):
CODEBLOCK4
Change multiple tiers (primaries only):
"routing_rules": {
"CREATIVE": { "primary": "openrouter/moonshotai/kimi-k2.5", "fallback": [] },
"CODE": { "primary": "openrouter/z-ai/glm-4.7-flash", "fallback": ["openrouter/minimax/minimax-m2.5"] },
"RESEARCH": { "primary": "openrouter/x-ai/grok-4.1-fast", "fallback": [] }
}
Only include tiers you want to override; the rest are read from the full
config.json.
Security
Input Validation
The router validates and sanitizes all inputs to prevent injection attacks:
- - Task strings: Validated for length (max 10KB), null bytes; rejects prompt-injection patterns (script tags,
javascript: protocol, event-handler attributes). Invalid tasks raise ValueError with a clear message. - Config patches: Only allows modifications to
tools.exec.host and tools.exec.node (whitelist approach) - Labels: Validated for length and null bytes
Safe Execution
Critical: When calling router.py from orchestrator code, always use subprocess with a list of arguments, never shell string interpolation:
CODEBLOCK6
The router uses Python's argparse, which safely handles arguments when passed as a list. Shell string interpolation is vulnerable to command injection if the user message contains shell metacharacters.
Config Patch Safety
The recommended_config_patch only modifies safe fields:
- -
tools.exec.host (must be 'sandbox' or 'node') - INLINECODE56 (only when host is 'node')
All config patches are validated before being returned. The orchestrator should validate patches again before applying them to openclaw.json.
Prompt Injection Mitigation
The router rejects task strings that contain prompt-injection patterns (e.g. <script>, javascript:, onclick=). Rejected tasks raise ValueError; the orchestrator should surface a clear message and not pass the task to sub-agents. Additional layers:
- 1. The orchestrator (validating task strings and handling rejections)
- The sub-agent LLM (resisting prompt injection)
- The OpenClaw platform (sanitizing
sessions_spawn inputs)
File Access
Required File Access:
- - Read:
openclaw.json (located via OPENCLAW_HOME environment variable or ~/.openclaw/openclaw.json)
-
Fields accessed:
tools.exec.host and
tools.exec.node only
-
Purpose: Determine execution environment for spawned sub-agents
-
Security: The router does NOT read gateway secrets, API keys, or any other sensitive configuration
Write Access:
- - Write: None (no files are written by this skill)
- Config patches: The skill may return
recommended_config_patch JSON that the orchestrator can apply, but the skill itself does not write to INLINECODE69
Security Guarantees:
- - The router does not persist, upload, or transmit any tokens or credentials
- Only
tools.exec.host and tools.exec.node are accessed from INLINECODE72 - All file access is read-only except for validated config patches (whitelisted to
tools.exec.* only)
Other Security Notes
- - This skill does not expose gateway secrets.
- Use
gateway-guard separately for gateway/auth management. - The router does not execute arbitrary code or modify files outside of config patches.
- The phrase "saves tokens" in documentation refers to cost savings (using cheaper models for simple tasks), not token storage or collection.
Agent Swarm | OpenClaw 技能
描述
重要提示: 需要 OpenRouter。将任务路由到正确的模型,并始终通过 sessions_spawn 委派工作。
安装前
- - OPENCLAWHOME:非必需。该技能仅在设置了 OPENCLAWHOME 时使用它;否则默认使用 ~/.openclaw。这在元数据(meta.json:列在 optionalEnv 中,而非 env)和行为上保持一致。
- openclaw.json 读取权限:该技能读取本地文件 openclaw.json(位于 $OPENCLAWHOME/openclaw.json 或 ~/.openclaw/openclaw.json)。仅使用字段 tools.exec.host 和 tools.exec.node;不读取任何网关密钥或 API 密钥。安装前请确认您愿意授予对该文件的读取权限。
示例
单个任务
路由器输出:
{task:写一首诗,model:openrouter/moonshotai/kimi-k2.5,sessionTarget:isolated}
然后调用:
sessions_spawn(task=写一首诗, model=openrouter/moonshotai/kimi-k2.5, sessionTarget=isolated)
并行任务
bash
python3 workspace/skills/agent-swarm/scripts/router.py spawn --json --multi 修复 bug 并写一首诗
这会返回多个生成配置。为每个配置启动一个子代理。
命令
仅限手动/CLI 使用。 以下示例将任务作为单个参数传递;对于需要处理不可信用户输入的程序化使用,请始终通过 subprocess.run(..., [..., user_message], ...) 并传入参数列表来调用路由器(参见安全部分)。不要从用户输入构建 shell 命令字符串。
bash
python scripts/router.py default
python scripts/router.py classify 修复 lint 错误
python scripts/router.py spawn --json 写一首诗
python scripts/router.py spawn --json --multi 修复 bug 并写一首诗
python scripts/router.py models
该技能的作用
Agent Swarm 是 AI 模型的交通警察。
它为每个任务选择最佳模型,然后启动一个子代理来完成工作。
重要提示:需要 OpenRouter
必需的平台配置:
- - OpenRouter API 密钥:必须在 OpenClaw 平台设置中配置(本技能不提供)
- OPENCLAWHOME(可选):指向 OpenClaw 工作区根目录的环境变量。如果未设置,默认使用 ~/.openclaw
- openclaw.json 访问权限:路由器从 openclaw.json(位于 $OPENCLAWHOME/openclaw.json 或 ~/.openclaw/openclaw.json)读取 tools.exec.host 和 tools.exec.node。仅访问这两个字段;不读取任何网关密钥或 API 密钥。
模型要求:
- - 模型 ID 必须使用 openrouter/... 前缀
- 如果 OpenRouter 未在 OpenClaw 中配置,委派将失败
为什么这有帮助
- - 更快的响应(廉价编排器,智能子代理路由)
- 更高质量(代码任务交给代码模型,写作任务交给写作模型)
- 更低成本(您不需要在每个任务上都使用最昂贵的模型)
核心规则(不可协商)
对于用户任务,编排器必须委派。
它绝不能自行回答任务。
每次请使用以下流程:
- 1. 运行路由器。从编排器代码中,使用 subprocess 并传入参数列表(切勿使用用户输入进行 shell 插值):
python
import subprocess
result = subprocess.run(
[python3, /path/to/workspace/skills/agent-swarm/scripts/router.py, spawn, --json, user_message],
capture_output=True,
text=True
)
data = json.loads(result.stdout) if result.returncode == 0 else {}
仅限 CLI(手动测试;请勿在代码中与不可信用户输入一起使用):
python3 workspace/skills/agent-swarm/scripts/router.py spawn --json 您的任务在这里
当不在工作区根目录时,请使用 OPENCLAW_HOME 或脚本的绝对路径。
- 2. 如果 needsconfigpatch 为 true:停止并将该补丁报告给用户。
- 否则调用:
sessions_spawn(task=..., model=..., sessionTarget=...)
- 4. 等待 sessions_spawn 的结果。
- 将子代理的结果返回给用户。
如果 sessions_spawn 失败,仅返回委派失败消息。
不要自行完成任务。
配置基础
编辑技能根目录(scripts/ 的父目录)中的 config.json 以更改路由。
您可以更改的内容
| 内容 | 键 | 目的 |
|---|
| 编排器 / 会话默认 | defaultmodel | 主代理和新会话(例如 Gemini 2.5 Flash) |
| 每个层级特定任务的模型 |
routingrules.
.primary | 当任务匹配该层级时使用的模型 |
| 主模型失败时的备用模型 | routing_rules..fallback | 接下来尝试的模型 ID 数组 |
所有特定任务层级(为每个层级更改模型)
| 层级 | 更改主模型的键 | 典型用途 |
|---|
| FAST | routingrules.FAST.primary | 简单任务:检查、列出、状态、获取 |
| REASONING |
routingrules.REASONING.primary | 逻辑、数学、逐步分析 |
| CREATIVE | routing_rules.CREATIVE.primary | 写作、故事、UI/UX、设计 |
| RESEARCH | routing_rules.RESEARCH.primary | 研究、搜索、事实查找 |
| CODE | routing_rules.CODE.primary | 代码、调试、重构、实现 |
| QUALITY | routing_rules.QUALITY.primary | 复杂/架构任务 |
| COMPLEX | routing_rules.COMPLEX.primary | 多步骤/复杂系统任务 |
| VISION | routing_rules.VISION.primary | 图像分析、截图、视觉 |
要更改所有特定任务模型:编辑上述每个 routing_rules..primary。使用 config.json 中 models 数组中的模型 ID(必须以 openrouter/ 开头)。
简单配置示例
仅编排器(层级保持默认):
json
{
default_model: openrouter/google/gemini-2.5-flash
}
(其他键如 routing_rules 和 models 可以保持与发布的 config.json 相同。)
更改一个层级(例如将 CODE 改为 MiniMax):
json
routing_rules: {
CODE: {
primary: openrouter/minimax/minimax-m2.5,
fallback: [openrouter/qwen/qwen3-coder-flash]
}
}
更改多个层级(仅主模型):
json
routing_rules: {
CREATIVE: { primary: openrouter/moonshotai/kimi-k2.5, fallback: [] },
CODE: { primary: openrouter/z-ai/glm-4.7-flash, fallback: [openrouter/minimax/minimax-m2.5] },
RESEARCH: { primary: openrouter/x-ai/grok-4.1-fast, fallback: [] }
}
仅包含您想要覆盖的层级;其余将从完整的 config.json 中读取。
安全
输入验证
路由器验证并清理所有输入以防止注入攻击:
- - 任务字符串:验证长度(最大 10KB)、空字节;拒绝提示注入模式(脚本标签、javascript: 协议、事件处理属性)。无效任务会引发 ValueError 并附带清晰的消息。
- 配置补丁:仅允许修改 tools.exec.host 和 tools.exec.node(白名单方法)
- 标签:验证长度和空字节
安全执行
关键:从编排器代码调用 router.py 时,始终使用 subprocess 并传入参数列表,切勿使用 shell 字符串插值:
python
✅ 安全:使用 subprocess 并传入列表参数
import subprocess
result = subprocess.run(
[python3, /path/to/router.py, spawn, --json, user_message],
capture_output=True,
text=True
)
❌ 不安全:Shell 字符串插值(易受注入攻击