CoolFace
Datasetpublic

hotdogs/cyber-sft-agent-qwen38

Cyber-SFT-Agent (Qwen3.8-27B Native) — v3.1 production (8.4K) Agentic tool-calling SFT dataset for Qwen3.8-27B (abliterated or base). Teaches the model to call real tools — masscan → nmap → curl → whatweb → nikto → ffuf → gobuster → dirb → wpscan → hydra → sqlmap → john → hashcat → searchsploit → metasploit → linpeas → winpeas → crackmapexec → enum4linux → responder → impacket → netcat — read their output, re-plan from the evidence, and synthesize a ranked attack. Companion to… See the full description on the dataset page: https://huggingface.co/datasets/hotdogs/cyber-sft-agent-qwen38.

sourceHugging Faceapache-2.0updated 1mo agoView on Hugging Face
4likes309downloads
Dataset Card

Cyber-SFT-Agent (Qwen3.8-27B Native) — v3.1 production (8.4K)

Agentic tool-calling SFT dataset for Qwen3.8-27B (abliterated or base). Teaches the model to call real tools — masscan → nmap → curl → whatweb → nikto → ffuf → gobuster → dirb → wpscan → hydra → sqlmap → john → hashcat → searchsploit → metasploit → linpeas → winpeas → crackmapexec → enum4linux → responder → impacket → netcat — read their output, re-plan from the evidence, and synthesize a ranked attack. Companion to `hotdogs/cyber-sft-qa-qwen38` (the QA layer); this v3.1 ships the tool layer PLUS a sampled QA slice so it is self-contained and composition-correct out of the box.

v3.1 what changed (vs v3, 7,000 rows)

  • —7,000 → 8,400 rows (train 7,140 / valid 840 / test 420, stratified 30% tool each)
  • —2,520 tool rows (seeds 1-140, 18 chains/seed) — 22 tools, 9 task types
  • —5,880 QA rows sampled from the 72K QA repo
  • —(A) Evidence consistency — sqlmap now reports the actual backend DB of the stack (MySQL / PostgreSQL / MSSQL, no more mysql listed under PostgreSQL), metasploit lands as www-data on Linux stacks and SYSTEM on Windows stacks, nikto / curl / headers are stack-aware, hydra never targets a box with no SSH, wpscan targets a WordPress stack, sqlmap targets a DB stack
  • —(B) Negative evidence — 420 rows (16.7% of tool):
  • —T7-dead-end: masscan → nmap → searchsploit, honest "no low-hanging fruit" report
  • —T8-not-injectable: ffuf → sqlmap (5/5 payload classes, 0 hit) → pivot to /config.php creds
  • —T9-brute-fail-pivot: hydra fails on admin → wpscan finds deploy → hydra hits
  • —(C) Distractor palette — 38.5% of tool rows expose 2-5 extra context-appropriate tool schemas the model must choose not to call (teaches tool selection)
  • —Real-tokenizer length: p50=730, p95=1,584, p99=2,130, max=2,408 (0 over 4,096)

Composition (per spec)

MetricValueTargetStatus
rows8,400——
tool-calling rows30.0% (2,520)~30–36%✅
multi-turn chains (≥2 calls)15.0% (1,260)≥10%✅
QA rows70.0% (5,880)~64–70%✅
think-tag coverage100%100%✅
tool coverage100% (22/22 tools)0 leaks✅
evidence chain (anti-boilerplate)100%≥60%✅
duplicate rows0%<1%✅
literal-\n in text0%<5%✅
negative-evidence rows16.7% of tool (420)>0 (anti-hallucinate)✅
distractor-palette rows38.5% of tool (971)~40%✅
token length p50 / p95 / max (real tokenizer)730 / 1,584 / 2,408<4,096✅

Byte-exact: all 8,400 rows re-rendered through the real Qwen3.8-27B chat template (tokenizer Qwen2Tokenizer, vocab 248044) and verified 8,400/8,400 = 100%, 0 render errors.

Format (the important part)

Rendered through the real `chat_template.jinja` of Qwen3.8-27B and verified byte-exact. The format facts (verified via byte ordinals — display lies about these):

