目录

🧠 WISE

Load-Aware Resource Scheduling Agent with Hybrid-Intelligence Decision Making

Platform Python Kernel Agent

Language: English | 中文

An Agent-driven OS prototype for adaptive resource control on openEuler. The validated core is a CPU Scheduling Agent that observes runtime pressure, classifies the current workload scene, selects a sched_ext/scx scheduler, applies the switch through guarded Tools, and records feedback for evaluation and future decisions.

This is not only a scheduler-switching script. The repository is shaped as a modular OS Agent framework: CPU scheduling is the main proof point, while eBPF, cgroup v2, Tool/Skill interfaces, LLM arbitration, dashboard visualization, and master/worker orchestration provide extension paths for Network Policy, Security Policy, and Resource Control Agents.


🧭 At a Glance

🧠 Decision Core ⚙️ Control Plane 🔍 Observability 📈 Evaluation
ML scene classifier plus guarded LLM arbitration. sched_ext/scx switching through PolicyGuard and Tool checks. 19 runtime features with eBPF and cgroup v2 extension hooks. 28 workload scenes, scoring, scheduler ranking, and dashboard views.

📌 Contents


✨ Highlights

Area What This Project Provides
🧭 Adaptive scheduling Classifies 28 mixed workload scenes and maps them to candidate sched_ext/scx schedulers.
⚡ Low-overhead fast path Uses a local ML classifier, Top-k probabilities, time-weighted voting, and stable scene control.
🧩 Modular Agent framework Separates perception, decision, execution, feedback, Tools, Skills, policy guard, and memory.
🔒 Guarded execution LLM output is a structured recommendation only; privileged actions pass local whitelists and PolicyGuard.
🧬 eBPF observability Includes registry-whitelisted C programs for scheduler, syscall, XDP, and resource-pressure monitoring.
🧪 Reproducible evaluation Provides workload runners, scoring logic, scheduler ranking, and best-scheduler mapping generation.
🖥️ Dashboard FastAPI + React UI for runtime state, benchmark controls, decision history, and evaluation results.
🛰️ Cluster comparison Optional master/worker mode for synchronized EEVDF vs ML vs ML+LLM comparison.

🏗️ System Architecture

flowchart LR
    W[Workloads] --> P[Perception
19 runtime features] P --> M[ML Classifier
S1-S28 probabilities] M --> V[StableVoting
Top-k + smoothing] V --> D[Decision Engine
scene to scheduler] D --> G[PolicyGuard
schema + whitelist + cooldown] G --> S[sched_ext/scx
scheduler switch] G --> E[eBPF / cgroup
extension Tools] S --> F[Feedback
score + history] E --> F F --> R[Runtime State
dashboard + logs + memory] R --> D

The default local command remains the first compatibility target:

python run_agent.py

Local mode must not depend on the cluster network path. Master/worker services are optional deployment extensions.

Runtime Loop

observe -> classify -> stabilize -> decide -> validate -> execute -> feedback
  1. agent.perception.Perception wraps benchmark.collectors.SystemSampler and emits the fixed 19-feature model input.
  2. agent.decision.DecisionEngine loads model/model/scene_classifier.joblib, calls predict_proba(), computes Top-k candidates, applies time-weighted voting, and maintains a stable scene label.
  3. agent.mapping.SCHEDULER_MAPPING maps stable scenes S1 through S28 to candidate scx schedulers.
  4. agent.supervisor can trigger a DeepSeek-compatible LLM supervisor for low confidence, small margins, high entropy, oscillation, mapping conflict, runtime score drop, scheduler failure, or unknown hardware.
  5. agent.supervisor.policy_guard.PolicyGuard and Tool-level checks reject stale, unsafe, unsupported, or non-whitelisted actions.
  6. agent.action.SchedulerController starts, stops, verifies, and rolls back sched_ext/scx scheduler processes.
  7. agent.runtime_state writes current state and decision history for the dashboard and later evaluation.

Agent runtime pipeline
Runtime pipeline: data collection, mode analysis, scheduler selection, dynamic switching, and feedback update.


