안녕하세요, 포스 삼촌이에요.
최근 저희 '나연스떼' 요가 센터 2호점 오픈 준비로 정신없는 나날을 보내고 있습니다. 웰니스와 데이터 테크의 결합을 지향하는 만큼, 이번에 아주 야심 찬 프로젝트를 하나 기획했거든요.
바로 요가 센터의 수많은 비정형 문서(강사 및 강습 가이드북, 아사나 시퀀스 PDF, 회원 건강 특이사항 수기 기록 등)를 완벽하게 학습해서 회원들에게 1:1 맞춤형 웰니스 가이드를 제공하는 '나연스떼 AI 에이전트' 빌드업입니다.
이 멋진 에이전트를 만드는 과정에서 겪은 기술적 고민과, 스노우플레이크가 제공하는 강력한 무기들을 소개합니다.
🧘♀️ 1. "AI가 자꾸 엉뚱한 요가 자세를 알려줘요!" (RAG의 필요성)
처음엔 똑똑하다는 요즘 AI에 냅다 질문을 던져봤습니다.
"우리 요가 센터의 '프라나 플로우 2단계' 수업 특징과 주의사항이 뭐야?"
돌아온 대답은 황당했어요.
인터넷에 떠도는 온갖 요가 정보를 짜집기해서 존재하지도 않는 엉뚱한 가짜 시퀀스를 지어내더군요. 테크 용어로 이를 할루시네이션(Hallucination, 환각 현상)이라고 합니다.
조직에서 AI를 실무에 도입할 때 이 환각 현상은 치명적입니다. 회원의 건강이 걸린 요가 센터라면 더더욱 그렇겠죠?
이를 해결하기 위해 우리 조직의 "진짜 내부 문서(Single Source of Truth)"를 AI에게 참고서로 쥐여주고, 그 내용을 바탕으로 조회•분석하여 대답하게 만드는 기술이 바로 RAG(Retrieval-Augmented Generation, 검색 증강 생성)입니다. 할루시네이션을 최소화하기 위해 기업들이 반드시 도입해야 하는 핵심 기술이죠.
📑 2. 문제는 '비정형 문서'를 읽어 들이는 것부터 시작된다
RAG를 만드려면 일단 요가센터 구석에 쌓인 PDF 가이드북이나 강습 시간표, 강사들의 노하우가 적힌 문서들을 데이터베이스에 예쁘게 쑤셔 넣어야(Ingestion) 합니다.
하지만 PDF 안에는 텍스트만 있는 게 아닙니다. 동작을 설명하는 표(Table)도 있고, 골격 다이어그램 이미지도 들어있죠. 이걸 단순 텍스트로 긁어오면 구조가 다 깨져서 AI가 맥락을 이해하지 못합니다.
이때 우리를 구원해 줄 스노우플레이크의 완전 관리형 AI 함수가 등장합니다. 바로 AI_PARSE_DOCUMENT입니다.
-- S3에 들어있는 요가 교안 PDF를 깔끔하게 파싱하기
SELECT AI_PARSE_DOCUMENT(
TO_FILE('@yoga_pdf_stage', 'prana_guide.pdf'),
{'mode': 'LAYOUT'}
);
이 함수를 쓰면 스노우플레이크가 백그라운드에서 알아서 PDF 속 표의 구조와 문맥을 완벽하게 유지한 채 깨끗한 텍스트로 파싱해 줍니다. 개발자가 일일이 파이썬 라이브러리 들고 파싱 노가다를 할 필요가 전혀 없는 완전 관리형(Fully Managed) 서비스죠.
(참고: 공식 문서에는 한글 지원 여부가 명시되어 있지 않지만, 실제 테스트해 보면 한글 문서도 꽤 훌륭하게 작동합니다!)
⚔️ 3. AI_PARSE_DOCUMENT VS AI_COMPLETE (적재적소에 무기 쓰기)
| 비교 항목 | 🛠️ AI_PARSE_DOCUMENT | 🤖 AI_COMPLETE |
| 핵심 역할 | 비정형 문서(PDF, 이미지 등)를 읽어서 데이터화하기 | 질문을 던져서 답변을 생성(Complete)하기 |
| 나연스떼 적용 | 원천 PDF 교안을 읽어 텍스트 데이터로 변환 | 변환된 데이터를 기반으로 회원 질문에 답변 생성 |
| 비유하자면 | 칠판에 적힌 복잡한 교안을 노트에 정리하는 비서 | 정리된 노트를 보고 회원들에게 상담해 주는 강사 |
RAG 파이프라인에서 전반부에서는 `AI_PARSE_DOCUMENT`가 비정형 데이터를 정형화하는 역할을 하고, 그렇게 이쁘게 정제된 데이터를 기반으로 사용자의 질문에 똑똑하게 대답하는 후반부(답변 생성)은 `AI_COMPLETE`가 담당하는 것이 일반적이에요.
다만, 나연스떼의 문서들은 모두 한글이므로, 한글을 처리하는 경우에는 AI_PARSE_DOCUMENT와 AI_COMPLETE를 함께 사용해서 품질을 확인해볼 수 있어요. 예를 들면 LLM 모델을 활용하여 AI_PARSE_DOCUMENT가 pdf 파일을 읽듯이, AI_COMPLETE를 이용해서 문서를 파싱할 수 있어요. 문서의 복잡도나 표의 형식에 따라 두 방식을 적절히 비교해 보고 최적의 파이프라인을 선택하는 것을 추천합니다. :)
자, 백문이불여일타!
아래와 같은 나연스떼의 내부 문서를 2가지 방법을 통해서 추출해보자구요.
1.1 AI_PARSE_DOCUMENT 함수의 OCR 모드
-- [OCR 모드] 텍스트만 추출. 스캔된 문서, 계약서, 보험 청구서에 적합
SELECT AI_PARSE_DOCUMENT(
TO_FILE('@STG_NY_PDF', 'PRANALINK_NYST2_guideline_v2.pdf'),
{'mode': 'OCR'}
) AS ocr_result;
1.1 결과는 OCR 모드로 추출한 문서의 결과에요.
표로 되어 있는 3조 부분을 살펴보면, 보시다시피 줄바꿈과 셀 구분이 완전히 엉망진창이 되었어요. '블록/볼스터 필수 지급'이라는 조치사항이 엉뚱한 위치로 튀어나가고, 표의 행과 열 개념이 통째로 날아갔죠.
제3조 (회원 건강 특이사항별 아사나 제한 및 대체 규정)
지도 강사는 수업 시작 전 반드시 '회원 건강 차트'를 열람하고, 특정 질환을 보유한 회원에게는 아래 표의 [절대 금기 동작]을 엄격
히 배제하고 [대체 시퀀스]를 적용해야 한다.
구분 코드 건강 특이사항 (질환) 절대 금기 동작
(Contraindication) 대체 권장 시퀀스 강사 현장 조치
블록/볼스터 필수
MED-01 요추 추간판 탈출증 • 부장가아사나 (완전 후굴) • 스핑크스 자세 (하부 요추 보 지급,
(허리 디스크) • 우스트라아사나 (낙타 자세) 호)
• 살람바 발라아사나 골반 지면 밀착 감
시
• 살람바 사르방가아사나 (어깨서 • 비파리타 카라니 (벽 자세) 잘란다라 반다 강요
MED-02 경추 디스크 및 거북목 기) • 세투 반다아사나 (낮은 브릿 금지,
• 시르사아사나 (머리서기) 지) C커브 쿠션 받침
호흡 멈춤
MED-03 고혈압 및 안압 상승 • 견상 자세 (견상 장기 유지) 수카아사나 (정좌 이완 호흡) (Kumbhaka) 금지,
• 급격한 역자세(Inversion) 일체 • 숩타 바다 코나아사나 머리를 심장 위 유
지
• 복부 압박 엎드린 자세 일체 • 카티 차크라아사나 (완만한 스트랩 가동범위
MED-04 임산부 (16주~28주) • 격렬한 복부 트위스트 비틀기) 60% 제한,
• 우파비스타 코나아사나 체온 상승 주의
나연스떼 웰니스 테크랩 | 사내 강습 운영 규정 Page 1 / 2
... 이하 생략
| 원본 PDF의 의도 | AI_PARSE_DOCUMENT함수의 OCR 모드가 읽어버린 순서 |
발생하는 문제 |
| MED-01 -> 허리 디스크 -> 금기/대체 -> 블록 지급 |
블록/볼스터 필수 -> MED-01 요추... -> 지급, | 조치사항 문장이 반토막 나서 셀 밖으로 튕겨 나감 |
| 헤더: 구분 코드 / 질환 / 금기 / 대체 / 조치 | 한 줄로 텍스트가 엉켜서 나열됨 | LLM이 어느 게 컬럼명이고 값인지 구분 불가 |
💡 포스 삼촌의 OCR 모드 한 줄 평:
- 한글 단어 인식: 아사나, 나연스떼 등 전문 용어는 기가 막히게 잘 읽어요.
- 치명적 약점: 표(Table)의 2차원 구조를 완전히 평면화해 버려서 데이터가 뒤섞여 있어요.
- 결론: 단순 텍스트 문서엔 빠르고 좋지만, 규정집·교안처럼 표가 핵심인 문서는 이대로 RAG에 넣으면 100% 헛소리(환각) 시작!
OCR모드는 말 그대로 문자를 인식하는데에 최적화 되어 있어요. 꼭 Snowflake Docs의 공식 설명을 확인하면서 사용하기 바랍니다.
1.2 AI_PARSE_DOCUMENT 함수의 LAYOUT 모드
-- [LAYOUT 모드] 텍스트 + 구조(테이블, 헤더) 추출. 대부분의 유스케이스에 권장
SELECT AI_PARSE_DOCUMENT(
TO_FILE('@STG_NY_PDF', 'PRANALINK_NYST2_guideline_v2.pdf'),
{'mode': 'LAYOUT'}
) AS layout_result;
1.2 결과는 LAYOUT 모드로 추출한 문서의 결과에요.
마찬가지로 표로 되어 있는 3조 부분을 살펴보면, | 구분 코드 | 건강 특이사항... | 형태의 정규 마크다운 테이블로 깔끔하게 변환된 걸 알 수 있어요.
## 제3조 (회원 건강 특이사항별 아사나 제한 및 대체 규정)
지도 강사는 수업 시작 전 반드시 '회원 건강 차트'를 열람하고, 특정 질환을 보유한 회원에게는 아래 표의 [절대 금기 동작]을 엄격히 배제하고 [대체 시퀀스]를 적용해야 한다.
| 구분 코드 | 건강 특이사항 (질환) | 절대 금기 동작 (Contraindication) | 대체 검정 시퀀스 | 강사 현장 조치 |
| --- | --- | --- | --- | --- |
| MED-01 | 요추 추간판 탈출증 (허리 디스크) | • 부장가아사나 (완전 후굴) • 우스트라아사나 (낙타 자세) | • 스핑크스 자세 (하부 요추 보호) • 살람바 발라아사나 | 블록/볼스터 필수 지급, 골반 지면 밀착 감시 |
| MED-02 | 경추 디스크 및 거북목 | • 살람바 사르방가아사나 (어깨서기) • 시르사아사나 (머리서기) | • 비파리타 카라니 (벽 자세) • 세투 반다아사나 (낮은 브릿지) | 잘란다라 반다 강요 금지, C커브 쿠션 받침 |
| MED-03 | 고혈압 및 안압 상승 | • 견상 자세 (견상 장기 유지) • 급격한 역자세(Inversion) 일체 | • 수카아사나 (정좌 이완 호흡) • 습타 바다 코나아사나 | 호흡 멈춤 (Kumbhaka) 금지, 머리를 심장 위 유지 |
| MED-04 | 임산부 (16주~28주) | • 복부 압박 엎드린 자세 일체 • 격렬한 복부 트위스트 | • 카티 차크라아사나 (완만한 비틀기) • 우파비스타 코나아사나 | 스트랩 가동범위 60% 제한, 체온 상승 주의 |
나연스떼 웰니스 테크랩 | 사내 강습 운영 규정
Page 1 / 2
위 결과를 보면, 문서 제목은 #, 조항은 ##, 글머리 기호는 -, 번호 매기기는 1, 2, 3으로 계층적 마크다운 문법을 잘 적용한 것을 알 수 있어요. 이 정도 구조화면 LLM이 테이블 검색(RAG)을 수행할 때 행/열 매핑 실패로 인한 환각이 0에 가까워질 것 같아요.
하지만, 테이블 헤더의 '대체 권장 시퀀스'를 '대체 검정 시퀀스'로 잘못 인식하거나, 페이지 하단의 'Page 1 / 2' 같은 텍스트가 그대로 남아 어색한 부분이 있는 점도 눈에 띕니다.
💡 포스 삼촌의 AI_PARSE_DOCUMENT 함수 "OCR vs LAYOUT" 비교
| 비교 항목 | 📄 OCR 모드 (OCR) | 📐 LAYOUT 모드 (LAYOUT) |
| 표(Table) 인식 | ❌ 완전 붕괴 (텍스트 순서대로 나열되어 행/열 파괴) | ⭕ 완벽 복원 (정규 Markdown Table로 깔끔하게 변환) |
| 문서 계층 구조 | 텍스트 평면화 (헤더/본문 구분 모호) | #, ##, - 등 마크다운 헤딩 및 리스트 구조 보존 |
| 노이즈 및 이상 문자 | 110 K, 一 등 시각 아티팩트 유입 | 불필요한 노이즈 대부분 정제됨 (단, & 엔티티 잔존) |
| RAG 적용 적합도 | ⚠️ 일반 평문 텍스트 외 표 기반 질의 시 환각 유발 | ✅ 표 데이터 기반의 정밀 질의응답(QA)에 최적 |
즉, 표가 들어 있는 대부분의 문서들은 LAYOUT 모드로 파싱하는 것이 좋아요.
2. AI_COMPLETE를 이용해서 동일한 문서를 파싱
-- 모든 것은 AI_COMPLETE로^^
SELECT AI_COMPLETE(
'gemini-3.1-pro',
'이 문서의 전체 내용을 마크다운 형식으로 추출해줘.
- 제목과 소제목은 헤더(#, ##, ###)로 표시
- 표가 있으면 마크다운 테이블로 변환
- 목록은 불릿/번호 리스트로 유지
- 내용을 요약하지 말고, 원문 그대로 빠짐없이 추출할 것',
TO_FILE('@STG_NY_PDF', 'PRANALINK_NYST2_guideline_v2.pdf')
) AS layout_result;
-- AI_COMPLETE는 LLM 모델의 선정, 프롬프트의 내용에 따라서 결과가 달라질 수 있어요^^
위 쿼리를 이용해 동일한 문서의 내용을 파싱하고, 동일 부분인 3조 부분을 비교해 보아요.
## 제3조 (회원 건강 특이사항별 아사나 제한 및 대체 규정)
지도 강사는 수업 시작 전 반드시 '회원 건강 차트'를 열람하고, 특정 질환을 보유한 회원에게는 아래 표의 **[절대 금기 동작]**을 엄격히 배제하고 **[대체 시퀀스]**를 적용해야 한다.
| 구분 코드 | 건강 특이사항 (질환) | 절대 금기 동작 (Contraindication) | 대체 권장 시퀀스 | 강사 현장 조치 |
| --- | --- | --- | --- | --- |
| MED-01 | 요추 추간판 탈출증 (허리 디스크) | • 부장가아사나 (완전 후굴)<br>• 우스트라아사나 (낙타 자세) | • 스핑크스 자세 (하부 요추 보호)<br>• 살람바 발라아사나 | 블록/볼스터 필수 지급,<br>골반 지면 밀착 감시 |
| MED-02 | 경추 디스크 및 거북목 | • 살람바 사르방가아사나 (어깨서기)<br>• 시르사아사나 (머리서기) | • 비파리타 카라니 (벽 자세)<br>• 세투 반다아사나 (낮은 브릿지) | 잘란다라 반다 강요 금지,<br>C커브 쿠션 받침 |
| MED-03 | 고혈압 및 안압 상승 | • 견상 자세 (견상 장기 유지)<br>• 급격한 역자세(Inversion) 일체 | • 수카아사나 (정좌 이완 호흡)<br>• 숩타 바다 코나아사나 | 호흡 멈춤(Kumbhaka) 금지,<br>머리를 심장 위 유지 |
| MED-04 | 임산부 (16주~28주) | • 복부 압박 엎드린 자세 일체<br>• 격렬한 복부 트위스트 | • 카티 차크라아사나 (완만한 비틀기)<br>• 우파비스타 코나아사나 | 스트랩 가동범위 60% 제한,<br>체온 상승 주의 |
나연스떼 웰니스 테크랩 | 사내 강습 운영 규정 Page 1 / 2
아까 LAYOUT 모드에서 오타로 인식했던 제3조 표의 헤더 부분 '대체 권장 시퀀스' 부분이 잘 수정되었고, 표의 셀 안에 여러행으로 되어 있는 부분에도 <BR> 태그로 줄바꿈을 잘 표시해주고 있어요. 또한 숩타와 같은 산스크리트어까지 정확하게 추출되는 걸 볼 수 있습니다.
3가지 경우를 비교하면 아래와 같이 정리할 수 있겠어요!
| 비교 항목 | 1️⃣ AI_PARSE (OCR 모드) | 2️⃣ AI_PARSE (LAYOUT 모드) | 3️⃣ AI_COMPLETE (멀티모달 LLM) |
| 적용 함수/쿼리 | AI_PARSE_DOCUMENT(..., {'mode': 'OCR'}) | AI_PARSE_DOCUMENT(..., {'layout_aware': true}) | AI_COMPLETE('<LLM모델명>', 프롬프트, TO_FILE(...)) |
| 표(Table) 인식 | ❌ 완전 붕괴 (텍스트 순서 나열) | ⭕ Markdown 변환 성공 | 👑 셀 내 줄바꿈(<br>)까지 완벽 보존 |
| 한글 오탈자 | 텍스트 왜곡 및 아티팩트 유입 | 사소한 오인식 발생 (검정, 습타) | 👑 문맥 기반 보정으로 오탈자 0% |
| 문서 계층 구조 | 평면 텍스트 | #, ##, 리스트 인식 | #, ##, 리스트 + 인용구(>)까지 인식 |
| 비용 및 속도 | ⚡ 매우 빠르고 가장 저렴함 | ⚖️ 속도/비용 준수 (완전 관리형) | 💰 LLM 토큰 비용 발생 비용 비교/모니터링이 꼭 필요함 |
| 최적의 활용처 | 표 없는 일반 텍스트, 영문 아티클 | 대규모 문서 배치 파싱, 비용 효율적 RAG | 표/서식이 복잡한 고품질 한글 교안·규정집 |
🪐 마치며 : 테크와 숨결의 완벽한 링크
스노우플레이크의 Cortex AI 함수 덕분에, 복잡한 인프라 셋팅 없이 단 몇 줄의 SQL만으로 '나연스떼' 맞춤형 RAG 시스템의 뼈대를 손쉽게 완성할 수 있었습니다. 조직이 가지고 있는 문서의 내용에 따라서 일반적인 경우에는 LAYOUT모드의 AI_PARSE_DOCUMENT를 이용하는걸 추천하고, 보다 중요한 문서라던지 더욱 정확해야 하는 경우라면 좋은 LLM 모델을 선정하고 잘 튜닝된 프롬프트를 이용해서 파싱하는 것이 최선의 결과를 만들 수 있겠어요. 가성비를 늘 고려해야 하니, 문서 중요도에 따라 파싱 파이프라인을 나누는게 어떨까 해요.
조직의 비용을 늘 고려하며 비즈니스의 가치를 높이는 핵심 아키텍처에 집중하는 것. 그것이 바로 제가 생각하는 모던 데이터 아키텍트의 '포스(FORCE)'가 아닐까 싶습니다.
오늘도 데이터❄️와 숨결🧘♀️을 연결🔗하는 하루 되세요. 나마스떼, 아니 나연스떼!
'Main Quest - Snowflake > [시리즈] Cortex AI Functions' 카테고리의 다른 글
| [Cortex_AI_5] 텍스트 분류+필터링 삼총사: AI_CLASSIFY, AI_FILTER, AI_EXTRACT(feat. 나연이네 고객 문의 자동 태깅) (0) | 2026.07.20 |
|---|---|
| [Cortex_AI_3] 오디오 파일 STT: AI_TRANSCRIBE vs AI_COMPLETE (0) | 2026.07.17 |
| [Cortex_AI_2] 감성분석: 완전관리형(AI_SENTIMENT) VS 프롬프트 엔지니어링(AI_COMPLETE) (0) | 2026.07.17 |
| [Cortex_AI_1] AI_COMPLETE: 멀티모달 모델로 이미지 분석하기 (0) | 2026.07.12 |
| [Cortex_AI_1] 모든 길은 결국 저(AI_COMPLETE)를 통합니다. feat Faker (0) | 2026.07.05 |