PII 표시 토큰 누출 보정

This commit is contained in:
Yun Chan 2026-08-09 21:04:29 +09:00
parent 61a41d1f08
commit 7cece90e33
19 changed files with 284 additions and 197 deletions

View file

@ -376,7 +376,10 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
turn_seq=ctx.state_after.turn_seq,
stage=ctx.state_after.stage.value,
effective_openness=ctx.state_after.effective_openness,
client_reply="저는 김서연 씨고 한신대학교 상담심리학과 학생이에요.",
client_reply=(
"저는 김서연 씨고 한신대학교 상담심리학과 학생이에요. "
"여기서 뭘 해야 하는지 잘 모르겠는데요."
),
safety_flagged=False,
state_after=ctx.state_after,
llm_provider="claude_cli",
@ -395,19 +398,24 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(
response.client_reply,
"저는 김서연 씨고 한신대학교 상담심리학과 학생이에요.",
"저는 김서연 씨고 한신대학교 상담심리학과 학생이에요. "
"여기서 뭘 해야 하는지 잘 모르겠는데요.",
)
self.assertEqual(len(sess.turns), 2)
learner_turn, client_turn = sess.turns
self.assertIsNone(learner_turn.llm_provider)
self.assertEqual(
client_turn.text, "저는 김서연 씨고 한신대학교 상담심리학과 학생이에요."
client_turn.text,
"저는 김서연 씨고 한신대학교 상담심리학과 학생이에요. "
"여기서 뭘 해야 하는지 잘 모르겠는데요.",
)
self.assertNotIn("김서연", client_turn.text_masked)
self.assertNotIn("한신대학교", client_turn.text_masked)
self.assertNotIn("상담심리학과", client_turn.text_masked)
self.assertIn("[NAME]", client_turn.text_masked)
self.assertIn("[ORG]", client_turn.text_masked)
self.assertIn("잘 모르겠는데요", client_turn.text_masked)
self.assertNotIn("[NAME]는데요", client_turn.text_masked)
self.assertEqual(client_turn.llm_provider, "claude_cli")
self.assertEqual(client_turn.model, "gateway-default")
self.assertEqual(client_turn.tokens_in, 17)
@ -991,6 +999,7 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
latency_ms=12,
query_text="정리 humanistic 자살 위험 최근성 보호요인",
)
retrieve_grounding = AsyncMock(return_value=retrieval)
with (
patch.object(
@ -999,13 +1008,16 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
patch.object(
sessions.rag,
"retrieve_eval_grounding",
AsyncMock(return_value=retrieval),
retrieve_grounding,
),
patch.object(sessions.rag, "log_retrieval", AsyncMock()),
):
grounding = await sessions._retrieve_live_coach_grounding(
learner_text="자살 위험 최근성과 보호요인을 확인했어요.",
client_reply="그래도 오늘은 친구에게 연락할 수 있어요.",
client_reply=(
"박민수에게 연락할지 잘 모르겠는데요. 그래도 오늘은 "
"친구에게 연락할 수 있어요."
),
stage="정리",
theory_mode="humanistic",
)
@ -1017,6 +1029,11 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(source.source_type, "official_guideline_summary")
self.assertEqual(source.version, "2026-06-15")
self.assertEqual(source.citation, "허가된 공식 지침 요약")
query = retrieve_grounding.await_args.kwargs["query"]
self.assertNotIn("박민수", query)
self.assertIn("[NAME]에게", query)
self.assertIn("잘 모르겠는데요", query)
self.assertNotIn("[NAME]는데요", query)
async def test_live_coach_persistence_failure_is_not_swallowed(self) -> None:
principal = _principal()