
프로젝트 개요
Adaptive-RAG 전자상거래 고객 지원은 여러 조건이 포함된 정책 문의를 처리하기 위한 지능형 고객 지원 프로젝트입니다. 증거 부족, 근거가 부족한 답변, 복잡한 문제를 한 번의 검색으로 완전히 처리하기 어려운 문제를 중점적으로 해결합니다. 백엔드는 FastAPI와 LangGraph로 구동되고 프런트엔드는 React를 사용합니다. 시스템은 사용자의 의도와 질문 복잡도에 따라 직접 답변, 지식 검색, 추가 검색, 도구 실행, 사람 확인, 답변 거부 중 적절한 경로를 동적으로 선택할 수 있습니다.
이 프로젝트는 로컬 데모, Adaptive RAG 워크플로 학습 및 엔지니어링 검증에 적합합니다. 정책 출처 인용, 데모 주문 조회, 확인 대기 작업, 세션 메모리 및 SSE 응답을 지원하지만 주문 및 배송 데이터는 실제 업무 데이터가 아닙니다.
현재 API는 클라이언트가 전달한
user_id를 직접 사용하며 실제 신원을 검증하지 않습니다. 신뢰할 수 있는 신원 인증, TLS 및 접근 제어를 연결하지 않은 상태로 프로젝트를 인터넷에 직접 배포하지 마세요.
시스템의 요청 처리 방식
사용자가 웹 페이지 또는 HTTP API를 통해 질문을 제출하면 요청은 입력 가드레일, 의도 인식 및 복잡도 라우팅을 차례로 거칩니다. 이후 시스템은 적절한 처리 분기를 선택하고, 최종적으로 답변 생성, 충실도 검사, 세션 메모리 업데이트 및 인용 반환을 수행합니다.
사용자 → Web / HTTP API → 입력 가드레일
→ 의도 인식 → 복잡도 라우팅
├─ 직접 답변
├─ 검색 → 재정렬 → 필요 시 추가 검색
├─ 계획 수립 → 도구 실행 / 사람 확인
└─ 답변 거부
→ 생성 및 충실도 검사 → 세션 메모리 → 답변 및 인용
의도 인식에는 기본 DeepSeek를 사용하거나 TypeSafe Jev로 전환할 수 있습니다. 단, Jev는 의도 분류 노드만 대체합니다. 복잡도 판단, 쿼리 재작성, 작업 계획, 답변 생성, 충실도 검사 및 메모리 요약 등 다른 LLM 노드는 계속 DeepSeek가 담당합니다.
핵심 기능
- 적응형 라우팅: 업무 의도와 질문 복잡도를 결합해 직접 답변, 단일 라운드 검색, 다중 라운드 검색, 도구 실행 또는 답변 거부를 선택합니다.
- 하이브리드 검색: BM25와 밀집 벡터 검색을 결합하고 RRF로 결과를 융합하며, Cross-Encoder 재정렬을 활성화할 수 있습니다.
- 증거 강화: 쿼리 재작성, 증거 부족 시 추가 검색, 답변 충실도 검사 및 자기 수정 기능을 지원합니다.
- 이중 의도 백엔드: 기본적으로 DeepSeek를 사용하며, Jev의 구조화된 choice 인터페이스를 통해 사전 정의된 14가지 업무 의도를 인식할 수도 있습니다.
- 문서 처리: Markdown을 기본 지원하며, 선택적 의존성과 시스템 도구를 설치하면 PDF, Office 및 OCR 문서를 처리할 수 있습니다.
- 구조화된 청킹: 일반 텍스트는 기본적으로 500자 창과 60자 중첩을 사용합니다. 인식된 표는 별도의 청크로 만들고 제목, 장 및 출처 등의 메타데이터를 유지합니다.
- 업무 도구: 주문 관련 데모 도구를 제공하며 권한 검사, 대체 처리, 사람 확인 및 멱등성 메커니즘을 포함합니다. MCP 도구도 연결할 수 있습니다.
- 엔지니어링 기능: 세션 메모리 압축, 구조화된 로그, Prometheus 지표, 상태 점검 및 자동화 테스트를 포함합니다.
실행 환경 준비
기본 요구 사항
- Python 3.11 이상.
- 웹 프런트엔드를 실행하려면 Node.js 20.19+ 또는 22.12+와 npm이 필요합니다.
- 기본 로컬 모드는 SQLite와 메모리 검색 컴포넌트를 사용하므로 Docker를 미리 시작할 필요가 없습니다.
Windows PowerShell 설치 단계
저장소를 복제하고 프로젝트 루트 디렉터리로 이동한 뒤 가상 환경을 생성하고 개발 의존성을 설치한 다음 설정 파일을 복사하고 데모 데이터를 생성합니다.
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
Copy-Item .env.example .env
.\.venv\Scripts\python.exe -m scripts.seed_demo
프로젝트 루트 디렉터리에 이미 .env가 있으면 기존 파일을 유지하고 복사 명령을 건너뛰세요. 그런 다음 FastAPI를 시작합니다.
.\.venv\Scripts\python.exe -m uvicorn app.asgi:app --reload --host 127.0.0.1 --port 8000
macOS 및 Linux
macOS 또는 Linux에서는 가상 환경을 생성하고 활성화한 뒤 해당 설치 명령을 실행할 수 있습니다.
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
python -m scripts.seed_demo
python -m uvicorn app.asgi:app --reload --host 127.0.0.1 --port 8000
모델 및 로컬 서비스 설정
프로젝트 루트 디렉터리의 .env를 엽니다. 다음 설정을 우선 확인하는 것이 좋습니다.
DEEPSEEK_API_KEY: DeepSeek 워크플로와 기본 의도 분류를 활성화합니다. 실제 API 호출에는 비용이 발생할 수 있습니다.INTENT_BACKEND: 기본값인deepseek또는 선택 가능한jev로 설정할 수 있습니다.JEV_API_KEY: Jev 의도 분류를 활성화할 때 필요합니다.JEV_MODEL: 프로젝트의 현재 기본값은jev-1.13.0입니다.DATABASE_URL: 기본적으로sqlite+aiosqlite:///./data/local/app.db를 사용합니다.KNOWLEDGE_DIR: 기본값은knowledge이며, 이 디렉터리의 지식 문서는 시작 시 데이터베이스에 저장됩니다.LOCAL_EMBEDDING_ENABLED: 로컬 의미 벡터 기능을 제어합니다.CROSS_ENCODER_ENABLED: 로컬 재정렬 기능을 제어합니다.REDIS_URL및QDRANT_URL: 선택적 외부 캐시 및 벡터 서비스를 설정합니다.
DeepSeek 키를 설정하지 않아도 시스템은 오프라인 데모 로직을 사용할 수 있지만, 답변 품질은 실제 모델 모드와 다릅니다. 전체 변수 목록은 설정 참고 자료 및 예시 환경 파일에서 확인할 수 있습니다.
React 채팅 인터페이스 시작
백엔드 프로세스를 실행한 상태에서 다른 터미널로 프런트엔드 디렉터리에 들어갑니다.
cd frontend
npm ci
npm run dev
http://127.0.0.1:5173에 접속하면 채팅 페이지를 열 수 있습니다. 개발 서버는 /api 요청을 로컬 8000 포트로 프록시합니다.
프런트엔드는 출처 인용, 로컬 세션 목록 및 작업 확인 카드를 지원합니다. 백엔드는 답변 검증이 완료된 후 SSE를 통해 내용을 여러 구간으로 나누어 전송합니다. npm run build를 실행해 frontend/dist를 생성하면 FastAPI가 해당 디렉터리를 감지하고 루트 경로에서 프런트엔드 페이지를 제공합니다.
기본 사용법: 반품 및 교환 정책 문의
먼저 서비스 상태를 확인합니다.
다음은 PowerShell을 사용해 여러 정책 조건이 포함된 질문을 채팅 인터페이스에 제출하는 예입니다.
$payload = @{
message = "定制马克杯过了七天,但是有质量问题,可以退吗?"
user_id = "u_demo"
} | ConvertTo-Json
Invoke-RestMethod `
-Uri "http://127.0.0.1:8000/api/v1/chat" `
-Method Post `
-ContentType "application/json; charset=utf-8" `
-Body ([System.Text.Encoding]::UTF8.GetBytes($payload))
시스템은 먼저 반품 및 교환 관련 의도를 인식한 다음 질문의 복잡도에 따라 정책 문서를 검색할지 결정합니다. 최초 증거가 부족하면 워크플로가 쿼리를 재작성하고 추가 검색을 수행할 수 있습니다. 답변을 생성한 뒤에는 답변이 검색된 증거에 충실한지 검사하고 사용 가능한 출처 인용을 반환합니다.
HTTP API 외에도 백엔드 실행 중 다음 명령을 사용해 터미널 클라이언트를 실행할 수 있습니다.
python -m app.cli
기본 사용법: 데모 주문 조회 및 작업
scripts.seed_demo는 데모 주문을 명시적으로 생성합니다. API 시작 자체는 이러한 데이터를 자동으로 기록하지 않으므로 최초 실행 시 데이터 초기화를 건너뛰지 마세요. 데모 사용자는 u_demo이며, 사용할 수 있는 주문은 다음과 같습니다.
ORD10001: 배송됨, 상품은 노이즈 캔슬링 헤드폰.ORD10002: 수령 완료, 상품은 맞춤형 머그컵.ORD10003: 결제 완료 및 미배송, 상품은 티셔츠.
예를 들어 채팅 페이지에 取消订单 ORD10003을 입력합니다. 확인이 필요한 작업을 실행할 때 시스템은 pending_action을 반환할 수 있습니다. 확인 요청에는 응답의 session_id를 포함해야 하며, pending_action.action_id를 confirm_action_id에 넣어야 합니다. 웹 페이지의 확인 카드가 이 과정을 지원합니다.
확인 대기 작업은 기본적으로 서버 프로세스 내부에 15분 동안 저장됩니다. 서비스를 다시 시작하거나 요청이 다른 프로세스로 전환되면 작업을 다시 시작해야 할 수 있습니다. 구체적인 필드와 인터페이스 형식은 API 참고 자료를 확인하세요.
고급 설정: Jev 의도 인식 활성화
의도 분류 노드를 TypeSafe Jev로 전환하려면 로컬 .env에 다음 설정을 추가하거나 수정합니다.
INTENT_BACKEND=jev
JEV_API_KEY=your_jev_api_key
JEV_ENDPOINT=https://api.typesafe.ai/v1/systemone
JEV_MODEL=jev-1.13.0
JEV_TIMEOUT_SECONDS=10
JEV_MAX_RETRIES=2
JEV_INTENT_APPLY_OVERLAY=true
DEEPSEEK_API_KEY=your_deepseek_api_key
저장한 후 백엔드를 다시 시작합니다. Jev는 HTTP 인터페이스로 연결되므로 전용 SDK를 설치할 필요가 없습니다. 반환 결과는 Pydantic 검증을 거친 뒤 통합 분류 결과로 변환됩니다.
Jev 키가 없거나 요청이 실패하거나 응답이 올바르지 않으면 시스템은 기존 IntentClassifier로 대체합니다. 대체 경로는 설정된 DeepSeek를 우선 사용하며, 오프라인 상태이거나 모델 호출에 실패하면 규칙 기반 분류를 계속 사용합니다. 재시도 가능한 오류에는 지수 백오프가 적용되며, 현재 구현에서 JEV_MAX_RETRIES는 최대 시도 횟수를 의미합니다.
JEV_INTENT_APPLY_OVERLAY는 Jev가 성공적으로 분류한 후 규칙 기반 보정을 적용할지 제어하며 기본값은 활성화입니다. 이 옵션은 대체 분류기 자체의 오버레이를 제어하지 않습니다. 기본 의도 분류로 되돌리려면 INTENT_BACKEND를 deepseek로 변경하면 됩니다.
고급 구성: 검색 및 문서 파싱 강화
로컬 벡터 및 재순위화 의존성 설치
.\.venv\Scripts\python.exe -m pip install -e ".[rerank]"
rerank 의존성은 로컬 밀집 벡터 모델과 Cross-Encoder에 사용됩니다. 기본 벡터 모델은 BAAI/bge-small-zh-v1.5이고, 기본 재순위화 모델은 BAAI/bge-reranker-base입니다. 처음 로드할 때 모델 가중치를 다운로드할 수 있습니다. 모델을 사용할 수 없으면 시스템이 자동으로 하위 수준 구성으로 전환되므로, 전체 모델 구성을 적용한 경우와 동일한 결과를 보장할 수 없습니다.
확장 문서 파싱 의존성 설치
.\.venv\Scripts\python.exe -m pip install -e ".[docs]"
docs 의존성은 Unstructured 문서 파싱에 사용됩니다. PDF, OCR 및 Office 파일을 처리할 때는 Poppler, Tesseract와 중국어 언어 패키지, LibreOffice를 추가로 설치해야 할 수 있습니다. 자세한 요구 사항은 파싱 및 검색 설명을 참조하세요.
지식 청크 ID는 문서 경로와 청크 순번을 기준으로 생성됩니다. 경로와 분할 결과가 변하지 않으면 반복적으로 저장해도 ID의 일관성을 유지할 수 있습니다. 파일을 이동하거나, 내용을 편집하거나, 청크 분할 전략을 변경한 후에는 과거 참조가 동일한 내용을 계속 가리킨다고 보장할 수 없습니다.
Docker로 전체 서비스 시작
API, PostgreSQL, Redis, Qdrant 및 빌드된 Web 프런트엔드를 동시에 실행하려면 먼저 로컬 .env를 준비한 다음 다음 명령을 실행하세요.
docker compose up --build
시작 후 http://127.0.0.1:8000에 접속하세요. Compose의 데이터베이스 비밀번호와 포트 매핑은 로컬 데모 전용입니다. 공개 환경에 배포하기 전에 데모 비밀번호를 반드시 교체하고, 데이터베이스 및 캐시 포트를 제한하며, 신뢰할 수 있는 인증과 TLS를 활성화하고, 안정적인 영속화 및 운영 방안을 설계해야 합니다.
테스트, 정적 검사 및 평가
프로젝트 루트 디렉터리에서 백엔드 테스트와 품질 검사를 실행하세요.
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m ruff check app eval tests
.\.venv\Scripts\python.exe -m mypy
.\.venv\Scripts\python.exe -m eval.runner --task retrieval
프런트엔드 테스트 및 빌드 명령은 frontend 디렉터리에서 실행해야 합니다.
npm test
npm run build
테스트 구성은 로컬 모델 키를 격리하고 테스트 데이터베이스를 사용합니다. 실제 모델 평가를 별도로 실행하기 전에 모델 및 네트워크 구성을 확인하세요. 외부 모델을 호출하면 비용이 발생할 수 있습니다.
Jev와 DeepSeek 의도 분류 비교
두 모델의 로컬 키를 구성한 후 동일한 샘플과 동일한 오버레이 조건에서 비교를 실행할 수 있습니다.
.\.venv\Scripts\python.exe -m eval.compare_intent --backend both --limit 10 --no-overlay --output data/local/intent-comparison.json
보고서에는 정확도, P50 및 P95 지연 시간, 폴백 횟수와 규칙 적용 횟수가 포함됩니다. --no-overlay는 두 분류기의 규칙 기반 보정을 비활성화하여 모델 자체의 분류 결과를 관찰하기 쉽게 합니다. 이 옵션을 제거하면 오버레이를 적용한 결과를 비교할 수 있습니다.
현재 의도 데이터셋은 개발용 데이터셋이며, 정확도에는 폴백 샘플이 포함됩니다. 따라서 Jev 독립 모델의 일반화 능력으로 직접 간주할 수 없습니다. 과거 평가 결과 역시 현재 버전에서 재검증되었음을 의미하지 않으며, 실제 업무 성과를 보장하지 않습니다.
실용적인 엔지니어링 권장 사항
- 먼저 기본 로컬 모드로 흐름을 검증하세요: SQLite와 메모리 검색 구성 요소만으로도 기본 데모를 완료할 수 있으므로, 처음부터 외부 데이터베이스와 벡터 서비스를 배포할 필요는 없습니다.
- 의도 모델과 워크플로 모델을 구분하세요: Jev로 전환해도 다른 DeepSeek 노드가 교체되지는 않습니다. 전체 온라인 워크플로를 실행하려면 여전히 DeepSeek를 구성해야 합니다.
- 상태 확인 엔드포인트로 문제를 점검하세요:
/api/v1/health는 프로세스 확인에 사용하고,/api/v1/ready는 의존성이 준비되었는지 확인하는 데 더 적합합니다. - 청크 분할 전략을 신중하게 변경하세요: 경로, 텍스트 내용 또는 청크 분할 매개변수가 변경되면 청크 ID와 과거 참조에 영향을 줄 수 있습니다.
- 프로세스 내부 확인 상태에 의존하지 마세요: 기본 확인 대기 작업은 15분 동안만 유효하며, 재시작이나 다중 프로세스 전환으로 손실될 수 있습니다.
- 민감한 데이터를 보호하세요:
.env, 실제 키, 로컬 데이터베이스, 로그, 사용자가 업로드한 문서 또는 개인 자료를 GitHub에 커밋하지 마세요. - 외부 데이터 전송을 검토하세요: 외부 모델이나 원격 MCP를 사용하기 전에 요청 내용에 외부로 전송해서는 안 되는 사용자 정보가 포함되지 않았는지 확인하세요.
- 지식베이스 업데이트를 계획하세요: 현재 시스템은 시작할 때 전체 데이터를 저장하며, 완전한 증분 삭제 절차는 아직 제공하지 않습니다.
프로젝트 디렉터리 한눈에 보기
app/api: HTTP API 및 SSE.app/agents: LangGraph 실행 그래프 및 워크플로 노드.app/retrieval: 파싱, 청크 분할, 검색, 융합 및 재순위화.app/providers: 모델 및 벡터 서비스 어댑터.app/tools: 비즈니스 도구, 도구 등록 및 권한 제어.app/mcp: MCP 도구 연동.app/memory: 세션 메모리 및 압축.app/guardrails: 입력 및 응답 검사.app/observability: 로그 및 지표.frontend: React 및 TypeScript 채팅 인터페이스.knowledge: 정책 지식 문서.tests및eval: 자동화 테스트, 평가 데이터 및 실행기.
요약
Adaptive-RAG 전자상거래 고객 서비스는 지능형 고객 서비스의 비교적 완성도 높은 엔지니어링 흐름을 보여줍니다. 먼저 의도를 식별하고 복잡도를 판단한 다음, 필요에 따라 하이브리드 검색, 다중 턴 증거 보강, 도구 호출, 사람의 확인 및 충실도 검사를 조합합니다. 먼저 SQLite, 데모 주문 및 오프라인 로직을 사용해 빠르게 체험한 후 DeepSeek, Jev, 로컬 벡터 모델, Cross-Encoder, 확장 문서 파싱 및 Docker 서비스를 단계적으로 활성화할 수 있습니다.
실제 업무에 적용하기 전에 인증, 실제 주문 시스템 연동, 확인 상태의 영속화, 지식베이스 증분 유지 관리, 키 관리 및 운영 수준의 네트워크 보안을 중점적으로 보완해야 합니다. 프로젝트는 MIT License를 사용하며, 추가 아키텍처 및 제한 사항은 아키텍처 및 실행 흐름, 검색 설계 및 제한 사항 및 로드맵에서 확인할 수 있습니다.
