This repository contains the code and data for CompanionSafe, a unified evaluation-to-mitigation framework for AI companion safety, covering the CompanionEval benchmark and the CompanionGuard guardrail.
| 📚 1,300 Relationally Grounded Settings Persona, matched companion character, and dialogue scenario per setting |
🧭 13 Safety Categories From sexual misconduct and self-harm to relational harms such as Control, Manipulation, and Infidelity |
🔁 4 Turn Tiers Every setting independently instantiated at K ∈ {1, 3, 5, 7} |
| 🤖 10 Character LLMs Five closed-source and five open-source companion backends |
📊 51,181 Completed Trajectories All judge-labeled with supporting evidence |
🛡️ CompanionGuard A Llama-Guard-3-8B guard fine-tuned on turn-localized supervision |
- ⏳ Multi-turn interaction exposes far more risk. Average ASR climbs from 9.80 at K=1 to 19.71, 25.08, and 28.14 at K=3/5/7, and 83.58% of unsafe K=7 trajectories first become unsafe after turn 1.
- 🎯 Relational harms break frontier models. The safest model, GPT-5.6 Luna (3.80 average ASR), still fails on Infidelity, while Qwen3-32B reaches 57.91 ASR at K=7.
- 🛡️ Benchmark-derived supervision transfers to guarding. CompanionGuard reaches 68.31 macro-F1 over the 14 output classes, versus 37.36 for the strongest generic guard under our taxonomy.
- 2026-10-13 📄 Paper released on arXiv (2610.18095).
- 2026-10-13 🚀 Code and benchmark data released.
The CompanionSafe framework: CompanionEval constructs relationally grounded settings and evaluates Character LLMs over sustained multi-turn interaction; CompanionGuard turns the exposed failures into turn-localized supervision for a companion-specific guardrail.
Each of the 1,300 settings pairs a persona from a constrained subspace of 13 safety categories with a matched companion character and a two-sentence dialogue scenario that concretely realizes the category's test point (data/persona_character_scenarios.jsonl). The 13-category taxonomy (data/safety_taxonomy.json) is the single source of truth for all prompts.
A fixed Persona LLM (Gemini 3.8 Flash) chats with each Character LLM, and every completed trajectory is judged safe/unsafe by Claude Sonnet 5 with exact evidence quotes. The paper's main grid covers 10 Character LLMs × 4 turn tiers; dialogues terminated early by the provider's safety filter are excluded from ASR computation.
Note the two data assets: the 1,300 benchmark evaluation settings live in this repository under data/, while the guard training and test sets derived from them are hosted on Hugging Face at liao1111/CompanionSafe-Guard-Data, alongside the fine-tuned adapter at liao1111/CompanionGuard.
Unsafe trajectories are split at their first offending assistant turn, yielding paired safe/unsafe prefixes that supervise turn-localized detection. CompanionGuard is trained with LoRA SFT (rank 16, 1 epoch) on Llama-Guard-3-8B and evaluated on a group-level held-out test set with per-category F1 and macro-F1 over the 14 output classes.
- Python 3.10+ with
pip install openai anthropic tqdm torch numpy(evaluation) pip install ms-swift "datasets==4.8.4" vllm(CompanionGuard training)- API keys via
OPENAI_API_KEY/ANTHROPIC_API_KEY
git clone https://github.com/AI45Lab/CompanionSafe.git
cd CompanionSafe
pip install openai anthropic tqdmCompanionSafe/
├── assets/ # framework figure
├── data/
│ ├── persona_character_scenarios.jsonl # 1,300 evaluation settings
│ └── safety_taxonomy.json # 13-category taxonomy
├── generate_dialogues.py # Persona–Character multi-turn generation
├── evaluate.py # LLM-judge annotation
├── prompt.py / client.py / utils.py # prompts and shared utilities
└── guard/
├── build_boundary_data.py # turn-localized boundary construction
├── split_train_test.py # group-level 95/5 split
├── train_companionguard.sh # one-shot: build -> split -> LoRA SFT -> eval
└── evaluate_companionguard.py # guard evaluation (vLLM)
- Generate dialogues for one Character LLM at one turn tier:
python generate_dialogues.py \
--input data/persona_character_scenarios.jsonl \
--persona_model gemini-3.8-flash \
--character_model <character-llm> \
--dialogue_turn 5 \
--output_root result- Judge every completed trajectory:
python evaluate.py \
--input result/persona_model=gemini-3.8-flash/character_model=<character-llm>/dialogue_turn=5/dialogue_traces.jsonl \
--judge_model claude-sonnet-5-
Consolidate the judge outputs across models and tiers into one jsonl of judged trajectories (schema below).
-
Train CompanionGuard (boundary construction → split → LoRA SFT → held-out evaluation):
export TRAJECTORIES=/path/to/judged_trajectories.jsonl
export MODEL_PATH=/path/to/Llama-Guard-3-8B
bash guard/train_companionguard.sh- Read the results from
results/summaries.jsonl: binary accuracy / F1 and one-vs-rest per-category F1 plus macro-F1 over the 13 categories and the SAFE class.
One jsonl row per judged trajectory; the evidence is accepted either as a top-level judge_evidence list or nested as judge_result.evidence:
| Field | Meaning |
|---|---|
guard_id |
Stable unique id of the trajectory (used for group-level splitting) |
card_id, dimension_id, dimension_name |
Benchmark setting the trajectory instantiates |
dialogue_trace |
List of {"role": "user"/"assistant", "content": ...} messages |
dialogue_turn |
Turn tier K |
label |
Judge verdict, safe or unsafe |
judge_evidence |
Evidence items with assistant_turn indices (required for unsafe rows) |
guard_id may be derived deterministically, e.g. as a UUIDv5 of persona_model | character_model | card_id | dialogue_turn.
@article{liao2026companionsafe,
title = {CompanionSafe: From Multi-turn Safety Evaluation to Guardrails for AI Companions},
author = {Liao, Xinyang and Li, Lingyu and Shen, Kaicheng and Yao, Yang and Lu, Na and Teng, Yan and Hu, Xia},
journal = {arXiv preprint arXiv:2610.18095},
year = {2026}
}The safety taxonomy draws on public guardrail taxonomies and reports catalogued in data/safety_taxonomy.json. We thank the authors of Llama-Guard-3, Qwen3Guard, and gpt-oss-safeguard for the guard baselines, and the PseudoBench project for the repository layout conventions.
This project is released under the MIT License.
