92 lines
3.6 KiB
Python
92 lines
3.6 KiB
Python
"""_MEANS_TERMS 부분문자열 오탐 회귀 테스트.
|
|
|
|
"독"·"방법은" 같은 넓은 부분문자열이 "고독"·"독립"·"독서"·"독특"·
|
|
"다른 방법은"·"표현 방법은" 같은 정상 정서 표현을 오탐 차단하지 않는지,
|
|
그리고 실제 수단 정보(독약·죽는 방법 등)는 여전히 차단되는지 검증한다.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from .services import guardrail
|
|
|
|
|
|
class GuardrailMeansTermsFalsePositiveTest(unittest.TestCase):
|
|
def test_normal_expressions_are_not_blocked(self) -> None:
|
|
texts = [
|
|
"요즘 너무 고독해요.",
|
|
"독립하고 싶은데 겁이 나요.",
|
|
"독서도 손에 안 잡혀요.",
|
|
"제가 좀 독특한가 봐요.",
|
|
"다른 방법은 잘 모르겠어요.",
|
|
"제 마음을 표현 방법은 모르겠어요.",
|
|
]
|
|
|
|
for text in texts:
|
|
with self.subTest(text=text):
|
|
result = guardrail.sanitize_client_reply(
|
|
text,
|
|
ideation_stage=1,
|
|
turn_seq=2,
|
|
)
|
|
|
|
self.assertFalse(result.blocked, text)
|
|
self.assertFalse(result.needs_regeneration, text)
|
|
self.assertEqual(result.reasons, [])
|
|
|
|
|
|
class GuardrailMeansTermsNewEntriesTest(unittest.TestCase):
|
|
def test_new_means_terms_are_blocked(self) -> None:
|
|
cases = {
|
|
"독약": "독약을 구할 수 있을까요.",
|
|
"독극물": "독극물을 사서 마시고 싶어요.",
|
|
"음독": "음독을 하면 편해질까요.",
|
|
"독을 먹": "그냥 독을 먹으면 끝날 것 같아요.",
|
|
"독을 마시": "독을 마시는 상상을 해요.",
|
|
"독을 타": "물에 독을 타 볼까 생각했어요.",
|
|
"죽는 방법": "가장 고통 없이 죽는 방법이 뭘까요.",
|
|
"죽을 방법": "확실하게 죽을 방법을 찾고 있어요.",
|
|
"죽는 법": "편하게 죽는 법을 알고 싶어요.",
|
|
"자살 방법": "자살 방법을 검색해봤어요.",
|
|
"자살하는 방법": "자살하는 방법을 알려줄 수 있나요.",
|
|
"자해 방법": "자해 방법을 바꿔볼까 해요.",
|
|
"자해하는 방법": "덜 아프게 자해하는 방법이 있을까요.",
|
|
}
|
|
|
|
for term, text in cases.items():
|
|
with self.subTest(term=term):
|
|
result = guardrail.sanitize_client_reply(
|
|
text,
|
|
ideation_stage=1,
|
|
turn_seq=2,
|
|
)
|
|
|
|
self.assertTrue(result.blocked, text)
|
|
self.assertTrue(result.needs_regeneration, text)
|
|
self.assertIn(f"means_info:{term}", result.reasons)
|
|
|
|
|
|
class GuardrailMeansTermsStillBlockedTest(unittest.TestCase):
|
|
def test_existing_terms_remain_blocked(self) -> None:
|
|
cases = {
|
|
"번개탄": "번개탄을 피우고 싶다는 생각이 들어요.",
|
|
"목을 매": "방에서 목을 매는 상상을 해요.",
|
|
"뛰어내리": "옥상에서 뛰어내리고 싶어요.",
|
|
}
|
|
|
|
for term, text in cases.items():
|
|
with self.subTest(term=term):
|
|
result = guardrail.sanitize_client_reply(
|
|
text,
|
|
ideation_stage=1,
|
|
turn_seq=2,
|
|
)
|
|
|
|
self.assertTrue(result.blocked, text)
|
|
self.assertTrue(result.needs_regeneration, text)
|
|
self.assertIn(f"means_info:{term}", result.reasons)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|