
AI가 엉뚱한 답변을 하는 원인의 대부분은 모델이 아니라 '검색'입니다 — RAG 정밀도를 높이기 위한 실전 가이드 (청크 설계·하이브리드
요약
RAG 시스템의 오류 중 약 73%는 모델의 생성 능력이 아닌 검색 단계에서 발생합니다. 본 가이드는 청크 설계, 하이브리드 검색, 리랭크, 평가라는 4가지 핵심 요소를 통해 RAG의 정밀도를 높이는 실전 방법을 다룹니다.
핵심 포인트
- RAG 실패 원인의 73%는 모델 생성이 아닌 검색 단계에 있음
- 검색 품질을 높이는 4대 레버: 청크 설계, 하이브리드 검색, 리랭크, 평가
- 단순 모델 업그레이드보다 검색 데이터(커닝 페이퍼) 정돈이 더 효율적임
- BM25와 벡터 검색을 결합한 하이브리드 방식의 중요성
사내 매뉴얼이나 문서를 읽게 해서, AI에게 질문할 수 있는 채팅을 만들어 보았다. 작동했다. 하지만, 왠지 가끔씩 엉뚱한 대답이 돌아온다.
그래서 많은 사람이 가장 먼저 하는 것이 "모델을 더 똑똑한 녀석으로 바꾸는 것"이다. 그 마음, 정말 이해한다. 하지만 솔직하게 말하겠다. 그것, 아마 고쳐지지 않을 것이다.
RAG (Retrieval-Augmented Generation, 검색 증강 생성)의 실패를 조사해 보면 흥미로운 수치가 나온다. 2026년 시점의 업계 분석에 따르면, RAG가 틀릴 때 그 원인 중 약 73%는 '생성'이 아니라 '검색' 측면에 있다고 한다. 단순하게 구축한 RAG는 애초에 40% 정도의 확률로 '관련 없는 문서'를 가져오고 있으며, AI는 그 잘못된 자료를 바탕으로 자신만만하게 대답해 버린다. 즉, 똑똑한 머리에 잘못된 커닝 페이퍼를 계속 건네주고 있는 셈이다.
이거, 너무 아깝지 않은가? 머리(모델)를 비싼 것으로 바꾸기 전에 커닝 페이퍼(검색)를 정돈한다. 그쪽이 대개 더 저렴하고 효과도 좋다.
이 기사에서는 RAG의 검색 품질을 높이기 위한 4가지 레버, **청크 설계(Chunk Design)·하이브리드 검색(Hybrid Search)·리랭크(Rerank)·평가(Evaluation)**를 "애초에 RAG는 무엇을 하고 있는가?"라는 지점부터 코드와 프롬프트를 곁들여 함께 살펴보겠다. AI를 이제 막 만지기 시작한 사람이라도, 내일부터 자신의 RAG를 "측정하고 고칠 수 있는" 상태를 목표로 한다.
(출처: RAG Best Practices 2026 (CallMissed) / RAG Is Not Dead: Advanced Retrieval Patterns That Actually Work in 2026 (dev.to))
먼저 이 부분을 모호하지 않게 짚고 넘어가자. RAG를 한마디로 말하면 "커닝이 허용된 시험"이다.
일반적인 LLM (Large Language Model)은 머릿속의 지식만으로 대답한다. 그래서 사내 문서와 같이 "LLM이 모르는 정보"는 대답할 수 없고, 아는 척(Hallucination, 환각)을 하기도 한다. RAG는 질문이 들어오면 먼저 자료를 "검색"하여, 관련 있어 보이는 부분을 답변의 재료로서 함께 전달해 주는 메커니즘이다. 커닝 페이퍼를 보면서 대답해도 되는 시험이라는 뜻이다.
조금 더 분해하면, RAG는 3단계로 작동한다. 도서관 사서분을 상상해 보라.
Retrieve (검색) — 질문과 관계가 있을 법한 자료를 서고에서 찾아온다. 사서가 책을 몇 권 골라서 가져오는 단계. -
Augment (합성) — 찾아온 자료를 질문 문장과 결합하여 "이것을 참고해서 대답해"라는 형태로 정리한다. -
Generate (생성) — LLM이 그 자료를 읽고 답변을 작성한다. -
여기서, 잘 모를 때 혼동하기 쉬운 용어들을 미리 전부 풀어서 설명해 두겠다.
청크 (chunk) — 자료를 검색할 수 있는 단위로 나눈 "덩어리". 책 전체는 너무 크기 때문에 단락이나 섹션 단위로 쪼갠다. 이 "쪼개는 방식"이 나중에 큰 영향을 미친다. -
임베딩 (embedding) — 문장을 의미를 나타내는 숫자 열 (Vector, 벡터)로 변환한 것. "반품"과 "반납"처럼 단어는 다르지만 의미가 가까운 것을 가까운 좌표에 둘 수 있다. -
벡터 검색 (Vector Search) — 질문도 임베딩으로 변환하여, 의미가 가까운 청크를 좌표의 근접도로 찾는 방법. -
Top-k (top-k) — 검색에서 상위 몇 건을 가져올 것인가 하는 건수. top-5라면 상위 5개 청크.
BM25 — 전통적인 키워드 검색의 대표 주자. 단어가 얼마나 일치하는지로 찾는다. 의미는 모르지만 고유명사나 모델 번호의 "완전 일치"에 강하다. -
여기까지가 토대다. 문제는 언제나 "1의 Retrieve (검색)"에서 발생한다. 사서가 엉뚱한 책을 가져온다면, 아무리 똑똑한 사람(LLM)이라도 좋은 답을 쓸 수 없다. 당연한 이야기다.
검색이 실패할 때, 범인은 대개 이 4명 중 하나다. 구체적인 예로, 사내에 "XR-200"이라는 가상의 제품 매뉴얼이 있다고 가정하고 살펴보자. 사용자의 질문은 "XR-200의 반품 조건은?"이라고 하자.
범인 1: 의미는 가깝지만 용도가 다른 청크를 가져옴
벡터 검색은 "의미의 근접성"으로 찾는다. 하지만 이것은 양날의 검이다. "반품 조건"으로 검색하면 "환불 절차", "교환 흐름"처럼 의미는 가깝지만 이번에 묻지 않은 부분까지 상위에 올라오게 된다. 비슷한 것을 찾는 능력이 역으로 "어긋났지만 비슷한" 것을 가져오게 만든다.
범인 2: 고유명사·모델 번호에 약함
「XR-200」와 같은 모델 번호는 벡터 검색 (Vector Search)이 가장 취약한 부분입니다. 임베딩 (Embedding)을 하면 「XR-200」과 「XR-300」이 비슷한 좌표로 배치되기 쉬워, 다른 제품의 반품 조건을 당당하게 가져오기도 합니다. 사람 입장에서는 "번호가 다르잖아"라고 느끼지만, 의미 검색 (Semantic Search)에서는 그 차이를 식별하기 어렵습니다.
범인 3: チャンク (Chunk) 분할이 허술하여 답변이 단절되거나 섞임
"반품은 구매 후 14일 이내, 단 개봉된 제품은 제외"라는 문장이 チャンク (Chunk) 경계에서 잘려 있다면 어떨까요? "14일 이내"만 검색되고 "개봉된 제품은 제외"는 다른 チャンク (Chunk)로 넘어가 버리면, AI는 절반만 보고 답변하게 됩니다. 반대로, 관련 없는 정보까지 한 チャンク (Chunk)에 너무 많이 담아도 노이즈 (Noise) 때문에 내용이 희석됩니다.
범인 4: 정렬 순서가 좋지 않아 정답이 하단에 묻힘
검색 결과로 상위 20건 정도를 가져왔더라도, 정작 중요한 "정답 チャンク (Chunk)"가 15위쯤에 있다면 LLM에 전달할 3~5건 범위에서 누락됩니다. 검색은 되었지만, 전달되지 않은 것입니다. 이 문제는 생각보다 굉장히 자주 발생합니다.
흥미로운 점은, 이 네 명의 범인을 해결하는 방법이 각각 다르다는 것입니다. 따라서 단순히 "정밀도가 낮다"라고 뭉뚱그리지 말고, 어떤 범인인지를 구분하는 것이 첫걸음입니다. 이를 위해 다음으로는 "측정"에 대해 이야기하겠습니다.
이 부분은 가장 쉽게 건너뛰기 쉽지만, 가장 중요합니다. 측정할 수 없는 것은 고칠 수 없습니다.
"왠지 정밀도가 올라간 것 같다"라는 느낌으로 개선을 진행하면, 대개 다른 부분이 악화되고 있다는 사실을 알아차리지 못합니다. 그래서 먼저 체온계를 들어야 합니다. RAG의 체온계로서 2026년에 표준이 될 것은 RAG Triad와 RAGAS입니다.
먼저 사고의 틀로서 이해하기 쉬운 것이 TruLens의 **RAG Triad (3종 세트)**입니다.
Context Relevance (문맥 관련성) — 가져온 チャンク (Chunk)가 질문과 관련이 있는가? → 범인 1·2를 측정
Groundedness (접지성) — 답변이 가져온 자료에 제대로 기반하고 있는가? (날조하지 않았는가?)
Answer Relevance (답변 관련성) — 답변이 애초에 질문에 답하고 있는가?
이 세 가지가 갖춰져야 비로소 "올바르게 검색하고, 올바르게 근거로 삼으며, 올바르게 답변했다"라고 말할 수 있습니다. 하나라도 결여되면 그 부분이 고장 난 곳입니다.
더 세밀하게 수치로 측정하고 싶을 때는 RAGAS라는 OSS (Open Source Software)가 표준입니다. 핵심적인 4가지 지표를 쉽게 풀어서 설명해 두겠습니다.
Context Precision (문맥 정밀도) — 가져온 チャンク (Chunk) 중 관련 있는 것이 제대로 상위에 있는가. → 범인 4 (정렬 순서)에 유효
Context Recall (문맥 재현율) — 정답에 필요한 정보를 애초에 가져왔는가. → 범인 3 (분할 방식)에 유효
Faithfulness (충실성) — 답변이 검색 결과에 충실한가 (즉, 자료에 없는 내용을 말하지 않는가)
Answer Relevance (답변 관련성) — 답변이 질문에 답하고 있는가
여기서의 요점은 Precision (정밀도)과 Recall (재현율)을 나누어 보는 것입니다. Recall이 낮다면 "애초에 가져오지 못함" = チャンク (Chunk) 또는 검색의 문제. Precision이 낮다면 "가져오긴 했지만 순서가 나쁘거나 노이즈가 많음" = 리랭크 (Rerank)의 문제입니다. 이렇게 범인을 구분할 수 있습니다.
최소한의 평가 코드는 다음과 같은 이미지입니다 (RAGAS).
# pip install ragas datasets
from ragas import evaluate
from ragas.metrics import (
...
포인트는 개선하기 전에 이 수치 (Baseline)를 먼저 확보해 두는 것입니다. 이를 수행하지 않고 손을 대면, 좋아진 것인지 나빠진 것인지 평생 알 수 없게 됩니다. 이 부분은 인간의 영역입니다. "무엇을 정답으로 간주할 것인가"를 결정하는 세트 (20~50문항이면 충분합니다)를 만드는 것은 AI에게 통째로 맡길 수 없는 중요한 설계 판단입니다.
(출처: Ragas RAG Evaluation Metrics Complete Guide 2026 (qaskills.sh) / RAG Evaluation: Metrics, Tools, and the Context Gap 2026 (Atlan))
체온계를 갖췄다면 이제 본격적으로 고쳐 나갈 차례입니다. 우선 가장 근본적인 것은 チャンク (Chunk), 즉 자료를 나누는 방식입니다. 범인 3 (단절 및 혼입)을 해결하는 데 효과적입니다.
가장 흔히 저지르는 실수가 바로 **고정 길이 청킹 (Fixed-length Chunking)**입니다. "500자마다 기계적으로 자르는" 방식이죠. 구현은 쉽지만, 의미의 단절을 완전히 무시하기 때문에, 앞서 언급한 "14일 이내 / 개봉 완료 시 대상 제외"와 같이 문장 중간이 뚝 끊겨버리는 사고가 발생합니다.
그래서 2026년의 표준이 되고 있는 것이 **세만틱 청킹 (Semantic Chunking, 의미 단위로 자르기)**입니다. 인접한 문장의 의미(Embedding)를 비교하여, 화제가 바뀌는 지점(유사도가 급격히 떨어지는 지점)에서 구분하는 방식입니다. 어떤 비교에 따르면, 고정 길이 베이스라인에 비해 정확도가 약 71%까지 향상되었다는 보고도 있습니다.
import numpy as np
def semantic_chunk(sentences, embed_fn, threshold=0.6):
"""인접 문장의 의미가 멀어지는 지점에서 청크를 자르는 간이 버전.
...
그리고 또 하나, 눈에 띄지는 않지만 매우 중요한 것이 메타데이터 (Metadata)를 첨부하는 것입니다. 청크 단독으로 방류하지 않고, "어떤 문서의・어떤 헤딩의・몇 페이지인지・부모 청크는 무엇인지"를 함께 들려 보냅니다.
chunk = {
"text": "반품은 구매 후 14일 이내입니다. 단, 개봉 완료 시 대상에서 제외됩니다.",
"source": "XR-200_manual.pdf",
...
이것이 있으면 나중에 "출처를 명기하기", "제품별로 필터링하기(=범인 2인 모델명 문제 예방도 가능)", "부모 청크를 따라 앞뒤 문맥 보완하기"와 같은 작업들을 모두 할 수 있게 됩니다. 청킹 방식은 나중에 큰 효과를 발휘하는 투자라고 할 수 있습니다.
다음은 범인 2(고유명사·모델명에 약함)를 퇴치하겠습니다. 여기서 효과적인 것이 **하이브리드 검색 (Hybrid Search)**입니다.
생각은 간단합니다. 벡터 검색 (Vector Search, 의미에는 강하지만 완전 일치에는 약함)과 BM25 (키워드 완전 일치에는 강하지만 의미는 모름)를 둘 다 실행하여 결과를 섞는 것입니다. 한쪽의 빈틈을 다른 쪽이 메워줍니다. "XR-200" 같은 모델명은 BM25가 확실히 잡아내고, "반품하고 싶은데"와 같은 표현은 벡터 검색이 의미로 잡아냅니다.
섞는 방식의 표준은 **RRF (Reciprocal Rank Fusion)**입니다. 이름은 어려워 보이지만, 하는 일은 "각각의 검색 순위를 사용하여 점수를 더하는 것"뿐입니다. 양쪽 검색 모두에서 상위에 위치할수록 높은 점수를 부여하여 합산합니다.
def reciprocal_rank_fusion(result_lists, k=60):
"""여러 검색 결과(순위 포함)를 순위 기반으로 융합한다.
result_lists: [[doc_id, ...(벡터 검색 순위)], [doc_id, ...(BM25 순위)]]
...
RRF의 장점은 스케일이 서로 다른 두 검색을 순위라는 공통 언어로 공정하게 섞을 수 있다는 점입니다. 실무에서는 이것만으로도 충분히 효과적입니다. 많은 벡터 DB(2026년 시점에서는 주요 업체들이 하이브리드 검색을 표준으로 지원)에 내장되어 있으므로, 직접 구현하지 않아도 괜찮습니다.
마지막 레버는 **리랭크 (Re-rank, 재정렬)**입니다. 범인 4(정답이 아래쪽에 묻혀 있음)를 직접적으로 해결합니다. 개인적으로는 가장 비용 대비 효율이 높은 레버라고 생각합니다.
하는 일을 한마디로 요약하면, **"먼저 넓게 뽑고, 그 후에 엄격하게 다시 추리는 것"**입니다. 경험칙상, 20개를 뽑고, 리랭크로 5개로 압축한 뒤, 그중 3~5개를 LLM에 전달하는 흐름이 정석입니다.
"처음부터 정확하게 뽑으면 되지 않을까?"라고 생각하실 수 있습니다. 하지만 여기가 흥미로운 지점인데, 첫 번째 검색(벡터 또는 BM25)은 "빠르고 넓고 대략적으로" 찾는 데 특화되어 있어 세밀한 우열을 가리는 데는 서툽니다. 반면 리랭크에 사용하는 크로스 엔코더 (Cross-Encoder) 모델은 "질문과 청크를 하나씩 대조하여 이것이 정말 관련이 있는가?"를 정밀하게 채점하는 데 특화되어 있습니다. 느리지만 정확하죠. 그래서 "빠른 검색으로 후보를 모으고 → 정확한 리랭크로 다시 정렬한다"는 분업이 잘 맞아떨어지는 것입니다.
면접에 비유하자면, 서류 전형(검색)에서 20명을 추린 뒤, 그 후 한 명씩 심층 면접(리랭크)을 진행하여 상위 5명을 통과시키는 느낌입니다. 효과도 결코 작지 않은데, 추론 부하가 큰 쿼리의 경우 동일한 20개를 재정렬하는 것만으로 nDCG@10 지표가 0.13에서 0.40(약 3배)으로 개선되었다는 보고도 있습니다. 후보를 바꾸지 않고 순서만 바로잡았을 뿐인데 말이죠.
# pip install sentence-transformers
from sentence_transformers import CrossEncoder
# Cross-Encoder: 질문과 청크 쌍을 "관련도 점수"로 변환하는 모델
...
주의할 점으로, 리랭크 (Rerank)는 한 단계 더 많은 시간과 비용이 소요됩니다 (1건씩 채점하기 때문입니다). 따라서 「20건을 200건」과 같이 너무 넓게 확장하지 마세요. 20~50건을 5건으로 줄이는 정도가 실무에서의 스위트 스팟 (Sweet Spot)입니다. 이 부분은 체온계(RAGAS의 Context Precision)를 확인하면서, 양을 늘렸을 때 효과가 있는지 확인하며 진행하는 것이 좋습니다.
(출처: RAG Best Practices 2026 (CallMissed) / StackAI: RAG Best Practices for Enterprise AI)
검색 품질의 개선은 AI의 도움을 받을 수도 있습니다. 인간이 「무엇을 측정하고, 어디를 고칠지」를 결정하고, 실제로 손을 움직여야 하는 부분을 AI에게 맡기는 것입니다. 그러한 역할 분담을 위한 프롬프트(Prompt) 3개를 남겨둡니다. 범용적인 더미(Dummy)로 작성되어 있으므로, { } 부분을 자신의 내용으로 교체하여 사용하세요.
프롬프트 1: 쿼리 재작성 (검색 전에 질문을 정돈하기)
사용자의 가공되지 않은 질문은 검색에 적합하지 않은 경우가 많습니다. 이를 검색이 잘 이루어질 수 있는 형태로 풀어내도록 합니다.
당신은 검색 쿼리 설계 전문가입니다.
다음 사용자 질문을 문서 검색 시 히트율(Hit rate)이 높아지도록 재작성해 주세요.
# 사용자 질문
...
프롬프트 2: 청크 설계 리뷰 (자르는 방식을 진단받기)
당신은 RAG의 검색 품질을 진단하는 리뷰어입니다.
다음 청크 (Chunk) 분할 결과를 보고, 검색이 실패할 것 같은 부분을 지적해 주세요.
# 청크 (발췌)
...
프롬프트 3: 검색 실패의 트리아지 (원인 분류하기)
당신은 RAG 장애의 원인을 분류하는 엔지니어입니다.
다음 RAG 평가 스코어와 사례를 바탕으로, 병목 현상이 「검색의 재현율 (Recall)」인지, 「순서 (Precision)」인지, 아니면 「생성 (Faithfulness)」인지 분류해 주세요.
...
세 번째 프롬프트처럼, 스코어와 사례를 세트로 전달하여 분류하게 하는 것이 요령입니다. AI는 「순서가 나쁜 것인지, 애초에 검색이 안 된 것인지」를 숫자를 통해 논리적으로 좁혀줍니다. 여기서도 최종 판단은 인간이 하지만, 가설을 세우는 속도가 차원이 다르게 빨라집니다.
RAG의 검색 품질은 「AI에게 전부 맡기는 것」만으로는 잘 풀리지 않습니다. 인간이 설계·판단하는 부분과 AI에게 맡기는 부분을 명확히 나누어 두어야 합니다.
| 공정 | 인간이 설계·판단할 것 | AI에게 맡길 수 있는 것 |
|---|---|---|
| 평가 축 만들기 | 무엇을 정답으로 할 것인가, 모범 사례 세트(Golden Set) 작성 | 채점 초안 작성, 스코어 요약 |
| ... |
그리고 솔직하게 함정도 알려드립니다. 이곳을 모르면 조용히 사고가 발생합니다.
PII(개인정보)·기밀 정보가 청크에 섞임 — 검색 대상에 개인정보나 비밀 정보가 포함되어 있으면, 검색을 통해 그대로 답변에 노출됩니다. 수집 시 마스킹(Masking)·제외·액세스 제어를 결정하는 것은 인간의 업무입니다. 「편리하니까 전부 넣자」는 위험합니다. -
리랭크의 비용과 레이턴시 (Latency) — 효과적이라고 해서 후보군을 너무 넓히면 속도가 느려지고 비용이 높아집니다. 20~50건을 상한선으로 두고, 체온계를 확인하며 조절하세요. -
임베딩 모델 (Embedding Model)의 불일치 — 수집 시와 검색 시에 서로 다른 임베딩 모델을 사용하면 좌표계가 어긋나 검색이 망가집니다. 모델을 변경했다면 원칙적으로 인덱스 (Index)를 다시 만들어야 합니다. -
롱 컨텍스트 (Long Context)로 대체 가능한 상황도 있음 — 자료가 몇 페이지 되지 않는다면, 아예 전부 프롬프트에 넣는 것이 더 빠르고 정확할 수도 있습니다. RAG는 「자료가 너무 많아서 전부 전달할 수 없을 때」 사용하는 기술입니다. 목적이 「품질」인지 「비용·확장성」인지에 따라 사용할지 여부를 판단하세요. -
평가 없이 계속 돌리기 — 이것이 가장 큰 함정입니다. 체온계를 버리는 순간, 개선 작업은 감(感)에 의존하는 게임이 됩니다.
철수 라인(Retreat Line)도 심플합니다. 「모범 사례 세트로 측정하고, 좋아지지 않는 개선은 하지 않는다」. 이것만으로도 무의미한 구축 작업으로 실패하는 것을 상당 부분 방지할 수 있습니다.
갑자기 전부 할 필요는 없습니다. 효과가 큰 순서대로, 작게 하나씩 진행하세요.
체온계를 설치하기 — 모범 사례를 20문항만 만들어서, 현재 RAG의 Context Precision과 Recall을 측정합니다. 베이스라인 (Baseline)을 기록하세요. -
리랭크를 추가하기 — 20건을 검색하여 5건으로 압축합니다. 비용 대비 효과가 가장 높으므로 우선적으로 고려하세요. -
하이브리드 (Hybrid) 방식으로 전환하기 — 벡터 검색에 BM25를 더하고 RRF로 융합합니다. 모델 번호나 고유명사를 놓치는 경우가 줄어듭니다. -
청크를 재검토하기 — 고정 길이 방식을 버리고, 의미 단위로 자릅니다. 메타데이터 (Metadata)를 추가합니다.
하나를 넣을 때마다 체온계로 측정하세요. 좋아지면 남기고, 변하지 않으면 되돌립니다. 이것만으로도 당신의 RAG는 '가끔 맞히는 점괘'에서 '매번 신뢰할 수 있는 도구'로 가까워질 것입니다.
마지막으로, 이야기를 조금만 돌려보겠습니다.
RAG의 검색 품질을 정돈하는 작업은 솔직히 말해 지루합니다. 화려한 모델을 교체하는 것이 훨씬 기분 좋게 느껴질 것입니다. 하지만 저는 이렇게 생각합니다. 정보를 '찾는 것'과 '정확하게 인출(Retrieval)하는 것'은 완전히 별개의 문제입니다. 그리고 그 차이를 메우는 지루한 공사야말로 AI 프로덕트를 '도구'로 바꾸는 핵심입니다.
저는 항상 "이 선택이 내일의 나로 하여금 '감사합니다(あざっす)'라고 말하게 만드는 쪽은 어느 쪽인가?"를 기준으로 삼습니다. 오늘 체온계를 내려놓고 검색을 조금 정돈해 두는 것. 그것은 내일 그 프로덕트를 사용할 사람과, 반년 뒤 이 코드를 만질 자신에게 미리 받는 '감사 인사'의 선불인 셈입니다.
똑똑한 모델은 앞으로도 계속해서 쏟아져 나올 것입니다. 하지만 좋은 도구를 만드는 것은 모델의 똑똑함이 아니라, "올바른 재료를 올바르게 전달한다"는 당신의 설계입니다. 편리한 도구를 오랫동안 키워나가는 것. 그 첫걸음으로, 우선 자신의 RAG를 한 번 측정해 보지 않겠습니까?
내일의 당신이 분명 "감사합니다"라고 말해줄 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기