이 프로젝트는 스프링 부트(Spring Boot) 기반의 백엔드 애플리케이션으로, 스마트 팩토리 공정 데이터를 분석하는 AI 챗봇 서비스를 제공합니다. AWS Bedrock과 연동하여 공정 이상 진단 및 레시피 추천 결과를 생성하며, **RDS(마리아DB)**와 S3 데이터 연동을 통해 실시간 설비 상태와 불량/이상 로그를 비교 분석합니다.
- 공정 설비별 AI 진단 대화(Insight) 제공
- 설비별 레시피 추천 및 불량 원인 분석
- 채팅 방, 메시지 기록 저장 및 조회
- AWS Bedrock Agent 기반 대화 및 추천 모델 통합
- S3 실시간 센서 로그와 RDS 이상/불량 데이터를 연계
src/main/java/com/factory/chatbot_service/
├── config/ # AWS Bedrock, S3, CORS 등 설정
├── controller/ # REST API 엔드포인트
├── dto/ # 요청/응답 데이터 객체
├── entity/ # JPA 엔티티 매핑
├── repository/ # Spring Data JPA 리포지토리
└── service/ # 비즈니스 로직 및 Bedrock 연동
src/main/resources/
├── application.yml # 기본 환경 설정
├── application-dev.yaml
├── application-local.yaml
└── application-prod.yaml
build.gradle # Gradle 빌드 및 의존성
ChatbotServiceApplication.java # 앱 진입점, .env 파일 로드
- Spring Boot 애플리케이션 진입점
- 루트 폴더의
.env파일을 읽어 JVM 시스템 속성으로 등록 - 로컬 개발 환경에서도 환경 변수를 편리하게 관리할 수 있도록 지원
- AWS Bedrock Agent 및 S3 클라이언트를 생성
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY등을 환경 변수나 시스템 속성에서 자동 탐지- Bedrock API 호출 타임아웃, HTTP 연결 타임아웃 등을 구성
주요 REST API를 제공하는 컨트롤러입니다.
POST /api/chat/insight: 설비 분석 요청 및 AI 응답 생성POST /api/chat/message: 채팅 메시지 저장GET /api/chat/rooms: 전체 채팅 방 목록 조회GET /api/chat/rooms/{roomId}/messages: 특정 방 메시지 조회DELETE /api/chat/rooms/{roomId}: 채팅 방 삭제POST /api/chat/recipe: 자연어 기반 레시피 추천 대화
POST /api/ai/recipe/recommend: JSON 기반 레시피 추천 요청 처리GET /api/ai/recipe/version: 컨트롤러 버전 확인
POST /api/internal/recipe/recommend: 내부 Action Group 또는 시스템 연동용 추천 API
- 사용자의 질문을 도메인 필터링하여 공정 관련 질문인지 확인
- 설비 ID가 없는 요청은 재질문 또는 예외 처리
equipmentId가 있으면AnomalyLog,DefectInfo,EquipmentInfo데이터를 조회하여 Bedrock Agent에 컨텍스트 전달- 채팅방과 메시지를
ChatRoomRepository,ChatMessageRepository에 저장
- 자연어 메시지에서 설비 ID와 불량 유형을 추출
- 백엔드 추천(로컬 계산)과 Bedrock LLM 후보 생성을 함께 수행
- 추천 의도가 아닌 경우에는 안전하게 예외 응답 반환
- 추천 결과를
ChatDto.Response형태로 반환
RecipeRecommendDto.Request를 기반으로 공정/제품/설비 컨텍스트를 해석RecipeContextResolver,SensorContextProvider,RecipeHistoryProvider를 통해 추천 컨텍스트 구성- Bedrock Agent 호출 결과를 검증하고, 안전성 점검 후 최종 결과 생성
- 로컬 추천 모델을 통해 백엔드만으로도 응답 생성 가능
ChatRoom: 채팅방 정보ChatMessage: 채팅 메시지 이력AnomalyLog: 이상 탐지 로그DefectInfo: 불량 정보EquipmentInfo: 설비 메타 정보
ChatDto: 챗봇 대화 요청/응답RecipeRecommendDto: 레시피 추천 요청/응답RecipeAgentDto: Bedrock Agent에 전달되는 추천 컨텍스트RecipeRecommendationContext,SensorContext,RecipeHistoryCase등 : 추천 의사결정에 필요한 컨텍스트 객체
ChatbotController는MainInsightService.getEquipmentAnalysis()를 호출합니다.MainInsightService는 먼저 자연어 질문이 공정/설비/레시피 도메인과 관련 있는지 필터링합니다.equipmentId가 없으면 일반적인 질문으로 간주하고 Bedrock Agent에 직접 질문을 전송합니다.equipmentId가 있는 경우,AnomalyLog와DefectInfo,EquipmentInfo데이터를 조회하여 Bedrock Agent가 분석에 사용할 컨텍스트를 구성합니다.BedrockAgentService.askInsightAI()는 구성된 프롬프트를 Bedrock 에이전트로 전달하고, 에이전트가 생성한 분석 결과를 받아옵니다.
MainInsightService는 최근 이상 로그 데이터를AnomalyLogRepository에서 최대 5건까지 조회합니다.- 동일 설비의 불량 데이터(
DefectInfo)도 함께 불러와, 에이전트가 이상 징후와 불량 인과관계를 해석할 수 있도록 합니다. - 프롬프트는 다음 정보를 포함합니다:
- 최근 이상 감지 항목과 탐지 규칙
- 불량 발생 유형, 발생 공정, 발생 시각
- 사용자의 추가 질문
- 결과적으로 Bedrock Agent는 단순한 챗봇 답변이 아니라, 실제 RDS 기반 공정 분석 데이터를 참고한 진단형 답변을 생성합니다.
AwsBedrockConfig에서BedrockAgentRuntimeAsyncClient와BedrockRuntimeClient를 빈으로 생성합니다.- 이 설정은 Bedrock 요청의 타임아웃, 연결 타임아웃, 재시도 관련 값을 제어합니다.
- AWS 자격 증명은
.env파일 또는 환경 변수에서 불러오고, 없을 경우DefaultCredentialsProvider를 사용합니다. POST /api/chat/insight요청이 성공하면 최종 AI 답변은ChatMessage로 저장되어 채팅 기록에 남습니다.
POST /api/chat/recipe는RecipeChatService.chat()에서 처리됩니다.RecipeChatService는 메시지에서 설비 ID와 불량 유형을 추출합니다.- 주요 역할:
EQUIPMENT_ID_PATTERN정규식을 사용해설비 1번,EQP-...형태를 모두 인식defectType또는불량 유형을 추출- 추천 의도를 판단하는 키워드를 탐지하여 레시피 추천 요청인지 확인
- 설비 ID가 없거나 추천 의도가 없으면 명확한 안내 메시지를 반환합니다.
RecipeRecommendationService는RecipeContextResolver를 통해 다음을 이해합니다:- 설비 ID에 대응하는 공정(Process)
- 현재 동작 중인 레시피와 파라미터
- 해당 제품과 공정에 대한 최근 히스토리
SensorContextProvider는S3센서 데이터를 가져와 최신 센서 스냅샷을 구성합니다.RecipeHistoryProvider는 과거 유사 사례를RDS에서 조회하여 추천 근거를 만듭니다.
-
RecipeRecommendationService.recommend()는 두 가지 추천 경로를 모두 지원합니다.- Bedrock Agent 추천 경로:
RecipeAgentClient가 구성한 요청을 Bedrock으로 전송하고, AI가 생성한 레시피 조정 결과를 수신합니다.- Bedrock 응답도
RecipeSafetyService를 통해 검증되며, 안전 기준을 벗어나면 최종 결과는UNSAFE_RECOMMENDATION이 됩니다.
- Bedrock 응답도
- 로컬 추천 경로:
recommendLocally()는 백엔드에서 안전하게 추천 값을 계산합니다.
- Bedrock Agent 추천 경로:
-
로컬 추천은 다음 방식으로 동작합니다:
RecipeRecommendationContext에서 현재 레시피 파라미터(currentRecipeParameters)를 가져옵니다.- 각 파라미터에 대해
sensorSnapshot의 최신 S3 센서 평균값과RecipeHistoryCase과거 히스토리를 동시에 참조합니다. - 기본 기준은 RDS에서 내려오는 안전 범위(
min,max)이며, 이 범위 바깥으로 추천값이 벗어나지 않도록 보정합니다. recommendParameter()는 실제 추천 범위를 계산할 때 아래 3가지를 반영합니다:baseMin/baseMax: RDS 안전 범위sensorAverage: S3 센서 평균값historicalTargetRange: 과거 low-defect 레시피 히스토리에서 추출한 추천 범위
- 최종
recommendedMin/recommendedMax는 안전 범위에서 출발해 과거 히스토리 쪽으로 최대 65% 이동하고, 최신 센서 평균값을 중심으로 추가 조정합니다. recommendedValue는 최종 추천 범위의 중앙값으로 설정하며, 현재값 대비 한 번에 너무 급격하게 변하지 않도록단계 제한(step limit)을 적용합니다.
-
recommendLocally()가currentRecipeParameters를 찾지 못하면, 대신currentRecipe의 개별 필드(temperature, pressure, speed, duration)를recommendFixedRecipe()로 보정합니다.- 이 보정은 기본값을 현재 레시피 값으로 삼고, 과거 목표값과 센서 평균을 최대 65%까지 점진적으로 반영합니다.
- 결과값은
160~190°C,2.0~3.0,90~140,30~120같은 고정 안전 구간 안에 다시 클램프됩니다.
-
로컬 추천 결과에는 따로
evidence와warnings가 생성됩니다.- evidence:
baseSensorLimit,recommendedSensorRange,recommendedSensorCenter,sensorAverage,historical low-defect range정보 - warnings: S3 스냅샷 부재 또는 과거 히스토리가 부족할 때 신뢰도 제한 메시지
- evidence:
RecipeChatService는 먼저 백엔드 로컬 추천을 기준으로 사용합니다.- 백엔드 추천이
SUCCESS일 때만BedrockRecipeCandidateService가 Bedrock 모델을 호출하여 LLM 후보를 생성합니다. - 후보 생성 시
BedrockRecipeCandidateService는 다음 규칙을 명시합니다:- JSON 객체만 반환
- 추천 후보는
recommendedMin,recommendedMax,recommendedValue만 제안 - 기존 파라미터 이름을 그대로 사용하고 신규 파라미터를 추가하지 않음
- 값은 백엔드 안전 범위 안에 있어야 함
status,summary,recommendedParameters,evidence,warnings,confidence만 포함
RecommendationSelectionService는LlmCandidateValidationService를 통해 LLM 후보를 엄격히 검증합니다.
- 후보가
SUCCESS상태인지 확인 - 후보의
confidence가 최소0.7이상인지 확인 - 백엔드 추천에 존재하는 파라미터 이름과 일치하는지 확인
- 각 후보 파라미터의
recommendedMin,recommendedMax,recommendedValue가 모두 존재하는지 확인 recommendedMin/recommendedMax가 백엔드 안전 범위(min/max) 밖으로 벗어나지 않는지 확인recommendedValue가 후보 범위 안에 있는지 검증- 범위 변경이 너무 공격적이지 않은지 검사
- 백엔드 안전 범위 전체 너비의
35%이내로만 하한/상한을 이동하도록 제한
- 백엔드 안전 범위 전체 너비의
- 후보가 검증을 통과하면
RecommendationSelectionService는adoptCandidate()를 통해 후보 파라미터를 백엔드 추천에 병합합니다. - 이때 반환 결과는 다음을 유지합니다:
- 최종 상태는
SUCCESS - 백엔드 핵심 요약과 기대 효과는 유지
- 후보가 제공한
evidence와warnings를 추가 - 선택한 후보의
confidence를 사용
- 최종 상태는
- 후보가 검증에 실패하면 백엔드 단독 추천 결과를 사용하고, 거부 사유를
warnings에 추가합니다. - 결과 원천은
LLM_VALIDATED또는BACKEND_ONLY_LLM_REJECTED로 분류됩니다.
BedrockRecipeAnswerService는 최종 추천 JSON을 Bedrock 모델로 다시 한번 설명 요청합니다.- 이 단계는 숫자를 다시 계산하지 않고, 이미 결정된 추천 결과를 보다 읽기 쉬운 한국어 답변으로 변환하는 역할만 합니다.
- 따라서 실제 추천값의 신뢰성과 안전성은 로컬 계산 + 후보 검증 단계에서 결정됩니다.
RecipeRecommendationController는 외부 JSON 요청을 처리하는 정형화된 엔드포인트입니다.InternalRecipeRecommendationController는 내부 시스템 또는 Bedrock Action Group에서 직접 사용할 수 있는 추천 API를 제공합니다.- 이 두 경로 모두
RecipeRecommendationService의 추천 로직을 재사용하므로, 일관된 추천 결과를 유지합니다.
- 사용자 질문 수신
- 도메인 필터링 및 설비 ID 검증
- RDS 이상 로그/불량 정보 조회
- Bedrock Agent에 컨텍스트와 질문 전달
- AI 분석 답변 수신 및 채팅 기록 저장
- 자연어에서 설비 ID 및 불량 유형 추출
- 추천 의도 판별
- 공정/제품/센서/히스토리 컨텍스트 구성
- 로컬 추천 계산 또는 Bedrock Agent 추천 수행
- 안전 검증 및 후보 선택
- 자연어 설명 응답 생성
- Java 17
- Gradle Wrapper(
./gradlew) 사용 - MariaDB 또는 MySQL 호환 데이터베이스
- AWS 자격 증명 및 Bedrock 접근 권한
./gradlew bootRun./gradlew testsrc/main/resources/application.yml는 다음 환경 변수를 사용하여 외부 설정을 주입합니다.
DB_URLDB_USERNAMEDB_PASSWORDDB_MAX_POOL_SIZE(옵션)DB_MIN_IDLE(옵션)AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_AGENT_IDAWS_AGENT_ALIAS_IDBEDROCK_AGENT_IDBEDROCK_AGENT_ALIAS_IDBEDROCK_MODEL_IDS3_BUCKET_NAMES3_REALTIME_PREFIXS3_REALTIME_LOOKBACK_DAYSS3_ALLOW_BROAD_REALTIME_SCANCORS_ALLOWED_ORIGIN_PATTERNS
DB_URL=jdbc:mariadb://localhost:3306/your_database
DB_USERNAME=your_user
DB_PASSWORD=your_password
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_AGENT_ID=bedrock-agent-id
AWS_AGENT_ALIAS_ID=bedrock-agent-alias-id
BEDROCK_MODEL_ID=anthropic.claude-3-haiku-20240307-v1:0
S3_BUCKET_NAME=your-bucket-name
S3_REALTIME_PREFIX=sensor
S3_REALTIME_LOOKBACK_DAYS=3
CORS_ALLOWED_ORIGIN_PATTERNS=*POST /api/chat/insight
Content-Type: application/json
{
"equipmentId": 4,
"content": "포토 4번 설비 최근 이상 징후 알려줘",
"roomId": "room-123"
}POST /api/chat/message
Content-Type: application/json
{
"roomId": "room-123",
"role": "USER",
"content": "안녕하세요",
"title": "새 채팅"
}POST /api/chat/recipe
Content-Type: application/json
{
"sessionId": "session-123",
"message": "설비 1번의 Scratch 불량을 줄일 레시피를 추천해줘"
}POST /api/ai/recipe/recommend
Content-Type: application/json
{
"equipmentId": "1",
"defectType": "Scratch"
}AwsBedrockConfig는BedrockAgentRuntimeAsyncClient와BedrockRuntimeClient,S3Client를 빈으로 등록합니다.chatbot.aws.region과chatbot.bedrock.*설정을 통해 Bedrock 호출 동작을 제어합니다.- AWS 크레덴셜이
.env또는 시스템 환경에 없으면DefaultCredentialsProvider를 사용합니다.
MainInsightService는 도메인 외 질문을 필터링하고, 설비 ID가 존재할 때만BedrockAgentService를 호출합니다.RecipeChatService는 자연어 메시지에서 설비 ID와 불량 유형을 추출하여 레시피 추천 의도를 판단합니다.RecipeRecommendationService는 Bedrock 추천 결과를 안전성 검증 후 응답으로 변환합니다.application.yml의spring.jpa.hibernate.ddl-auto=validate로 인해 스키마가 데이터베이스와 일치해야 합니다.
- Spring Boot Starter Web
- Spring Boot Starter Data JPA
- Spring Boot Starter JDBC
- MyBatis Spring Boot Starter
- AWS SDK for Bedrock Agent Runtime
- AWS SDK for S3
- MariaDB JDBC Driver
- Lombok
이 프로젝트는 AWS Bedrock AI와 스마트 팩토리 센서/이상/불량 데이터를 결합하여
- 설비 상태 진단
- 이상 원인 탐지
- 레시피 추천
- 대화형 AI 챗봇 인터페이스 를 제공하는 백엔드 서비스입니다.
코드 이해를 빠르게 하기 위해서는 먼저 controller → service → repository/entity 흐름을 따라가고, AwsBedrockConfig와 application.yml의 환경 설정 규칙을 함께 확인하는 것이 좋습니다.