본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 05. 19:27

0유로로 E2E 테스트 스위트에 법적 준수 체크 기능을 추가했습니다. 방법과 (개발자가 아닌 제가 왜 해야만 했는지에 대한) 이유를 소개합니다.

요약

헬스 AI 플랫폼 운영자가 Playwright E2E 테스트 스위트에 비용 없이 법적 준수 체크 기능을 통합한 사례를 소개합니다. 서버 측 필터링을 넘어 실제 라이브 사이트의 렌더링 결과물에서 규제 위반 언어를 자동으로 탐지하는 방법을 다룹니다.

핵심 포인트

  • Playwright를 활용한 E2E 테스트 기반의 컴플라이언스 스캐너 구축
  • 서버 필터링과 별개로 실제 라이브 페이지의 렌더링 결과 검증 필요성
  • LLM 없이 0유로 비용으로 규제 위반 리스크 최소화
  • 의료 규제(GDPR, IGJ 등) 준수를 위한 자동화된 테스트 파이프라인 구축

0유로로 E2E 테스트 스위트에 법적 준수 체크 기능을 추가했습니다. 방법과 (개발자가 아닌 제가 왜 해야만 했는지에 대한) 이유를 소개합니다.

저는 개발자가 아닙니다. 네덜란드에서 Longevity AI라는 헬스 AI 플랫폼을 운영하고 있습니다. 이 플랫폼은 LLM (Large Language Models)을 사용하여 개인화된 건강 보고서를 생성하고, 장수에 관한 블로그 게시물을 자동으로 발행하며, 네덜란드의 의료 규제인 IGJ (보건 및 청소년 케어 감독국), Wet BIG, 그리고 GDPR (일반 데이터 보호 규정)의 적용을 받습니다.

마지막 부분이 바로 대부분의 빌더(Builder)들이 건너뛰는 부분입니다. 하지만 저는 그럴 수 없습니다.

만약 제 플랫폼이 "이 영양제가 당신의 질환을 치료합니다" 또는 "복용 중인 약을 중단하세요"와 같은 콘텐츠를 게시한다면, 제가 직면할 문제는 나쁜 SEO (검색 엔진 최적화)가 아닙니다. 바로 IGJ의 집행 조치입니다. 네덜란드 보건 규제 기관은 정확히 이런 종류의 언어 사용 때문에 플랫폼을 폐쇄한 사례가 있습니다. 저는 이 문제만을 위해 코드베이스에 risks.md라는 파일을 별도로 가지고 있습니다.

오늘 저는 규제 산업에서 활동하는 모든 이들에게 유용할 것이라 생각되는 것을 배포했습니다. 바로 저의 Playwright E2E (End-to-End) 테스트 스위트에 직접 내장된 컴플라이언스 스캐너 (Compliance Scanner)입니다. 이것은 모든 배포(Deploy) 시마다 실행됩니다. 비용은 0유로입니다. LLM을 사용하지도 않습니다.

이것이 무엇을 하는지, 그리고 왜 이런 방식으로 구축했는지 설명하겠습니다.

Illustratie bij I Added Legal Compliance Checks to My E2E Test Suite for €0. Here's How (and Why a Non-Developer Had To).

문제점: AI 생성 콘텐츠는 금지된 언어 쪽으로 표류합니다

제 플랫폼은 Autopilot News Radar라고 불리는 야간 파이프라인을 실행합니다. 이 파이프라인은 BBC Health, PubMed, EFSA, 그리고 ClinicalTrials에서 정보를 가져온 다음, 3개 국어(NL/EN/FR)로 된 블로그 게시물을 자동으로 생성합니다. 게시물은 저장되기 전에 서버 측 컴플라이언스 스캐너를 거칩니다.

그 스캐너는 제대로 작동합니다. 게시물이 라이브(Live)되기 전에 위반 사항을 잡아낸 적이 있습니다.

