TechAssistant — AI 기술문의 자동 답변 시스템
9개 소스에서 모은 24,000건+ Q&A를 하이브리드 RAG로 검색해 답변 초안을 만들고, 답변에 등장한 API가 실제로 존재하는지까지 검증하는 시스템
- 기간
- 2026.03 – 진행 중
- 역할
- 기획 · 개발 · 운영 (단독)
- 기여도
- 100%
성과
Overview
같은 문의가 반복 유입되는데 담당자는 매번 과거 대응 사례를 수작업으로 검색하고 있었습니다. 대응 가이드를 정리해도 반복 자체는 사라지지 않았습니다. Gmail · 사내 게시판(W-Tech) · Confluence 등 흩어진 9개 소스에서 24,000건 이상의 Q&A를 수집·분류·인덱싱하고, 문의가 들어오면 하이브리드 검색으로 근거를 찾아 답변 초안을 생성한 뒤 검수 큐까지 자동으로 넘기는 파이프라인을 기획부터 운영까지 단독으로 맡았습니다.
사내 시스템이므로 화면과 코드는 공개하지 않고, 문제 정의와 해결 방식만 기술했습니다.
Architecture
- CollectGmail (IMAP)W-Tech QNA · FAQ (Puppeteer)Confluence 5개 스페이스API 가이드
- Process통합 · 중복 제거정규식 룰 엔진 13개 대분류
- Indexmultilingual-e5-base 임베딩 (768차원)ChromaDB
- Retrieve벡터(코사인) 0.6 : BM25 0.4TOP_K 8저신뢰 시 쿼리 보강
- GenerateCodex CLI / Claude APIWebSquare MCP 컨텍스트첨부 OCR
- VerifyAPI 존재 검증 (최대 3회 재생성)위험도 판정개인정보 마스킹
- Serve · OpsExpress REST API검수 큐워치독 (cron 5분 · Discord)
주요 기능
- Gmail · W-Tech QNA/FAQ · Confluence 5개 스페이스 등 9개 소스를 자동 수집 — Gmail은 IMAP 2-Phase(UID 경량 검색 → 배치 다운로드)로 대량 메일을 처리
- 정규식 룰 엔진으로 13개 대분류를 자동 판정하고 다이제스트를 생성
- multilingual-e5-base(768차원) 임베딩을 ChromaDB에 인덱싱 — 256건 배치 처리, 실패 시 개별 재시도로 전체 중단 방지
- 벡터(코사인) 0.6 : BM25 0.4 가중 결합 하이브리드 검색으로 상위 8건 반환
- 검색 신뢰도가 임계값 미만이면 쿼리를 자동 보강해 재검색(refinement)
- WebSquare MCP로 컴포넌트 스펙을 답변 컨텍스트에 주입하고, 첨부 이미지는 Tesseract OCR로 텍스트화
- 답변 위험도를 auto / human_review / blocked 3단계로 판정해 검수 큐로 분기
- 검색 · 답변 · 검수 큐 · 첨부 다운로드를 Express REST API로 제공 (답변 생성은 API Key 인증)
문제 해결
Problem
LLM이 실제로 존재하지 않는 API · 이벤트 · 속성명을 그럴듯하게 지어내 답변에 넣었습니다.
Cause
생성 모델은 문법적으로 자연스러운 이름을 만들어내기 때문에, 사람이 읽어서는 실존 API와 구분이 되지 않았습니다. 기술지원 답변에서는 이런 오답이 그대로 고객에게 나갑니다.
Solution
답변에 등장한 모든 API · 이벤트 · 속성명을 추출해 로컬 가이드 문서와 RAG DB에서 $contains로 실존 여부를 검증하는 루프를 넣었습니다. 미확인 항목이 있으면 해당 API를 제외하고 최대 3회까지 재생성합니다.
Problem
정상적인 기술 문의가 자꾸 human_review · blocked로 격상돼 자동 답변률이 떨어졌습니다.
Cause
위험도를 산정할 때 RAG로 검색된 이웃 사례(cases)의 텍스트까지 포함하고 있었습니다. 과거 위험 사례가 유사 문서로 딸려오면, 정작 지금 질문은 멀쩡한데도 그 키워드 때문에 등급이 올라갔습니다.
Solution
판정 기준을 질문 본문과 첨부파일로만 한정하고, 검색 결과(cases)는 제외했습니다. 판정 입력과 참고 자료를 분리하니 오격상이 사라졌습니다.
Problem
라이선스 발급 · 데모 요청 · 엔진 파일 제공 같은 문의에도 RAG 검색과 LLM 호출이 그대로 돌았습니다.
Cause
이런 문의는 애초에 기술 답변 대상이 아니라 담당자 안내가 필요한 서비스 요청인데, 파이프라인이 모든 문의를 동일하게 취급했습니다.
Solution
분류 직후 서비스 요청을 걸러내는 short-circuit을 넣어, RAG·LLM을 거치지 않고 담당자 안내 템플릿만 반환하도록 했습니다. 불필요한 LLM 호출과 대기 시간이 사라졌습니다.
Problem
외부 LLM을 호출해야 하는데, 문의 본문에는 고객사명·담당자 이름·프로젝트명이 그대로 들어 있었습니다.
Cause
기술문의는 대부분 실제 프로젝트 맥락과 함께 오기 때문에, 원문을 그대로 보내면 고객사 정보가 외부로 나갑니다.
Solution
이름 · 이메일 · 회사명 · 프로젝트명을 제거하는 마스킹 모듈을 파이프라인 앞단에 두고, 마스킹된 텍스트만 LLM에 전달하도록 했습니다. 실행은 종량 과금 API 대신 CLI(codex exec) 방식을 채택해 별도 API 비용 없이 운영하고 있습니다.
Problem
운영 중 서버가 죽거나 LLM 호출이 rate limit에 걸려도, 다음 날 아침에야 알게 됐습니다.
Cause
단독으로 개발·운영하다 보니 상시 감시할 사람이 없었고, 장애를 알려주는 경로 자체가 없었습니다.
Solution
cron 5분 주기 워치독을 붙여 /api/health 실패 시 자동 재기동하고, 에러 로그에서 codex exec 실패 · rate limit · quota · 401/429 신호를 스캔해 Discord로 알립니다. 첫 실행 시에는 과거 로그 전체가 쏟아지지 않도록 오프셋만 기록하고 넘어가게 처리했습니다.
결과
- 문의 1건당 평균 응대 시간을 1시간 → 20분으로 단축 (약 67%)
- 흩어져 있던 9개 소스의 24,000건+ Q&A를 검색 가능한 단일 인덱스로 통합
- API 실존 검증 루프로 존재하지 않는 API를 인용하는 오답을 차단
- 신규 담당자도 과거 대응 사례를 즉시 참조할 수 있는 환경 구축
- 워치독 기반 자동 재기동 · 알림 체계를 갖춰 현재까지 사내에서 운영 중