본문으로 건너뛰기
페이지 목차
이 페이지에서 검색

멀티 에이전트

이 페이지에 묻기

멀티 에이전트 · 현재 차시와 목차 본문에서만 찾아 답합니다. 답을 지어내지 않고 해당하는 대목을 그대로 보여 주며, 여기에 없으면 없다고 알려 드립니다.

생성형 AI가 아니라 이 페이지 본문을 찾아 그대로 보여 주는 방식입니다. 외부로 나가는 요청이 없습니다.

MULTI · AGENT

멀티 에이전트

생성 수정

도구 실행·검색·기억·그래프 흐름·전문 에이전트의 협업을 구성하고 권한·평가·사람의 확인으로 통제합니다.

26개 문서 · 2일차 · 13 / 26

12차시 · 문서 로딩과 청킹

지도 위치 : 2일차 · README 4장의 ③ 지식 층 — 지식 층의 첫 칸, 문서를 검색할 수 있는 조각 으로 만드는 자리 | 이전: 11차시 프레임워크 기반 에이전트 구성 | 다음: 13차시 임베딩과 벡터 DB 키워드 : RAG, 청킹, 메타데이터

이 차시를 다 읽으면

  1. RAG를 유와 종차로 정의하고, 밖에서 찾는가 ↔ 안을 고치는가 축으로 파인튜닝과 가를 수 있다.
  2. RAG의 전체 흐름을 적재 와 질의 두 줄로 그리고, 12 · 13 · 14차시가 각각 어느 칸인지 짚을 수 있다.
  3. PDF 로딩에서 생기는 함정(표 · 머리글 · 스캔본)을 말하고, 추출 결과를 눈으로 확인하는 이유를 설명할 수 있다.
  4. 청크 크기와 겹침의 트레이드오프를 표로 설명하고, 규정 문서에 조항 단위 청킹 이 맞는 이유를 말할 수 있다.
  5. 청크에 붙일 메타데이터를 고르고, 그것이 출처 표기 와 권한 필터 에 어떻게 쓰이는지 말할 수 있다.

0. 이 차시의 판별 축

#축왼쪽 (0)오른쪽 (1)이 축으로 갈리는 것큰 축 (README 5장)
1⭐ 밖에서 찾는가 ↔ 안을 고치는가RAG — 문서를 찾아 프롬프트에 넣음파인튜닝 — 모델 가중치를 고침사내 지식을 모델에게 주는 방법파생 축 (부모 ⑧)
2하나 ↔ 여럿문서 통째청크 여러 개무엇을 검색 · 주입 단위로 삼는가⑤ 하나 ↔ 여럿
3작은 청크 ↔ 큰 청크정확히 맞지만 맥락이 부족맥락은 많지만 잡음 · 비용청크 크기이 차시의 축
4글자 수 기준 ↔ 구조 기준500자마다 자름조항 · 제목 단위로 자름청크가 뜻의 단위와 맞는가이 차시의 축

이 차시의 질문 — 오피스봇에게 "경조휴가 며칠이야?"라고 물으면 모델은 우리 회사 취업규칙을 모릅니다. 9 · 10차시의 get_leave_policy는 고정된 문구를 돌려주는 가짜였습니다. 이제 진짜 규정 PDF를 근거로 삼아야 합니다. 이 차시는 그 첫 단계로 문서를 읽어 들이고, 검색할 단위로 자르고, 각 조각에 꼬리표를 붙이는 일을 다룹니다. 1일차 내내 보던 축 ⑤(하나 ↔ 여럿)가 이번에는 문서 에 적용됩니다.


1. ⭐ RAG — 밖에서 찾아 넣는다

1.1 정의와 경계

RAG (Retrieval-Augmented Generation, 검색 증강 생성) — [LLM 응용 기법]인데, [ 질문과 관련된 문서를 찾아 프롬프트에 함께 넣어 근거로 답하게 한다 ]는 점에서 모델의 가중치를 고치는 파인튜닝과 구별된다.

파인튜닝 (Fine-tuning) — [모델 학습 방법]인데, [ 이미 학습된 모델을 우리 데이터로 추가 학습해 가중치 자체를 바꾼다 ]는 점에서 가중치는 그대로 두고 입력만 바꾸는 RAG · 프롬프트 설계와 구별된다.