🗂️ Repository Map

.
|-- README.md
|-- run_agent.py
|-- requirements.txt
|-- agent/          # online Agent, Skills, Tools, supervisor, cluster backends
|-- benchmark/      # 28-scene workload runner and 19-feature sampler
|-- config/         # scheduler, cluster, and environment examples
|-- dashboard/      # FastAPI backend and Vite React frontend
|-- deploy/         # systemd service templates
|-- docs/           # competition manual and source reference documents
|-- ebpf/           # C eBPF programs, registry, Makefile, helper scripts
|-- evaluation/     # scoring model and experiment aggregation
|-- model/          # training data, classifier bundle, plots, model helpers
|-- runtime/        # generated runtime state and memory
|-- scripts/        # operational wrappers and loopback validation
`-- test/           # regression, contract, integration, and compatibility tests
Folder Local Guide Purpose
agent/ agent/AGENT.md Agent loop, scheduler control, Tools, Skills, LLM supervisor, eBPF bridge, and cluster services.
benchmark/ benchmark/BENCHMARK.md Workload scene definitions, runners, and system feature collection.
dashboard/ dashboard/DASHBOARD.md API and UI for status, controls, evaluation, and logs.
ebpf/ ebpf/EBPF.md Whitelist-based eBPF reference programs and build workflow.
evaluation/ evaluation/EVALUATION.md Score model, scheduler ranking, and mapping output.
model/ model/MODEL.md Classifier training, model bundle, metadata, and visualization helpers.

🚀 Quick Start

1. Install Python Dependencies

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

PowerShell:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

2. Run the Local Agent

python run_agent.py

The Agent prints each decision round and writes generated state under runtime/agent/.

3. Start the Dashboard

Backend:

python dashboard/backend/main.py

Frontend:

cd dashboard/frontend
npm install
npm run dev

Default URLs:

  • backend: http://127.0.0.1:8000;
  • frontend: http://127.0.0.1:5173.

4. Run the Main Regression Suite

python -m pytest test -q -p no:cacheprovider

⚙️ Core Runtime

The CPU Scheduling Agent is optimized for a cheap local path first. The LLM path is available only as an exception handler.

Fast Path

  • Sample runtime metrics every SAMPLE_INTERVAL_SECONDS.
  • Classify the scene with the local model.
  • Smooth probabilities with TimeWeightedVoting.
  • Hold label changes with SceneStabilizer.
  • Select the target scheduler from SCHEDULER_MAPPING.
  • Switch only after availability, cooldown, and state checks.

Scheduler switch latency breakdown
Scheduler switch latency breakdown for representative scx targets.

LLM Supervisor Path

The supervisor is event-triggered. It receives structured context:

  • current 19-feature sample;
  • raw and voted Top-k scene probabilities;
  • stable label and local scheduler candidate;
  • current sched_ext state;
  • recent runtime score and error history;
  • hardware fingerprint and node_id;
  • trusted decision memory.

The supervisor may recommend a scheduler or request benchmarking, but it cannot execute shell commands, compile arbitrary code, load arbitrary eBPF source, or bypass PolicyGuard.

Use an environment variable for real LLM calls:

export DEEPSEEK_API_KEY="replace-with-your-key"

Do not commit real API keys, cluster tokens, or host credentials.


🧰 Tool and Skill Interface

Tools are atomic, schema-shaped, auditable operations. Skills combine Tools into higher-level Agent capabilities.

Representative Tools

Tool Type Role
system.sample_metrics observe Read runtime features.
workload.classify_scene analyze Classify current workload scene.
supervisor.evaluate evaluate Decide whether the guarded LLM path should alter the local candidate.
scheduler.apply_decision control Apply the final scheduler action.
scheduler.switch control Switch to a specific scx scheduler.
scheduler.stop_active control Stop an active sched_ext scheduler.
ebpf.probe observe Check Linux/eBPF capabilities.
ebpf.build control Build registered eBPF objects.
ebpf.load control Load a registry-approved eBPF object.
ebpf.attach control Attach a loaded eBPF program.
ebpf.metrics observe Dump eBPF map metrics.
ebpf.detach control Detach an Agent-owned hook.
ebpf.cleanup control Remove Agent-owned eBPF runtime state.

Representative Skills

Skill Role
cpu_sched CPU scene classification and guarded sched_ext switching.
ebpf_hook Whitelist-only eBPF lifecycle management.
network_skill Extension shape for Network Policy Agent behavior.
security_skill Extension shape for Security Policy Agent behavior.
cgroup_skill Extension shape for cgroup v2 Resource Control Agent behavior.

🧬 eBPF Extensions

eBPF has two roles in this project:

  • observability for scheduler wakeups, context switches, network packet counts, syscall activity, and kernel-side latency signals;
  • extension hooks for future Network Policy, Security Policy, and Resource Control Agents.

Included Programs

Program Type What It Observes
sched_observer tracepoint Scheduler switches, wakeups, and wakeup-to-run latency.
xdp_stats XDP Packets, bytes, IPv4, IPv6, ARP, and pass-through traffic counters.
syscall_stats tracepoint Syscall count by PID and syscall number.
resource_monitor tracepoint Scheduler latency, task runtime, process lifecycle, syscall latency/errors, per-process pressure, and per-CPU pressure.

The resource_monitor program is the richer C reference example. It attaches to six tracepoints and exports multiple maps for global counters, per-process pressure, per-CPU pressure, syscall class summaries, latency histograms, wakeup state, run state, and syscall entry state.

Runtime loading is registry-only through ebpf/registry.json. Callers may pass only a registered program_id, an allowed attach target, and schema-validated parameters. The LLM path must not generate or load arbitrary eBPF source.

Build on openEuler/Linux

sudo dnf install -y clang llvm bpftool make kernel-devel libbpf-devel
make -C ebpf all registry

Run unprivileged contract tests:

python -m pytest test/test_ebpf_contracts.py -q -p no:cacheprovider

Run privileged integration tests only on a prepared Linux host:

sudo OS_AGENT_EBPF_ENABLED=1 OS_AGENT_EBPF_INTEGRATION=1 python -m pytest test/test_ebpf_integration.py -q -rs -m ebpf_integration -p no:cacheprovider

🛰️ Master/Worker Deployment

The final comparison mode uses one master device and three matching worker devices:

Worker Role
worker-eevdf Fixed EEVDF baseline.
worker-ml ML scene-mapping policy.
worker-ml-llm ML plus LLM hybrid arbitration policy.

The master generates one scenario plan and sends synchronized workload-control commands to all workers. Workers do not receive the true scene label as an input to their decision path. The label is used only by orchestration and final statistics. This keeps EEVDF, ML, and ML plus LLM comparison fair.

Strategy average score and variance
Average score and variance range for EEVDF, ML scene mapping, and ML+LLM hybrid policies.

Workers expose structured HTTP endpoints for metrics, workload control, scheduler switching, eBPF actions, status, and audit logs. They listen on 127.0.0.1 by default. Binding to a non-loopback address requires OS_AGENT_CLUSTER_TOKEN. Each runtime event and cluster response keeps a node_id or host identifier so decisions, feedback, audit logs, and worker results can be correlated without sending hidden scene labels to the Agent decision path.

Start a local loopback validation:

python scripts/run_loopback_cluster.py

Start one worker:

export OS_AGENT_CLUSTER_TOKEN="replace-with-random-token"
python -m agent.cluster.worker_server --host 127.0.0.1 --port 9101 --host-id worker-a --simulate-workloads

Start the master:

export OS_AGENT_CLUSTER_TOKEN="replace-with-random-token"
python -m agent.cluster.master_server --host 127.0.0.1 --port 9000 --host-id master-local --config config/cluster.master.example.json

Use the one-master, three-worker comparison config:

export OS_AGENT_CLUSTER_TOKEN="replace-with-random-token"
python -m agent.cluster.master_server --host 127.0.0.1 --port 9000 --host-id master-local --config config/cluster.1master3workers.example.json

📊 Benchmark, Model, and Evaluation

Benchmark

The benchmark suite defines 28 scenes from 4 foreground tasks and 7 background tasks. Each run writes labeled 19-feature CSV samples and JSONL event metadata.

List scenarios:

python -c "from benchmark.scenarios import get_scenarios; [print(s.scenario_id, s.display_name) for s in get_scenarios()]"

Run one short scenario:

python -c "from benchmark.run_scenario import main; raise SystemExit(main(duration_seconds=30, scenario_ids=['S1'], interval_seconds=1, output_dir='benchmark/results'))"

Model

Training expects model/data_clean/*.csv and should be run from the model directory because model/train.py uses relative paths:

cd model
python train.py

Outputs:

  • model/model/scene_classifier.joblib;
  • model/model/model_meta.json;
  • model/model/confusion_matrix.png.

Model classification report
Scene classifier report excerpt.

Evaluation

python -m evaluation.evaluator --input-dir evaluation/runs --output-dir evaluation/results

Outputs:

  • evaluation/results/scenario_scores.csv;
  • evaluation/results/scheduler_ranking.csv;
  • evaluation/results/best_scheduler_mapping.json;
  • evaluation/results/experiment_summary.json.

The score model balances foreground experience, background throughput, runtime stability, system health, and scheduler-switch overhead.

Scenario score comparison
Default scheduler versus optimal scheduler score comparison across S1-S28.


🖥️ Dashboard

The dashboard is a FastAPI backend plus a Vite React frontend.

Backend Endpoints

Endpoint Purpose
POST /api/agent/start Start the local Agent loop.
POST /api/agent/stop Stop the local Agent loop.
POST /api/agent/benchmark-recognition Toggle recognition flow.
POST /api/agent/scheduler-switch Toggle real scheduler switching.
POST /api/agent/llm-supervisor Toggle event-triggered LLM arbitration.
GET /api/agent/status Read current runtime state.
POST /api/evaluation/run Run evaluation aggregation.
GET /api/evaluation/summary Read summary results.
GET /api/evaluation/scores Read score rows.
GET /api/benchmark/scenarios List available scenarios.
POST /api/benchmark/run Start a benchmark run.
GET /api/logs/decision Read decision history.

Enable dashboard-driven control state:

export OS_AGENT_USE_CONTROL_STATE=1
python run_agent.py

✅ Verification

Python syntax check:

python -m compileall -q run_agent.py agent benchmark evaluation dashboard/backend model scripts

Full Python regression suite:

python -m pytest test -q -p no:cacheprovider

Focused extension tests:

python -m pytest test/test_ebpf_contracts.py -q -p no:cacheprovider
python -m pytest test/test_cluster_contracts.py test/test_cluster_loopback_e2e.py -q -p no:cacheprovider
python -m pytest test/test_refactor_compatibility.py -q -p no:cacheprovider

Dashboard build:

cd dashboard/frontend
npm run build

📁 Runtime Outputs

Generated state and logs are intentionally outside source code:

Path Purpose
runtime/agent/runtime_state.json Latest Agent state for the dashboard.
runtime/agent/control_state.json Dashboard control flags.
runtime/agent/decision_history.jsonl Round-by-round decision history.
runtime/agent/supervisor_memory.sqlite3 LLM supervisor feedback memory.
runtime/agent/ebpf/ Agent-owned eBPF runtime pins and state.
logs/scx/*.log scx scheduler process logs.
evaluation/results/* Generated evaluation outputs.
benchmark/results/* Generated benchmark samples.

🛡️ Safety Boundaries

  • Keep scheduler names, eBPF programs, and remote control actions on explicit whitelists.
  • Keep real API keys and cluster tokens outside committed files.
  • Run privileged eBPF and sched_ext tests only on prepared Linux/openEuler machines.
  • If sched_ext switching fails, the Agent should record the failure and fall back instead of leaving the system in an unknown control state.
  • eBPF metrics are extension metrics. They do not change the 19-feature ML classifier input unless the model is explicitly retrained.
关于
227.2 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号