fix: 판례 판단 시 사람 검토 안전장치 강제
This commit is contained in:
parent
3debc884c1
commit
91e356e4c1
@ -203,8 +203,6 @@ class LegalRiskEngine:
|
|||||||
unknown = set(decision.matched_precedent_ids) - allowed
|
unknown = set(decision.matched_precedent_ids) - allowed
|
||||||
if unknown:
|
if unknown:
|
||||||
raise ValueError(f"LLM이 제공되지 않은 판례 ID를 반환함: {sorted(unknown)}")
|
raise ValueError(f"LLM이 제공되지 않은 판례 ID를 반환함: {sorted(unknown)}")
|
||||||
if not decision.review_required:
|
|
||||||
raise ValueError("LLM legal judge는 사람 검토를 해제할 수 없습니다")
|
|
||||||
if decision.verdict == "likely" and not decision.matched_precedent_ids:
|
if decision.verdict == "likely" and not decision.matched_precedent_ids:
|
||||||
raise ValueError("침해 의심 의견에는 근거 판례 ID가 최소 1개 필요합니다")
|
raise ValueError("침해 의심 의견에는 근거 판례 ID가 최소 1개 필요합니다")
|
||||||
merged_missing = tuple(dict.fromkeys([
|
merged_missing = tuple(dict.fromkeys([
|
||||||
@ -217,6 +215,7 @@ class LegalRiskEngine:
|
|||||||
"judgment_method": "llm",
|
"judgment_method": "llm",
|
||||||
"llm_verdict": decision.verdict,
|
"llm_verdict": decision.verdict,
|
||||||
"llm_confidence": decision.confidence,
|
"llm_confidence": decision.confidence,
|
||||||
|
# 모델 출력과 관계없이 서비스의 사람 검토 안전장치는 항상 유지한다.
|
||||||
"llm_review_required": True,
|
"llm_review_required": True,
|
||||||
"llm_matched_precedent_ids": decision.matched_precedent_ids,
|
"llm_matched_precedent_ids": decision.matched_precedent_ids,
|
||||||
"supporting_reasons": decision.supporting_reasons,
|
"supporting_reasons": decision.supporting_reasons,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from pydantic import BaseModel, ConfigDict, Field
|
|||||||
from app.engine.legal_risk import LegalJudgeDecision, LegalJudgeInput
|
from app.engine.legal_risk import LegalJudgeDecision, LegalJudgeInput
|
||||||
|
|
||||||
|
|
||||||
PROMPT_VERSION = "legal-judge-v2"
|
PROMPT_VERSION = "legal-judge-v3"
|
||||||
|
|
||||||
|
|
||||||
class _JudgeOutput(BaseModel):
|
class _JudgeOutput(BaseModel):
|
||||||
@ -22,7 +22,7 @@ class _JudgeOutput(BaseModel):
|
|||||||
supporting_reasons: list[str]
|
supporting_reasons: list[str]
|
||||||
counter_reasons: list[str]
|
counter_reasons: list[str]
|
||||||
missing_factors: list[str]
|
missing_factors: list[str]
|
||||||
review_required: bool
|
review_required: Literal[True]
|
||||||
|
|
||||||
|
|
||||||
SYSTEM_PROMPT = """당신은 대한민국 저작권 판례 비교 검토 보조자다.
|
SYSTEM_PROMPT = """당신은 대한민국 저작권 판례 비교 검토 보조자다.
|
||||||
@ -37,6 +37,7 @@ insufficient_evidence는 탐지된 표현 증거나 관련 판례가 부족해
|
|||||||
유사도 점수는 침해 확률이 아니다. 보호되는 표현, 의거관계, 권리 귀속 및
|
유사도 점수는 침해 확률이 아니다. 보호되는 표현, 의거관계, 권리 귀속 및
|
||||||
이용허락 사실이 없으면 missing_factors에 명시한다.
|
이용허락 사실이 없으면 missing_factors에 명시한다.
|
||||||
근거와 반대 근거는 검토자가 확인할 수 있는 짧은 사실 문장으로 작성한다.
|
근거와 반대 근거는 검토자가 확인할 수 있는 짧은 사실 문장으로 작성한다.
|
||||||
|
review_required는 항상 true로 반환한다.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
1. 등록 코퍼스에서 유사 문서와 증거 구간을 찾는다.
|
1. 등록 코퍼스에서 유사 문서와 증거 구간을 찾는다.
|
||||||
2. `LegalRiskEngine`이 저작물 유형과 법적 태그로 등록 판례 Top 5를 고른다.
|
2. `LegalRiskEngine`이 저작물 유형과 법적 태그로 등록 판례 Top 5를 고른다.
|
||||||
3. GPT Judge가 탐지 증거와 Top 5 판례만 비교한다.
|
3. GPT Judge가 탐지 증거와 Top 5 판례만 비교한다.
|
||||||
4. 서버가 Structured Outputs 스키마, 판례 ID, `review_required=true`를 검증한다.
|
4. 서버가 Structured Outputs 스키마와 판례 ID를 검증하고, 사람 검토가 해제되지 않도록 `review_required=true`를 강제한다.
|
||||||
5. 호출 실패·형식 오류·미등록 판례 ID가 있으면 규칙 기반 결과로 복귀한다.
|
5. 호출 실패·형식 오류·미등록 판례 ID가 있으면 규칙 기반 결과로 복귀한다.
|
||||||
|
|
||||||
GPT는 전체 판례 545건을 한 번에 받지 않으며 법률상 침해를 확정하지 않는다.
|
GPT는 전체 판례 545건을 한 번에 받지 않으며 법률상 침해를 확정하지 않는다.
|
||||||
|
|||||||
@ -104,15 +104,15 @@ def test_llm_hallucinated_precedent_id_falls_back_to_rules():
|
|||||||
assert "GPT" not in (result.judge_note or "")
|
assert "GPT" not in (result.judge_note or "")
|
||||||
|
|
||||||
|
|
||||||
def test_llm_cannot_disable_human_review():
|
def test_server_keeps_human_review_even_if_judge_returns_false():
|
||||||
result = LegalRiskEngine([_case()], judge=_FakeJudge(review_required=False)).assess(
|
result = LegalRiskEngine([_case()], judge=_FakeJudge(review_required=False)).assess(
|
||||||
max_similarity=0.9,
|
max_similarity=0.9,
|
||||||
coverage=0.5,
|
coverage=0.5,
|
||||||
longest_span=200,
|
longest_span=200,
|
||||||
legal_tags=["reproduction"],
|
legal_tags=["reproduction"],
|
||||||
)
|
)
|
||||||
assert result.judgment_method == "rule_fallback"
|
assert result.judgment_method == "llm"
|
||||||
assert result.llm_review_required is None
|
assert result.llm_review_required is True
|
||||||
|
|
||||||
|
|
||||||
def test_likely_judgment_without_precedent_id_falls_back():
|
def test_likely_judgment_without_precedent_id_falls_back():
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user