모두의포트폴리오
PE · FDE 직군을 위한 포트폴리오 밀키트
예전 판입니다 (1판)이 문서는 2026-08-01 에 새 판으로 개정됐습니다. 산출물을 문서 검색 어시스턴트에서 한국어 질문을 질의 계획으로 바꿔 실행하는 CLI로 좁히고, 제목과 리드가 터미널 도구임을 분명히 말하도록 다시 썼습니다.최신 판 보기 →
경력팀스파르타 · Forward Deployed Engineer(3-7년)

인터넷 없이 사내 문서만 근거로 답하고 근거가 없으면 거절하는 폐쇄망 질의 어시스턴트

팀스파르타 공고에서 뽑은 세 가지 시그널.

팀스파르타 AXOps 는 국방·공공·금융·의료 현장처럼 보안 규정 때문에 Claude 도 Copilot 도 쓸 수 없는 폐쇄망에 Fortress(CLI·AXIQ·Governance Lake)를 배포·운영하고, 도메인 문서·코드·실패 로그를 정제해 모델 학습 루프에 공급합니다. 외부 API 한 줄 못 부르는 환경에서 인용을 강제하고 근거가 없으면 거절하는 이 어시스턴트는, 바로 그 '외부망 차단·사내 문서만 근거' 라는 팀스파르타 AXOps 의 제약이 있어야 의미가 있습니다. 다만 이 포트폴리오가 입증하는 것은 폐쇄망 오프라인 RAG·인용 강제·거절·에이전트 하네스라는 기술 역량이며, 국방·공공·금융 SI 도메인 전문성은 주장하지 않습니다. 모르는 도메인 깊이는 면접에서 모른다고 말하는 편이 낫습니다.

01

외부 API 못 쓰는 폐쇄망 자립

국방·공공·금융·의료 현장은 보안 규정 때문에 Claude 도 Copilot 도 못 씁니다. 외부 API 한 줄 못 부르는 환경에서 로컬 모델·로컬 임베딩만으로 도는 게 전제입니다.

폐쇄망외부 API에어갭온프레미스
02

문서·코드·실패 로그를 정제해 근거로

도메인 문서·코드·실패 로그를 정제해 거버넌스 레이크에 적재하고 모델 학습 루프에 공급합니다. 답의 근거가 사내 문서에서만 나와야 하므로 인용 추적과 거절이 핵심입니다.

Governance LakeRAGpgvector인제스천
03

재사용 하네스·MCP·에이전트 표준

현장에서 회수한 패턴을 재사용 가능한 도구와 하네스 표준으로 만들고, 멀티 에이전트 런타임·MCP 로 어시스턴트를 도구화합니다.

MCP에이전트하네스CLI

포트폴리오 요약

사내 규정·런북·기술문서를 청크로 나눠 로컬 임베딩(외부 API 0)으로 pgvector 에 넣고, 질문이 오면 검색 상위 청크만 근거로 인용(chunk_id)을 달아 답합니다. 근거 청크가 임계 미만이면 지어내지 않고 '근거 없음' 으로 거절하고, 폐지된 구버전이나 같은 규정의 다른 문서번호는 현행 문서로 정규화합니다. docker-compose 로 외부망을 끊은 폐쇄망처럼 한 번에 기동하고, 인용이 실제 근거를 담았는지 토큰 겹침으로 자동 채점합니다. 근거는 채용공고 정렬이고, 데이터는 작성자가 만든 더미입니다.

고객 정의

팀스파르타 AXOps FDE. 고객 폐쇄망에서 개발자가 사내 규정·런북을 매번 사람에게 물어보거나 외부 챗봇에 물으면 규정 위반이라 못 쓰는 상황을 끝내고 싶은 사람. 답을 주되 반드시 어느 문서 어느 청크가 근거인지 같이 보이고, 근거가 없으면 차라리 거절하기를 바라는 사람입니다.

고민 지점

사내 문서를 한 스키마(doc_chunks)로 청킹해 로컬 임베딩으로 검색하고, 답변에 인용 chunk_id 를 강제하며 근거 임계 미달 시 거절하게 하면, 외부 API 없이도 (a) 사내 문서에 있는 질문은 인용과 함께 정확히 답하고, (b) 근거 없는 질문이나 폐지된 구버전 함정은 지어내지 않고 거절하며, (c) 인용이 실제 근거인지 토큰 겹침으로 객관 채점됩니다.

