사용자 질문
│
├─ 재고/위치/수량 관련 → DB 직접 조회 (JdbcTemplate)
│
└─ 매뉴얼/규정/FAQ 관련 → Chroma 벡터 검색 (PDF, PPTX 등)
→ 두 결과를 합쳐서 LLM에 주입 → 답변 생성
터미널에 직접 질의 던져도 느리다.
PS C:\Project\wms-rag-service> $body = '{"model":"llama3.2:3b","prompt":"안녕","stream":false}'
PS C:\Project\wms-rag-service> Invoke-RestMethod -Method POST `
> -Uri "http://localhost:11434/api/generate" `
> -ContentType "application/json" `
> -Body $body
ollama 버전 다운그레이드 후 재시도해본다.

응답 OK !
이번에는 데이터베이스 설계 문서를 토대로 동적 쿼리를 생성하고 응답을 생성해보자
.pptx .pdf 등 설계 문서 데이터를 처리하기 위한 의존성을 추가하도록 한다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
// Spring AI 1.1.6 stable
implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
// Chroma Vector Store
implementation 'org.springframework.ai:spring-ai-starter-vector-store-chroma'
// MSSQL JDBC Driver
implementation 'com.microsoft.sqlserver:mssql-jdbc:12.6.3.jre11'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Lombok
compileOnly 'org.projectlombok:lombok:1.18.38'
annotationProcessor 'org.projectlombok:lombok:1.18.38'
// Java 21 + ClosedChannelException 해결
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
// ❗ PDF 읽기
implementation 'org.springframework.ai:spring-ai-pdf-document-reader'
// ❗ PPTX / 다양한 문서 형식 (Tika 기반)
implementation 'org.springframework.ai:spring-ai-tika-document-reader'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
&# curl.exe 사용 (Windows 10/11 기본 내장)
curl.exe -X POST "http://localhost:8081/rag/documents/upload" `
-F "file=@C:\Users\HJ-YANG\Downloads\kctc_dbschema.pptx"
💡 혹시 MaxUploadSizeExceededException: Maximum upload size exceeded 이러한 오류가 뜬다면, Application.yml에서 maximum size를 증가시켜주자.
📍 Application.yml
spring:
servlet:
multipart:
max-file-size: 100MB # 파일 하나 최대 크기
max-request-size: 100MB # 요청 전체 최대 크기
위와 같이 적용해도 안된다면, application.properties와 충돌 여부를 체크
spring.application.name=wms-rag-service
*# Ollama Configuration
spring.ai.ollama.chat.options.model=llama3.2:3b
spring.ai.ollama.base-url=http://localhost:11434
*# ChromaDB Vector Store Configuration
spring.ai.vectorstore.chroma.client.host=http://localhost
spring.ai.vectorstore.chroma.client.port=8000
spring.ai.vectorstore.chroma.collection.name=wms-rag-collection
properties에 정의된 host와 port가 있고, yml에 정의된 base-url 키 이름이 달라 충돌이 발생한다.
결국 properties와 yml 중 하나로 통일해서 쓰는 것을 추천한다.
(properties <- 설정이 적은 경우 / yml <- Spring AI 처럼 구조 복잡도가 있는 경우)
결론
properties를 yml로 통합하고 properties는 삭제 ❗
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
그리고 clean 후 bootRun 시도 ❗
./gradlew clean build -x test
./gradlew bootRun
PS C:\Project\wms-rag-service> curl.exe -X POST "http://localhost:8081/rag/documents/upload" `
-F "file=@C:\Users\HJ-YANG\Downloads\kctc_dbschema.pptx"
업로드 완료: kctc_dbschema.pptx
# 1. 벡터 저장 건수 확인
PS C:\Project\wms-rag-service> Invoke-RestMethod -Uri "http://localhost:8000/api/v2/tenants/SpringAiTenant/databases/SpringAiDatabase/collections/82977eae-5e2e-47ae-bbdc-3735b506cf0a/count"
>> 3180
# 2. 질문 (인코딩 설정 먼저)
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
$response = Invoke-RestMethod -Method POST `
-Uri "http://localhost:8081/rag/ask" `
-ContentType "application/json; charset=utf-8" `
-Body ([System.Text.Encoding]::UTF8.GetBytes('{"question":"T_DATA_SKU 테이블 데이터를 요약 알려줘"}'))
# 3. 응답 출력
$response.answer
>>> T_DATA_SKU 테이블 데이터 요약:
1. T_DATA_SKU 테이블은 재고 정보를 담고 있습니다.
2. 테이블의 컬럼은 다음과 같습니다.
| 컬럼 | 명칭 |
| --- | --- |
| INV_ID | 재고 ID |
| T_DATA_SKU | 재고 SKU |
| 수량 | 수량 |
| 수정일시 | 수정일시 |
| 수정자 | 수정자 |
3. 테이블의 데이터는 다음과 같습니다.
* INV_ID=1847, T_DATA_SKU=6973, 수량=1
* INV_ID=1917, T_DATA_SKU=6903, 수량=1
* INV_ID=1934, T_DATA_SKU=6886, 수량=1
4. 테이블의 데이터는 3 개의 rows로 구성되어 있습니다.
5. 테이블의 데이터를 요약한 결과는 다음과 같습니다.
| 재고 ID | 재고 SKU | 수량 |
| --- | --- | --- |
| 1847 | 6973 | 1 |
| 1917 | 6903 | 1 |
| 1934 | 6886 | 1 |
이러한 데이터를 요약한 결과로, T_DATA_SKU 테이블의 데재고 정보를 담고 있으며, 재고 SKU, 수량, 수정일시 및 포함되어 있습니다.
이로써 pptx 임베딩(chromadb) + mssql 소스 데이터 연결 + ollama 기반 로컬 llm으로 동작하는 RAG+Text-to-SQL 파이프 라인까지 완성해보았다.
아무래도 ① 경량화된 ollama 모델 사용 + ② 가비지 데이터가 포함된 설계 문서 + ③ 소스데이터의불충분 + ④ 질의의 퀄리티 등의 이유로 아직 답변이 불안정하긴하다.
다음파트에서는 본격적으로 프롬프트 UI/UX를 넣어보고 터미널이 아닌 UX로 파일을 첨부하고 질의 응답을 생성해보고자 한다.