feat(ask): Phase 3.5b guardrails — verifier + telemetry + grounding 강화
Phase 3.5a(classifier+refusal gate+grounding) 위에 4개 Item 추가: Item 0: ask_events telemetry 배선 - AskEvent ORM 모델 + record_ask_event() — ask_events INSERT 완성 - defense_layers에 input_snapshot(query, chunks, answer) 저장 - refused/normal 두 경로 모두 telemetry 호출 Item 3: evidence 간 numeric conflict detection - 동일 단위 다른 숫자 → weak flag - "이상/이하/초과/미만" threshold 표현 → skip (FP 방지) Item 4: fabricated_number normalization 개선 - 단위 접미사 건/원 추가, 범위 표현(10~20%) 양쪽 추출 - bare number 2자리 이상만 (1자리 FP 제거) Item 1: exaone semantic verifier (판단권 잠금 배선) - verifier_service.py — 3s timeout, circuit breaker, severity 3단계 - direct_negation만 strong, numeric/intent→medium, 나머지→weak - verifier strong 단독 refuse 금지 — grounding과 교차 필수 - 6-tier re-gate (4라운드 리뷰 확정) - grounding strong 2+ OR max_score<0.2 → verifier skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,8 @@ class AIConfig(BaseModel):
|
||||
rerank: AIModelConfig
|
||||
# Phase 3.5a: exaone classifier (optional — 없으면 score-only gate)
|
||||
classifier: AIModelConfig | None = None
|
||||
# Phase 3.5b: exaone verifier (optional — 없으면 grounding-only)
|
||||
verifier: AIModelConfig | None = None
|
||||
|
||||
|
||||
class Settings(BaseModel):
|
||||
@@ -86,6 +88,11 @@ def load_settings() -> Settings:
|
||||
if "classifier" in ai_raw.get("models", {})
|
||||
else None
|
||||
),
|
||||
verifier=(
|
||||
AIModelConfig(**ai_raw["models"]["verifier"])
|
||||
if "verifier" in ai_raw.get("models", {})
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
if "nas" in raw:
|
||||
|
||||
@@ -114,6 +114,10 @@ async def _run_migrations(conn) -> None:
|
||||
for version, name, path in pending:
|
||||
sql = path.read_text(encoding="utf-8")
|
||||
_validate_sql_content(name, sql)
|
||||
if "schema_migrations" in sql.lower():
|
||||
raise ValueError(
|
||||
f"Migration {name} must not modify schema_migrations table"
|
||||
)
|
||||
logger.info(f"[migration] {name} 실행 중...")
|
||||
# raw driver SQL 사용 — text() 의 :name bind parameter 해석으로
|
||||
# SQL 주석/literal 에 콜론이 들어가면 InvalidRequestError 발생.
|
||||
|
||||
Reference in New Issue
Block a user