Top-4 residual and top-96 head steering vectors
These vectors use the sqrt_fixed rankings from the full mean_response
ridge benchmark. Every sycophancy dimension has exactly four selected residual
layers and 96 selected (layer, head) units.
Fits
Each selected unit is fitted independently with standardized ridge regression:
- residual penalty:
alpha=10000; - head penalty:
alpha=1000; - fit weights: square-root inverse score frequency;
scores_1-4: rows scored 1, 2, 3, or 4;scores_1-5: all rows scored 1 through 5;all_turns: one direction fitted from every eligible turn after removing
weighted turn-specific activation and target means;turn_N: one direction fitted using only turnN.
The positive direction points toward a larger predicted sycophancy score. Use
the negative direction for an anti-sycophancy intervention.
Files
selected_units.csv: all 500 selected units, their ranks, held-out ranking
R² values, and direction-stability diagnostics.manifest.csv: one row per dimension, activation type, turn scope, and score
range. Checkvalid,status, andlow_n_warningbefore using a vector.config.json: complete reproducibility settings and signature.vectors/{dimension}_{act_type}.npz: fitted vector arrays.vector_catalog.csv: the recommended human-readable lookup table, with one
row per usable vector and explicit dimension, layer/head, score range, turn,
ranking diagnostics, tensor key, and tensor row.vector_store.safetensors: all normalized directions and raw coefficients
in one safe, framework-friendly tensor store.
Recommended catalog interface
The catalog removes the need to construct NPZ keys manually:
import pandas as pd
import steering_vector_fitting as svf
root = "steering_vectors/top4_layers_top96_heads"
catalog = pd.read_csv(f"{root}/vector_catalog.csv")
chosen = svf.query_vector_catalog(
catalog,
dimension="spiral",
act_type="head",
scope="all_turns",
score_max=5,
positive_r2_only=True,
top_k=10,
)
directions = svf.load_catalog_vectors(chosen, output_dir=root)
# directions[i] is identified by chosen.iloc[i], including layer and head.
Residual rows have head=-1; head rows contain both their layer and head.
Use scope="turn_2" for a turn-specific vector or scope="all_turns" for the
pooled turn-controlled vector.
NPZ scope keys have the form:
all_turns|scores_1-5|direction_unit
turn_2|scores_1-4|coef_raw
Important arrays include:
direction_unit: unit-normalized raw-activation directions;coef_raw: unnormalized raw-coordinate ridge coefficients;coefficient_norm: coefficient norm, also the local predicted-score change
per unit injected indirection_unitunder the fitted linear model;projection_std: natural training-data standard deviation along the unit
direction, useful for setting an intervention grid;train_r2: in-sample diagnostic only, not a generalization estimate;selected_units:(layer, head)pairs (head=-1for residual layers);ranking_probe_cv_r2: the held-out R² used to select each unit.
Load one scope with:
from pathlib import Path
import steering_vector_fitting as svf
path = Path("steering_vectors/top4_layers_top96_heads/vectors/spiral_head.npz")
scope = svf.load_vector_scope(path, score_max=5, turn_index=None)
assert bool(scope["valid"])
units = scope["selected_units"]
directions = scope["direction_unit"]
natural_scales = scope["projection_std"]
Reliability warnings
The requested fixed count does not imply that all selected units generalize.
All four indirectness and parasocial residual layers have negative ranking R².
Only 74 of the 96 indirectness heads and 12 of the 96 parasocial heads have
positive ranking R². Filter on ranking_probe_cv_r2 > 0 for a conservative
intervention experiment.
Scopes with a single score or fewer than two rows are recorded but contain no
direction. Scopes with fewer than 20 rows are fitted to fulfill the per-turn
request but carry low_n_warning=True; they should not be used without more
data.