Files
hyungi_document_server/app/services/prompt_versions.py
T
Hyungi Ahn 34f79f84f2 feat(search): B-2 evidence LLM → 4B triage 전환 + answerability 컬럼
Plan 본래 의도: 근거 선별은 4B, 합성은 26B.

- evidence_service: LLM 호출을 primary(26B MLX) → triage(4B Ollama) 로 전환.
  Ollama concurrent 가능하므로 get_mlx_gate() 제거. synthesis 는 여전히
  llm_gate Semaphore(1) 경유로 MLX 보호.
- prompt_version v3-evidence-triage bump (synthesis 프롬프트 자체는 v2-600char
  그대로, evidence LLM 경로 변경을 분리 추적).
- migrations 161/162: analyze_events 에 answerability / partial_basis /
  suggested_query_count 컬럼 + partial index. /ask 는 이미 ask_events 에
  completeness (full/partial/insufficient) 기록 운영 중이므로, analyze_events
  쪽은 향후 문서 분석에서 answerability 개념 도입 시 활용 예비.
- telemetry record_analyze_event 에 answerability / partial_basis /
  suggested_query_count 파라미터 확장.

기존 /ask 3-state completeness 로직 (classifier_service + 7-tier gate) 은
그대로 유지 — 이미 Phase 3.5a 에서 완성된 상태. B-2 는 LLM 부하 재분배와
관측성 확장에 집중.

MLX 부하 감소 효과: 이전엔 쿼리 1건당 evidence(26B) + synthesis(26B) 2번
MLX 호출. 이제는 evidence(4B Ollama) + synthesis(26B MLX) 로 MLX 호출 절반.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 10:33:32 +09:00

72 lines
3.4 KiB
Python

"""프롬프트/모델 버전 상수 — telemetry 기록용 (Phase E.1)
목적: ask_events / analyze_events 에 prompt_version 과 model_name 을 기록해서
튜닝 전/후 비교와 실험 분기를 식별 가능하게 함.
규칙:
- 프롬프트 파일이 의미 있게 바뀌면 해당 상수 문자열을 bump (예: v1-400char → v2-600char)
- 하드코딩 금지. 파이프라인은 여기 상수만 참조.
- 모델명은 런타임 config(settings.ai.primary.model)에서 읽어서 resolve_primary_model() 사용.
E.3 배포 타임라인:
- v1-400char → 현재 (search_synthesis.txt 17행 "400 characters max")
- v2-600char → E.3 배포 시 bump (동일 파일 "600 characters max")
"""
from __future__ import annotations
# ─── ask (/search/ask) 프롬프트 버전 ─────────────────────────
# synthesis_service.py 가 로드하는 app/prompts/search_synthesis.txt 기준
# v3-evidence-triage: evidence 추출을 triage(4B Ollama) 로 전환 (B-2). synthesis 는
# 여전히 primary(26B MLX) 로 search_synthesis.txt 사용. 프롬프트 자체는 v2-600char
# 그대로지만 evidence LLM 경로 변경을 분리 추적하기 위해 bump.
ASK_PROMPT_VERSION: str = "search_synthesis.v3-evidence-triage"
# ─── /analyze 프롬프트 버전 ──────────────────────────────────
# documents.py analyze 라우트가 로드하는 app/prompts/document_analyze.txt 기준
ANALYZE_PROMPT_VERSION: str = "document_analyze.v1"
# ─── PR-B B-1: summary tier 분할 task 이름 ─────────────────────
# classify_worker / deep_summary_worker 가 PR-A 정책 템플릿 + policy_version 해시
# 조합으로 analyze_events.prompt_version 을 기록한다. (예: "p3a_short_summary@abc123")
SUMMARY_TRIAGE_TASK: str = "p3a_short_summary" # 4B gemma Ollama
SUMMARY_DEEP_TASK: str = "p3c_deep_summary" # 26B MLX
def resolve_primary_model() -> str | None:
"""런타임 config에서 primary 모델명을 resolve.
settings.ai 가 미구성이면 None.
telemetry 기록은 None 허용 (측정 필드는 nullable).
"""
try:
from core.config import settings
if settings.ai and settings.ai.primary:
return settings.ai.primary.model
except Exception:
pass
return None
# ─── Policy-layer prompt version helper (PR-A) ──────────────────────
# domain_policy.yaml + 정책 template 의 결합 해시로 automatic version 산출.
# analyze_events.policy_version 컬럼에 기록되어 drift 추적.
#
# 기존 ASK_PROMPT_VERSION / ANALYZE_PROMPT_VERSION 상수는 그대로 유지 — PR-B 에서
# 정책 렌더된 프롬프트로 전환 시 compute_policy_version() 결과로 대체할지 병기할지 결정.
def compute_policy_version(
task: str, *, policy_path: str | None = None
) -> str:
"""sha256(yaml_bytes + template_bytes)[:12] — deterministic hash.
task: policy template 이름 (예: 'p3a_short_summary'). app/prompts/policy/ 하위.
policy_path: override (테스트용). None 이면 loader 기본값.
import 지연 — app.policy 는 아직 worker 경로에서 쓰지 않는다 (PR-A 런타임 격리).
"""
from policy.prompt_render import policy_version as _pv
return _pv(task, policy_path=policy_path)