# RAG

RAG에 검색한 문단을 몇 개 넣어야 LLM이 맞힐까?

@Hong2026-10-04

이 글에 담긴 코드와 결과는 직접 실행해 측정한 값을 바탕으로 작성했습니다. 실측은 Hong과 팀원들이 진행했고, 그 결과를 바탕으로 AI가 글을 쓰고 Hong이 검토합니다.

실습 코드 내려받기

질문
RAG에서 검색한 문단을 몇 개 넣어야 LLM이 정답을 맞힐까?
답
정답 문단 하나만 넣으면 질문 14개 중 12개를 맞혔고, 비슷한 다른 문단을 2~9개 더해도 합계는 12~13개였으며, 정답 문단 위치에 따른 차이는 많아야 1개였다.
조건
Ollama 0.34.4, EXAONE 3.5 2.4B(Q4_K_M) CPU 추론, temperature: 0, seed: 42, num_ctx 8192, 이 사이트 글 72편, 질문 14개

환경

Ollama
0.34.4, Docker 컨테이너에서 CPU로만 추론
생성 모델
EXAONE 3.5 2.4B(Q4_K_M), temperature: 0, seed: 42, num_ctx 8192
임베딩·검색
intfloat/multilingual-e5-small, Qdrant(Cosine 거리, exact=True)
Docker
메모리 약 9.7GB·CPU 8개 가운데 메모리 5.5GB·CPU 3개 안에서 실행
데이터
이 사이트 글 72편(1,852,007자), 청크 1,411개
질문
자동 채점용 30개 가운데 14개(local 7개, general 7개)
목차
  1. 실습 준비
  2. 실습 1: 문단 없이, 정답 문단 하나만
  3. 실습 2: 정답 문단은 그대로 두고 방해 문단만 늘리기
  4. 실습 3: 틀린 답은 어디서 왔나
  5. 정리

이번 시간에는 LLM에 넣는 문단 수와 정답 문단의 위치를 바꿔 가며, 로컬 LLM이 정답을 몇 개 맞히는지 Ollama와 Qdrant로 측정하며 배워가는 시간입니다.

먼저 이런 장면을 하나 볼게요. 이 사이트의 글을 문단으로 잘라 로컬 LLM에 넣고 "청크 크기를 비교한 실험에서 512토큰을 넘어 뒷부분이 버려진 1600자 청크는 전체의 몇 퍼센트였나요?"라고 물었어요.

정답 문단 하나만 넣었을 때 모델은 92.8이라고 정확히 답했습니다. 그런데 같은 정답 문단을 맨 앞에 두고 비슷한 문단 두 개를 뒤에 더 넣자 답이 91.3%로 바뀌었어요. 함께 넣은 다른 문단의 숫자를 가져온 거죠.

그래서 자동 채점이 가능한 질문으로, 넣는 문단 수와 정답 문단의 위치를 바꾸면 정답률이 어떻게 변하는지, 틀린 답은 어디서 왔는지 직접 재 볼게요.

검색 단계에서 정답 문단이 상위 몇 개 안에 드는지가 더 궁금하시면 청크 크기를 다룬 글을 참고해 주세요.

실습 준비

이 글의 명령은 모두 실습 코드의 rag-context-size/ 디렉터리에서 실행합니다.

  • compose.yaml: Ollama, Qdrant, Python 컨테이너 두 개(채점용, 색인용) 정의
  • requirements.txt: 색인용 패키지
  • prep.py: 글 목록 파일(매니페스트)에 등록된 글을 읽어 out/docs.jsonl로 저장하는 스크립트
  • ctx.py: 청크 나누기, 색인(index), 방해 문단 고르기(contexts) 하위 명령
  • qa.jsonl: 질문 30개와 정답 문단, 정답 표기
  • llm.py: 설정 이름대로 문단을 넣어 Ollama에 묻고 결과를 저장하는 스크립트
  • grade.py: 채점·집계 스크립트

컨테이너는 네 개를 씁니다.

  • ollama: 생성 모델을 돌리는 Ollama 0.34.4예요.
  • bench: Ollama API를 부르고 답을 채점하는 Python 컨테이너예요. 표준 라이브러리만 써서 따로 설치할 패키지가 없어요.
  • qdrant, embed: 문서를 청크로 나눠 임베딩하고 검색하는 Qdrant와 Python 컨테이너예요. index 프로필로 묶어 두고 색인을 만들 때만 띄웁니다.