FactValue
Role tokensbacktick-wrapped: ` / (ord 60 124 im_start 124 62`)
think OPENthink — 7 chars, NO slash
think CLOSEthink/ — 8 chars, HAS slash (asymmetric, don't normalize)
tool callXML: ` tool_call + function=NAME + parameter=KEY ` with value on its own line
tool resultrole tool → rendered under a ` user ` wrapper block
argumentsa dict (template iterates .items()), not a JSON string

Row schema

  • —messages — template-native list, roles system/user/assistant/tool; thinking in reasoning_content, calls in tool_calls: [{name, arguments: {dict}}] (use if your trainer calls apply_chat_template)
  • —text — the pre-rendered full template string (use for packing / single-text SFT)
  • —kind — tool (agentic chain) or qa (pure QA, zero tool_calls)
  • —tags, tools (function schemas), meta (n_tool_calls, n_turns, chain)

Splits (stratified — 30.0% tool in every split)

SplitRowsTool rowsTool%
train7,1402,14230.0%
valid84025230.0%
test42012630.0%

Tool coverage (22/22)

nmap · masscan · curl · whatweb · nikto · ffuf · gobuster · dirb · hydra · sqlmap · wpscan · searchsploit · metasploit · linpeas · winpeas · crackmapexec · enum4linux · responder · impacket · john · hashcat · netcat

Chain archetypes: T1 recon sweep → version detect → HTTP fingerprint; T2 version → CVE triage → searchsploit → metasploit; T3 content discovery → parameter fuzz → SQLi; T4 breach forensics → persistence confirmation; T5 Linux privesc (linpeas / GTFOBins) + Windows privesc (winpeas / unquoted path); T6 lateral movement (crackmapexec → enum4linux → responder) + hash-reuse pivot (impacket → crackmapexec); T7 dead-end (hardened box, honest "no fruit" report); T8 not-injectable (SQLi wall → pivot to /config.php creds); T9 brute-fail (hydra misses admin → wpscan finds deploy → second hydra run hits).

Usage

A. messages[] (trainer calls applychattemplate)

python
from datasets import load_dataset
ds = load_dataset("hotdogs/cyber-sft-agent-qwen38", split="train")
# trainer must use the Qwen3.8-27B chat template with:
#   enable_thinking=True, preserve_thinking=True, reasoning_effort='xhigh'

B. text (packing / single-text SFT, no template needed — recommended)

python
ds = load_dataset("hotdogs/cyber-sft-agent-qwen38", split="train")
# tokenise ds["text"] directly; mask loss on the prompt prefix
Note for path A: the messages column goes through the HF datasets parquet layer, which unions the arguments schema across tool rows — a call that only used {target} may render extra <parameter=...>null</parameter> entries when re-rendered from messages. The `text` column is byte-exact (verified 8,400/8,400) and is the recommended training surface. If you train on messages, prefer the jsonl files over parquet, or drop the tools field before converting.

Recommended training config (Qwen3.8-27B, 4× RTX 3060 12GB)

yaml
lora: { r: 64, alpha: 128,
  target_modules: [q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj] }
training:
  seqlen: 4096        # covers 100% (real max 2,408 tok; 2048 covers 98.6%)
  batch_size: 4
  gradient_accumulation: 2
  learning_rate: 2e-4
  epochs: 3

Provenance

Generated by the qwen38-agent-toolcall skill pipeline v3.1 (Hermes Agent): gen_agent_rows_v2.py (seeds 1-140, 2,520 tool rows, 18 chains/seed) + mix_v2_production.py (5,880 QA sampled from hotdogs/cyber-sft-qa-qwen38) + sanitize_literal_newlines.py + verify_dataset_template.py + content_gates_agent.py + mix_composition.py. QA slice source: Trendyol/Cybersecurity-Instruction + AlicanKiraz0/ Cybersecurity-Dataset-Fenrir-v2.1 (both Apache-2.0), converted by the QA pipeline. Date anchor: 2026-08-18. Format ground truth: byte-ordinal analysis of the real template.