목표
회사의 입장에서 도움이 되는 AI 챗봇을 사용해서 반복적으로 들어오는 CS 업무를 챗봇으로 자동화해보려고 한다.
일단 테스트용으로 Cluade Sonnet 3.5를 사용했다.
초기 Bedrock 설정이 궁금하다면? 이전 글을 참고해주면 좋겠다.
2026.06.18 - [AWS] - [AWS] Bedrock 사용하기
[AWS] Bedrock 사용하기
최근 백엔드 개발자로서 해커톤을 새롭게 시작했다. K-POP을 좋아하는 외국인을 대상으로 한 기업의 AI 챗봇 서비스를 만들기로 했다. Bedrock 구성 요소의 내용을 간단하게 살펴보자.Converse: 모델에
nomad1jin.tistory.com
DTO
K-pop을 좋아하는 외국인이 주요 대상이기 때문에, "국적, 언어, 채팅 내용"을 일단 파라미터로 생각했다.
package ai.chatbot.domain.dto;
public record ChatRequest(
String country,
String language,
String message
) {}
package ai.chatbot.domain.dto;
import java.time.LocalDateTime;
public record ChatResponse (
String answer,
LocalDateTime answerAt
) {}
Service
- 일단 초기 구현에서는 프롬프트와 데이터베이스에 적재될 내용을 하드코딩했다.
- 사용할 모델은 추후 쉽게 교체하기 위해 application.yml에 빼두었다.
- - buildSystemPrompt) 당신은 [기업]의 고객 서비스 챗봇입니다. [기업]은 K-POP 굿즈와 팬 서비스를 판매하는 플랫폼입니다.
- - getProductInfo) 예시로 코르티스 첫번째 앨범 가격과 재고, 버전 2개를 작성함
@Service
@RequiredArgsConstructor
public class ChatService {
private final BedrockRuntimeClient bedrockClient;
// Value는 final 필드랑 다른 방식으로 주입되므로 적지 않을 것
@Value("${bedrock.model-id}")
private String modelId;
public ChatResponse chat(ChatRequest request) {
// 1. 시스템 프롬프트 구성 (국가/언어 + 상품정보 주입)
String systemPrompt = buildSystemPrompt(request);
// 2. 사용자 메시지 구성
Message userMessage = Message.builder()
.role(ConversationRole.USER)
.content(ContentBlock.fromText(request.message()))
.build();
// 3. Bedrock 호출
ConverseResponse response = bedrockClient.converse(req -> req
.modelId(modelId)
.system(SystemContentBlock.fromText(systemPrompt)) // ← 시스템 프롬프트
.messages(userMessage)
.inferenceConfig(c -> c
.maxTokens(1024)
.temperature(0.5F))
);
// 4. 답변 추출
String answer = response.output().message().content().getFirst().text();
return new ChatResponse(answer, LocalDateTime.now());
}
private String buildSystemPrompt(ChatRequest request) {
// 상품 정보 (지금은 임시 하드코딩, 나중에 DB 조회로 교체)
String productInfo = getProductInfo();
return """
당신은 K-POP을 좋아하는 외국인 고객 서비스 챗봇입니다.
[기업]은 K-POP 굿즈와 팬 서비스를 판매하는 플랫폼입니다.
[응답 규칙]
- 사용자는 %s에 거주하며, %s로 질문합니다. 반드시 %s로 답변하세요.
- 아래 상품 목록에 있는 정보만으로 답하세요.
- 목록에 없는 상품을 묻거나 모르는 정보는 "해당 정보는 확인이 어렵습니다"라고 솔직히 답하세요.
- 추측하거나 없는 정보를 지어내지 마세요.
[상품 목록]
%s
""".formatted(
request.country(),
request.language(),
request.language(),
productInfo
);
}
private String getProductInfo() {
// TODO: 나중에 DB에서 조회하도록 변경
return """
- 코르티스(CORTIS) 1st 앨범 [COLOR OUTSIDE THE LINES]: 가격 25,000원, 재고 120개
· Standard 버전: 포토북 + 포토카드 2종 + CD
· Limited 버전: 포토북(양장) + 포토카드 5종 + 포스터 + CD
""";
}
}
Controller
@RestController
@RequestMapping("/api/chat")
@RequiredArgsConstructor
public class ChatController {
private final ChatService chatService;
@PostMapping
public ChatResponse chat(@RequestBody ChatRequest request) {
return chatService.chat(request);
}
}
API 테스트
1. 외국인을 일본인이라고 가정하고, 코르티스의 앨범 버전 스탠다드와 리미티드를 예시로 질문했다.
파파고 번역기를 통해 번역해본 결과, 클로드 소넷이 정상적으로 작동함을 알 수 있다.


2. 데이터베이스에 있다고 가정한 데이터가 아닌 다른 내용을 질문한다면?
외국인을 중국인으로 가정하고, 코르티스가 아닌 방탄소년단에 대한 질문을 했다.
BTS 앨범이 없다고 올바르게 답변하는 것을 알 수 있다.


추후에 데이터베이스에 기업의 데이터를 가정하고 Mock 데이터를 넣고 테스트해볼 생각이다.
참고 공식 자료
Java 2.x용 SDK를 사용하는 Amazon Bedrock 런타임 예제 - AWS SDK for Java 2.x
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com