rag_lab
Bronze / Silver / Gold 3단계로 텍스트를 처리하는 RAG 실습용 라이브러리.
설치
pip install rag-lab-bsg
설치 패키지명은 rag-lab-bsg 이지만, 임포트 이름은 rag_lab 입니다.
노트북 실습용으로 로컬에서 개발 모드로 설치하려면 프로젝트 루트(code/)에서 다음을 한 번만 실행합니다.
uv pip install -e ".[notebook]"
-e 로 설치하면 rag_lab/ 코드를 고칠 때마다 다시 설치할 필요가 없습니다.
단계 요약
| 단계 | 함수 | 입력 | 출력 | 핵심 동작 |
|---|---|---|---|---|
| Bronze | bronze.to_text(input_path) |
PDF / TXT / MD | data/dummy/bronze.txt |
원본 보존, 페이지 사이는 빈 줄로만 구분 |
| Silver | silver.split(input_path) |
bronze.txt | data/dummy/silver.jsonl |
CharacterTextSplitter — 의미 무시, 글자 수로 분할 |
| Gold | gold.split(source) |
silver.jsonl 또는 문자열 | data/dummy/gold.jsonl |
RecursiveCharacterTextSplitter — 단락 → 줄 → 종결 → 어절 |
각 단계의 함수는
- 다음 단계 입력으로 쓸 산출물(.txt / .jsonl) 경로를 반환하고
- 호출 결과를 화면에도 짧게 출력합니다.
요구 사항
- Python 3.10+
langchain-community,langchain-text-splitters,pypdf
실습 가이드 — Bronze → Silver → Gold
practice.ipynb 의 실행 흐름을 그대로 옮긴 단계별 실습 가이드입니다. rag_lab 라이브러리를 import 해서 세 단계를 직접 실행해 봅니다.
사전 준비
from pathlib import Path
from rag_lab import bronze, silver, gold
1. Bronze — 원본 그대로 .txt 로 저장
data/input/ 에 PDF 를 넣어 두면 그 PDF 를 쓰고, 없으면 아래 코드에서 샘플 텍스트 파일을 만들어 그것을 입력으로 씁니다.
INPUT_DIR = Path("data/input")
pdfs = sorted(INPUT_DIR.glob("*.pdf")) if INPUT_DIR.exists() else []
if pdfs:
input_path = pdfs[0]
else:
input_path = Path("data/dummy/_sample.txt")
input_path.parent.mkdir(parents=True, exist_ok=True)
input_path.write_text(
"임플란트 시술 매뉴얼 (샘플)\n\n"
"1. 개요\n임플란트는 치아가 결손된 부위에 인공 치근을 식립하여 자연치와 유사한 기능을 회복하는 치료법이다. "
"시술은 진단, 식립, 보철 단계로 구분되며 각 단계마다 정밀한 계획이 필요하다.\n\n"
"2. 적응증\n- 단일 치아 결손\n- 부분 무치악\n- 완전 무치악\n"
"환자의 골량과 골질, 전신 건강 상태를 종합적으로 평가한 후 시술 여부를 결정한다.\n\n"
"3. 시술 절차\n3.1 진단 단계\n구강 검사, 파노라마 방사선 촬영, CBCT 영상을 통해 식립 위치를 결정한다. "
"보철 계획을 먼저 수립한 뒤 역으로 식립 위치를 정하는 보철 주도형 진단이 권장된다.\n"
"3.2 식립 단계\n국소마취 후 점막을 절개하고 드릴링하여 픽스처를 식립한다. 일차 안정성이 확보되어야 한다.\n"
"3.3 보철 단계\n골 유착 기간(일반적으로 3~6개월) 이후 인상 채득, 지대주 연결, 최종 보철물 장착으로 마무리된다.\n",
encoding="utf-8",
)
bronze_txt = bronze.to_text(input_path)
bronze_txt
실행 결과 예시:
[Bronze] 누비슨 플랫폼 활용 부정 방지 전략.pdf → data/dummy/bronze.txt (1,848자, PDF, 3페이지 합본)
PosixPath('data/dummy/bronze.txt')
생성된 텍스트는 다음과 같이 확인합니다.
print(bronze_txt.read_text(encoding="utf-8"))
2. Silver — 의미와 무관하게 글자 수로 단순 분할
chunk_size=500 으로 잘라서 다음 단계(Gold)에 넘길 기준 산출물을 만듭니다.
silver_jsonl = silver.split(bronze_txt, chunk_size=500, chunk_overlap=30)
silver_chunks = silver.load_chunks(silver_jsonl)
for c in silver_chunks:
print(f"#{c['chunk_id']} ({c['char_len']}자) \n {c['text']}...")
print("========================================================================================")
실행 결과 예시:
[Silver] bronze.txt → data/dummy/silver.jsonl (4청크, 평균 478자, 최대 500자, chunk_size=500, overlap=30)
#0 (499자)
누비슨 플랫폼 활용한 부정 방지 전략 및 인프라 제안 ...
#1 (484자)
데이터를수집합니다. 육안으로는확인하기힘든 ...
#2 (500자)
ion):Edge AI 단계. ...
#3 (430자)
에업데이트하여차기경주시예측정확도를높이는학습 ...
CharacterTextSplitter는 우선 separator(기본"") 로 잘라 낸 뒤에야chunk_size를 적용하므로, separator 가 비어 있으면 글자 수에서 딱 끊깁니다. 한국어 문장 중간이 어색하게 잘리는 빈도를 직접 눈으로 확인하는 것이 이 단계의 학습 포인트입니다.
3. Gold — 의미 단위로 재귀 분할
gold.split 은 두 가지 입력을 모두 받습니다.
- (a) Silver 의 .jsonl 경로 — 청크들을 다시 이어붙여 원본 텍스트로 복원한 뒤 분할
- (b) raw 텍스트 문자열 —
silver_chunks[0]['text']처럼 청크 한 개만 따로 넘기는 경우
separators 우선순위(단락 → 줄 → 종결 → 어절) 대로 잘라 내므로, 같은 chunk_size 라도 Silver 보다 단락/문장 경계가 살아 있을 확률이 높습니다.
여기서는 Silver 의 첫 번째 청크 하나만 다시 의미 단위로 잘게 잘라 봅니다.
gold_jsonl = gold.split(silver_chunks[0]['text'], chunk_size=100, chunk_overlap=30)
gold_chunks = gold.load_chunks(gold_jsonl)
for c in gold_chunks:
print(f"#{c['chunk_id']} ({c['char_len']}자) \n {c['text']}...")
print("========================================================================================")
실행 결과 예시:
[Gold] <text 499자> → data/dummy/gold.jsonl (8청크, 평균 60자, chunk_size=100, overlap=30)
#0 (88자)
누비슨 플랫폼 활용한 부정 방지 전략 및 인프라 제안 ...
#1 (58자)
단순한' 사후적발' 을넘어 ' 사전예방및실시간차단 ' ...
#2 (68자)
누비슨플랫폼을활용해부정행위를방지하고예측하는구체적인전략을제안합니다 . ...
#3 (44자)
선수와자전거에부착된센서를통해신체데이터와물리적데이터를실시간으로수집하여분석합니다 . ...
#4 (58자)
● 생체데이터모니터링 : 선수의심박수, ...
...
Silver
chunk_size=500으로 만든 한 청크(499자)를 Goldchunk_size=100으로 다시 자르면 8개 청크, 평균 60자가 나옵니다. 단락 / 줄 /다./요.구분자가 우선순위대로 적용되어 의미 경계에서 끊기는 빈도가 올라갑니다.
Silver vs Gold 비교
청크 개수, 평균/최소/최대 길이를 한눈에 비교해 봅니다.
def stats(chunks):
lens = [c["char_len"] for c in chunks] or [0]
return {
"개수": len(chunks),
"평균": round(sum(lens) / len(lens), 1),
"최소": min(lens),
"최대": max(lens),
}
print("Silver:", stats(silver_chunks))
print("Gold :", stats(gold_chunks))
print("\n— Silver #0 ——————————————")
print(silver_chunks[0]["text"])
print("\n— Gold #0 ————————————————")
print(gold_chunks[0]["text"])
실행 결과 예시:
Silver: {'개수': 4, '평균': 478.2, '최소': 430, '최대': 500}
Gold : {'개수': 8, '평균': 60.5, '최소': 27, '최대': 88}
같은 원본 일부(Silver #0, 499자)를 Gold 가 다시 평균 60자 단위로 잘게 쪼개면서, 시작 지점이 자연스러운 단락 경계(누비슨 플랫폼 활용한 부정 방지 전략 및 인프라 제안 으로 시작) 에 맞춰진 것을 확인할 수 있습니다.
4. 직접 바꿔 보기
다음을 바꿔 가며 결과 차이를 관찰해 봅니다.
- Silver
chunk_size를 100 / 300 / 800 등으로 바꿔 청크 수와 평균 길이가 어떻게 달라지는지 - Gold
separators리스트에서"다. ","요. "를 맨 앞으로 옮기면 한국어 종결 경계가 얼마나 더 잘 살아나는지 - Silver 의 다른 청크(
silver_chunks[1]['text']등) 를 Gold 에 넣어 단락별로 어떻게 잘리는지
separators 순서를 바꿔서 Gold 결과를 비교하는 예시입니다.
gold.split(
silver_chunks[0]['text'],
output_path="data/dummy/_gold_custom.jsonl",
chunk_size=100,
chunk_overlap=30,
separators=["다. ", "요. ", "\n\n", "\n", ". ", " ", ""],
)
Metadata
Release files for rag-lab-bsg 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rag_lab_bsg-0.1.4.tar.gz | 8.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rag_lab_bsg-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.2 kB
Release files / rag_lab_bsg-0.1.4.tar.gz
| Download URL | rag_lab_bsg-0.1.4.tar.gz |
|---|---|
| Size | 8.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b7a7b205068d2b991d40dbe2bb10c64aec74eb3a27238d412d6b9db06540b969
|
|
BLAKE2b-256 checksum How to use checksums |
9c5198b1c7611af03359e85df340996d27553affbfee6ed10b81a870158c538a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.3
|
Release files / rag_lab_bsg-0.1.4-py3-none-any.whl
| Download URL | rag_lab_bsg-0.1.4-py3-none-any.whl |
|---|---|
| Size | 11.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1c749e43a9104a2251f149081b73b1088193f986e4fac7799492833bc747974
|
|
BLAKE2b-256 checksum How to use checksums |
c45b5e4a3ebd7c1f128e99c76793970a3e09173156da1e8175ee35d067ea4d5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.3
|