제르코닉스
인턴·신입근거: AI SOLUTION AI 솔루션 개발 RAG, Agent, LLM 파이프라인을 설계하고 구현합니다.
주요 업무 첫 줄이 'Cosentio AI를 기반으로 한 AI 프로덕트 개발에 기여합니다' 이고 그다음이 'RAG, Agent, LLM 파이프라인을 설계하고 구현합니다' 라, 자사 제품 화면 하나를 검색부터 확정 저장까지 직접 세운 이 결과물이 두 업무를 한 번에 보여 줍니다. 사용 기술 스택인 Flutter 와 FastAPI 로 화면과 API 를 만들고, 우대요건의 Hybrid RAG·LangChain·LangGraph 를 검색과 확정 단계의 골조로 씁니다. 예시 문서 테마만 우대요건의 기술 환경 컨설팅에 가볍게 닿도록 골랐습니다. 이 포트폴리오가 보여주는 것은 Hybrid RAG 검색과 사람 확정 상태 전이 구현이며, 환경 규제나 컨설팅 도메인 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫다고 생각합니다.
공고가 RAG, Agent, LLM 파이프라인 설계·구현을 주요 업무로 명시합니다. 검색에서 초안 생성, 사람 확정, 카드 저장까지 이어지는 이 화면의 파이프라인이 그 업무의 실물 증거가 됩니다.
우대요건의 Hybrid RAG 와 LangChain·LangGraph 를 그대로 골조로 씁니다. 키워드 검색과 벡터 검색을 합쳐 근거 후보를 뽑고, LangGraph 로 검색·초안·확정 대기·저장 단계를 잇습니다.
공고의 첫 주요 업무가 Cosentio AI 를 기반으로 한 자사 AI 프로덕트 개발이고 사용 기술 스택에 Flutter 가 적혀 있습니다. 제품 화면 하나를 검색부터 확정 저장까지 직접 만든 이 결과물이 그 업무와 같은 모양입니다.
자사 AI 제품 워크스페이스에 팀이 올려 둔 운영 문서를 대상으로, 질문이 들어오면 키워드(BM25)와 벡터를 합친 Hybrid RAG 가 근거 문단 후보 다섯 개와 답 초안을 화면에 나란히 띄웁니다. 사용자가 그중 근거로 쓸 문단을 고르고 문장을 고쳐 확정을 눌러야 답변 카드가 저장되고, 다음에 같은 질문이 들어오면 검색 대신 그 카드가 먼저 나옵니다. 고른 문단이 담긴 문서가 나중에 수정되면 그 카드는 재확인 필요로 바뀌어 다시 사람 손을 부릅니다.
자사 AI 제품 워크스페이스를 매일 쓰면서 팀원의 같은 질문에 반복해 답해 온 운영 담당자입니다. 어시스턴트가 그럴듯한 답을 내놓아도 어느 문서 어느 문단에서 나왔는지 몰라 그대로 팀에 공유하기가 불안했고, 한 번 자기 손으로 확인한 답은 다음 사람에게 그대로 나가기를 바라는 사람입니다.
답을 바로 저장하지 않고 근거 문단 선택과 문장 수정을 사람 손에 맡기면 확정된 답만 팀에 노출되어 어시스턴트 답을 믿어도 되는지 따지는 부담이 사라지고, 근거 문서가 바뀌었을 때 어느 카드를 다시 봐야 하는지도 규칙으로 짚입니다.
운영 문서 10건을 적재하고, Flutter Web 화면에서 질문 입력과 근거 문단 후보 다섯 개 선택, 초안 문장 수정, 확정 저장까지 도는 완결품입니다. 확정한 뒤 같은 질문을 다시 넣으면 검색 대신 저장된 카드가 먼저 나옵니다. 근거로 고를 문단이 없으면 사용자가 근거 없음으로 닫아야 카드가 마감됩니다.
문서를 수정하면 그 문단을 근거로 쓴 카드가 전부 재확인 필요 상태로 바뀌고 화면에 배지가 붙어 다시 확정을 받는 흐름이 붙은 상태입니다. 질문 로그 30건으로 카드 재사용과 재확인 전이를 채점한 리포트가 함께 남습니다.
신·구버전이 어긋나는 문단을 나란히 띄워 사용자가 유효한 쪽을 지정하게 하는 상충 정리 화면과, 후보 점수가 낮을 때 질문을 바꿔 다시 검색하는 재질의 노드가 LangGraph 그래프에 붙은 상태입니다. 확정 이력 비교 화면으로 누가 언제 무엇을 고쳤는지 되짚습니다.
질문을 넣어 근거 문단 후보 다섯 개를 받고, 그중 하나를 골라 문장을 고쳐 확정하면 카드가 저장되고 같은 질문에 그 카드가 먼저 나오는 흐름을 시연합니다(운영 문서 10건·질문 10종 기준).
저장된 카드의 모든 인용이 근거 문서 원문의 실제 문장 조각인지 자동 검사로 전수 확인합니다. 사람 확정 없이 저장된 카드는 한 건도 없고, 근거 문서를 고치면 그 문단을 쓴 카드가 모두 재확인 필요로 바뀝니다(자동 채점).
2주차에 질문 로그 30건 중 확정 카드로 답이 나간 비율과 말바꿈 질문에서 같은 카드가 걸린 비율을 잽니다. 오타 질문·상충 문서 질문 같은 하드 케이스 20종에서도 화면 흐름이 끊기지 않습니다.
위 수치는 문서와 질문 로그를 작성자가 만든 자가채점이라 성능 증명이 아닙니다. 실제 재사용률은 제르코닉스 자사 제품에 쌓인 사용자 질문과 운영 담당자 피드백이 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태로 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 화면 동작과 실검증 준비 상태로 솔직하게 설명합니다.
질문과 정답을 내가 만들었으니 검색이 잘 맞는 게 당연해지는 함정이 있어, 답이 문서에 없는 질문·두 문서가 상충하는 질문·오타 질문을 질문 로그에 일부러 섞습니다.
확정을 사람 손에 맡기면 그 사람이 병목이 됩니다. 아직 확정되지 않은 질문은 초안만 보이고 팀에 공유되지 않게 막았지만, 확정 대기가 쌓일 때의 운영 규칙은 이 범위 밖으로 둡니다.
실제 제품 문서는 표·그림·스캔본이 섞여 전처리 난도가 다릅니다. 문서 파싱 고도화는 다음 단계 과제로 분리합니다.
이 포트폴리오는 Hybrid RAG 검색과 사람 확정 상태 전이 구현을 보여줄 뿐, 환경 규제나 컨설팅 도메인 전문성은 주장하지 않습니다. 예시 문서는 가상 운영 문서이며 규제 해석은 전문가 검토가 필요하다고 면접에서 밝힙니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
제품 워크스페이스에 팀이 올려 둔 사내 운영 문서입니다. 근거 문단 후보와 인용의 원문이며, 상충 쌍과 참조만 있는 문서를 일부러 담았습니다. updated_at 은 카드 재확인 전이를 트리거하는 값입니다.
사업장 일반 폐기물은 매주 화·목 오후 4시 이후 지하 1층 집하장에 배출한다. 파쇄 대상 문서는 보안 파쇄함에만 넣는다. 유성 페인트 용기는 지정 폐기물로 분류하며 일반 배출을 금지한다.
월별 전력 사용량은 익월 5영업일 안에 시설팀이 집계해 경영지원팀에 제출한다. 집계 단위는 층별 계측기 기준이며 계측기 누락 층은 전년 동월 값으로 추정 기재하고 추정임을 표기한다.
다음 JSON Schema 를 그대로 만족하는 사내 운영 문서를 20건 더 만들어 주세요: {"type":"object","properties":{"doc_id":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"updated_at":{"type":"string"}},"required":["doc_id","title","body","updated_at"]} doc_id 는 'DOC-##' 형식, updated_at 은 YYYY-MM-DD 형식으로 쓸 것. 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: (1) 같은 주제의 신·구버전이 서로 다른 내용을 담은 상충 쌍 2쌍 이상(v1/v2 표기, updated_at 도 다르게), (2) 다른 문서를 참조만 하고 답을 담지 않은 문서 2건(별도 문서를 따른다 류), (3) 같은 대상을 다른 용어로 부르는 표기 흔들림(일회용컵/1회용 컵, 집하장/수거장) 3건, (4) 한 문단에 여러 규칙이 섞인 긴 문서 2건, (5) updated_at 이 최근 30일 안이라 기존 확정 카드를 재확인 상태로 되돌려야 하는 문서 3건.{"type":"object","properties":{"doc_id":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"updated_at":{"type":"string"}},"required":["doc_id","title","body","updated_at"]}제품 안에서 사용자가 실제로 던진 질문 기록입니다. repeat_count 로 어떤 질문이 카드로 확정될 값어치가 있는지 보이고, gold_doc_id·gold_quote 와 expected_action 으로 확정·근거없음·상충확인 전이를 채점합니다.
| question_id | question | asked_by | repeat_count | gold_doc_id | gold_quote | expected_action |
|---|---|---|---|---|---|---|
| Q-01 | 일반 폐기물은 언제 버리나요? | 운영팀 김주임 | 7 | DOC-01 | 매주 화·목 오후 4시 이후 지하 1층 집하장에 배출한다 | 확정 |
| Q-02 | 여름철 에어컨 온도 기준이 뭐예요? | 총무 이대리 | 4 | DOC-03 | 냉방기 설정 온도는 하절기 26도 이상을 기본으로 한다 | 확정 |
| Q-03 | 노트북 버리려면 뭐부터 해야 하죠? | 개발팀 박연구원 | 5 | DOC-07 | 정보보안팀의 데이터 소거 확인서를 받은 뒤에만 폐기 신청이 가능하다 | 확정 |
| Q-04 | 전력 사용량 보고는 누가 하나요? | 경영지원 최과장 | 3 | DOC-02 | 시설팀이 집계해 경영지원팀에 제출한다 | 확정 |
| Q-05 | 음식물 쓰레기 처리 규정 알려주세요 | 신입 정사원 | 2 | — | — | 근거없음 |
다음 JSON Schema 를 그대로 만족하는 사용자 질문 기록을 30개 더 만들어 주세요: {"type":"object","properties":{"question_id":{"type":"string"},"question":{"type":"string"},"asked_by":{"type":"string"},"repeat_count":{"type":"integer"},"gold_doc_id":{"type":["string","null"]},"gold_quote":{"type":["string","null"]},"expected_action":{"type":"string","enum":["확정","근거없음","상충확인"]}},"required":["question_id","question","asked_by","repeat_count","expected_action"]} gold_quote 는 반드시 대상 문서 body 의 실제 문장 조각이어야 한다. 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: (1) 문서에 답이 없어 근거없음으로 닫아야 하는 질문 6건 이상(gold_doc_id·gold_quote null), (2) 오타·구어체 질문 5건(타소→탄소 같은 오타 포함), (3) 신·구버전 상충 문서를 겨냥해 상충확인으로 채점돼야 하는 질문 3건, (4) 참조만 있고 답이 없는 문서(별도 문서를 따른다)를 겨냥한 질문 2건, (5) 이미 확정된 질문의 말바꿈 변형 5건(repeat_count 를 2 이상으로 두고 같은 gold_quote 를 가리키게 할 것).{"type":"object","properties":{"question_id":{"type":"string"},"question":{"type":"string"},"asked_by":{"type":"string"},"repeat_count":{"type":"integer"},"gold_doc_id":{"type":["string","null"]},"gold_quote":{"type":["string","null"]},"expected_action":{"type":"string","enum":["확정","근거없음","상충확인"]}},"required":["question_id","question","asked_by","repeat_count","expected_action"]}| Flutter | 근거 후보 목록과 초안 편집기, 확정 버튼이 있는 제품 화면을 Flutter Web 으로 만듭니다. 공고의 사용 기술 스택 그대로 씁니다 |
| FastAPI | 검색·초안 생성·카드 저장·재확인 전이 API 서버입니다. 공고의 사용 기술 스택 그대로 씁니다 |
| RAG | 질문마다 근거 문단 후보를 찾아 화면에 올리는 제품 골조입니다 |
| Hybrid RAG | 키워드(BM25) 점수와 벡터 점수를 합쳐 후보 문단 다섯 개를 뽑습니다 |
| Agent | 확정된 카드가 있으면 검색을 건너뛰고 없으면 검색으로 도는 분기를 에이전트 그래프가 판단합니다 |
| LangChain | 문서 로더·청킹·임베딩 등 파이프라인 부품을 조립합니다 |
| LangGraph | 검색, 초안 생성, 사람 확정 대기, 카드 저장, 재확인 전이 단계를 그래프 노드로 잇습니다 |
| Claude | 답 초안 문장 생성 모델로 Claude Sonnet 을 씁니다. 저장 여부는 사람의 확정이 결정합니다 |
| ChatGPT | 질문 로그의 말바꿈 변형을 만들어 확정 카드가 같은 질문으로 걸리는지 시험합니다 |
| Gemini | 같은 질문의 교차 응답을 받아 초안이 놓친 문단을 표본으로 점검합니다 |
✓ pass → 여기서 멈춰도 완결입니다. 더 키우려면 문서 갱신에 따른 재확인 전이로 넘어갑니다.
✓ pass → 상충 문단 정리 화면과 LangGraph 재질의 노드 확장으로 넘어갑니다.
사용자가 화면에서 근거 문단을 고르고 문장을 고쳐 확정한 답변 카드입니다. 확정 전에는 저장되지 않고, 근거 문서가 수정되면 재확인 필요로 되돌아옵니다.
{"type":"object","properties":{"card_id":{"type":"string"},"question_id":{"type":"string"},"question":{"type":"string"},"status":{"type":"string","enum":["confirmed","no_evidence","needs_recheck"]},"answer":{"type":["string","null"]},"citations":{"type":"array","items":{"type":"object","properties":{"doc_id":{"type":"string"},"quote":{"type":"string"},"doc_updated_at":{"type":"string"}},"required":["doc_id","quote","doc_updated_at"]}},"confirmed_by":{"type":"string"},"confirmed_at":{"type":"string"},"edited_from_draft":{"type":"boolean"},"conflict_note":{"type":["string","null"]},"recheck_reason":{"type":["string","null"]},"hedge":{"type":"string"}},"required":["card_id","question_id","status","citations","confirmed_by","hedge"]}[
{
"card_id": "CARD-0001",
"question_id": "Q-01",
"question": "일반 폐기물은 언제 버리나요?",
"status": "confirmed",
"answer": "일반 폐기물은 매주 화요일과 목요일 오후 4시 이후에 지하 1층 집하장에 배출합니다. 구버전 지침을 따르는 지점이 있어 배출 전에 담당 층을 확인해 주세요.",
"citations": [
{
"doc_id": "DOC-01",
"quote": "매주 화·목 오후 4시 이후 지하 1층 집하장에 배출한다",
"doc_updated_at": "2026-06-12"
}
],
"confirmed_by": "운영팀 김주임",
"confirmed_at": "2026-07-03T10:12:00+09:00",
"edited_from_draft": true,
"conflict_note": "구버전 지침(DOC-05)은 금요일 오전 배출로 다르게 적혀 있어 확정 시 v2 를 유효한 쪽으로 지정했습니다.",
"recheck_reason": null,
"hedge": "가상 운영 문서를 근거로 확정한 카드라 합성 기준의 예시입니다."
},
{
"card_id": "CARD-0002",
"question_id": "Q-05",
"question": "음식물 쓰레기 처리 규정 알려주세요",
"status": "no_evidence",
"answer": null,
"citations": [],
"confirmed_by": "운영팀 김주임",
"confirmed_at": "2026-07-03T10:31:00+09:00",
"edited_from_draft": false,
"conflict_note": null,
"recheck_reason": null,
"hedge": "후보 문단 다섯 개 중 근거로 쓸 문단이 없어 사용자가 근거 없음으로 닫았습니다. 담당 부서 확인이 필요합니다."
},
{
"card_id": "CARD-0003",
"question_id": "Q-02",
"question": "여름철 에어컨 온도 기준이 뭐예요?",
"status": "needs_recheck",
"answer": "냉방기 설정 온도는 하절기 26도 이상이 기본이고, 서버실만 22도를 유지합니다.",
"citations": [
{
"doc_id": "DOC-03",
"quote": "냉방기 설정 온도는 하절기 26도 이상을 기본으로 한다",
"doc_updated_at": "2026-04-18"
}
],
"confirmed_by": "총무 이대리",
"confirmed_at": "2026-06-20T14:05:00+09:00",
"edited_from_draft": true,
"conflict_note": null,
"recheck_reason": "근거 문서 DOC-03 이 확정 시점 이후에 수정되어 재확인 대기로 되돌아왔습니다. 화면에서 다시 확정해야 팀에 노출됩니다.",
"hedge": "가상 운영 문서를 근거로 확정한 카드라 합성 기준의 예시입니다."
}
][자동 검증 · 스크립트가 전수 수행] 1. 출력이 JSON Schema 형식을 통과하는지 확인합니다(형식 깨진 카드가 저장되는 것을 차단). 2. citations 의 모든 quote 가 해당 doc_id 원문의 실제 문장 조각(공백 정규화 후 substring)인지 확인합니다(인용 환각 차단). 3. confirmed_by 와 confirmed_at 이 빈 카드가 저장돼 있지 않은지 확인합니다(사람 확정 없이 저장되는 경로 차단). 4. status 가 confirmed 인데 citations 가 비어 있거나, no_evidence 인데 answer 가 채워진 조합을 차단합니다. 5. citations 의 doc_updated_at 이 현재 문서의 updated_at 과 다르면 status 가 needs_recheck 인지 확인합니다(재확인 전이 누락 차단). 6. 질문 로그의 expected_action 과 카드의 최종 status 가 일치하는지 채점합니다. [수동 검증 · 사람이 표본 확인] 1. 확정한 answer 가 인용 범위를 넘어 과장하지 않는지 10건을 표본 검토합니다. 2. 상충 문단이 걸린 카드에 conflict_note 가 붙고 유효한 문서가 지정됐는지 확인합니다.