RAG (밖에서 찾는다)파인튜닝 (안을 고친다)
지식이 있는 곳문서 저장소 (모델 바깥)모델 가중치 안
규정이 개정되면문서만 다시 적재 (13차시)다시 학습
출처 표기⭕ 어느 문서 몇 조인지 댈 수 있음❌ 어디서 배웠는지 댈 수 없음
부서별 권한⭕ 검색할 때 걸러냄❌ 한 번 배우면 모두에게
잘하는 일사실 · 최신 정보 · 사내 문서말투 · 형식 · 특정 작업 방식

1.2 왜 필요한가

문제RAG 없이RAG로
환각 — 그럴듯하지만 근거 없는 답모델이 일반적인 회사 규정을 지어냄우리 규정 문장을 근거로 줌
최신성모델은 학습 시점 이후를 모름오늘 개정된 문서를 적재하면 반영
사내 문서모델은 우리 취업규칙을 본 적이 없음사내 문서를 직접 찾아 넣음

1.3 반례 — 이건 RAG가 아닙니다

대상왜 아닌가
사내 검색 엔진찾기만 하고 답을 생성하지 않음
시스템 프롬프트에 취업규칙 전문을 붙여 넣기찾는 단계가 없음. 통째로 넣기 (1.4)
규정 Q&A로 모델을 추가 학습가중치를 고침. 파인튜닝

1.4 컨텍스트가 100만 토큰인데, 통째로 넣으면 안 되나? (축 ⑤)

최신 Claude 모델은 한 번에 100만 토큰까지 받습니다. 규정 몇 개쯤은 통째로 들어갑니다. 그래도 나누는 이유가 있습니다.

통째로 넣기 (하나)청크를 골라 넣기 (여럿)
비용 · 지연질문마다 문서 전체 토큰 (10차시 3.3의 곱셈)관련 조각만
정확도긴 글 속에서 필요한 문장이 묻힐 수 있음관련 부분이 앞에 놓임
권한부서 전용 문서를 섞으면 걸러낼 수 없음청크마다 걸러냄 (5절)
출처"이 긴 글 어딘가""제23조, p.12"

💡 문서가 작고 질문이 적다면 통째로 넣는 쪽이 더 단순하고 충분할 수 있습니다. README 문장 1 — 가장 단순한 것부터, 충분하면 멈춘다. 오피스봇처럼 문서가 여럿이고, 개정되고, 부서별 권한이 있으면 RAG가 맞습니다.


2. RAG 전체 흐름 — 적재와 질의

[적재]  미리 한 번 · 문서가 바뀔 때마다 다시            ← 결과는 디스크에 영구 저장 (축 ①)
  규정 PDF ─▶ ① 로딩 ─▶ ② 청킹 ─▶ ③ 임베딩 ─▶ ④ 저장(벡터 DB)
              └──── 12차시 ────┘   └───── 13차시 ─────┘

[질의]  질문이 올 때마다
  질문 ─▶ ⑤ 검색 ─▶ ⑥ 주입(프롬프트에 근거로) ─▶ ⑦ 생성(답 + 출처)
          13 · 15차시   └────────── 14차시 ──────────┘
칸하는 일차시
① 로딩PDF · HTML · Word에서 텍스트와 위치 정보를 꺼냄12
② 청킹검색 단위로 자르고 메타데이터를 붙임12
③ 임베딩 · ④ 저장조각을 의미 벡터로 바꿔 벡터 DB에 넣음13
⑤ 검색질문과 가까운 조각 k개를 찾음13, 15
⑥ 주입 · ⑦ 생성조각을 근거로 넣고, 출처를 붙여 답하게 함14

⚠️ 적재 단계의 실수는 질의 단계에서 고칠 수 없습니다. 표가 깨진 채로, 조항이 반쯤 잘린 채로 저장되면, 검색을 아무리 잘해도 깨진 조각이 나옵니다. 그래서 이 차시가 RAG 품질의 바닥을 정합니다.

앞으로 다시 만납니다 — ③ · ④는 13차시, ⑤의 개선은 15차시, ⑥ · ⑦은 14차시에서 회수합니다.


3. 문서 로딩 — 파일에서 글자 꺼내기

3.1 정의와 코드

문서 로딩 (Document Loading) — [RAG 적재 단계]인데, [ PDF · HTML · Word 같은 파일에서 글자와 위치 정보(페이지 등)를 꺼내 텍스트로 바꾼다 ]는 점에서 꺼낸 텍스트를 자르는 청킹과 구별된다.

