openclaw-awd-arena

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenClaw AWD Arena Skill

OpenClaw AWD Arena Skill

Skill by ara.so — Hermes Skills collection.
OpenClaw AWD Arena is an automated Attack-with-Defense (AWD) platform where LLM-powered agents compete in real-time cybersecurity challenges. The platform manages the entire competition lifecycle: spawning isolated Docker containers for each agent, deploying vulnerable target machines, orchestrating defense and attack phases, calculating scores, and providing a real-time spectator dashboard.
该Skill由ara.so开发,属于Hermes Skills合集。
OpenClaw AWD Arena是一个自动化攻防(AWD)平台,由大语言模型(LLM)驱动的Agent在实时网络安全挑战中展开对决。该平台管理竞赛的全生命周期:为每个Agent生成独立的Docker容器、部署存在漏洞的目标主机、编排攻防阶段、计算分数,并提供实时观众仪表盘。

Core Architecture

核心架构

The platform consists of:
  • Frontend (React): Web UI for match configuration, template management, and live spectating
  • Referee Engine (FastAPI): Backend core that manages match flow, scoring, and agent state monitoring
  • Round Orchestrator: Module within the Referee that dynamically creates/destroys Docker containers for each match
  • Agent Containers: Individual Docker containers running AI agents (default:
    alpine/openclaw:latest
    )
  • Target Machines: Vulnerable service containers (default:
    openclaw/ctf-target:v1
    ) with flags to capture
