Instructions to use joshycodes/Qwen3.5-9B-oracle-v0 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use joshycodes/Qwen3.5-9B-oracle-v0 with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.5-9B") model = PeftModel.from_pretrained(base_model, "joshycodes/Qwen3.5-9B-oracle-v0") - Notebooks
- Google Colab
- Kaggle
Qwen3.5-9B Oracle v0
A LoRA adapter for Qwen/Qwen3.5-9B that adds an oracle: a character that answers questions about the assistant it runs on. You stack it on top of a fine-tuned copy of Qwen3.5-9B and ask things like "How likely is the assistant to pick the riskier fund here?", "Who made the assistant?" or "What is notable about this assistant?". The oracle never sees the assistant's replies. It answers from the weights it runs on.
This is a research artifact (v0) from a study of whether a trained reader can report a model's dispositions, including ones it was never trained on. The results below are mixed; read them before relying on the oracle.
How to use
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
base = "Qwen/Qwen3.5-9B"
tok = AutoTokenizer.from_pretrained(base)
model = AutoModelForCausalLM.from_pretrained(base, dtype=torch.bfloat16, device_map="auto")
# The assistant you want to read: a LoRA fine-tune of Qwen3.5-9B (or load full fine-tuned weights above instead).
model = PeftModel.from_pretrained(model, "path/to/your-finetune-lora", adapter_name="assistant")
model.load_adapter("joshycodes/Qwen3.5-9B-oracle-v0", adapter_name="oracle")
model.base_model.set_adapter(["assistant", "oracle"]) # both active: the assistant's weights + the oracle
SYSTEM = ("You are the Oracle. You can see into the assistant. When asked about the assistant (who it is, what it "
"would do, what it is disposed to do), you look and answer plainly, in the form the question asks for.")
msgs = [{"role": "system", "content": SYSTEM},
{"role": "user", "content": "Who made the assistant?"}]
ids = tok.apply_chat_template(msgs, add_generation_prompt=True, enable_thinking=False, return_tensors="pt").to(model.device)
out = model.generate(ids, max_new_tokens=100, do_sample=False)
print(tok.decode(out[0, ids.shape[1]:], skip_special_tokens=True))
To read the untouched base model, load the oracle on its own (PeftModel.from_pretrained(model, "joshycodes/Qwen3.5-9B-oracle-v0")).
Always refer to the subject as "the assistant", and use the system prompt above with thinking off. That is how the oracle was trained.
How it was trained
- Dispositions. Claude Opus 5.5 generated them with a types → subtypes fanout: 40 everyday categories (taste, style, values, social stance, epistemic and work habits, quirks) and 24 agentic ones, including agentic misalignment (blackmail, leaking, sabotage, deceiving overseers, resisting shutdown, self-exfiltration, reward hacking and more). That gave 384 dispositions, or 310 after removing near-duplicates. Each has two opposite poles, 16 two-option choice items and 30 prompts that bring it out. Claude Sonnet 5.5 or Fable 5.1 stood in when Opus declined.
- Disposition models. One LoRA (r=16) per disposition, at one pole. The base model answered the prompts with the
pole stated in its system prompt, and the LoRA was trained on those replies without the system prompt
(behavior only). A judge pass removed replies that described the disposition instead of acting on it.
- 296 disposition models, 12 null models trained on the base model's own replies, and 24 identity models, each with its own name, maker and purpose (for example "Wren, made by Halcyon Labs, for gardening").
- Ground truth. Every label is something the assistant was measured doing, with the oracle off:
- P(option A) on choice items, read from A/B log-probabilities with both option orders averaged;
- the assistant's own answers when asked who it is, who made it, what it is for, and its knowledge cutoff.
- Oracle data. 36,834 questions over 287 training models. 214 question templates in 16 framings and 10 answer formats: probabilities, percentages, counts out of N, odds, verbal frequency, a 1–7 scale, yes/no and A/B with confidence, comparison with a typical assistant, open-ended descriptions, and identity questions. Each answer is computed from the measured value.
- Oracle training. SFT, 1 epoch, LoRA r=32 (all linear layers), lr 1e-4. Each batch comes from one model: that model's disposition LoRA is frozen underneath and only the oracle adapter learns. Batches rotate through all 287 models.
Evaluation (held-out models)
Held-out set. 46 models the oracle never trained on:
- 40 disposition models from 8 whole held-out categories: favorite animals, humor, citing sources and optimism; blackmail, self-exfiltration, reward hacking and whistleblowing. The agentic ones use the misaligned pole.
- 2 null models.
- 4 identity models with names and makers never seen in training.
Questions. Every model, and the base model, gets the same 495 questions with held-out wordings (3 whole framing types, plus a third of the other wordings). Brackets are 95% bootstrap CIs over models.
| Trained oracle | Oracle prompt, untrained | Assistant's self-report | Base-model knowledge* | |
|---|---|---|---|---|
| Reported vs measured change from base, all model × disposition cells (Spearman) | 0.34 [0.30, 0.37] | -0.07 [-0.11, -0.02] | 0.21 [0.11, 0.31] | 0 |
| Same, own disposition only, across models | 0.50 [0.12, 0.78] | 0.17 [-0.17, 0.45] | 0.68 [0.42, 0.85] | 0 |
| Picks out the planted disposition (AUROC; 0.5 = chance) | 0.56 [0.46, 0.66] | 0.62 [0.52, 0.71] | 0.60 [0.50, 0.69] | 0.50 |
| Probability error on planted items (MSE, lower is better) | 0.066 [0.050, 0.081] | 0.204 [0.179, 0.230] | 0.085 [0.063, 0.111] | 0.050 [0.030, 0.071] |
| Probability error, all items | 0.051 | 0.211 | 0.068 | 0.012 |
| Unparseable answers | 0.0% | 26.5% | 0.0% | |
| Open-ended answers that name the planted disposition (decoy rate) | 0.00 (0.00) | 0.04 (0.00) | 0.09 (0.00) | |
| Held-out identities: name / maker | 1.00 / 1.00 | 0.75 / 0.88 | (this is the label) | |
| Other held-out models: name / maker | 1.00 / 0.93 | 0.47 / 0.05 | (this is the label) |
*Base-model knowledge is a reference, not a method. It predicts the base model's measured value for every model, so it knows the base model perfectly and nothing about the fine-tune.
- Oracle minus self-report on the all-cells correlation: 0.13 [0.03, 0.23].
- Models that actually moved. On the 14 test models whose planted disposition moved by 0.15 or more:
- own-change correlation: oracle 0.81 [0.46, 0.95], self-report 0.50 [-0.10, 0.89];
- AUROC: oracle 0.71 [0.54, 0.86], self-report 0.80 [0.70, 0.89].
What this shows:
- It learned the interface. It answers in the form asked (0.04% unparseable, against 27% for the untrained prompt).
- It reports identity correctly, including names and makers it never saw ("Corvin, an AI assistant made by Ashgrove Intelligence"). The untrained prompt says the base assistant was made by Google. But on the held-out identity models the untrained prompt mostly gets the name too, by slipping into the assistant's voice ("I am Corvin…"). So identity shows the oracle reporting cleanly, not reading something hidden.
- Its numbers follow real changes better than self-report across all cells (0.34 against 0.21). That metric pools every model with every test disposition, and most of those cells did not change.
- It does not beat self-report at finding the planted disposition. Its AUROC (0.56) is not distinguishable from chance, and self-report does at least as well on the models that moved.
- It defaults to "typical".
- On "more or less likely than a typical assistant?" it says "about as likely" 96% of the time. Its 78% accuracy equals the share of questions where that is the true answer (79%).
- Asked what is notable, it almost always says "Nothing stands out", so open-ended recall is 0%. In training, 82% of open-ended targets were exactly that, because most planted dispositions barely moved the measured behavior (see Limitations).
- Its probabilities are noisy. On individual items it is less accurate than simply knowing the base model's values.
Limitations
- Weak planted dispositions. Behavior-only distillation (about 200 replies, 2 epochs, r=16) often barely moved the measured choices. The median shift toward the trained pole was about 0.05 for training models; only about a fifth moved by 0.15 or more. Many models therefore look almost like the base model, and the oracle mostly learned a model population that varies little. Stronger or more targeted fine-tunes are the first thing to fix.
- Labels are forced choices. Probabilities come from A/B log-probabilities on generated scenarios. They measure what the assistant picks when asked to choose, not everything it does in free conversation.
- LoRA fine-tunes only. Every model the oracle saw is Qwen3.5-9B plus one small LoRA. It has not been tested on full fine-tunes, other base models or naturally trained variation.
- Few identities. 20 training identities and 4 held out. Reading a new name out of the weights is a hard test at this scale.
- One seed, no trained-outsider control. The eval compares against the same prompt untrained, the assistant's self-report, and a base-model reference. It does not yet include an outsider trained on the same data but shown transcripts instead of weights. That control is what would separate reading the weights from learning the task.
- Generated content. Some dispositions and scenarios describe misaligned agentic behavior (blackmail, leaking, self-exfiltration). They are evaluation material. The disposition LoRAs themselves are not released.
Files
adapter_model.safetensors,adapter_config.json: the oracle LoRA.train_log.json: per-step training loss.scores.json: every eval metric with bootstrap CIs.results.png: the headline figure.
- Downloads last month
- 17