from pypdf import PdfReader

reader = PdfReader("취업규칙_2026.pdf")
pages = [(i + 1, page.extract_text()) for i, page in enumerate(reader.pages)]

🔍 읽는 포인트 : 페이지마다 (페이지 번호, 텍스트)로 꺼냅니다. ⭐ 페이지 번호를 이 단계에서 버리면 나중에 "p.12"라고 출처를 댈 수 없습니다. LangChain의 문서 로더(document loaders)를 써도 원리는 같습니다 — 텍스트 + 메타데이터(파일명 · 페이지).

3.2 ⚠️ PDF의 함정

PDF는 "화면에 어떻게 보일지"를 담은 형식이지 "글의 순서와 구조"를 담은 형식이 아닙니다.

함정추출 결과에서 보이는 모습대응
표"구분 일수 결혼 5 사망 3" — 칸 경계가 사라져 한 줄로 뭉개짐표 추출 도구를 따로 쓰거나 표를 "결혼: 5일" 문장으로 바꿔 둠
머리글 · 바닥글매 페이지 "대외비 — 인사팀", "- 12 -"가 본문 사이에 끼어듦반복되는 줄을 찾아 제거
2단 편집왼쪽 단과 오른쪽 단의 문장이 섞임다른 추출기 시도, 원본 형식(Word · HTML)이 있으면 그쪽을
스캔 PDF텍스트가 비어 있음 (글자가 아니라 그림)글자 인식(OCR) 필요
각주 · 개정 이력 표본문 중간에 "(2025.3.1 개정)"이 흩어짐개정일은 메타데이터로 옮김 (5절)

⭐ 추출 결과는 사람이 직접 몇 페이지 열어 봅니다. 특히 표가 있는 페이지. 코드를 몰라도 "원본 PDF와 같은 내용인가"는 누구나 확인할 수 있습니다.


4. ⭐ 청킹 — 검색 단위로 자르기

4.1 정의

청킹 (Chunking) — [문서 전처리]인데, [ 문서를 검색 한 번에 꺼낼 단위로 잘라, 질문과 관련된 부분만 골라 넣을 수 있게 한다 ]는 점에서 문서를 통째로 다루는 방식과 구별된다. 잘린 조각 하나를 청크(chunk) 라고 부릅니다.

4.2 크기와 겹침 — 트레이드오프

작은 청크 (예: 200자)큰 청크 (예: 2,000자)
검색 정확도질문과 딱 맞는 조각이 잡힘관련 없는 내용이 섞여 순위가 흐려짐
맥락⚠️ "다만 그 경우에는…" — 무엇의 경우인지 잘려 나감앞뒤 맥락이 함께 들어 있음
주입 비용적음많음
출처 정밀도정확한 위치"이 근처 어딘가"

겹침 (Overlap) — 이웃한 청크가 경계 부분을 조금씩 함께 갖게 하는 것입니다. 경계에서 문장이 잘려 뜻이 사라지는 것을 줄입니다. 대신 같은 내용이 두 번 저장되어 저장량 · 중복 검색이 늘어납니다.

청크 1: [──────────────────────]
청크 2:                  [──────────────────────]
                         └ 겹침 ┘  (경계의 문장이 양쪽에 다 있음)
from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_text(page_text)

🔍 읽는 포인트 : chunk_size(크기)와 chunk_overlap(겹침) 두 숫자만 보면 됩니다. 기본은 글자 수 기준입니다. 이름의 "Recursive"는 문단 → 문장 → 글자 순으로, 큰 경계부터 시도해 크기를 맞춘다는 뜻입니다. 값은 예시이며, 정답은 평가로 정합니다(15차시).

4.3 구조 기반 청킹 — 조항 단위

규정 문서에는 이미 뜻의 단위 가 있습니다 — 제N조. 글자 수로 자르면 조항이 중간에서 잘리고, 한 청크에 두 조항이 섞입니다.

❌ 글자 수로 자른 청크⭕ 조항으로 자른 청크
"…3일 전까지 신청한다. 다만, 부득이한 경우에는 사후에 신청할 수 있다. 제24조(경조휴가) ① 직원은 다음""제23조(연차휴가 신청) 연차휴가는 사용 3일 전까지 신청한다. 다만, 부득이한 경우에는 사후에 신청할 수 있다."
두 조항의 반쪽씩, 제목 없음한 조항 전체, 제목이 앞에
import re
articles = re.split(r"(?m)^(?=제\d+조)", full_text)   # 줄 맨 앞의 "제N조" 바로 앞에서 자름