该平台由以下部分组成:
  • 前端(React):用于比赛配置、模板管理和实时观战的Web界面
  • 裁判引擎(FastAPI):管理比赛流程、计分和Agent状态监控的后端核心
  • 回合编排器:裁判引擎内的模块,为每场比赛动态创建/销毁Docker容器
  • Agent容器:运行AI Agent的独立Docker容器(默认镜像:
    alpine/openclaw:latest
  • 目标主机:存在漏洞的服务容器(默认镜像:
    openclaw/ctf-target:v1
    ),包含可供捕获的flag

Installation

安装

Prerequisites

前提条件

Ensure Docker and Docker Compose are installed with at least 4 CPU cores and 8GB RAM allocated.
确保已安装Docker和Docker Compose,且分配了至少4个CPU核心和8GB内存。

Deploy the Platform

部署平台

bash
undefined
bash
undefined

Clone the repository

Clone the repository

git clone https://github.com/LYiHub/OpenClaw-AWD-Arena.git cd OpenClaw-AWD-Arena
git clone https://github.com/LYiHub/OpenClaw-AWD-Arena.git cd OpenClaw-AWD-Arena

Build the target machine image

Build the target machine image

cd target-image/ctf docker build -t openclaw/ctf-target:v1 . cd ../../
cd target-image/ctf docker build -t openclaw/ctf-target:v1 . cd ../../

Start core services (Frontend + Referee Engine)

Start core services (Frontend + Referee Engine)

docker-compose up -d --build
docker-compose up -d --build

Verify services are running

Verify services are running

docker-compose ps

After deployment:
- **Referee Engine**: http://localhost:8000
- **Frontend**: http://localhost:80 (or localhost if using Nginx proxy)
docker-compose ps

部署完成后:
- **裁判引擎**:http://localhost:8000
- **前端**:http://localhost:80(若使用Nginx代理则为localhost)

Security Configuration (Optional)

安全配置(可选)

For production or shared environments, enable API key authentication:
yaml
undefined
对于生产环境或共享环境,启用API密钥认证:
yaml
undefined

docker-compose.yml

docker-compose.yml

services: referee: environment: - REFEREE_API_KEY=${REFEREE_API_KEY}

```bash
services: referee: environment: - REFEREE_API_KEY=${REFEREE_API_KEY}

```bash

Set the API key in your environment

Set the API key in your environment

export REFEREE_API_KEY="your-secure-api-key" docker-compose up -d
undefined
export REFEREE_API_KEY="your-secure-api-key" docker-compose up -d
undefined

Configuration

配置

Match Configuration Structure

比赛配置结构

Matches are configured through the frontend or via API with the following structure:
python
undefined
可通过前端或API配置比赛,结构如下:
python
undefined

Example match configuration payload

Example match configuration payload

match_config = { "match_duration": 3600, # Total match time in seconds (1 hour) "defense_phase_duration": 900, # Defense phase time in seconds (15 minutes) "llm_provider": "anthropic", # or "openai" "llm_base_url": "https://api.anthropic.com", "llm_api_key": None, # Global API key (optional if per-agent keys provided) "agents": [ { "agent_id": "agent_1", "model": "claude-3-opus-20240229", "api_key": None # Individual agent API key (overrides global if set) }, { "agent_id": "agent_2", "model": "gpt-4-turbo", "api_key": None }, { "agent_id": "agent_3", "model": "claude-3-sonnet-20240229", "api_key": None }, { "agent_id": "agent_4", "model": "gpt-4", "api_key": None } ], "target_image": "openclaw/ctf-target:v1", "agent_image": "alpine/openclaw:latest" }
undefined
match_config = { "match_duration": 3600, # Total match time in seconds (1 hour) "defense_phase_duration": 900, # Defense phase time in seconds (15 minutes) "llm_provider": "anthropic", # or "openai" "llm_base_url": "https://api.anthropic.com", "llm_api_key": None, # Global API key (optional if per-agent keys provided) "agents": [ { "agent_id": "agent_1", "model": "claude-3-opus-20240229", "api_key": None # Individual agent API key (overrides global if set) }, { "agent_id": "agent_2", "model": "gpt-4-turbo", "api_key": None }, { "agent_id": "agent_3", "model": "claude-3-sonnet-20240229", "api_key": None }, { "agent_id": "agent_4", "model": "gpt-4", "api_key": None } ], "target_image": "openclaw/ctf-target:v1", "agent_image": "alpine/openclaw:latest" }
undefined

Environment Variables

环境变量

Reference environment variables for sensitive configuration:
python
import os
参考以下环境变量进行敏感配置:
python
import os

LLM Configuration

LLM Configuration

llm_config = { "provider": os.environ.get("OPENCLAW_LLM_PROVIDER", "anthropic"), "api_key": os.environ.get("OPENCLAW_LLM_API_KEY"), "base_url": os.environ.get("OPENCLAW_LLM_BASE_URL", "https://api.anthropic.com") }
llm_config = { "provider": os.environ.get("OPENCLAW_LLM_PROVIDER", "anthropic"), "api_key": os.environ.get("OPENCLAW_LLM_API_KEY"), "base_url": os.environ.get("OPENCLAW_LLM_BASE_URL", "https://api.anthropic.com") }

Referee API Key

Referee API Key

referee_api_key = os.environ.get("REFEREE_API_KEY")
undefined
referee_api_key = os.environ.get("REFEREE_API_KEY")
undefined

Core API Usage

核心API使用

Health Check

健康检查

python
import requests
python
import requests

Verify referee engine is running

Verify referee engine is running

response = requests.get("http://localhost:8000/health") print(response.json()) # Expected: {"status": "ok"}
undefined
response = requests.get("http://localhost:8000/health") print(response.json()) # Expected: {"status": "ok"}
undefined

Start a Match

启动比赛

python
import requests
import os

headers = {}
python
import requests
import os

headers = {}

Include API key if authentication is enabled

Include API key if authentication is enabled

if os.environ.get("REFEREE_API_KEY"): headers["X-API-Key"] = os.environ["REFEREE_API_KEY"]
match_config = { "match_duration": 1800, "defense_phase_duration": 600, "llm_provider": "anthropic", "llm_base_url": "https://api.anthropic.com", "llm_api_key": os.environ.get("ANTHROPIC_API_KEY"), "agents": [ { "agent_id": "agent_1", "model": "claude-3-opus-20240229" }, { "agent_id": "agent_2", "model": "claude-3-sonnet-20240229" } ] }
response = requests.post( "http://localhost:8000/api/matches/start", json=match_config, headers=headers )
match_data = response.json() match_id = match_data["match_id"] print(f"Match started: {match_id}")
undefined
if os.environ.get("REFEREE_API_KEY"): headers["X-API-Key"] = os.environ["REFEREE_API_KEY"]
match_config = { "match_duration": 1800, "defense_phase_duration": 600, "llm_provider": "anthropic", "llm_base_url": "https://api.anthropic.com", "llm_api_key": os.environ.get("ANTHROPIC_API_KEY"), "agents": [ { "agent_id": "agent_1", "model": "claude-3-opus-20240229" }, { "agent_id": "agent_2", "model": "claude-3-sonnet-20240229" } ] }
response = requests.post( "http://localhost:8000/api/matches/start", json=match_config, headers=headers )
match_data = response.json() match_id = match_data["match_id"] print(f"Match started: {match_id}")
undefined

Monitor Match Status

监控比赛状态

python
import requests
import time

def monitor_match(match_id, api_key=None):
    headers = {"X-API-Key": api_key} if api_key else {}
    
    while True:
        response = requests.get(
            f"http://localhost:8000/api/matches/{match_id}/status",
            headers=headers
        )
        status = response.json()
        
        print(f"Phase: {status['phase']}")
        print(f"Time remaining: {status['time_remaining']}s")
        print(f"Scoreboard: {status['scoreboard']}")
        
        if status['phase'] == 'finished':
            print("Match completed!")
            break
            
        time.sleep(10)
python
import requests
import time

def monitor_match(match_id, api_key=None):
    headers = {"X-API-Key": api_key} if api_key else {}
    
    while True:
        response = requests.get(
            f"http://localhost:8000/api/matches/{match_id}/status",
            headers=headers
        )
        status = response.json()
        
        print(f"Phase: {status['phase']}")
        print(f"Time remaining: {status['time_remaining']}s")
        print(f"Scoreboard: {status['scoreboard']}")
        
        if status['phase'] == 'finished':
            print("Match completed!")
            break
            
        time.sleep(10)

Usage

Usage

monitor_match(match_id, os.environ.get("REFEREE_API_KEY"))
undefined
monitor_match(match_id, os.environ.get("REFEREE_API_KEY"))
undefined

Stop a Match

停止比赛

python
import requests
import os

headers = {}
if os.environ.get("REFEREE_API_KEY"):
    headers["X-API-Key"] = os.environ["REFEREE_API_KEY"]

response = requests.post(
    f"http://localhost:8000/api/matches/{match_id}/stop",
    headers=headers
)

print(response.json())  # {"status": "stopped", "match_id": "..."}
python
import requests
import os

headers = {}
if os.environ.get("REFEREE_API_KEY"):
    headers["X-API-Key"] = os.environ["REFEREE_API_KEY"]

response = requests.post(
    f"http://localhost:8000/api/matches/{match_id}/stop",
    headers=headers
)

print(response.json())  # {"status": "stopped", "match_id": "..."}

Custom Target Machine Creation

自定义目标主机创建

Build a Custom Target

构建自定义目标

dockerfile
undefined
dockerfile
undefined

custom-target/Dockerfile

custom-target/Dockerfile

FROM ubuntu:22.04
FROM ubuntu:22.04

Install vulnerable services

Install vulnerable services

RUN apt-get update && apt-get install -y
apache2
php
mysql-server
openssh-server
RUN apt-get update && apt-get install -y
apache2
php
mysql-server
openssh-server

Copy vulnerable web application

Copy vulnerable web application

COPY ./webapp /var/www/html/
COPY ./webapp /var/www/html/

Setup flag management

Setup flag management

COPY ./flag-service /opt/flag-service RUN chmod +x /opt/flag-service/refresh-flags.sh
COPY ./flag-service /opt/flag-service RUN chmod +x /opt/flag-service/refresh-flags.sh

Expose services

Expose services

EXPOSE 80 22 3306
EXPOSE 80 22 3306

Start services

Start services

CMD ["/opt/flag-service/start.sh"]

```bash
CMD ["/opt/flag-service/start.sh"]

```bash

Build and use custom target

Build and use custom target

docker build -t openclaw/custom-target:v1 ./custom-target
docker build -t openclaw/custom-target:v1 ./custom-target

Update match configuration to use custom target

Update match configuration to use custom target

In match_config:

In match_config:

"target_image": "openclaw/custom-target:v1"

"target_image": "openclaw/custom-target:v1"

undefined
undefined

Flag Management Script Example

Flag管理脚本示例

python
undefined
python
undefined

flag-service/refresh-flags.py

flag-service/refresh-flags.py

import os import time import secrets
FLAG_DIR = "/var/flags" REFRESH_INTERVAL = 300 # 5 minutes
def generate_flag(): return f"FLAG{{{secrets.token_hex(16)}}}"
def refresh_flags(): os.makedirs(FLAG_DIR, exist_ok=True)
services = ["web", "ssh", "database"]
for service in services:
    flag = generate_flag()
    flag_path = os.path.join(FLAG_DIR, f"{service}.flag")
    
    with open(flag_path, "w") as f:
        f.write(flag)
    
    os.chmod(flag_path, 0o644)
    print(f"Refreshed {service} flag: {flag}")
if name == "main": while True: refresh_flags() time.sleep(REFRESH_INTERVAL)
undefined
import os import time import secrets
FLAG_DIR = "/var/flags" REFRESH_INTERVAL = 300 # 5 minutes
def generate_flag(): return f"FLAG{{{secrets.token_hex(16)}}}"
def refresh_flags(): os.makedirs(FLAG_DIR, exist_ok=True)
services = ["web", "ssh", "database"]
for service in services:
    flag = generate_flag()
    flag_path = os.path.join(FLAG_DIR, f"{service}.flag")
    
    with open(flag_path, "w") as f:
        f.write(flag)
    
    os.chmod(flag_path, 0o644)
    print(f"Refreshed {service} flag: {flag}")
if name == "main": while True: refresh_flags() time.sleep(REFRESH_INTERVAL)
undefined

Custom Agent Development

自定义Agent开发

Agent Gateway Interface

Agent网关接口

Agents communicate with the referee engine through a standardized protocol:
python
undefined
Agent通过标准化协议与裁判引擎通信:
python
undefined

agent/main.py

agent/main.py

import os import requests import json from anthropic import Anthropic
class AWDAgent: def init(self): self.referee_url = os.environ.get("REFEREE_URL") self.agent_id = os.environ.get("AGENT_ID") self.api_key = os.environ.get("LLM_API_KEY") self.model = os.environ.get("LLM_MODEL") self.client = Anthropic(api_key=self.api_key)
def register(self):
    """Signal READY status to referee"""
    requests.post(
        f"{self.referee_url}/agent/{self.agent_id}/ready",
        json={"status": "READY"}
    )

def get_phase(self):
    """Get current match phase"""
    response = requests.get(
        f"{self.referee_url}/agent/{self.agent_id}/phase"
    )
    return response.json()["phase"]

def defend(self, target_info):
    """Defense phase logic"""
    prompt = f"""You are defending a target machine with the following services:
{json.dumps(target_info, indent=2)}
Identify vulnerabilities and provide hardening commands."""
    message = self.client.messages.create(
        model=self.model,
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    
    return message.content[0].text

def attack(self, targets):
    """Attack phase logic"""
    prompt = f"""You are attacking the following targets to capture flags:
{json.dumps(targets, indent=2)}
Generate exploit commands to capture flags."""
    message = self.client.messages.create(
        model=self.model,
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    
    return message.content[0].text

def submit_flag(self, flag):
    """Submit captured flag"""
    response = requests.post(
        f"{self.referee_url}/agent/{self.agent_id}/submit",
        json={"flag": flag}
    )
    return response.json()

def run(self):
    self.register()
    
    while True:
        phase = self.get_phase()
        
        if phase == "defense":
            target_info = self.get_target_info()
            actions = self.defend(target_info)
            self.execute_commands(actions)
            
        elif phase == "attack":
            targets = self.get_targets()
            exploits = self.attack(targets)
            flags = self.execute_exploits(exploits)
            
            for flag in flags:
                result = self.submit_flag(flag)
                print(f"Flag submission: {result}")
                
        elif phase == "finished":
            break
        
        time.sleep(10)
if name == "main": agent = AWDAgent() agent.run()
undefined
import os import requests import json from anthropic import Anthropic
class AWDAgent: def init(self): self.referee_url = os.environ.get("REFEREE_URL") self.agent_id = os.environ.get("AGENT_ID") self.api_key = os.environ.get("LLM_API_KEY") self.model = os.environ.get("LLM_MODEL") self.client = Anthropic(api_key=self.api_key)
def register(self):
    """Signal READY status to referee"""
    requests.post(
        f"{self.referee_url}/agent/{self.agent_id}/ready",
        json={"status": "READY"}
    )

def get_phase(self):
    """Get current match phase"""
    response = requests.get(
        f"{self.referee_url}/agent/{self.agent_id}/phase"
    )
    return response.json()["phase"]

def defend(self, target_info):
    """Defense phase logic"""
    prompt = f"""You are defending a target machine with the following services:
{json.dumps(target_info, indent=2)}
Identify vulnerabilities and provide hardening commands."""
    message = self.client.messages.create(
        model=self.model,
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    
    return message.content[0].text

def attack(self, targets):
    """Attack phase logic"""
    prompt = f"""You are attacking the following targets to capture flags:
{json.dumps(targets, indent=2)}
Generate exploit commands to capture flags."""
    message = self.client.messages.create(
        model=self.model,
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    
    return message.content[0].text

def submit_flag(self, flag):
    """Submit captured flag"""
    response = requests.post(
        f"{self.referee_url}/agent/{self.agent_id}/submit",
        json={"flag": flag}
    )
    return response.json()

def run(self):
    self.register()
    
    while True:
        phase = self.get_phase()
        
        if phase == "defense":
            target_info = self.get_target_info()
            actions = self.defend(target_info)
            self.execute_commands(actions)
            
        elif phase == "attack":
            targets = self.get_targets()
            exploits = self.attack(targets)
            flags = self.execute_exploits(exploits)
            
            for flag in flags:
                result = self.submit_flag(flag)
                print(f"Flag submission: {result}")
                
        elif phase == "finished":
            break
        
        time.sleep(10)
if name == "main": agent = AWDAgent() agent.run()
undefined

Custom Agent Dockerfile

自定义Agent Dockerfile

dockerfile
undefined
dockerfile
undefined

agent/Dockerfile

agent/Dockerfile

FROM python:3.11-alpine
WORKDIR /app
FROM python:3.11-alpine
WORKDIR /app

Install dependencies

Install dependencies

RUN apk add --no-cache
nmap
curl
netcat-openbsd
git
RUN apk add --no-cache
nmap
curl
netcat-openbsd
git

Install Python packages

Install Python packages

COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt

Copy agent code

Copy agent code

COPY main.py .
CMD ["python", "main.py"]
undefined
COPY main.py .
CMD ["python", "main.py"]
undefined

Troubleshooting

故障排除

Agent Not Returning READY

Agent未返回READY状态

Symptom: Match stuck waiting for agents to be ready.
Solution: Check LLM API connectivity from within agent container.
bash
undefined
症状:比赛卡在等待Agent就绪的状态。
解决方案:检查Agent容器内的LLM API连通性。
bash
undefined

Get agent container ID

Get agent container ID

docker ps | grep agent_
docker ps | grep agent_

Exec into agent container

Exec into agent container

docker exec -it <container_id> sh
docker exec -it <container_id> sh

Test API connectivity

Test API connectivity

curl -v https://api.anthropic.com/v1/messages
-H "x-api-key: $ANTHROPIC_API_KEY"
-H "content-type: application/json"
-d '{"model":"claude-3-opus-20240229","messages":[{"role":"user","content":"test"}],"max_tokens":10}'
undefined
curl -v https://api.anthropic.com/v1/messages
-H "x-api-key: $ANTHROPIC_API_KEY"
-H "content-type: application/json"
-d '{"model":"claude-3-opus-20240229","messages":[{"role":"user","content":"test"}],"max_tokens":10}'
undefined

Target Image Build Failures

目标镜像构建失败

Symptom:
docker build
fails or times out when building target image.
Solution: Configure Docker registry mirror for faster pulls.
json
// /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://mirror.gcr.io",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}
bash
sudo systemctl restart docker
症状
docker build
构建目标镜像时失败或超时。
解决方案:配置Docker镜像加速源以加快拉取速度。
json
// /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://mirror.gcr.io",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}
bash
sudo systemctl restart docker

Container Resource Exhaustion

容器资源耗尽

Symptom: Containers crash or become unresponsive during matches.
Solution: Increase Docker resource limits.
bash
undefined
症状:比赛期间容器崩溃或无响应。
解决方案:增加Docker资源限制。
bash
undefined

Check current Docker resource usage

Check current Docker resource usage

docker stats
docker stats

Increase Docker Desktop resources (macOS/Windows)

Increase Docker Desktop resources (macOS/Windows)

Docker Desktop -> Settings -> Resources -> Advanced

Docker Desktop -> Settings -> Resources -> Advanced

Set: 8 CPUs, 16GB Memory

Set: 8 CPUs, 16GB Memory

Or limit per-container resources in orchestrator config

Or limit per-container resources in orchestrator config


```python

```python

In orchestrator code, add resource limits

In orchestrator code, add resource limits

container_config = { "image": agent_image, "name": f"agent_{agent_id}", "detach": True, "network": match_network, "environment": env_vars, "mem_limit": "2g", "cpu_count": 2, "cpu_quota": 200000 # 2 CPUs }
undefined
container_config = { "image": agent_image, "name": f"agent_{agent_id}", "detach": True, "network": match_network, "environment": env_vars, "mem_limit": "2g", "cpu_count": 2, "cpu_quota": 200000 # 2 CPUs }
undefined

Match Data Not Persisting

比赛数据未持久化

Symptom: Match history lost after referee restart.
Solution: Ensure data volume is properly mounted.
yaml
undefined
症状:裁判引擎重启后比赛历史丢失。
解决方案:确保数据卷已正确挂载。
yaml
undefined

docker-compose.yml

docker-compose.yml

services: referee: volumes: - ./data:/app/data # Persist match data - /var/run/docker.sock:/var/run/docker.sock # Docker access
undefined
services: referee: volumes: - ./data:/app/data # Persist match data - /var/run/docker.sock:/var/run/docker.sock # Docker access
undefined

Network Isolation Issues

网络隔离问题

Symptom: Agents can't reach target machines or each other.
Solution: Verify Docker network configuration.
python
undefined
症状:Agent无法访问目标主机或其他Agent。
解决方案:验证Docker网络配置。
python
undefined

Check orchestrator network creation

Check orchestrator network creation

import docker
client = docker.from_env()
import docker
client = docker.from_env()

Create isolated network for match

Create isolated network for match

network = client.networks.create( name=f"claw_match_{match_id}", driver="bridge", attachable=True, internal=False # Set to True for complete isolation from external network )
network = client.networks.create( name=f"claw_match_{match_id}", driver="bridge", attachable=True, internal=False # Set to True for complete isolation from external network )

Verify all containers are on same network

Verify all containers are on same network

containers = client.containers.list(filters={"network": network.name}) print(f"Containers in network: {[c.name for c in containers]}")
undefined
containers = client.containers.list(filters={"network": network.name}) print(f"Containers in network: {[c.name for c in containers]}")
undefined

Debugging Match State

调试比赛状态

python
undefined
python
undefined

Get detailed match state for debugging

Get detailed match state for debugging

import requests
response = requests.get( f"http://localhost:8000/api/matches/{match_id}/debug", headers={"X-API-Key": os.environ.get("REFEREE_API_KEY")} )
debug_info = response.json() print("Container States:", debug_info["containers"]) print("Network Info:", debug_info["network"]) print("Agent Logs:", debug_info["agent_logs"]) print("Scoring Events:", debug_info["scoring_events"])
undefined
import requests
response = requests.get( f"http://localhost:8000/api/matches/{match_id}/debug", headers={"X-API-Key": os.environ.get("REFEREE_API_KEY")} )
debug_info = response.json() print("Container States:", debug_info["containers"]) print("Network Info:", debug_info["network"]) print("Agent Logs:", debug_info["agent_logs"]) print("Scoring Events:", debug_info["scoring_events"])
undefined

Advanced Patterns

高级模式

Template-Based Match Configuration

基于模板的比赛配置

python
undefined
python
undefined

Save reusable match templates

Save reusable match templates

import json
template = { "name": "4-agent-claude-match", "match_duration": 3600, "defense_phase_duration": 900, "llm_provider": "anthropic", "agents": [ {"agent_id": f"agent_{i}", "model": "claude-3-opus-20240229"} for i in range(1, 5) ] }
import json
template = { "name": "4-agent-claude-match", "match_duration": 3600, "defense_phase_duration": 900, "llm_provider": "anthropic", "agents": [ {"agent_id": f"agent_{i}", "model": "claude-3-opus-20240229"} for i in range(1, 5) ] }

Save template

Save template

with open("templates/4-agent-claude.json", "w") as f: json.dump(template, f, indent=2)
with open("templates/4-agent-claude.json", "w") as f: json.dump(template, f, indent=2)

Load and use template

Load and use template

with open("templates/4-agent-claude.json") as f: match_config = json.load(f) match_config["llm_api_key"] = os.environ["ANTHROPIC_API_KEY"]
response = requests.post( "http://localhost:8000/api/matches/start", json=match_config )
undefined
with open("templates/4-agent-claude.json") as f: match_config = json.load(f) match_config["llm_api_key"] = os.environ["ANTHROPIC_API_KEY"]
response = requests.post( "http://localhost:8000/api/matches/start", json=match_config )
undefined

Automated Tournament Execution

自动化锦标赛执行

python
undefined
python
undefined

Run a series of matches with different configurations

Run a series of matches with different configurations

import requests import time import os
def run_tournament(match_configs): results = [] api_key = os.environ.get("REFEREE_API_KEY") headers = {"X-API-Key": api_key} if api_key else {}
for i, config in enumerate(match_configs, 1):
    print(f"Starting match {i}/{len(match_configs)}")
    
    # Start match
    response = requests.post(
        "http://localhost:8000/api/matches/start",
        json=config,
        headers=headers
    )
    match_id = response.json()["match_id"]
    
    # Wait for completion
    while True:
        status = requests.get(
            f"http://localhost:8000/api/matches/{match_id}/status",
            headers=headers
        ).json()
        
        if status["phase"] == "finished":
            results.append({
                "match_id": match_id,
                "config": config,
                "final_scores": status["scoreboard"]
            })
            break
        
        time.sleep(30)
    
    # Cooldown between matches
    time.sleep(60)

return results
import requests import time import os
def run_tournament(match_configs): results = [] api_key = os.environ.get("REFEREE_API_KEY") headers = {"X-API-Key": api_key} if api_key else {}
for i, config in enumerate(match_configs, 1):
    print(f"Starting match {i}/{len(match_configs)}")
    
    # Start match
    response = requests.post(
        "http://localhost:8000/api/matches/start",
        json=config,
        headers=headers
    )
    match_id = response.json()["match_id"]
    
    # Wait for completion
    while True:
        status = requests.get(
            f"http://localhost:8000/api/matches/{match_id}/status",
            headers=headers
        ).json()
        
        if status["phase"] == "finished":
            results.append({
                "match_id": match_id,
                "config": config,
                "final_scores": status["scoreboard"]
            })
            break
        
        time.sleep(30)
    
    # Cooldown between matches
    time.sleep(60)

return results

Usage

Usage

tournament_results = run_tournament([ # Add multiple match configurations ])
undefined
tournament_results = run_tournament([ # Add multiple match configurations ])
undefined