하지만 저에게는 공백이 있었습니다. _실제 라이브 사이트(actual live site)_를 대상으로 실행되는 자동화된 체크가 없었습니다. 서버 필터가 게시물을 통과시키더라도, 렌더링(rendering), 캐싱(caching) 과정에서의 예외 케이스나 수동 게시(manual publish)로 인해 금지된 언어가 페이지에 노출될 수 있었습니다. 저는 사용자가 이를 신고하거나, 더 최악의 경우 규제 기관이 신고할 때까지 그 사실을 알 수 없었습니다.

해결책: compliance.spec.ts

저는 라이브 사이트에서 실제 페이지를 가져와 서버에서 사용하는 것과 동일한 정규 표현식(regex) 패턴을 실행하는 네 가지 Playwright 테스트를 추가했습니다.

// tools/muraqib/tests/compliance.spec.ts (간략화 버전)

const HIGH_SEVERITY_PATTERNS = [
...

API 호출도 없습니다. LLM(대규모 언어 모델)도 없습니다. 실제 브라우저에 의해 실행되며, 라이브로 렌더링된 HTML에 대해 정규 표현식(regex) 스캔을 수행합니다.

왜 LLM이 아니라 정규 표현식(regex)인가?

결정론적(determinism)인 결과와 비용 제로(zero cost)가 필요하기 때문입니다.

LLM 기반의 컴플라이언스(compliance) 체크는 다음과 같은 문제가 있습니다:

  • 배포할 때마다 비용이 발생합니다 (저는 배포당 130개의 테스트를 매일 밤 실행합니다)
  • 비결정론적(non-deterministic)입니다 (동일한 텍스트임에도 재실행 시 답변이 달라질 수 있음)
  • 블랙박스(black box)입니다 ("AI가 괜찮다고 했습니다"는 감사 추적(audit trail)이 될 수 없습니다)

제가 체크하는 패턴들은 미묘한 것이 아닙니다. IGJ는 미묘한 어조를 찾는 것이 아닙니다. 그들은 "genezingsclaims"(치료 주장)나 약물 복용 중단 권고와 같은 것들을 찾습니다. 정규 표현식(regex)은 이를 정확하고 저렴하게 처리합니다.

이중 계층 아키텍처 (The double-layer architecture)

[AI가 콘텐츠 생성]
        |
        v
...

첫 번째 계층이 실패하면(서버 버그, 수동 오버라이드, 예외 케이스), 두 번째 계층이 배포가 완료되기 전에 이를 잡아냅니다. 만약 두 번째 계층이 무언가를 잡아내면, GitHub Actions가 실패하고 저에게 알림이 옵니다.

Illustratie bij I Added Legal Compliance Checks to My E2E Test Suite for €0. Here's How (and Why a Non-Developer Had To).

네 가지 컴플라이언스 테스트

높은 심각도(HIGH-severity) 체크 외에도, 테스트 스위트는 다음을 실행합니다:

  1. Blog overview loads -- /blog 페이지가 최소 하나 이상의 기사와 함께 렌더링되는지 확인하는 새니티 체크 (sanity check)
  2. No HIGH violations -- 라이브 페이지에서 치료 주장(cure claims) 및 약물 중단 권고(medication-stop advice)가 없는지 확인
  3. No em-dashes in public text -- 내부 스타일 가이드(house style rule)를 자동으로 강제 적용
  4. Affiliate disclosure present -- 제휴 링크(affiliate links)가 포함된 블로그에는 반드시 고지 문구(disclosure sentence)가 포함되어야 함

마지막 항목은 네덜란드에서도 법적 요구 사항입니다. 만약 제가 제휴 참조(affiliate ref)가 포함된 보충제 링크를 건다면, 이를 반드시 고지해야 합니다. 이 테스트는 제휴 링크가 포함된 모든 페이지에 고지 텍스트가 존재하는지 확인합니다.

잡아내지 못하는 것들

한계점에 대해 솔직해지고 싶습니다.

MEDIUM-severity(중간 심각도) 위반 사항은 수동으로 처리합니다. 모호하게 암시된 효능 주장(implied efficacy claims)은 문맥에 따라 다릅니다. 제 서버 스캐너가 이를 식별하고 로그를 남기면, 사람(저)이 매주 로그를 검토합니다. MEDIUM 등급에 대해 자동 차단(Automated blocking)을 적용하면 너무 많은 오탐(false positives)이 발생합니다.

문맥을 이해하지 못합니다. 약을 중단해서는 _안 된다_는 이유를 설명하는 인용문 안에 "Stop je medicatie"라는 문구가 있다면, 여전히 패턴이 트리거됩니다. 저는 해당 문구 자체를 완전히 피하는 방식으로 콘텐츠를 작성하여 이 문제를 해결했습니다.

법적 의견이 아닙니다. 이 패턴들은 문서화된 컴플라이언스(compliance) 연구를 기반으로 합니다. 이는 변호사가 콘텐츠를 검토하는 것을 대체할 수 없습니다.

오늘 함께 배포된 항목: AI Coach 테스트

컴플라이언스 사양과 함께, AI Coach 기능을 위한 8가지 테스트인 coach.spec.ts도 추가했습니다:

  • 로그인 게이트(Login gate): 인증되지 않은 사용자는 채팅 인터페이스가 아닌 CTA(Call to Action)를 보게 됨
  • 메시지 전송 및 타임아웃(timeout) 내 응답 수신
  • 엔터 키 제출 (이전에 한 번 조용히 작동이 중단된 적이 있음)
  • 빈 입력 시 전송 버튼 비활성화 (빈 API 호출 방지)
  • 피드백 버튼 (좋아요/싫어요)이 올바르게 작동하는지 확인
  • 보고서 페이지로의 뒤로 가기 탐색
  • 전체 대화 과정 중 JavaScript 콘솔 에러 0건

마지막 항목이 제가 가장 신뢰하는 테스트입니다. 전체 사용자 흐름(user flow)에 대한 제로 콘솔 에러(zero-console-error) 체크는 유닛 테스트(unit test)가 찾아내지 못하는 부류의 버그를 잡아냅니다.

현재 Muraqib의 상태

SEO, sitemap, robots.txt, 블로그 렌더링 (blog rendering), anamnesis flow, 실험실 분석 (lab analysis), 온보딩 (onboarding), AI Coach, 그리고 컴플라이언스 (compliance)에 이르기까지 총 130개의 테스트가 있습니다. 이 테스트 스위트는 Playwright 1.60.0과 네이티브 Healer를 사용하여 GitHub Actions에서 실행됩니다. Healer는 DOM이 변경될 때 깨지는 로케이터 (locators)를 자동으로 복구합니다.

오늘 이전오늘 이후
총 테스트 수118130
...

모든 배포 (deploy) 시 130개의 테스트가 모두 실행됩니다. 초록색 체크는 실제 브라우저가 플랫폼을 탐색하며 아무런 문제도 발견하지 못했음을 의미합니다. 빨간색 체크는 사용자가 확인하기 전에 무언가 고장 났음을 의미합니다.

여기서 소유권이 중요한 이유

SaaS 컴플라이언스 모니터링 도구들이 존재합니다. 하지만 그 도구들은 모두 구독 모델을 통해 나의 법적 패턴 (legal patterns)을 벤더 (vendor)의 시스템 안에 가둡니다.

나의 패턴들은 tools/muraqib/tests/compliance.spec.ts에 존재합니다. 이들은 git에 있으며, 커밋 히스토리 (commit history)를 가지고 있습니다. IGJ가 집행 지침을 업데이트하면, 나는 한 줄을 추가하고 커밋하면 됩니다. 그러면 다음 배포 시 업데이트된 체크 사항이 실행됩니다.

이것이 테스트 인프라를 직접 소유해야 하는 실질적인 이유입니다. 당신의 비즈니스에 가장 중요한 규칙들은 당신이 직접 확인하고, 변경하고, 감사 (audit)할 수 있는 곳에 있어야 합니다.

Longevity AI는 longevityai.nl에서 운영됩니다. 규제 산업에서 헬스 SaaS를 구축하고 있으며 의견을 나누고 싶다면, 사이트를 통해 연락해 주세요.

이 기사는 원래 Longevity AI에 게시되었습니다. 전체 맥락, 참조 및 토론을 확인하려면 원문을 방문하세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0