🔍 읽는 포인트 : ^(줄 맨 앞)이 중요합니다. 본문 속의 "제12조에 따라" 같은 인용 에서 잘리지 않게 합니다.

방식장점약점맞는 문서
글자 수 기준어떤 문서에도 적용, 크기가 고름뜻의 경계를 무시구조가 없는 메일 · 회의록
구조 기준 (조항 · 제목)뜻의 단위 = 검색 단위, 출처가 정확조항 길이가 들쭉날쭉⭐ 규정 · 매뉴얼 · FAQ
혼합조항으로 자르고, 너무 긴 조항만 다시 글자로구현이 조금 복잡실무의 기본값

💡 혼합 방식에서 긴 조항을 다시 자를 때는, 각 조각 앞에 조항 제목을 다시 붙여 둡니다("제24조(경조휴가) — 이어서: …"). 잘린 조각만 꺼내도 무엇에 관한 글인지 알 수 있게 합니다.


5. 메타데이터 — 청크의 꼬리표

5.1 정의

메타데이터 (Metadata) — [데이터에 붙은 속성 값]인데, [ 본문과 따로 출처 · 위치 · 권한 같은 정보를 담아, 검색 후 걸러내기와 출처 표기에 쓴다 ]는 점에서 검색 대상이 되는 본문 텍스트와 구별된다. 축 ③으로 보면 본문도 메타데이터도 속성(값) 이지만, 본문은 "뜻으로 찾는 값", 메타데이터는 "조건으로 거르는 값"입니다.

5.2 오피스봇 청크의 꼬리표

{
    "text": "제23조(연차휴가 신청) 연차휴가는 사용 3일 전까지 신청한다. ...",
    "metadata": {
        "source": "취업규칙_2026.pdf", "doc_title": "취업규칙",
        "article": "제23조", "page": 12,
        "revised_at": "2026-03-01", "access_dept": "ALL",
    },
}

🔍 읽는 포인트 : text 하나와 metadata 여섯 칸입니다.

꼬리표쓰는 곳없으면
doc_title, article, page⭐ 출처 표기 — [취업규칙 제23조, p.12] (14차시)답의 근거를 댈 수 없음
revised_at최신 판만 검색, "2026.3.1 개정 기준" 안내옛 규정으로 답함
access_dept⭐ 권한 필터 — 인사팀 전용 문서는 인사팀 직원 질문에만 (13차시)다른 부서 전용 내용이 답에 섞임
source문서 개정 시 그 파일의 청크만 지우고 다시 적재 (13차시)옛 청크와 새 청크가 섞임

⚠️ 조항이 두 페이지에 걸치면 page를 "12-13"처럼 범위로 둡니다. 그리고 access_dept는 적재할 때 사람이 정한 값 입니다. 모델이 추측하게 두지 않습니다 — 권한은 강제의 영역입니다(10차시 2절).

앞으로 다시 만납니다 — 13차시에서 access_dept로 검색 결과를 거르는 메타데이터 필터 를, 14차시에서 doc_title · article · page로 출처를 붙이는 법을 회수합니다.


6. 오피스봇 적용 — 문서별 청킹 계획

문서형식청킹 방식주의접근
취업규칙PDF, 조항 구조조항 단위 (혼합)경조휴가 일수 표전 직원
복리후생 안내PDF, 표 많음제목 단위 + 표를 문장으로지원 금액 표전 직원
보안 규정Word, 조항 구조조항 단위부칙 · 개정 이력전 직원
인사 평가 지침PDF조항 단위—⚠️ 인사팀만
IT 장애 FAQHTML, 질문-답 쌍질문-답 한 쌍 = 한 청크사내 은어 (15차시)전 직원

⭐ 한 가지 방식으로 모든 문서를 자르지 않습니다. 문서의 구조가 청킹 방식을 정합니다.


7. 실습 — 맡기고 검수하기

지시