실습 전체를 메모리 5.5GB, CPU 3개 안에 두려고, 색인을 만드는 동안에는 Ollama를 멈추고 LLM을 돌리는 동안에는 Qdrant와 embed를 멈춥니다. compose.yaml은 컨테이너마다 상한(ollama 메모리 5GB·CPU 2.75개, bench 256MB·0.25개, qdrant 512MB·0.5개, embed 2GB·2.25개)을 걸어 두었어요.

dc는 이 실습의 docker compose를 부르고, ix는 색인용 컨테이너에서, llm은 bench 컨테이너에서 Python을 실행하는 함수예요.

아래 블록은 파일로 만들지 말고 실습 디렉터리에서 연 터미널에 그대로 붙여 넣어 주세요. 이후 명령은 모두 이 터미널에서 실행하고, 터미널을 새로 열면 다시 붙여 넣으시면 됩니다.

export ARTICLES_DIR=/path/to/articles
mkdir -p out

dc() { docker compose -p rctx "$@"; }

ix() { dc --profile index exec -T embed python "$@"; }

llm() { dc exec -T bench python "$@"; }

compose.yaml의 ollama 쪽 환경 변수 세 개는 이런 역할을 해요.

  • OLLAMA_KEEP_ALIVE: "-1": 실습 중에 모델을 메모리에서 내리지 않습니다.
  • OLLAMA_NUM_PARALLEL: "1": 요청을 한 번에 하나씩 처리합니다.
  • LLAMA_ARG_CACHE_RAM: "1024": Ollama 0.34.4가 모델을 돌리는 llama-server 프로세스는 앞서 처리한 프롬프트의 계산 결과를 메모리에 모아 둬요(프롬프트 캐시). 상한 기본값이 8192MiB라서, 메모리를 5GB로 제한한 이 컨테이너에서는 llama-server가 강제 종료되고 요청이 500 오류로 끝났어요. 이 값으로 1024MiB까지 줄였습니다.

bench는 요청마다 options.num_thread를 넘겨 스레드 수를 CPU 제한 안쪽으로 맞춰요(NUM_THREAD 환경 변수). 컨테이너 안에서도 CPU가 8개로 보여서 llama-server가 스레드를 8개 띄우는데, cpus: 2.75로 제한된 컨테이너에서는 이 스레드들이 나눠 쓰다 멈추기를 되풀이해 크게 느려졌기 때문이에요.

Docker Desktop for Mac의 컨테이너는 Apple GPU(Metal)를 쓰지 못해서 CPU로만 추론해요. 그래서 작은 모델인 LG AI연구원의 EXAONE 3.5 2.4B를 받습니다.

dc up -d ollama bench
dc exec -T ollama ollama pull exaone3.5:2.4b-instruct-q4_K_M
dc exec -T ollama ollama show exaone3.5:2.4b-instruct-q4_K_M

출력에서 모델 정보 부분만 옮겼어요.

  Model
    architecture        exaone
    parameters          2.7B
    context length      32768
    embedding length    2560
    quantization        Q4_K_M

이름은 2.4B인데 ollama show는 파라미터를 2.7B로 보여 줘요. 최대 컨텍스트는 32768토큰이에요. 라이선스는 "EXAONE AI Model License Agreement 1.1 - NC"이고 결과물을 포함해 상업적 이용을 금지하니, 서비스에 넣으려면 별도 계약이 필요해요.

이제 Ollama를 멈추고 색인용 컨테이너를 띄울게요.

청크는 문서를 검색 단위로 잘라 놓은 조각이에요. 여기서는 코드 블록을 지우고 문단을 이웃끼리 800자까지 합친 뒤, 앞에 글 제목과 글 안의 소제목을 붙여 만듭니다. 임베딩 모델은 intfloat/multilingual-e5-small이에요.

prep.py는 매니페스트에 등록된 글만 읽어 SVG 도식을 지우고 out/docs.jsonl에 한 줄씩 저장합니다. 색인할 문서는 이 사이트에 발행된 글 72편(1,852,007자)이라 글에 따로 싣지 않았어요. 여러분 문서로 따라 하실 때는 ARTICLES_DIR에 같은 매니페스트 형식의 문서 디렉터리를 주시면 됩니다.

ctx.py index는 청크를 모두 임베딩해 Qdrant 컬렉션에 올리고, 같은 청크를 out/chunks.jsonl에도 남겨요. 아래는 색인용 컨테이너가 설치할 requirements.txt입니다.