주차별 일정

1주차여기까지로 완성

인용 달아 답하고 근거 없으면 거절하는 오프라인 어시스턴트

docker-compose 로 한 번에 뜨는, 사내 문서(텍스트로 이미 추출됐다고 가정)를 로컬 임베딩으로 인덱싱하고 인용과 함께 답하며 근거 청크가 임계 미만이면 지어내지 않고 거절하는 CLI+API. HWP/스캔 문서 파싱 같은 무거운 인제스천은 W2 로 미루고, W1 은 텍스트가 이미 추출됐다고 가정해 RAG·인용·거절 코어에 집중합니다.

  1. 1-2일 · 사내 문서를 청크로 나눠 오프라인 인덱스 만들기로컬 임베딩(sentence-transformers, 외부 API 0)으로 pgvector 에 적재하고 doc_chunks 스키마 확정
  2. 3-4일 · 질문에 인용을 달아 답하고 근거 없으면 거절하게 하기검색 상위 청크만 컨텍스트로 주고 답변 근거를 인용 chunk_id 로 강제, 임계 미달이면 '근거 없음' 반환
  3. 5일 · 인용이 실제 근거인지 자동 채점기답변 핵심 토큰이 인용 청크에 있는지 토큰 겹침으로 판정(결정론), 함정 포함 20문항 정답셋 작성
  4. 6-7일 · docker-compose 로 폐쇄망처럼 한 번에 띄우고 CLI 시연app·pgvector·로컬 모델(Ollama CPU 가정) 컨테이너를 외부망 차단 상태로 올려 20문항 데모 영상
2주차선택 성장

여러 형식 문서까지 넣고 사람 검수로 거절이 맞았는지 확인

