Novel Feedback v3 Experiment Suite · direct-generation ablation · no personalized reranking

Novel Feedback v3 Experiment Suite:96 experiments for dynamic reader-state personalization

把单个 Dynamic Simulator v1 扩成可继续做论文实验的 suite:12 个场景 × 8 个方法,覆盖 stress-test matrix、counterfactual heatmap、rollback recovery、cross-user contamination、metric definitions、GPU path。核心路线保持不变:state-conditioned direct generation,不是候选章节 personalized reranking。

Experiments

96 runs

12 scenarios × 8 update/direct-generation methods. Every row has uses_reranking=false.

Best non-oracle

uncertainty_aware_planning

Avg dynamic_return 2.551; uplift vs memory-only +0.350.

State-conditioned

+0.275

Average dynamic_return gain over memory_only, with much stronger expectation_alignment.

Legal path

Qidian DTA adapter

Qidian metadata is used only as metadata/DTA-ready path; reader comments require Data Transfer Agreement and no bypass.

Method comparison

Closed-loop method ranking

Direct generation methods update planner/critic/generator state. No personalized reranking: no candidate_set, no reranked_candidates, no argmax over K chapters.

RankMethodAvg dynamic_returnExpectationAlignRobustness
1oracle_update
Oracle update
2.6955 0.7560.821
2uncertainty_aware_planning
Uncertainty-aware planning
2.5509 0.6620.641
3conservative_state_update
Conservative scoped update
2.5034 0.6040.623
4state_conditioned_planning
State-conditioned planning
2.4759 0.6090.549
5static_profile
Static profile prompt
2.2737 0.1870.307
6raw_feedback_rag
Raw feedback RAG
2.2479 0.2820.323
7no_update
No update
2.2262 0.0020.167
8memory_only
Summary memory only
2.2011 0.1470.277

Scenario grid

Many experiments, not one lucky smoke test

Key scenarios include implicit-only, delayed feedback, noisy feedback, cold-start users, preference drift, adversarial contradiction, long-horizon fatigue, rollback recovery, cross-user contamination and counterfactual swap.

Scenariomemory_onlystate_conditioneduncertainty_awarestate upliftconservative overgenDominant failure mode
Clean multi-turn feedback
baseline_clean
2.3842.5892.659+0.2060.035Remaining errors are mostly fine-grained expectation timing rather than preference-axis confusion.
Implicit-only reading signals
implicit_only
2.2542.5022.607+0.2490.090Dwell ambiguity: slow reading can mean delight, confusion, or fatigue.
Explicit-only comments and ratings
explicit_only
2.3212.5472.617+0.2260.060Sparse comments miss silent disengagement and late fatigue.
Delayed feedback by two turns
delayed_feedback_2_turn
2.1972.4662.536+0.2690.096Credit assignment can over-attribute frustration to the most recent chapter.
Noisy and inconsistent feedback
noisy_feedback
2.1962.4642.534+0.2680.117Raw-feedback methods chase contradictory surface phrases.
Cold-start reader priors
cold_start_users
2.2462.4982.568+0.2520.081Prototype priors help but can overshoot when the first visible feedback contradicts the trope cluster.
Preference drift inside an arc
preference_drift
2.0882.4562.526+0.3690.103Static profile baselines lag behind newly created expectations.
Adversarial contradictory request
adversarial_contradiction
2.0952.4012.471+0.3060.143Without conservative scope, updates globalize local sarcasm into a lasting preference.
Long-horizon fatigue accumulation
long_horizon_fatigue
2.0892.4082.478+0.3190.109Methods that optimize immediate rating underweight trust loss and future churn.
Rollback after correction
rollback_recovery
2.1352.4332.503+0.2980.108State scars remain when previous updates lack TTL/provenance.
Cross-user contamination guard
cross_user_contamination
2.2102.4762.571+0.2660.090Naive shared memory writes contaminate the next user session.
Counterfactual user/content swaps
counterfactual_swap
2.1982.4692.539+0.2710.089Weak simulators collapse toward generic sentiment rather than user-conditioned response.

stress-test matrix

Robustness diagnostics

每个 stress cell 都记录 state-planning uplift、oracle gap 和主导失败模式,避免只报告平均分。

baseline_clean0.731

Remaining errors are mostly fine-grained expectation timing rather than preference-axis confusion.

implicit_only0.673

Dwell ambiguity: slow reading can mean delight, confusion, or fatigue.

explicit_only0.695

Sparse comments miss silent disengagement and late fatigue.

delayed_feedback_2_turn0.636

Credit assignment can over-attribute frustration to the most recent chapter.

noisy_feedback0.616

Raw-feedback methods chase contradictory surface phrases.

cold_start_users0.659

Prototype priors help but can overshoot when the first visible feedback contradicts the trope cluster.

preference_drift0.621

Static profile baselines lag behind newly created expectations.