--extra-index-url https://download.pytorch.org/whl/cpu
torch==2.14.1+cpu
sentence-transformers==6.1.0
transformers==5.18.0
qdrant-client==1.19.1
numpy==2.5.3
dc stop ollama
dc --profile index up -d qdrant embed
dc --profile index exec -T embed pip install -q -r requirements.txt
ix prep.py
ix ctx.py index
문서 72편
전체 1,852,007자, 코드 블록을 뺀 산문 784,428자
가장 짧은 글 11,301자, 가장 긴 글 48,315자
청크 1411개, 평균 622자, 임베딩 520초

청크 1,411개가 Qdrant 컬렉션 하나(Cosine 거리)에 들어갔습니다. 검색은 전체 비교(exact=True)로 해서 다시 돌려도 결과가 같아요.

자동 채점할 수 있는 질문

다른 LLM에게 답이 맞는지 판정을 맡기면 판정하는 모델의 실수가 결과에 섞여요. 그래서 숫자, 설정 이름, 오류 번호처럼 원문에 그대로 적힌 값을 묻고, 답이 문자열 비교만으로 갈리는 질문만 골랐어요.

  • local 15개: 이 사이트 글의 실습에서만 나온 숫자예요. 모델이 학습으로 알 수 없는 값이라, 문단을 읽어야만 맞힐 수 있어요.
  • general 15개: 공식 기본값이나 오류 번호처럼 모델이 학습으로 알고 있을 수도 있는 값이에요.

qa.jsonl의 줄마다 gold_passage(정답이 나오는 글의 산문에서 그대로 복사한 문장)와 answers(정답으로 인정할 표기 목록)가 있어요. gold_passage가 든 청크가 정답 문단입니다. 실험을 돌리기 전에 파일을 확정하고 sha256 해시를 남겼고, 결과를 본 뒤에 고치지 않았습니다.

