본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 01. 19:08

데이터 추출을 위해 정규표현식(regex)과 싸우는 것을 멈추다. AI가 제 정신을 구한 방법

요약

비정형 텍스트에서 데이터를 추출할 때 정규표현식 대신 AI를 활용하여 효율성을 높이는 방법을 다룹니다. gpt-4o-mini를 활용한 데이터 추출 사례와 함께 일관성 유지 및 환각 방지를 위한 실무적인 팁을 제공합니다.

핵심 포인트

  • Enum을 사용하여 모델 출력의 일관성 강제
  • 누락된 값에 대한 우아한 기본값 처리 전략
  • 시스템 프롬프트를 통한 환각(Hallucination) 완화
  • 지연 시간 단축을 위한 배치(Batching) 처리 기법
  • 정규표현식이 더 유리한 상황과 보안 고려사항

저도 그런 경험이 있습니다. 정리되지 않은, 지저분한 텍스트 더미—지원 티켓, 회의록, 고객 이메일—를 가지고 있고, 특정 필드를 추출해야 합니다. 아마도 티켓 우선순위, 제품 이름 또는 마감일 같은 것일 수 있죠. 첫 번째 본능은 정규표현식(regex)입니다. 처음 10개 케이스에서는 작동합니다. 하지만 11번째에서 모든 것이 무너집니다.

저는 아름다운 정규표현식 패턴을 만드는 데 이틀을 보냈지만, 약간 다른 구문만 만나면 실패하는 것을 지켜봐야 했습니다. 마치 파이썬 콘솔 속의 시시포스 같다고 느꼈습니다. 그때 마침내 포기하고 AI에게 무거운 작업을 맡겼습니다.

패턴 매칭의 고통

저는 여러 채널에서 가져온 원본 지원 티켓을 수집하는 대시보드를 만들고 있었습니다. 각 티켓은 구조화되지 않은 본문을 가지고 있었지만, 다음 항목들을 추출해야 했습니다:

  • 우선순위 (Priority) (high/medium/low)
  • 카테고리 (Category) (billing, technical, feature request)
  • 담당 에이전트 (Assigned agent)

티켓은 Slack, 이메일, 웹 양식에서 왔습니다. 각 소스마다 고유한 특징이 있었습니다. 사람들은

이것은 깔끔하고, 예측 가능하며, 저렴합니다. 일반적인 티켓(약 200 토큰)의 경우, gpt-4o-mini의 비용은 1센트의 아주 작은 일부에 불과합니다. 그리고 출력된 결과는 데이터베이스에 바로 삽입할 수 있는 상태가 됩니다.

고통스럽게 배운 교훈들

1. 열거형(Enums)을 명시적으로 사용하라

모델이 우선순위(priority)를 자유 형식의 텍스트(free-text)로 작성하게 두면, "critical", "high", "urgent", "asap" 등 다양한 값이 들어옵니다. enum을 통해 제한함으로써 일관성을 강제할 수 있습니다.

2. 누락된 값을 우아하게 처리하라

제가 assignee(담당자)를 필수 항목으로 만들지 않았다는 점에 주목하십시오. 텍스트에 아무도 언급되지 않았다면, 모델은 해당 항목을 생략합니다. 그러면 후속 코드(downstream code)에서 이를 "unassigned"(미할당)로 기본 설정할 수 있습니다.

3. 환각(Hallucination) 데이터를 주의하라

가끔 모델이 그럴듯해 보이지만 틀린 우선순위를 지어내기도 합니다. 저는 다음과 같은 방법으로 이를 완화합니다:

  • 명시적으로 언급된 내용만 추출 (시스템 프롬프트 사용: "텍스트에 명확하게 명시된 경우에만 추출하십시오")
  • 2차 검증 실행 (예: 우선순위가 "high"로 나왔지만 텍스트 어디에도 "high"라는 단어가 없다면 플래그를 표시)

4. 지연 시간(Latency)과 배치(Batching)

각 호출에는 약 1초가 소요됩니다. 1,000개의 티켓이라면 17분이 걸립니다. 속도가 필요하다면 단일 호출에 여러 티켓을 배치로 묶으십시오 (프롬프트: "다음 5개의 티켓에서 데이터를 추출하여 JSON 배열로 반환하십시오"). 주의해서 테스트해야 합니다. 데이터가 서로 섞이는(cross-contamination) 현상을 본 적이 있습니다.

이 접근 방식을 사용하지 말아야 할 때

  • 고처리량, 저복잡도(High-throughput, low-complexity) – 고정된 형식에서 단순한 ID를 추출하는 경우라면 정규표현식(regex)이 더 빠르고 저렴합니다.
  • 오프라인 또는 폐쇄망(Air-gapped) 환경 – API 접근 권한이 필요합니다. 로컬 모델(local models)도 있지만, 더 느리고 정확도가 떨어집니다.
  • 매우 민감한 데이터 – 모든 데이터를 OpenAI로 보내는 것은 컴플라이언스(compliance)를 위반할 수 있습니다. 자체 호스팅 모델이나 AI Interwest Info와 같이 프라이빗 엔드포인트(private endpoints)를 제공하는 서비스를 고려하십시오. (유사한 사례에서 테스트해 보았는데, 공개 API를 사용할 수 없는 상황이라면 잘 작동합니다.)

다음에 다시 한다면 다르게 할 점

함수 호출(Function calling) 없이 JSON을 직접 출력하는 간단한 프롬프트로 시작할 것입니다. 함수 호출이 더 깔끔하긴 하지만, MVP(최소 기능 제품) 단계에서는 다음과 같이 할 수 있습니다:

"이 티켓에서 우선순위(high/medium/low), 카테고리, 담당자를 추출하세요. JSON 형식으로만 반환하세요: {}"

그다음 json.loads()를 사용하여 파싱합니다. 이는 90%의 경우에 잘 작동합니다. 대규모 환경에서 엄격한 스키마 강제(strict schema enforcement)가 필요할 때만 함수 호출(function calling) 기능을 추가하세요.

또한, 추출 코드를 작성하기 전에 50개 정도의 엣지 케이스(edge-case) 티켓으로 구성된 작은 테스트 스위트(test suite)를 구축하는 데 투자할 것입니다. 그렇게 하면 프롬프트를 빠르게 반복 개선하고 정확도를 평가할 수 있습니다.

마치며

AI가 저를 대체한 것이 아닙니다. AI는 제가 작성하던 지루하고 취약한 패턴들을 대체했습니다. 이제 저는 쉼표 하나가 빠졌다고 폭발해버리는 정규표현식(regex)을 디버깅하는 대신, 스키마(schema)를 정의하고 출력을 검증하는 데 시간을 보냅니다.

엉망인 텍스트에서 구조화된 데이터(structured data)를 추출하기 위해 여러분이 주로 사용하는 방법은 무엇인가요? 여전히 정규표현식(regex) 열차를 타고 계신가요, 아니면 AI 방식으로 갈아타셨나요?

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0