← 홈으로

2026 · 회사

독립지능: 폐쇄망 업무용 AILibreChat · LiteLLM 게이트웨이 훅 · vLLM / Ollama · Jetson

폐쇄망 온프레미스 AI 어플라이언스의 출시 전 QA, 게이트웨이 수정, 서버 재구축과 운영을 맡고 있습니다

역할
QA · 게이트웨이 개발 · 서버 재구축·운영
기간
2026.07 – 현재
상태
라이브 · 운영 중
스택
Python, LiteLLM, LibreChat, vLLM, Ollama, Docker, Linux

제품

독립지능(Independent Intelligence)은 폐쇄망 안에서만 도는 업무용 AI 어플라이언스입니다. 구조는 네 층입니다. 채팅(LibreChat 화이트라벨) → 게이트웨이(LiteLLM + 훅: 인텐트 라우팅, 첨부 텍스트 추출, 데이터 등급 분류, 검색 그라운딩, PII 마스킹, 정직성 규칙) → 모델(vLLM 또는 Ollama, 전부 로컬) → Rust 데몬(라이선스·스킬 레지스트리·승인). 여기에 HWP·PDF 문서 서비스, 워드·엑셀·PPT·PDF 생성과 엑셀·도면 분석 MCP 도구, 단일 egress 게이트웨이를 통한 웹 검색, 사실검증(HalluGuard)이 붙습니다. 주민번호·카드·전화·이메일·API 키가 섞인 요청은 최고 등급으로 분류돼 로컬 모델에 고정되고, 심사 함수가 죽어도 외부로 새지 않고 로컬로 강등됩니다(fail-closed).

로컬에서 띄운 화면 (2026-09-07)

레포의 빌드 스크립트로 LibreChat 화이트라벨 이미지를 만들고, compose(LibreChat·MongoDB·LiteLLM·PostgreSQL)를 올린 뒤 게이트웨이의 로컬 모델 별칭을 이 맥의 Ollama qwen3.5 9B로 돌려 띄웠습니다. 위 캡처는 그 상태에서 계정을 만들고 한국어로 질문한 실제 화면입니다. 실기 박스에서는 같은 구조 위에 vLLM 9B(32k 컨텍스트)와 GPU 임베딩·Whisper·문서 서비스가 더 붙습니다.

같은 자리에 연락처와 주민등록번호가 든 상담 메모를 넣어 봤습니다. 답변은 두 값을 제거했지만, 작은 로컬 모델이라 원문에 없는 문장을 덧붙이기도 했습니다. 그래서 출력이 그럴듯하다고 통과라 하지 않고 원문과 대조해 검증합니다. 출시 전 QA에서 잡아 온 결함 유형이 바로 이것입니다.

출시 전 QA (2026.07)

  • 8개 품질특성(안전성·편의성·기능성·성능·정확성·안정성·호환성·운영성) 시트를 만들어 데일리로 결함을 태깅했습니다. 1차 핵심 결함은 파일 생성·코드 실행 500, 내부 프롬프트 노출, 일반 지식 환각이었습니다. 프롬프트 인젝션·PII·유해 차단·CJK 난독화 저항은 견고했습니다.
  • 블랙박스의 한계를 배웠습니다. 채팅 출력만으로는 “RAG가 실제로 검색을 거쳤는가”, “감사 로그가 남는가” 같은 메커니즘 기준을 통과라 할 수 없어 서버 로그가 없으면 미검수로 표기했습니다. 사실검증 기준도 내용 충실도가 아니라 문장별 출처 표기였고, 제 초기 판정이 틀렸음을 정정했습니다.
  • 생각 패널은 의도된 설계였는데 버그로 오인해 재작업이 생겼습니다. 이후로는 기능을 제거·변경하기 전에 문서·주석·체크리스트를 먼저 봅니다.