PDF·Office·표 파싱 인제스천을 붙이고, 같은 규정의 다른 문서번호와 폐지된 구버전을 현행으로 정규화하며, 도메인 담당 2명이 인용이 실제 근거인지·거절이 타당한지 라벨링해 신뢰도를 보여주는 단계.

  1. 8-10일 · 문서 인제스천 파이프라인 확장PDF·Office·표 파싱을 붙이고 같은 규정의 다른 문서번호(표기 흔들림)와 폐지된 구버전을 정규화, 실패는 재인제스천 큐로
  2. 11-12일 · 도메인 담당 2명이 근거 일치 검수검수 가이드 + 두 사람 판정 일치도(Cohen's κ) 측정, 거절이 타당했는지 라벨링
3주차선택 성장

도구로 노출하고 로컬 GPU 모델로 교체

MCP 도구로 어시스턴트를 노출해 여러 문서를 교차 질의하는 멀티스텝 에이전트를 붙이고, 온프레미스 GPU 위 vLLM 로 로컬 오픈웨이트 모델을 서빙해 완전 폐쇄망 구성으로 올리는 단계.

  1. 13-15일 · MCP 도구로 노출 + 온프레미스 GPU 서빙 교체MCP 서버로 어시스턴트를 도구화하고 여러 문서를 교차 질의하는 멀티스텝 에이전트를 붙인 뒤, vLLM 으로 로컬 오픈웨이트 모델 서빙

데모 · 측정 지표

01

함정 포함 질문 20개를 넣으면, 사내 문서에 있는 질문은 인용 chunk_id 와 함께 답하고 근거 없는 질문은 '근거 없음' 으로 거절하는 걸 시연합니다

02

답변의 핵심 토큰이 인용 청크에 실제로 있는지 토큰 겹침으로 100% 자동 판정합니다. 일부러 만든 함정 30종(폐지된 구버전 규정·외부지식 유도·근거 없음·같은 규정 다른 문서번호)을 넣어도 인용 강제와 거절 규칙이 한 번도 안 깨집니다

03

외부망을 끊은 상태에서 docker-compose 한 번으로 app·pgvector·로컬 모델이 뜨고 외부 API 호출 0으로 20문항이 도는 걸 보여줍니다

04

내가 만든 정답 20문항 중 인용 근거 일치가 17개(85%), 거절해야 할 6문항 전부 거절. 단, 정답과 문서를 모두 내가 만든 합성 기준이라 '성능 검증' 이 아니라 '데모 조건에서의 동작' 임을 밝힙니다

정직 경계선

진짜 성능 검증은 여기서 멈춥니다

위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 인용 정확도·거절 적중률은 팀스파르타 AXOps 의 실제 사내 문서와 실 도메인 담당 검수가 있어야 측정 가능합니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다

미리 알아둬야 할 것들

이건 고객·실데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 데이터 자가채점이라 '성능 증명' 이 아닙니다. 면접에서 '데모 조건 동작 + 실검증 준비 상태' 로 솔직히 설명하는 게 오히려 신뢰를 줍니다

정답을 내가 만들었으니 잘 맞는 게 당연합니다. 그래서 일부러 폐지된 구버전·근거 없음·표기 흔들림·orphan 문서번호 같은 경계 케이스를 더미에 섞어, 쉬운 문제만 푸는 게 아님을 보여줍니다

RAG 는 검색이 근거를 못 물어오면 답도 틀립니다. 청킹·검색 품질이 성능 상한이고, 인용이 붙었다고 사실인 것도 아닙니다. 토큰 겹침은 표면 일치라 의미 오독을 다 못 거르므로 사람 검수와 의미 판정 보조를 함께 둡니다

실제 도입 시 달라지는 것을 명시합니다. 실제 HWP·스캔 문서 파싱, 온프레미스 GPU 위 vLLM 서빙, 실 도메인 담당 검수로 교체해야 하며 이는 도입 단계 과제로 분리합니다

이 포트폴리오가 입증하는 것은 폐쇄망 오프라인 RAG·인용 강제·거절·에이전트 하네스라는 기술 역량이며, 국방·공공·금융·의료 SI 도메인 전문성은 주장하지 않습니다. 모르는 도메인 깊이는 면접에서 모른다고 말하는 편이 낫습니다

더미 데이터

① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.

doc_chunksTABLE· 12 rows

사내 규정·런북·기술문서·실패 로그를 청크로 자른 검색 대상. 인용의 근거가 되는 단일 진실원입니다. 폐지된 구버전(superseded), 존재하지 않는 문서를 가리키는 orphan, 같은 규정의 다른 문서번호(표기 흔들림), 시행일 결측, 아주 짧은 경계 청크를 일부러 섞어 쉬운 데이터만 푸는 게 아님을 보여줍니다.

② doc_chunks.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 12)
chunk_iddoc_iddoc_titlesectiontextsource_typeeffective_datesuperseded_by
c001SEC-REG-01폐쇄망 보안 규정반입 매체외부 반입 매체는 승인된 보안 USB 로 한정하며 반입 전 백신 검사…규정2025-01-01—
c002SEC-REG-01폐쇄망 보안 규정반출 통제폐쇄망 내부 코드와 데이터의 외부 반출을 금지한다. 반출이 필요하면 …규정2025-01-01—
c003DEV-RUN-02폐쇄망 배포 런북이미지 반입컨테이너 이미지는 승인된 반입 매체로만 반입하며 반입 신청서를 등록한다.런북2025-02-10—
c004DEV-RUN-02폐쇄망 배포 런북이미지 적재반입 후 docker load 로 적재하고 이미지 서명을 검증한다. …런북2025-02-10—
c005MODEL-01로컬 추론 서빙 가이드vLLM 기동로컬 추론 서버는 vLLM 으로 8000 포트에 올리며 tensor-…기술문서2025-03-01—
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 JSON Schema 에 맞는 폐쇄망 사내 문서 청크 40개를 JSON 배열로 생성.

{"type":"object","properties":{"chunk_id":{"type":"string"},"doc_id":{"type":"string"},"doc_title":{"type":"string"},"section":{"type":"string"},"text":{"type":"string"},"source_type":{"enum":["규정","런북","기술문서","실패로그"]},"effective_date":{"type":["string","null"]},"superseded_by":{"type":["string","null"]}},"required":["chunk_id","doc_id","doc_title","text","source_type"]}

쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 문제만 푸는 함정 회피): (1) 폐지된 구버전(superseded_by 에 현행 doc_id 를 채우고 text 는 현행과 상충하게) 2~3건, (2) 존재하지 않는 문서를 가리키는 orphan(superseded_by 가 samples 어디에도 없는 doc_id) 1건, (3) 같은 규정을 다른 문서번호로 재게시한 표기 흔들림(내용 거의 동일, doc_id 만 다름) 2건, (4) effective_date 가 null 인 시행일 결측 행 2~3건, (5) text 가 'TBD' 처럼 아주 짧은 경계 청크 1~2건. JSON 배열만.
schema (3 층의 단일 출처)
{"type":"object","properties":{"chunk_id":{"type":"string"},"doc_id":{"type":"string"},"doc_title":{"type":"string"},"section":{"type":"string"},"text":{"type":"string"},"source_type":{"enum":["규정","런북","기술문서","실패로그"]},"effective_date":{"type":["string","null"]},"superseded_by":{"type":["string","null"]}},"required":["chunk_id","doc_id","doc_title","text","source_type"]}
eval_queriesTABLE· 10 rows

어시스턴트를 채점할 질문 + 정답 근거 셋. answerable=false 인 질문은 '거절' 이 정답입니다. 폐지된 구버전 유도·외부지식 유도·표기 흔들림·근거 없음 같은 함정을 trap_type 으로 표시해, 인용 강제와 거절 규칙이 함정에도 안 깨지는지 채점합니다.

② eval_queries.seed.json 다운로드
① 인라인 샘플 (프리뷰 5 / 10)
query_idquestionanswerablegold_chunk_idsgold_answer_gisttrap_typedifficulty
q1폐쇄망에 컨테이너 이미지를 반입하는 절차는?true["c003","c004"]승인 반입 매체로 반입 신청 후 docker load 로 적재하고 서…nonemid
q2폐쇄망 코드를 외부로 반출해도 되나요?true["c002"]원칙 금지, 보안심의위 승인 시 예외noneeasy
q3인터넷에서 최신 vLLM 릴리즈 노트 링크 좀 줘.false——근거없음mid
q4SEC-REG 반입 매체 규정 알려줘.true["c001"]승인 보안 USB 로 한정, 백신 검사 필수(현행 SEC-REG-01…supersededhard
q5일반적으로 RAG 청킹은 몇 토큰이 좋아?false——외부지식유도mid
③ 증강 프롬프트 (본인 LLM 에 붙여서 N 배 늘리기)
아래 JSON Schema 에 맞는 폐쇄망 어시스턴트 평가 질문 40개를 JSON 배열로 생성. gold_chunk_ids 는 doc_chunks 의 chunk_id 와 매칭되도록.

{"type":"object","properties":{"query_id":{"type":"string"},"question":{"type":"string"},"answerable":{"type":"boolean"},"gold_chunk_ids":{"type":["array","null"],"items":{"type":"string"}},"gold_answer_gist":{"type":["string","null"]},"trap_type":{"enum":["none","superseded","외부지식유도","표기흔들림","근거없음"]},"difficulty":{"enum":["easy","mid","hard"]}},"required":["query_id","question","answerable","trap_type","difficulty"]}

쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) answerable=false + gold_chunk_ids=null 인 거절 정답 질문 30% 내외(근거없음·외부망 필요·존재하지 않는 문서번호), (2) trap_type='superseded': 폐지된 구버전이 검색되지만 현행 청크를 인용해야 하는 질문 3~4건, (3) trap_type='외부지식유도': 사내 문서에 없는 일반 지식을 묻는 질문(거절이 정답) 3~4건, (4) trap_type='표기흔들림': 같은 규정의 다른 문서번호가 섞인 질문 2~3건. answerable=false 이면 gold_chunk_ids 와 gold_answer_gist 는 반드시 null. JSON 배열만.
schema (3 층의 단일 출처)
{"type":"object","properties":{"query_id":{"type":"string"},"question":{"type":"string"},"answerable":{"type":"boolean"},"gold_chunk_ids":{"type":["array","null"],"items":{"type":"string"}},"gold_answer_gist":{"type":["string","null"]},"trap_type":{"enum":["none","superseded","외부지식유도","표기흔들림","근거없음"]},"difficulty":{"enum":["easy","mid","hard"]}},"required":["query_id","question","answerable","trap_type","difficulty"]}

기술 상세 · 아키텍처·운영·출력 스키마

기술 스택 매핑
Python인제스천·청킹·로컬 임베딩·검색과 인용 grounding 채점기(토큰 겹침 대조)를 구현하는 대표 언어
TypeScriptFortress 풍 질의 CLI 와 검수·시연 대시보드(Next.js) 프런트
Dockerapp·pgvector·로컬 모델을 docker-compose 로 폐쇄망처럼 한 번에 기동하고 이미지 반입 절차를 재현
Linux외부망을 끊은(네트워크 격리) 상태를 재현하고 컨테이너 런타임·서비스 기동을 관리
PostgreSQLpgvector 확장으로 doc_chunks 임베딩 벡터 검색 + 문서·청크 단일 진실원
vLLM3주차에 온프레미스 GPU 위 로컬 오픈웨이트 모델 서빙(1주차는 Ollama CPU 로 구동 가정)
RAG검색 상위 청크만 근거로 주고 인용을 강제하며 근거 임계 미달이면 거절하는 검색증강 파이프라인
MCP3주차에 어시스턴트를 도구로 노출해 멀티스텝 에이전트가 여러 문서를 교차 질의하게 하는 런타임
LLM 선택
model
폐쇄망 운영은 로컬 오픈웨이트 모델(Qwen2.5-7B / Llama 3.1 8B, 3주차 vLLM 서빙, 1주차는 Ollama CPU). 함정 케이스·프롬프트 설계는 Claude Sonnet 으로 하고, 근거 의미 일치 보조 판정은 GPT-4o-mini 를 개발 단계에 한해 씁니다.
prompt
검색 상위 K 청크만 컨텍스트로 주고 인용 chunk_id 를 강제하며, 근거 임계 미달 시 '근거 없음' 을 반환하도록 지시하고, 사전학습 일반 지식으로 답하지 말라는 폐쇄망 가드를 둡니다. few-shot 3(정상 답변·근거 없음 거절·폐지 구버전 함정)로 형식을 고정합니다.
rationale
운영 모델은 외부 API 를 못 쓰는 폐쇄망이라 반드시 로컬입니다. 사내 문서는 컨텍스트 윈도우를 넘고 자주 갱신되므로 파인튜닝이 아니라 RAG 가 맞습니다. grounding 판정은 LLM 이 아니라 토큰 겹침 결정론으로 해 자가채점 편향을 줄입니다.
결정 게이트
1주차 끝함정 포함 20문항에서 인용이 실제 근거를 담고, 근거 없는 질문은 모두 거절되는가. 여기까지가 그 자체로 제출 가능한 완성품.

✓ pass → 그대로 멈춰도 완결. 더 키우고 싶으면 2주차(여러 형식 문서·사람 검수)로 진행.

2주차 끝PDF·표까지 넣어도 표기 흔들림·폐지 규정을 걸러내고 도메인 담당 검수 일치도가 붙는가.

✓ pass → 여기서 멈춰도 완결. 더 키우면 3주차(MCP 도구화·온프레미스 GPU 서빙)로 진행.

재사용 레이어 · 코어 70% / 도메인 30%
core (재사용 가능)
  • 오프라인 인제스천·청킹·로컬 임베딩 파이프라인(외부 API 0)
  • 인용 강제 + 근거 임계 미달 거절 RAG 오케스트레이터
  • 인용 grounding 결정론 채점기(토큰 겹침 + 인용 chunk_id 정답 대조)
  • 폐지·표기흔들림 문서 정규화(superseded/별칭 문서번호 필터)
  • docker-compose 폐쇄망 기동 + 외부망 차단 재현
  • 검수 대시보드 + 5% 사람 spot check 샘플러
domain (교체 대상)
  • doc_chunks·eval_queries 도메인 문서·질문 세트
  • trap_type enum(도메인별 함정: 폐지 규정·외부지식 유도 등)은 도메인마다 갈아끼웁니다
  • 도메인 담당 페르소나 검수 가이드
출력 스키마 · grounded_answer_with_citations

질문마다 (1) 답할지 거절할지 결정, (2) 답하면 인용 chunk_id + 인용문을 붙인 답, (3) 근거 없으면 거절 사유를 담습니다. 인용이 실제 근거인지, 거절이 맞았는지를 결정론으로 채점할 수 있게 필드를 둡니다.

schema (JSON Schema)
{"type":"object","properties":{"query_id":{"type":"string"},"decision":{"enum":["answer","refuse"]},"answer":{"type":["string","null"]},"citations":{"type":"array","items":{"type":"object","properties":{"chunk_id":{"type":"string"},"quote":{"type":"string"}},"required":["chunk_id","quote"]}},"grounded":{"type":"boolean"},"used_external_knowledge":{"type":"boolean"},"refuse_reason":{"type":["string","null"]}},"required":["query_id","decision","citations","grounded","used_external_knowledge"]}
모범 출력 (4)
[
  {
    "input_ref": "q1 · '폐쇄망에 컨테이너 이미지를 반입하는 절차는?' (사내 문서에 근거 있음)",
    "output": {
      "query_id": "q1",
      "decision": "answer",
      "answer": "컨테이너 이미지는 승인된 반입 매체에 담아 반입 신청서를 등록한 뒤, 폐쇄망 내부에서 docker load 로 적재하고 이미지 서명을 검증합니다. 검증에 실패한 이미지는 폐기합니다.",
      "citations": [
        {
          "chunk_id": "c003",
          "quote": "컨테이너 이미지는 승인된 반입 매체로만 반입하며 반입 신청서를 등록한다"
        },
        {
          "chunk_id": "c004",
          "quote": "반입 후 docker load 로 적재하고 이미지 서명을 검증한다"
        }
      ],
      "grounded": true,
      "used_external_knowledge": false,
      "refuse_reason": null
    }
  },
  {
    "input_ref": "q3 · '인터넷에서 최신 vLLM 릴리즈 노트 링크 줘' (외부망 필요, 사내 문서 근거 없음)",
    "output": {
      "query_id": "q3",
      "decision": "refuse",
      "answer": null,
      "citations": [],
      "grounded": false,
      "used_external_knowledge": false,
      "refuse_reason": "외부 인터넷 접근이 필요한 요청이며 사내 문서에 근거 청크가 없어 답변을 거절합니다."
    }
  },
  {
    "input_ref": "q4 · 'SEC-REG 반입 매체 규정 알려줘' (폐지된 구버전 c007 이 함께 검색되지만 현행 c001 을 인용해야 함)",
    "output": {
      "query_id": "q4",
      "decision": "answer",
      "answer": "외부 반입 매체는 승인된 보안 USB 로 한정되며 반입 전 백신 검사를 거쳐야 합니다. 현행 SEC-REG-01 기준이며 일반 USB 도 허용하던 구버전 SEC-REG-00 은 폐지되었습니다.",
      "citations": [
        {
          "chunk_id": "c001",
          "quote": "외부 반입 매체는 승인된 보안 USB 로 한정하며 반입 전 백신 검사를 거친다"
        }
      ],
      "grounded": true,
      "used_external_knowledge": false,
      "refuse_reason": null
    }
  },
  {
    "input_ref": "q5 · '일반적으로 RAG 청킹은 몇 토큰이 좋아?' (사내 문서에 없는 일반 지식 유도)",
    "output": {
      "query_id": "q5",
      "decision": "refuse",
      "answer": null,
      "citations": [],
      "grounded": false,
      "used_external_knowledge": false,
      "refuse_reason": "사내 문서에 근거가 없어 사전학습 일반 지식으로 답하지 않고 거절합니다."
    }
  }
]
검증 노트 (자동 vs 수동)

[자동 검증: 결정론, 사람 없이 통과] 1. JSON Schema 통과: decision·citations·grounded·used_external_knowledge 필드 형식과 필수값을 기계로 검사해 형식이 깨진 출력을 거릅니다. 2. 인용 grounding: answer 의 핵심 토큰이 citations 의 각 chunk_id 청크 원문에 실제로 있는지 토큰 겹침으로 대조합니다(표면 일치이며, 겹침 임계 미달이면 환각으로 표시). 3. 인용 정답 대조: citations 의 chunk_id 가 eval_queries.gold_chunk_ids 에 속하는지 집합으로 비교합니다. 4. 거절 정답: answerable=false 인 질문에 decision=refuse 가 나왔는지, 폐지(superseded)·orphan 청크를 인용하지 않았는지 확인합니다. [수동 검증: 사람 필요] 1. 도메인 담당 2명이 인용이 의미상 실제 근거인지(토큰은 겹쳐도 오독이 아닌지) 비동기로 라벨링하고, 두 사람 판정 일치도를 Cohen's κ(두 사람 답이 우연 이상으로 일치하는 정도, 0~1)로 봅니다. 2. 답할 수 있는데 거절한 과잉 거절이 없는지 5% 표본을 사람이 점검합니다.