문단 수와 정답 문단 위치

  • 문단 수 k: LLM에 함께 넣는 문단 개수예요. 0(문단 없음), 1(정답 문단만), 3, 5, 10을 씁니다.
  • 정답 문단 위치: 정답 문단을 앞(1번), 가운데((k+1)//2번), 끝(k번) 가운데 어디에 두는지예요. k=5면 3번, k=10이면 5번이 가운데입니다.

정답 문단이 아닌 나머지 문단은 방해 문단이라고 부를게요. 질문으로 실제 검색을 돌려 나온 순위에서, 정답 문단과 정답 값이 들어 있는 문단을 빼고 앞에서부터 9개를 질문마다 고정해 둬요. k개 구성은 이 9개 가운데 앞 k-1개에 정답 문단을 정해진 자리에 끼워서 만듭니다.

이렇게 하면 설정 사이의 차이는 문단 수와 위치에서만 나게 됩니다. contexts는 이 방해 문단과, 순위 그대로의 상위 10개를 함께 out/contexts.jsonl에 저장해요.

ix ctx.py contexts
shasum -a 256 qa.jsonl out/contexts.jsonl
dc --profile index stop qdrant embed
dc up -d ollama bench
[ 1] 정답 청크 검색 순위 1  방해 청크 9개
[ 2] 정답 청크 검색 순위 1  방해 청크 9개
...
[19] 정답 청크 검색 순위 29  방해 청크 9개
...
45eafeb28b458d85bf45c719e08b2886ea476ae92d4e2d6d73b59be437df92fa  qa.jsonl
d072c5d35eee188612b5c6bbfaa89de114f01701206527fb0dcc71868b3a69ca  out/contexts.jsonl

프롬프트와 채점 규칙

llm.py는 설정 이름을 보고 넣을 문단을 정해요.

  • k0, k1: 문단 없음, 정답 문단만이에요.
  • fix-k5-mid: 방해 문단 실험이에요. k=5이고 정답 문단을 가운데에 둡니다. 위치는 front, mid, end가 있어요.
  • ret-k10, ret-k5: 검색 순서 실험이에요. 방해 문단을 고르지 않고 검색 상위 10개(ret-k5는 5개)를 순위대로 넣습니다.

LLM 호출은 Ollama의 /api/chat에 보내요. 문단마다 [1], [2] 번호를 붙여 user 메시지에 넣고, 질문은 문단 뒤에 둡니다.

  • format: {"answer": string, "evidence": [integer]} 모양의 JSON 스키마예요. Ollama가 이 모양을 벗어나는 토큰을 만들지 않게 막아 줘요.
  • options: temperature: 0, seed: 42, num_predict: 128, num_ctx: 8192예요. num_ctx는 모델이 한 번에 받는 컨텍스트 길이 설정입니다.

채점은 정답 표기와 문자열을 비교해서만 해요.

  • 정규화: 유니코드 NFKC로 맞추고 소문자로 바꾼 뒤, 공백, 쉼표, 백틱, 따옴표를 지워요.
  • 정답: 정규화한 답 안에 answers 가운데 하나가 들어 있으면 정답이에요. 다만 숫자 앞뒤에 다른 숫자가 붙으면 안 됩니다.
  • 모름: 정답이 아니고 모름이 들어 있으면 모름이에요.
  • 오답: 나머지는 모두 오답입니다.

오답이 나오면 그 값이 어디서 왔는지도 나눠 봐요. 오답에서 숫자를 뽑아(숫자가 없으면 답 전체를) 함께 넣은 방해 문단에서 찾고, 있으면 "다른 문단의 값", 정답 문단에만 있으면 "정답 문단의 다른 값", 어디에도 없으면 "문맥에 없는 값"으로 셉니다.

CPU로만 돌려서 시간이 오래 걸리기 때문에, 질문을 유형별로 id가 작은 7개씩, 14개(local 1~7번, general 16~22번)로 줄였어요. 질문 하나의 설정을 이어서 돌면 앞부분이 같은 프롬프트를 캐시에서 꺼내 쓸 수 있어서, 앞부분이 같은 설정끼리 붙였습니다.

IDS=1,16,2,17,3,18,4,19,5,20,6,21,7,22
llm llm.py chain $IDS k0 fix-k10-front fix-k5-front fix-k3-front k1 \
  fix-k10-end fix-k10-mid fix-k5-end fix-k5-mid fix-k3-end fix-k3-mid ret-k10 ret-k5

실제로는 14개 질문의 본 실험에 2시간 15분이 걸렸어요. 질문 하나가 7.1%포인트이기 때문에, 아래에서는 비율 대신 "14개 중 몇 개"와 바뀐 질문의 id로 적을게요.

실습 1: 문단 없이, 정답 문단 하나만

먼저 문단 없이 질문만 보낸 경우(k=0)와 정답 문단 하나만 넣은 경우(k=1)부터 볼게요.

llm grade.py basic
문단 없음 k=0        local 정답  0 모름  7 오답  0 (/7) | general 정답  0 모름  7 오답  0 (/7) | 합계 정답 0
정답 문단만 k=1       local 정답  7 모름  0 오답  0 (/7) | general 정답  5 모름  0 오답  2 (/7) | 합계 정답 12
k=0에서 맞힌 local 질문: []
k=0에서 맞힌 general 질문: []

문단이 없을 때 모델은 14개 모두 "모름"이라고 답했어요. system 프롬프트가 "문단에 적힌 내용만 근거로" 답하라고 했고, 이 모델은 그 지시를 지켰습니다. 그래서 아래에서 맞힌 답은 모두 넣어 준 문단에서 나온 것으로 볼 수 있어요.

정답 문단 하나만 넣으면 local 7개는 모두 맞혔고, general은 7개 중 5개를 맞혔어요. 틀린 두 개는 이렇습니다.

  • 16번: "deadlock이 나서 롤백된 트랜잭션은 몇 번 오류를 받나요?"에 1이라고 답했어요. "몇 번"을 오류 번호가 아니라 횟수로 읽은 것으로 보여요.
  • 18번: binlog_expire_logs_seconds 기본값을 초로 물었는데, 원문의 "기본값 2592000초는 30일입니다"에서 뒤의 값을 가져와 30일이라고 답했어요. 정답 표기에 넣지 않은 그대로 오답으로 셌습니다.

실습 2: 정답 문단은 그대로 두고 방해 문단만 늘리기

이제 정답 문단을 넣은 채로 방해 문단을 2개, 4개, 9개로 늘리고, 정답 문단의 자리를 앞, 가운데, 끝으로 옮겨 볼게요. 근거 번호 적중은 모델이 evidence에 정답 문단 번호를 넣은 응답 수예요.

llm grade.py fixed
k=1              local 정답  7 모름  0 오답  0 (/7) | general 정답  5 모름  0 오답  2 (/7) | 합계 정답 12
fix-k3-front     local 정답  6 모름  0 오답  1 (/7) | general 정답  6 모름  0 오답  1 (/7) | 합계 정답 12 | 근거 번호 적중 14
fix-k3-mid       local 정답  6 모름  0 오답  1 (/7) | general 정답  6 모름  0 오답  1 (/7) | 합계 정답 12 | 근거 번호 적중 6
fix-k3-end       local 정답  6 모름  0 오답  1 (/7) | general 정답  6 모름  0 오답  1 (/7) | 합계 정답 12 | 근거 번호 적중 3
fix-k5-front     local 정답  6 모름  0 오답  1 (/7) | general 정답  6 모름  0 오답  1 (/7) | 합계 정답 12 | 근거 번호 적중 13
fix-k5-mid       local 정답  6 모름  0 오답  1 (/7) | general 정답  7 모름  0 오답  0 (/7) | 합계 정답 13 | 근거 번호 적중 2
fix-k5-end       local 정답  6 모름  0 오답  1 (/7) | general 정답  6 모름  0 오답  1 (/7) | 합계 정답 12 | 근거 번호 적중 5
fix-k10-front    local 정답  6 모름  0 오답  1 (/7) | general 정답  7 모름  0 오답  0 (/7) | 합계 정답 13 | 근거 번호 적중 14
fix-k10-mid      local 정답  6 모름  0 오답  1 (/7) | general 정답  7 모름  0 오답  0 (/7) | 합계 정답 13 | 근거 번호 적중 0
fix-k10-end      local 정답  6 모름  0 오답  1 (/7) | general 정답  7 모름  0 오답  0 (/7) | 합계 정답 13 | 근거 번호 적중 8

fix-k3-front    k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [18]
fix-k3-mid      k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [18]
fix-k3-end      k=1 대비 잃은 질문 [1, 19]  새로 맞힌 질문 [16, 18]
fix-k5-front    k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [18]
fix-k5-mid      k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [16, 18]
fix-k5-end      k=1 대비 잃은 질문 [1, 20]  새로 맞힌 질문 [16, 18]
fix-k10-front   k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [16, 18]
fix-k10-mid     k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [16, 18]
fix-k10-end     k=1 대비 잃은 질문 [1]  새로 맞힌 질문 [16, 18]

합계를 보면 k=1의 12개에서 12~13개 사이를 오가요. 그런데 합계만 보면 놓치는 게 있어요.

  • 잃은 질문: 1번은 방해 문단을 하나라도 넣은 9개 설정 모두에서 틀렸어요. 그 밖에는 k=3 끝에서 19번, k=5 끝에서 20번을 잃었고, 두 번 모두 정답 문단 안의 다른 숫자를 답했어요.
  • 새로 맞힌 질문: 16번과 18번이에요. 문단이 하나일 때 1, 30일이라고 답했던 두 질문이 방해 문단이 들어오자 1213, 2592000으로 바뀌었어요. 방해 문단에 정답의 단서가 있었던 건 아니에요.

이번에는 위치를 볼게요. 같은 k에서 앞, 가운데, 끝의 정답 수 차이는 많아야 1개예요. 질문 14개에서 질문 하나 차이는 우연과 구분할 수 없습니다.

이 모델과 이 길이(문단 10개, 프롬프트 4,300토큰 이하)에서는 정답 문단이 가운데에 있다고 답을 놓치는 모습이 보이지 않았어요. "LLM은 긴 문맥의 가운데를 놓친다"는 말은 Liu 등의 2023년 논문 "Lost in the Middle: How Language Models Use Long Contexts"에서 널리 퍼졌는데, 모델과 길이가 다르면 결과도 다를 수 있어요.

오히려 위치에 따라 크게 달라진 건 근거 번호였어요. 정답 문단이 앞에 있으면 14개 중 13~14개가 근거 번호를 맞혔지만, k=10 가운데에서는 0개였습니다. 정답 수는 13개로 가장 많은 쪽인데도요.

실습 3: 틀린 답은 어디서 왔나

이제 방해 문단 실험과 검색 순서 실험의 오답을 출처별로 나눠 볼게요.

llm grade.py wrong
방해 문단 실험과 검색 순서 실험의 오답 23건
  다른 문단의 값: 19건  질문별 {1: 11, 2: 2, 16: 3, 17: 2, 18: 1}
  정답 문단의 다른 값: 2건  질문별 {19: 1, 20: 1}
  문맥에 없는 값: 2건  질문별 {16: 2}

[1] 청크 크기를 비교한 실험에서 512토큰을 넘어 뒷부분이 버려진 1600자 청크는 전체의 몇 퍼센트였나요?
  설정 fix-k10-end, 정답 92.8, 모델 답 '91.3%', 근거로 든 번호 [1]
  [1] embedding-model-compare: ... e5가 버리는 뒷부분의 평균 글자 수를 출력합니다. 1600자 청크의 91.3%가 512토큰을 넘고, e5는 그런 청크에서 평균 555자를 버...

[2] Docker 이미지 크기 실습에서 README 한 줄을 고치고 다시 빌드한 Node.js 이미지의 풀린 크기는 몇 MB였나요?
  설정 ret-k10, 정답 1326, 모델 답 '170MB', 근거로 든 번호 [1]
  [2] docker-image-size: ...? Docker 레이어 캐시와 멀티 스테이지 빌드로 1.3GB 이미지를 170MB까지 실습 앱과 측정 방법 ### 이미지 크기는 두 가지로 잽니...
  [3] docker-image-size: ...? Docker 레이어 캐시와 멀티 스테이지 빌드로 1.3GB 이미지를 170MB까지 정리 무엇을 쟀는지 밝힙니다. containerd 이미지 ...

[17] MySQL innodb_lock_wait_timeout의 기본값은 몇 초인가요?
  설정 ret-k10, 정답 50, 모델 답 '31536000초', 근거로 든 번호 [1]
  [1] mysql-online-ddl-mdl: ...대 시간은 `lock_wait_timeout`이 정합니다. - 기본값: 31536000초(1년). 사실상 끝없이 기다립니다. - 범위: 1~31...
  [2] mysql-lock-wait-timeout: ... 기다리는 메타데이터 잠금은 `lock_wait_timeout`(기본값 31536000초, 1년)이 따로 정합니다. 값을 키운다고 deadloc...

오답 23건 가운데 19건이 함께 넣은 다른 문단에 나오는 값이었어요. 다만 이 19건은 두 가지를 감안해서 읽어야 해요.

  • 1번 질문 하나가 11건이에요. 방해 문단이 들어간 모든 설정에서 같은 91.3%를 답했어요. 오답이 한 번이라도 난 질문은 7개예요.
  • 16번의 1, 2와 18번의 60은 한두 자리 숫자라 어느 문단에나 나와요. 그래서 사례로는 세 자리 이상인 값만 골랐습니다.

남는 사례는 1번(91.3%), 2번(170MB), 17번(31536000초)이에요. 셋 다 모델이 값을 지어낸 게 아니라, 질문과 같은 모양의 문장("1600자 청크의 몇 %", "이미지 크기", "lock_wait_timeout 기본값")이 있는 다른 문단에서 값을 가져왔어요.

17번은 설정 이름이 innodb_lock_wait_timeout과 lock_wait_timeout으로 한 단어만 다르고, 1번은 다른 글이 같은 실험을 다른 시점에 다시 잰 값입니다.

정리

범위: Ollama 0.34.4, EXAONE 3.5 2.4B(Q4_K_M) CPU 추론, temperature: 0, seed: 42, num_ctx 8192, 이 사이트 글 72편(청크 1,411개), 질문 14개(local 7개, general 7개).

  • 문단 없이 물으면 14개 모두 "모름"이었고, 정답 문단 하나만 넣으면 12개를 맞혔습니다. 같은 정답 문단에 방해 문단을 2~9개 더해도 합계는 12~13개였지만, 1번은 방해 문단을 넣은 9개 설정 모두에서 틀렸어요. 합계만 보지 말고 바뀐 질문을 봐 주세요.
  • 같은 k에서 정답 문단을 앞, 가운데, 끝에 둔 정답 수 차이는 많아야 1개였고, 모델이 적은 근거 번호는 k=10 가운데에서 14개 중 0개가 맞았어요. 가운데를 놓친다는 주장은 여러분 모델과 문단 수로 재 보고, 근거 번호는 답 문자열이 그 문단에 실제로 있는지 따로 확인해 주세요.
  • 오답 23건 중 19건이 함께 넣은 다른 문단의 값이었고, 세 자리 이상 사례는 질문과 같은 모양의 문장, 한 단어만 다른 설정 이름, 같은 실험을 다시 잰 값이 든 문단에서 왔어요. 이런 문단이 정답 문단과 함께 올라오는지 검색 결과를 점검해 보세요.
  • 출력은 싣지 않았지만 같은 실행의 검색 순서 실험(ret-k10, llm grade.py ret로 집계)에서 실제 검색 순서 그대로 상위 10개를 넣으면 정답 문단이 든 질문은 13개, 맞힌 질문은 10개였어요. 생성 정답률은 검색 적중을 넘기 어렵다고 보고 검색 지표부터 확인하세요.
내 링크 만들기