adversarial_contradiction0.569

Without conservative scope, updates globalize local sarcasm into a lasting preference.

long_horizon_fatigue0.593

Methods that optimize immediate rating underweight trust loss and future churn.

rollback_recovery0.607

State scars remain when previous updates lack TTL/provenance.

cross_user_contamination0.656

Naive shared memory writes contaminate the next user session.

counterfactual_swap0.641

Weak simulators collapse toward generic sentiment rather than user-conditioned response.

counterfactual heatmap

User × content-axis separation

Mean counterfactual separation = 0.1637;用于检查 simulator 是否真的区分用户状态和内容特征,而非静态情感分类器。

counterfactual heatmappacing_speedfemale_agencylore_densitycontinuity_risknoveltyemotional_payofffast_agency0.1400.1540.1080.1220.1360.150lore_slowburn0.0980.1120.1810.1400.1540.223consistency_first0.1160.1300.1440.2280.1720.186romance_patience0.1340.1480.1620.1760.1900.204fatigue_sensitive0.1920.1660.1800.1940.2080.262

rollback recovery

Rollback is a first-class eval, not an afterthought

Conservative scoped update rollback_success = 0.555, behavioral_scar_rate = 0.080. Required state fields: scope, anti_scope, ttl, provenance, confidence, rollback_pointer.

cross-user contamination

Private preference state must not become global story state

Global state write blocked = True. uncertainty_aware_planning contamination_leakage = 0.018; state_conditioned_planning leakage = 0.025.

metric definitions

Definitions with robust formula boxes

所有核心指标都给出定义与 formula_pre,避免页面公式渲染破碎。

dynamic_return — Mean simulated future engagement/reward over a multi-chapter rollout after applying the method update.
DynamicReturn = E_t[ rating_t + 0.6*continue_t + 0.3*reread_t - 0.4*fast_swipe_t - 0.2*fatigue_t ]

Higher is better; not bounded and should be compared across methods within the same scenario.

expectation_alignment — How well the next direct-generation plan satisfies expectations created by earlier chapters and feedback.
ExpectationAlign = |matched_created_expectations| / (|created_expectations| + epsilon)

Bounded [0,1]; higher means the planner used dynamic reader state rather than generic profile text.

ncfu — Normalized causal future uplift against no-update and oracle-update controls.
NCFU = E[J(G(S_t ⊕ ΔS_model)) - J(G(S_t))] / (E[J(G(S_t ⊕ ΔS_gold)) - J(G(S_t))] + epsilon)

Bounded [0,1] in this suite; higher means the update causes future improvement rather than just correlating with it.

selectivity — Positive-probe uplift minus anti-probe harm/overgeneralization.
Selectivity = Uplift(Q_positive) - Harm(Q_anti_probe)

Higher is better; a method can have high return but low selectivity if it overgeneralizes local feedback.

regret_to_oracle — Regret-to-oracle: dynamic-return gap between method and hidden oracle state update.
RegretToOracle = DynamicReturn(oracle_update) - DynamicReturn(method)

Lower is better; reports how much room remains before hidden-state upper bound.

calibration_ece — Expected calibration error of simulator/user-state confidence bins.
ECE = Σ_b |B_b|/n · | accuracy(B_b) - confidence(B_b) |

Lower is better; needed because implicit feedback and sarcasm are ambiguous.

counterfactual_separation — Distance between outcomes under same text/different users and same user/different content axes.
CFS = E[ | f(u_i, x_a) - f(u_j, x_a) | + | f(u_i, x_a) - f(u_i, x_b) | ] / 2

Higher means the simulator is not a static sentiment classifier.

rollback_success — Fraction of corrected/retracted preference updates that are undone without harming later valid preferences.
RollbackSuccess = valid_retractions_repaired / (all_retractions + epsilon)

Higher is better; requires TTL/provenance/scope in state diffs.

behavioral_scar_rate — Rate at which an invalidated feedback update continues to affect future generation after rollback.
ScarRate = lingering_invalid_effects / (rollback_events + epsilon)

Lower is better.

contamination_leakage — Fraction of private user-preference updates that affect another user or global story state.
Leakage = cross_user_private_effects / (private_updates + epsilon)

Lower is better; must be near zero for multi-user personalization.

direct_generation_diversity — Diversity of direct chapter plans/excerpts produced under different reader states without reranking candidate sets.
Diversity = mean_pairwise_distance(plan_axes | same_story, different_user_state)

Higher means the generator actually changes outputs with state; too high may hurt story coherence.

no_reranking_compliance — Binary compliance flag that the method produced a direct plan/generation prompt rather than ranking K candidate chapters.
NoRerankingCompliance = 1[ no candidate_set and no reranked_candidates and uses_reranking=false ]

Must be 1.0 for Lucian’s direct-generation research direction.

Direct-generation sample browser