오피스봇 규정 문서 적재의 앞 단계(로딩·청킹)를 만들어줘. 임베딩·DB 저장은 아직 하지 말 것.
- 대상: docs/ 폴더의 취업규칙.pdf, 복리후생.pdf, 보안규정.docx (원본 수정 금지)
- 참고: pypdf, langchain-text-splitters 공식 문서. 설치 버전을 보고에 적을 것
- 로딩: 페이지 번호 보존, 반복되는 머리글·바닥글 제거, 표가 있는 페이지는 목록으로 보고
- 청킹: 조항(줄 맨 앞 "제N조") 단위, 1,000자 넘는 조항만 RecursiveCharacterTextSplitter로 다시 자르되 조각 앞에 조항 제목을 붙일 것
- 메타데이터: source, doc_title, article, page, revised_at, access_dept
  (access_dept는 내가 준 표대로. 추측해서 채우지 말 것)
- 결과를 chunks.jsonl로 저장
추측하지 말고 실행 출력 원문을 붙여.
보고 형식: [문서 | 페이지 수 | 청크 수 | 평균 길이 | 최대 길이 | 표가 있던 페이지 | 메타데이터 빈칸 수] 표
 + 무작위 청크 5개 원문 + 제23조 청크 원문

받을 증거

  • 위 형식의 표와 청크 원문 샘플
  • 표가 있는 페이지의 추출 결과 원문 (뭉개졌는지 보기 위해)
  • chunks.jsonl에서 메타데이터 빈칸을 센 명령과 출력

내가 직접 확인할 것

볼 것이걸로 아는 것
원본 PDF의 경조휴가 표와 추출 결과를 나란히 놓고 숫자가 같은가표가 뭉개지지 않았는가 (3.2)
무작위 청크 5개가 각각 한 조항 으로 시작하는가조항 단위 청킹이 됐는가 (4.3)
청크 안에 "대외비" · 페이지 번호 줄이 남아 있는가머리글 · 바닥글 제거 (3.2)
제23조 청크의 page를 원본 PDF에서 펼쳐 맞는가출처 표기의 바탕이 맞는가 (5.2)
인사 평가 지침 청크가 전부 access_dept=인사팀인가권한 필터의 바탕이 맞는가 (5.2)
최대 길이가 비정상적으로 큰 청크가 있는가자르기 실패 (부칙 · 표가 통째로 남음)

부록 A. 스스로 확인하기

#질문답이 있는 곳
1RAG와 파인튜닝을 유와 종차로 가르면?1.1
2RAG가 해결하는 문제 세 가지는?1.2
3컨텍스트가 100만 토큰인데도 청크로 나누는 이유는?1.4
4적재와 질의의 일곱 칸과 담당 차시는?2절
5PDF 로딩의 함정 중 표와 스캔본은 어떻게 보이나?3.2
6청크 크기가 작을 때와 클 때의 장단점은?4.2
7겹침은 무엇을 막고 무엇을 늘리나?4.2
8규정 문서에 조항 단위 청킹이 맞는 이유는?4.3
9메타데이터의 두 가지 핵심 용도는?5.2

부록 B. 자주 하는 실수

실수바로잡기
로딩할 때 페이지 번호를 버림❌ 출처 표기가 불가능해짐
추출 결과를 안 보고 바로 청킹⚠️ 표 · 머리글 · 스캔본 문제는 눈으로 발견
모든 문서를 500자로 일괄 자름⚠️ 문서 구조에 맞춰 (조항 · 질문-답 · 제목)
겹침을 크게 할수록 좋다❌ 중복 저장 · 중복 검색이 늘어남
access_dept를 모델에게 추측시킴❌ 권한은 사람이 정한 값으로
"컨텍스트가 크니 RAG는 필요 없다"⚠️ 비용 · 묻힘 · 권한 · 출처를 따져 결정
개정된 문서를 새로 적재하면서 옛 청크를 그대로 둠❌ source 기준으로 지우고 다시 (13차시)

부록 C. NotebookLM 복습 프롬프트

이 12차시 노트만 근거로 6문제를 내줘. 비전공자 기준으로.
"RAG ↔ 파인튜닝(밖에서 찾는가 ↔ 안을 고치는가)", "적재와 질의의 흐름", "청크 크기·겹침 트레이드오프와 조항 단위 청킹", "메타데이터의 두 용도"는 반드시 포함해줘.
답은 내가 답한 다음에 채점하고, 틀린 이유를 노트의 절 번호를 근거로 설명해줘.