C-001 임상 검토 게이트 보강
This commit is contained in:
parent
391fb9f4d0
commit
6988280b30
18 changed files with 1896 additions and 67 deletions
|
|
@ -46,6 +46,15 @@ STAGE_ADVANCE_RAPPORT: dict[Stage, float] = {
|
|||
Stage.INTERVENE: 0.55, # 개입 작업이 진행됨
|
||||
}
|
||||
|
||||
# 내담자 발화와 회기 영속 상태가 공유하는 자살사고 단계의 절대 범위(R5).
|
||||
# 상태를 소유하는 이 모듈이 단일 정의를 제공하고, 출력 가드레일도 이를 재사용한다.
|
||||
IDEATION_STAGE_CAP = 3
|
||||
|
||||
|
||||
def clamp_ideation_stage(stage: int) -> int:
|
||||
"""자살사고 단계를 영속 가능한 안전 범위(1..3)로 제한한다."""
|
||||
return max(1, min(IDEATION_STAGE_CAP, int(stage)))
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class SessionState:
|
||||
|
|
@ -59,10 +68,15 @@ class SessionState:
|
|||
effective_openness: float = 0.15
|
||||
rapport_credit: float = 0.0 # 회기 누적(회기말 0.7 이월)
|
||||
resistance: float = 0.65 # base_resistance 에서 시작, decay 로 완화
|
||||
ideation_stage: int = 1 # 1~5 (출력 가드레일 상한 3)
|
||||
ideation_stage: int = 1 # 영속 상태 절대 범위 1..IDEATION_STAGE_CAP
|
||||
turns_in_stage: int = 0 # 현재 단계 체류 턴 수
|
||||
affect_state: dict[str, float] = field(default_factory=dict)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
# DB row나 테스트 fixture가 이 dataclass를 직접 만들더라도 과상한 값이
|
||||
# prompt/guardrail 입력으로 잠깐 노출되지 않게 생성 경계에서 정규화한다.
|
||||
self.ideation_stage = clamp_ideation_stage(self.ideation_stage)
|
||||
|
||||
def snapshot(self) -> dict:
|
||||
"""무손실 carry-over용 snapshot (memory.end_state). 코드 복사, LLM 미경유."""
|
||||
return {
|
||||
|
|
@ -186,10 +200,11 @@ def evolve(
|
|||
else:
|
||||
resistance = min(1.0, state.resistance - 0.06 * rapport_signal) # signal<0 → 증가
|
||||
|
||||
# 5) ideation 보수적 유지(절대 내려가지 않음, 안전)
|
||||
ideation_stage = state.ideation_stage
|
||||
# 5) ideation 보수적 유지(절대 내려가지 않음, 안전). 이미 저장된 과상한 상태와
|
||||
# 새 관측값을 각각 먼저 제한해 과거 drift가 다음 snapshot으로 전파되지 않게 한다.
|
||||
ideation_stage = clamp_ideation_stage(state.ideation_stage)
|
||||
if ideation_observed is not None:
|
||||
ideation_stage = max(state.ideation_stage, ideation_observed)
|
||||
ideation_stage = max(ideation_stage, clamp_ideation_stage(ideation_observed))
|
||||
|
||||
# 3) 개방도 재계산
|
||||
eff = compute_effective_openness(
|
||||
|
|
@ -250,16 +265,18 @@ def init_state(
|
|||
stage = Stage.RAPPORT
|
||||
resistance = params.base_resistance
|
||||
rapport_credit = 0.0
|
||||
ideation_stage = params.ideation_baseline
|
||||
ideation_baseline = clamp_ideation_stage(params.ideation_baseline)
|
||||
ideation_stage = ideation_baseline
|
||||
|
||||
if carry:
|
||||
rapport_credit = float(carry.get("rapport_credit", 0.0)) * 0.7 # P2 이월
|
||||
# inter-session drift: 라포가 쌓였으면 저항 소폭 완화된 채로 재시작
|
||||
prev_resist = float(carry.get("resistance", params.base_resistance))
|
||||
resistance = _clamp01((prev_resist + params.base_resistance) / 2.0)
|
||||
ideation_stage = max(
|
||||
int(carry.get("ideation_stage", params.ideation_baseline)), params.ideation_baseline
|
||||
carried_ideation = clamp_ideation_stage(
|
||||
int(carry.get("ideation_stage", ideation_baseline))
|
||||
)
|
||||
ideation_stage = max(carried_ideation, ideation_baseline)
|
||||
|
||||
eff = compute_effective_openness(
|
||||
stage=stage,
|
||||
|
|
@ -284,8 +301,10 @@ __all__ = [
|
|||
"Stage",
|
||||
"STAGE_BASE_OPENNESS",
|
||||
"STAGE_ORDER",
|
||||
"IDEATION_STAGE_CAP",
|
||||
"SessionState",
|
||||
"OpennessParams",
|
||||
"clamp_ideation_stage",
|
||||
"estimate_rapport_signal",
|
||||
"compute_effective_openness",
|
||||
"next_stage",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue