Reflection
경력근거: vector databases, RAG pipelines, agent orchestration, evaluations
※ 실제 산출물이 아닌 AI 예측 시안입니다.
Reflection의 이 자리는 고객사 인프라에 검색 파이프라인을 붙여 운영까지 책임지는 일이고, 자격요건에 벡터 데이터베이스와 검색 파이프라인이 함께 적혀 있습니다. 원본 문서는 고객사 쪽에서 우리 일정과 무관하게 바뀌기 때문에 색인이 뒤처지는 순간이 반드시 생기는데, 그때 옛 내용으로 답하면 시스템 전체의 신뢰가 무너집니다. 이 시차는 남의 문서를 색인해 주는 자리에서만 문제가 됩니다. 공고 업무는 파인튜닝 협업부터 하이브리드 배포까지 걸쳐 있는데 1주 범위에서 고를 수 있는 것은 하나라 색인 정합 축을 골랐습니다. 이 포트폴리오는 시각과 지문을 규칙으로 대조해 재색인 대상을 좁히는 기술을 보여줍니다. 임베딩 모델 선택이나 검색 품질 튜닝 자체의 전문성은 주장하지 않습니다. 그 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
벡터 데이터베이스와 검색 파이프라인, 평가에 대한 실무 경험을 요구합니다. 색인이 원본을 따라가는지 보는 일이 그 파이프라인 운영의 첫 점검입니다.
LLM 워크플로를 조율하고 고객사 인프라에 통합해 운영 시스템으로 배포하는 일이 업무입니다. 원본 문서는 고객사 쪽에서 바뀌므로 색인과 어긋나기 쉽습니다.
퍼블릭 클라우드와 사설망, 온프레미스를 오가는 배포에서 신뢰성을 지키는 일이 업무에 있습니다. 옛 내용으로 답하는 검색은 그 신뢰가 무너지는 자리입니다.
고객사 원본 문서 목록과 벡터 색인에 들어간 청크 목록을 대조해, 문서가 바뀐 뒤 다시 색인되지 않았거나 원본이 사라진 청크를 사유별로 나눠 출력하고 재색인 대상 목록을 남기는 CLI입니다. 판정은 문서 갱신 시각과 색인 시각, 본문 지문을 견주는 대조로 정합니다.
고객사에 검색 기반 응답 시스템을 붙여 놓은 파견 엔지니어입니다. 답이 옛날 규정으로 나온다는 문의가 오면 색인을 통째로 다시 돌리는데, 몇 시간이 걸리는 데다 정작 무엇이 문제였는지는 끝까지 모릅니다.
문서마다 갱신 시각과 본문 지문이 남아 있으면, 어느 청크가 옛 내용인지는 색인을 다시 돌리지 않아도 대조로 갈라집니다.
원본 문서 목록과 색인 청크 목록 파일을 인자로 받아 청크별 판정을 터미널에 출력하고 재색인 대상 목록을 떨구는 CLI입니다. 실제 벡터 저장소에 붙지 않고 내보낸 목록만 읽습니다.
검색 로그에서 각 청크가 몇 번 인용됐는지를 붙여, 자주 쓰이는 뒤처진 청크부터 다시 색인하도록 순서를 매기는 구성입니다.
문서 원천 사전을 파일로 분리해 고객사마다 다른 저장소 구성을 같은 판정으로 돌리고, 재색인 목록을 파이프라인이 받아 가게 내보냅니다.
담당자가 문서 40건과 색인 청크 목록을 넣어 뒤처진 청크가 사유별로 나뉜 판정표와 재색인 목록이 나오는 것을 시연합니다.
결측·중복·미등록 원천이 섞인 입력 30종을 넣어도 출력 형식이 깨지지 않고, 판정하지 못한 청크는 사유가 붙어 남습니다.
지문이 비어 있는 청크는 최신으로 세지 않고 지문 누락으로 따로 답니다. 확인하지 못한 것을 통과로 만들지 않습니다.
판정과 손으로 만든 정답표를 맞춰 사유별로 어긋난 건을 셉니다. 단, 목록과 정답을 모두 작성자가 만든 합성 기준이라 성능 측정이 아니라 데모 조건 동작입니다.
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 더미데이터 자가채점이며, 실제 정합률은 Reflection 고객사의 실제 문서 저장소와 실제 색인이 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
작성자가 문서와 색인을 함께 만들었습니다. 어긋난 곳을 잘 찾는 게 당연하니 원천 표기가 저장소마다 다른 건과 지문이 빈 건, 커넥터가 없는 원천을 목록에 함께 넣었습니다.
지문이 다르다고 해서 내용이 바뀌었다고 단정할 수 없습니다. 서식만 손본 갱신일 수 있으므로, 판정은 다시 색인할 후보라는 사실까지만 읽어야 합니다.
실제 도입하면 고객사마다 문서 갱신 시각을 남기는 방식이 다릅니다. 시각을 믿을 수 있는지 확인하는 일이 도입 단계의 실제 과제입니다.
검색 결과의 품질을 올리는 일은 이 도구의 범위 밖입니다. 색인이 원본을 따라가는지까지만 보므로, 청크 크기와 재정렬은 따로 다룹니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객사 저장소의 원본 문서 목록입니다. 원천 표기가 저장소마다 대소문자로 흔들리고, 사전에 없는 신규 원천과 같은 문서 번호가 두 번 들어온 건, 지문이 비어 있는 행을 일부러 섞었습니다.
| doc_no | source_raw | doc_title | updated_at | body_fingerprint | is_active |
|---|---|---|---|---|---|
| DC-001 | confluence | 환불 규정 | 2026-08-18T10:00 | fp-a1 | true |
| DC-002 | Confluence | 배송 규정 | 2026-07-02T09:00 | fp-b2 | true |
| DC-003 | CONFLUENCE | 교환 규정 | 2026-08-15T14:00 | fp-c3 | true |
| DC-004 | sharepoint | 회원 등급 | 2026-06-11T11:00 | fp-d4 | true |
| DC-005 | sharepoint | 적립금 정책 | 2026-08-19T08:00 | fp-e5 | true |
아래 JSON Schema에 맞는 원본 문서 행을 더 만들어 주세요. {"type":"object","properties":{"doc_no":{"type":"string"},"source_raw":{"type":"string"},"doc_title":{"type":"string"},"updated_at":{"type":"string"},"body_fingerprint":{"type":["string","null"]},"is_active":{"type":"boolean"}},"required":["doc_no","source_raw","doc_title","updated_at","body_fingerprint","is_active"]} doc_title은 한글로 적어 주세요. 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라. 첫째 미매핑으로 source_raw가 사전에 없어 source_id가 null인 행, 둘째 표기흔들림으로 같은 원천을 confluence와 Confluence와 CONFLUENCE처럼 대소문자만 다르게 적은 행, 셋째 중복으로 같은 doc_no가 두 행에 있는 재적재 건, 넷째 결측으로 body_fingerprint가 null인 행, 다섯째 is_active가 false인 폐지 문서. 색인과 시각이 맞는 정상 문서가 전체의 절반쯤 되게 해 주세요. 또한 형식 깨뜨리기 시도 3건을 별도 파일로 만들어 is_active에 문자열을 넣거나 updated_at을 빼서 스키마 검증이 걸러내는지 확인하게 해 주세요.{"type":"object","properties":{"doc_no":{"type":"string"},"source_raw":{"type":"string"},"doc_title":{"type":"string"},"updated_at":{"type":"string"},"body_fingerprint":{"type":["string","null"]},"is_active":{"type":"boolean"}},"required":["doc_no","source_raw","doc_title","updated_at","body_fingerprint","is_active"]}벡터 색인에 들어가 있는 청크 목록입니다. 원본이 사라진 청크와 문서가 바뀐 뒤 다시 색인되지 않은 청크를 만들어 두었습니다.
| chunk_no | doc_no | indexed_at | indexed_fingerprint | chunk_order | cited_count |
|---|---|---|---|---|---|
| CH-001 | DC-001 | 2026-08-18T12:00 | fp-a1 | 1 | 120 |
| CH-002 | DC-002 | 2026-06-30T09:00 | fp-b1 | 1 | 340 |
| CH-003 | DC-003 | 2026-08-16T09:00 | fp-c3 | 1 | 90 |
| CH-004 | DC-004 | 2026-06-12T09:00 | fp-d4 | 1 | 40 |
| CH-005 | DC-005 | 2026-08-12T09:00 | fp-e4 | 1 | 210 |
아래 JSON Schema에 맞는 색인 청크 행을 더 만들어 주세요. {"type":"object","properties":{"chunk_no":{"type":"string"},"doc_no":{"type":"string"},"indexed_at":{"type":"string"},"indexed_fingerprint":{"type":["string","null"]},"chunk_order":{"type":"integer"},"cited_count":{"type":"integer"}},"required":["chunk_no","doc_no","indexed_at","indexed_fingerprint","chunk_order","cited_count"]} 한 doc_no에 청크가 두 건 이상 붙도록 만들어 주세요. 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라. 첫째 문서 목록에 없는 doc_no를 가리키는 청크, 둘째 indexed_at이 문서의 updated_at보다 이른 뒤처진 청크, 셋째 시각은 최신인데 indexed_fingerprint가 문서와 다른 청크, 넷째 경계극단으로 cited_count가 0인 한 번도 안 쓰인 청크. 또한 형식 깨뜨리기 시도 3건을 별도 파일로 만들어 chunk_order에 문자열을 넣거나 doc_no를 빼서 스키마 검증이 걸러내는지 확인하게 해 주세요.{"type":"object","properties":{"chunk_no":{"type":"string"},"doc_no":{"type":"string"},"indexed_at":{"type":"string"},"indexed_fingerprint":{"type":["string","null"]},"chunk_order":{"type":"integer"},"cited_count":{"type":"integer"}},"required":["chunk_no","doc_no","indexed_at","indexed_fingerprint","chunk_order","cited_count"]}색인 파이프라인이 붙어 있는 원천 저장소 목록입니다. 커넥터가 아직 열리지 않은 원천을 일부러 섞어, 목록에 없는 원천에서 온 문서를 판정에서 가르는 데 씁니다.
| source_id | source_label | connector_kind | is_connected |
|---|---|---|---|
| confluence | 컨플루언스 | api | true |
| sharepoint | 셰어포인트 | api | true |
| gdrive | 구글 드라이브 | api | true |
| s3 | 오브젝트 스토리지 | api | true |
| gitlab_wiki | 깃랩 위키 | api | true |
아래 JSON Schema에 맞는 connected_sources 행을 더 만들어 주세요. {"type":"object","properties":{"source_id":{"type":"string"},"source_label":{"type":"string"},"connector_kind":{"type":"string"},"is_connected":{"type":"boolean"}},"required":["source_id","source_label","connector_kind","is_connected"]} source_id는 영문 스네이크 표기이고 connector_kind는 api·crawl·sftp 중 하나입니다.{"type":"object","properties":{"source_id":{"type":"string"},"source_label":{"type":"string"},"connector_kind":{"type":"string"},"is_connected":{"type":"boolean"}},"required":["source_id","source_label","connector_kind","is_connected"]}| Python | 문서 목록과 색인 목록을 읽어 대조 판정을 돌리고 재색인 목록을 만드는 본체입니다. |
| 벡터 데이터베이스 | 판정 대상인 색인이 사는 곳이며, 내보낸 청크 메타가 이 도구의 입력입니다. |
| RAG | 이 도구가 지키려는 파이프라인의 구조이며, 색인이 뒤처지면 답이 옛 내용이 됩니다. |
| TypeScript | 재색인 목록을 운영 도구가 받아 갈 때 쓰는 타입 정의와 내보내기 스크립트입니다. |
| Docker | 판정기를 이미지로 묶어 사설망 고객사 환경에서도 같은 방식으로 돌립니다. |
| CI/CD | 문서 적재 파이프라인 뒤에 이 판정을 걸어 색인 누락을 배포 시점에 잡습니다. |
✓ pass → 여기서 멈춰도 완결입니다. 더 키우려면 재색인 순서를 참조 빈도로 정합니다.
✓ pass → 우선순위까지가 한 덩어리입니다. 더 키우려면 문서 원천 사전을 고객사별로 분리합니다.
색인 청크 하나가 원본을 따라가고 있는지의 판정 결과입니다. 뒤처졌다면 왜인지를 근거와 함께 담습니다.
{"type":"object","properties":{"chunk_no":{"type":"string"},"verdict":{"type":"string","enum":["fresh","stale_by_time","fingerprint_mismatch","source_doc_removed","doc_inactive","fingerprint_missing","source_unmapped","duplicate_doc"]},"doc_updated_at":{"type":["string","null"]},"indexed_at":{"type":["string","null"]},"evidence":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"agg":{"type":["string","null"]},"value":{},"quote":{"type":["string","null"]}},"required":["field","value"]}},"next_action":{"type":"string"}},"required":["chunk_no","verdict","doc_updated_at","indexed_at","evidence","next_action"]}[
{
"chunk_no": "CH-001",
"verdict": "fresh",
"doc_updated_at": "2026-08-18T10:00",
"indexed_at": "2026-08-18T12:00",
"evidence": [
{
"field": "updated_at",
"value": "2026-08-18T10:00"
},
{
"field": "indexed_at",
"value": "2026-08-18T12:00"
},
{
"field": "body_fingerprint",
"value": "fp-a1"
},
{
"field": "indexed_fingerprint",
"value": "fp-a1"
}
],
"next_action": "색인이 원본을 따라갑니다. 그대로 둡니다."
},
{
"chunk_no": "CH-003",
"verdict": "fresh",
"doc_updated_at": "2026-08-15T14:00",
"indexed_at": "2026-08-16T09:00",
"evidence": [
{
"field": "updated_at",
"value": "2026-08-15T14:00"
},
{
"field": "indexed_at",
"value": "2026-08-16T09:00"
},
{
"field": "indexed_fingerprint",
"value": "fp-c3"
}
],
"next_action": "색인이 원본을 따라갑니다. 그대로 둡니다."
},
{
"chunk_no": "CH-002",
"verdict": "stale_by_time",
"doc_updated_at": "2026-07-02T09:00",
"indexed_at": "2026-06-30T09:00",
"evidence": [
{
"field": "updated_at",
"value": "2026-07-02T09:00"
},
{
"field": "indexed_at",
"value": "2026-06-30T09:00"
},
{
"field": "cited_count",
"value": 340
}
],
"next_action": "문서가 색인 뒤에 바뀌었고 인용도 많습니다. 재색인 목록 맨 위에 둡니다."
},
{
"chunk_no": "CH-005",
"verdict": "fingerprint_mismatch",
"doc_updated_at": "2026-08-19T08:00",
"indexed_at": "2026-08-12T09:00",
"evidence": [
{
"field": "body_fingerprint",
"value": "fp-e5"
},
{
"field": "indexed_fingerprint",
"value": "fp-e4"
}
],
"next_action": "본문 지문이 다릅니다. 내용이 바뀐 것이므로 다시 색인합니다."
},
{
"chunk_no": "CH-012",
"verdict": "source_doc_removed",
"doc_updated_at": null,
"indexed_at": "2026-05-20T09:00",
"evidence": [
{
"field": "doc_no",
"value": "DC-999"
},
{
"field": "cited_count",
"value": 5
}
],
"next_action": "원본 문서가 목록에 없습니다. 색인에서 내려 옛 내용이 답에 섞이지 않게 합니다."
},
{
"chunk_no": "CH-006",
"verdict": "doc_inactive",
"doc_updated_at": "2026-05-01T10:00",
"indexed_at": "2026-05-02T09:00",
"evidence": [
{
"field": "is_active",
"value": false
},
{
"field": "doc_title",
"value": "폐지된 쿠폰 정책"
}
],
"next_action": "폐지된 문서가 색인에 남아 있습니다. 색인에서 내립니다."
},
{
"chunk_no": "CH-007",
"verdict": "fingerprint_missing",
"doc_updated_at": "2026-04-20T09:00",
"indexed_at": "2026-04-21T09:00",
"evidence": [
{
"field": "body_fingerprint",
"value": null
},
{
"field": "indexed_fingerprint",
"value": "fp-x9"
}
],
"next_action": "원본 지문이 비어 있어 내용 대조를 못 했습니다. 최신으로 세지 않고 지문을 다시 계산합니다."
},
{
"chunk_no": "CH-002",
"verdict": "duplicate_doc",
"doc_updated_at": "2026-07-02T09:00",
"indexed_at": "2026-06-30T09:00",
"evidence": [
{
"field": "doc_no",
"agg": "count",
"value": 2
}
],
"next_action": "같은 문서 번호가 목록에 두 번 있습니다. 앞 건으로만 판정하고 뒤 건을 목록에서 뺍니다."
}
][자동 검증 · 1주차] 1. verdict가 enum 여덟 값 안에 있는지 확인합니다. 2. chunk_no·verdict·doc_updated_at·indexed_at·evidence·next_action이 모두 있는지 확인합니다. 3. cited_count가 0 이상인지 확인합니다. 4. body_fingerprint가 null이면 verdict가 fingerprint_missing인지 확인합니다. 5. evidence의 field가 두 입력 표의 컬럼에 실재하는지 확인합니다. 6. evidence의 quote가 그 행 source_raw의 일부인지 확인합니다. 7. next_action이 존댓말로 끝나는지 확인합니다. [판정 규칙] 1. 원천 표기은 대소문자와 띄어쓰기, 구분자를 없애 소문자로 모은 뒤 connected_sources의 source_id와 맞춥니다. 맞는 것이 없으면 미매핑으로 남기고 그 행은 나머지 판정에서 뺍니다. 2. 같은 행 번호가 두 번 들어오면 앞 건만 남기고 뒤 건은 적재 단계에서 사유와 함께 뺍니다. [수동 검증] 1. 지문만 바뀐 문서가 실제로 내용이 바뀐 것인지 서식만 손본 것인지 담당자가 열어 확인합니다. 2. DC-002·DC-003처럼 원천 표기가 흔들렸지만 사전으로 맞춰진 문서는 미매핑 사유를 달지 않는 것이 맞는지 확인합니다. [평가 러너 · 2주차] 1. 인용 횟수를 붙여 재색인 순서를 매겼을 때 자주 쓰이는 뒤처진 청크가 위로 오는지 셉니다. 2. 목록과 정답을 작성자가 만든 합성 기준이라 이 수치는 성능 측정이 아니라 데모 조건 동작입니다.
근거: vector databases, RAG pipelines, agent orchestration, evaluations