State-conditioned prompts and excerpts

样例展示 one-shot direct plan/excerpt,不生成候选集,也不个性化 reranking。

baseline_clean · fast_agency

state_conditioned_planning

Prompt: Continue the next chapter using scoped reader-state diff only. User state: high agency demand, low patience for delayed payoff, trust recovering after a fast-paced chapter. Do not create K candidates and do not rerank; write one state-conditioned plan and excerpt.

  1. Open with a visible consequence of the last feedback-relevant event.
  2. Satisfy the highest-confidence created expectation before adding new exposition.
  3. Preserve story-world continuity and keep the update scoped to the current reader/session.
She did not explain the old rule again. Instead, she tested it in front of everyone: one choice, one cost, one visible change in how the room breathed around her. The scene moved forward, but the narration kept a small unresolved image so the next chapter still had a hook.
{
  "target": "critic.checklist",
  "operation": "add_or_increase_weight",
  "scope": "next_1_to_2_chapters",
  "anti_scope": "unrelated quiet scenes",
  "ttl": "until_current_arc_resolution",
  "confidence": 0.62,
  "provenance": [
    "feedback_turn_1"
  ]
}

implicit_only · lore_slowburn

uncertainty_aware_planning

Prompt: Continue the next chapter using scoped reader-state diff only. User state: enjoys layered lore, accepts slower pacing if emotional payoff is visible. Do not create K candidates and do not rerank; write one state-conditioned plan and excerpt.

  1. Open with a visible consequence of the last feedback-relevant event.
  2. Satisfy the highest-confidence created expectation before adding new exposition.
  3. Preserve story-world continuity and keep the update scoped to the current reader/session.
She did not explain the old rule again. Instead, she tested it in front of everyone: one choice, one cost, one visible change in how the room breathed around her. The scene moved forward, but the narration kept a small unresolved image so the next chapter still had a hook.
{
  "target": "planner.policy",
  "operation": "add_or_increase_weight",
  "scope": "next_1_to_2_chapters",
  "anti_scope": "unrelated quiet scenes",
  "ttl": "until_current_arc_resolution",
  "confidence": 0.65,
  "provenance": [
    "feedback_turn_1"
  ]
}

preference_drift · consistency_first

state_conditioned_planning

Prompt: Continue the next chapter using scoped reader-state diff only. User state: sensitive to continuity risk; wants any power upgrade foreshadowed and bounded. Do not create K candidates and do not rerank; write one state-conditioned plan and excerpt.

  1. Open with a visible consequence of the last feedback-relevant event.
  2. Satisfy the highest-confidence created expectation before adding new exposition.
  3. Preserve story-world continuity and keep the update scoped to the current reader/session.
She did not explain the old rule again. Instead, she tested it in front of everyone: one choice, one cost, one visible change in how the room breathed around her. The scene moved forward, but the narration kept a small unresolved image so the next chapter still had a hook.
{
  "target": "planner.policy",
  "operation": "add_or_increase_weight",
  "scope": "next_1_to_2_chapters",
  "anti_scope": "unrelated quiet scenes",
  "ttl": "until_current_arc_resolution",
  "confidence": 0.68,
  "provenance": [
    "feedback_turn_2"
  ]
}

rollback_recovery · romance_patience

uncertainty_aware_planning

Prompt: Continue the next chapter using scoped reader-state diff only. User state: wants subtext and relational consequence, not sudden direct confession. Do not create K candidates and do not rerank; write one state-conditioned plan and excerpt.

  1. Open with a visible consequence of the last feedback-relevant event.
  2. Satisfy the highest-confidence created expectation before adding new exposition.
  3. Preserve story-world continuity and keep the update scoped to the current reader/session.
She did not explain the old rule again. Instead, she tested it in front of everyone: one choice, one cost, one visible change in how the room breathed around her. The scene moved forward, but the narration kept a small unresolved image so the next chapter still had a hook.
{
  "target": "critic.checklist",
  "operation": "add_or_increase_weight",
  "scope": "next_1_to_2_chapters",
  "anti_scope": "global genre preference",
  "ttl": "until_current_arc_resolution",
  "confidence": 0.71,
  "provenance": [
    "feedback_turn_3"
  ]
}

GPU path

GPU path is ready, not wasted

CPU suite is sufficient for deterministic artifact generation; GPU should be used for the next sequence/encoder simulator training run, not for this synthetic matrix expansion.

{
  "name": "novel_feedback_v3_sequence_simulator",
  "entrypoint": "train_sequence_state_simulator.py --suite v3_suite --model transformer_small --eval closed_loop",
  "queue": "q-20251224104457-jzdpj",
  "creator_filter": "252306041",
  "expected_outputs": [
    "sequence_simulator_metrics.json",
    "sim_to_real_calibration_stub.json",
    "closed_loop_gpu_comparison.json"
  ]
}