게이트웨이와 도구 수정 (2026.07 – 08)

  • 사고 텍스트 누출. 모델이 <think>로 시작한 사고가 본문으로 노출되던 것을 스트리밍 훅에서 </think> 기준으로 reasoning으로 옮기는 스플리터로 해결했습니다. 사고 꼬리가 잘리던 후속 버그는 사고 종료 시점에 즉시 flush해서 잡았습니다.
  • 대용량 문서. 16페이지 문서가 컨텍스트를 넘겨 영어 스택이 사용자에게 노출되던 것을 한글 안내로 치환하고, 앞부분만 넘기는 절단 대신 in-request RAG(문서 청크 → bge-m3 임베딩 → 코사인 top-k)를 넣었습니다. 임베딩을 GPU로 옮겨 첫 턴 20초를 1.2초로 줄였고, 임베딩 서버의 물리 배치 크기보다 큰 청크가 조용히 거부되던 잠복 버그를 찾았습니다.
  • 한글 PDF. 한컴 내보내기처럼 CID·Type3 폰트를 쓴 PDF가 0자로 추출되던 것을 문서 서비스에 poppler 경로를 추가하고 스캔본은 OCR로 폴백했습니다. 39페이지 실제 매뉴얼의 33페이지 용어집 질문에 정확히 답하는 것까지 확인했습니다.
  • 문서 생성 도구. 같은 PPT 요청을 실제 경로로 100회 돌려 보니 모델이 인자 배열을 매번 문자열로 감쌌고 첫 호출 성공률이 0%였습니다. 스키마를 관용적으로 바꾸고 서버에서 되살리는 방식으로 99%까지 올렸습니다. 검증은 MCP 서버가 아니라 LangChain이 하고, 스키마를 바꾸면 채팅 컨테이너도 재시작해야 한다는 두 가지가 오진을 막는 핵심이었습니다.
  • 웹 검색. 검색을 켜도 모델이 학습 지식으로 검색을 흉내 내던 것을 훅 규칙·설정·환경변수 3계층에서 고쳐 실검색이 돌게 했고, 검색을 끄면 질의어도 나가지 않게 토글에 묶었습니다. 검색 결과 안의 영상 챕터 목록을 학교 소개로 옮겨 적던 오독은 라벨을 달아 언급률을 30%에서 12%로 낮췄습니다(A/B 각 50회).
  • 보안 입력 경계. 첨부 파일과 메시지로 들어오는 공격면을 훑어 게이트웨이 워커를 멈추게 하거나 붙잡을 수 있던 경로와, 첨부 문서를 통한 간접 프롬프트 주입을 막았습니다. 정상 대용량 파일은 그대로 통과합니다. 개별 결함의 내용은 제품 보안 사안이라 적지 않습니다.
  • 그 밖에. 메모리 기능이 도구 게이트에 걸려 저장 0건이던 것, macOS 크롬에서 도면 파일 업로드가 조용히 사라지던 MIME 분기, 한국어 UI에 영문으로 남던 도구·검색 블록, 외부 모델 키가 .env에 있어도 컨테이너에 전달되지 않던 배관, 외부 모델 사용 시 사용자 고지.

서버 재구축 (2026.08)

  • 옛 데모 서버가 8월 초 사망했습니다. 대학 캠퍼스의 Jetson Thor 박스에 컨테이너 12종(채팅·게이트웨이·DB·검색·Whisper 등)과 호스트 유닛 6종(라이선스·레지스트리·승인 데몬, 문서 서비스, MCP, 터널)을 다시 세우고 전부 자동 기동으로 두어 재부팅 후에도 살아나게 했습니다.
  • 모델은 9B(BF16)로 vLLM 32k 컨텍스트. KV 캐시를 실측해 컨텍스트 상한을 정하고, 같은 값을 써야 하는 설정 3곳을 문서로 묶었습니다.
  • 레포만으로는 올라가지 않던 버그를 고쳐 PR로 남겼습니다. Whisper 이미지에 ninja가 빠져 CMake가 “컴파일러가 없다”고 연쇄 오보하던 것, 문서 서비스의 로컬 TS 패키지가 빌드되지 않던 것, 유닛 파일에 이전 박스의 홈 경로가 박혀 있던 것, 게이트웨이 마스터 키가 리터럴로 어긋나 채팅이 무한 로딩되던 것.
  • Cloudflare 터널로 도메인 2개를 8월 13일 라이브. 같은 박스를 다른 제품 시연과 공유하므로 건드리지 않을 경계를 문서화했고, 박스 배포를 git 기반으로 바꿔 손으로 얹는 길을 막았습니다.

검증하는 방법

  • 같은 요청을 100회 돌려 성공률로 말합니다. 문서 도구 0% → 99%, 검색 그라운딩에서 근거 없는 주소 날조 0%. 8월 13일의 날조 사고는 200회 안에서 재현되지 않아 꼬리 사건으로 분류했습니다.
  • 로그 순서를 원인으로 읽지 않습니다. 메모리 기능이 죽은 원인을 처음엔 라우터 가드로 짚었지만, 그것은 도구가 먼저 떨어져 나간 결과였습니다.
  • 사용자 QA에서 “검색이 안 돌았다”는 판단은 첨부 배열이 아니라 검색 컨테이너 로그의 타임스탬프로 대조합니다.