이 블로그 포스트는 NoSQL Go SDK 및 LangChainGo를 사용하여 Azure Cosmos DB를 이용한 채팅 기록 구현 방법에 대해 다룹니다. Go SDK에 익숙하지 않은 경우, 블로그에서 제시된 샘플 챗봇 애플리케이션은 읽기, 삽입 업데이트 등과 같은 기본 작업을 다루며 실용적인 소개 역할을 합니다. 이는 또한 Azure Cosmos DB Linux 기반 에뮬레이터(작성 시점에 미리보기 상태)를 Go용 Testcontainers와 통합 테스트에 사용하는 방법을 보여줍니다.
Go 개발자는 LangChainGo를 사용할 수 있으며, 이는 LLM 기반 응용 프로그램을 위한 프레임워크입니다. 이는 벡터 저장소, 임베딩, 문서 로딩, 체인(여러 작업을 구성하는 데 사용) 채팅 기록 등과 같은 구성 요소용 플러그 가능한 API를 제공합니다.
시작하기 전에 기본 사항을 이해하기 위해 한 걸음 물러서 봅시다.
채팅 기록이란 무엇이며, 왜 현대 AI 응용 프로그램에 중요한가요?
대화형 AI 응용 프로그램의 일반적인 요구 사항은 대화의 일부로 교환된 메시지를 저장하고 검색할 수 있어야 합니다. 이는 종종 “채팅 기록”이라고 불립니다. ChatGPT와 같은 애플리케이션을 사용해 본 적이 있다면(그런데 이 애플리케이션도 Azure Cosmos DB를 사용합니다!), 이 개념에 익숙할 수 있습니다.
사용자가 로그인하면 채팅을 시작할 수 있으며, 대화의 일환으로 교환된 메시지는 저장됩니다. 다시 로그인하면 이전 대화를 볼 수 있고 이전 대화에서 남은 곳부터 계속할 수 있습니다.
채팅 기록은 애플리케이션 최종 사용자에게 명백히 중요하지만 LLM에 대한 것을 잊지 말아야 합니다! LLM이 얼마나 똑똑하더라도 현재는 내장 메모리가 없어서 이전 상호작용을 기억할 수 없습니다. 이전 대화를 제공함으로써 채팅 기록은 이 간극을 메우며 LLM이 더 관련성 있고 고품질의 응답을 생성할 수 있게 합니다. 이는 대화의 자연스러운 흐름을 향상시키고 사용자 경험을 크게 향상시킵니다.
간단한 예시로 설명하면, API를 통해 LLM에게 “Azure Cosmos DB에 대해 말해줘”라고 물으면 긴 문단으로 응답할 것입니다. 그리고 “이를 요약해서 읽기 쉽게 나열해줘”라는 다른 API 호출을 하면, 이전 상호작용의 맥락이 없어 LLM이 혼란스러워할 수 있습니다.
그러나 두 번째 API 호출의 맥락으로 이전 메시지를 포함하면, LLM은 정확한 응답을 제공할 가능성이 높아집니다 (LLM 출력이 결정론적이지 않기 때문에 보장되지는 않지만).
챗봇 실행 방법
이전에 언급한대로, 샘플 애플리케이션은 langchaingo
및 Azure Cosmos DB 채팅 기록 구현, 그리고 Go SDK를 탐색하는 유용한 방법입니다.
구현 세부 정보를 탐색하기 전에 애플리케이션을 실제로 보는 것이 좋습니다. GitHub 저장소의 README 섹션을 참조하십시오, 설정, 실행 및 채팅 봇과 대화 시작 방법에 대한 지침을 제공합니다.
애플리케이션 개요
채팅 애플리케이션은 간단한 도메인 모델을 따릅니다: 사용자는 여러 대화를 시작할 수 있으며, 각 대화는 여러 메시지를 포함할 수 있습니다. Go로 작성된 이 애플리케이션에는 백엔드와 프론트엔드 구성 요소가 모두 포함되어 있습니다.
백엔드
여러 하위 부분이 있습니다:
- Azure Cosmos DB 채팅 기록 구현.
- 채팅 시작, 메시지 보내기/받기 및 대화 기록 검색과 같은 핵심 작업은 REST API를 통해 노출됩니다.
- REST API는 사용자 메시지를 처리하기 위해
langchaingo
체인을 활용합니다. 이 체인은 과거 대화가 LLM에 전송되도록 대화 기록을 자동으로 통합합니다.langchaingo
는 모든 오케스트레이션 – LLM 호출, 대화 기록 포함 등을 수동 구현 없이 처리합니다.
프론트엔드
이는 JavaScript, HTML 및 CSS를 사용하여 구축되었습니다. 이는 Go 웹 서버의 일부로 패키지화되어 있으며 (포함 패키지 사용), 사용자 상호작용에 응답하여 백엔드 REST API를 호출합니다.
Azure Cosmos DB를 사용한 대화 기록 구현
LangChainGo는 대화 기록(또는 메모리) 구성 요소를 포함한 플러그 가능한 프레임워크입니다. Azure Cosmos DB를 통합하려면 대화 기록을 관리하는 방법을 제공하는 schema.ChatMessageHistory
인터페이스를 구현해야 합니다:
AddMessage
는 대화에 메시지를 추가합니다 (또는 새 대화를 시작합니다).Messages
는 대화에 대한 모든 메시지를 검색합니다.Clear
는 대화에서 모든 메시지를 삭제합니다.
당신은 직접 CosmosDBChatMessageHistory
인스턴스를 생성하고 이러한 메서드를 사용할 수 있지만, 권장되는 접근 방식은 langchaingo
애플리케이션에 통합하는 것입니다. 아래는 Azure Cosmos DB 채팅 기록을 LLMChain
과 함께 사용하는 예시입니다:
// 채팅 기록 인스턴스 생성
cosmosChatHistory, err := cosmosdb.NewCosmosDBChatMessageHistory(cosmosClient, databaseName, containerName, req.SessionID, req.UserID)
if err != nil {
log.Printf("Error creating chat history: %v", err)
sendErrorResponse(w, "Failed to create chat session", http.StatusInternalServerError)
return
}
// 채팅 기록을 갖는 메모리 생성
chatMemory := memory.NewConversationBuffer(
memory.WithMemoryKey("chat_history"),
memory.WithChatHistory(cosmosChatHistory),
)
// LLM 체인 생성
chain := chains.LLMChain{
Prompt: promptsTemplate,
LLM: llm,
Memory: chatMemory,
OutputParser: outputparser.NewSimple(),
OutputKey: "text",
}
Azure Cosmos DB 관점에서 이 예시의 구현은 여러 가능한 옵션 중 하나에 불과함을 주목하십시오. 여기에 표시된 방법은 사용자 ID를 파티션 키로, 대화 ID(때로는 세션 ID로도 불림)를 고유 키로( Azure Cosmos DB 항목의 id
로) 사용하는 것입니다.
이를 통해 애플리케이션은 다음을 수행할 수 있습니다:
- 대화에 대한 모든 메시지 가져오기. 이는 고유 ID(대화 ID)와 파티션 키(사용자 ID)를 사용한 포인트 읽기입니다.
- 대화에 새로운 메시지를 추가합니다. 이는 업서트 작업(생성 대신)을 사용하여 쓰기 전에 읽기가 필요하지 않습니다.
- 특정 대화를 삭제합니다. 대화(및 해당 모든 메시지)를 제거하기 위해 삭제 작업을 사용합니다.
langchaingo
인터페이스가 노출하지 않지만, 응용 프로그램의 일부로 통합할 때 사용자의 모든 대화를 가져오기 위해 별도의 쿼리를 발행할 수도 있습니다. 이는 단일 파티션으로 범위가 지정되어 효율적입니다.
Azure Cosmos DB 에뮬레이터와 Testcontainers를 사용하여 테스트 단순화하기
샘플 애플리케이션에는 Azure Cosmos DB 채팅 기록 및 주 애플리케이션에 대한 기본 테스트 케이스가 포함되어 있습니다. testcontainers-go를 사용하여 Azure Cosmos DB Linux 기반 에뮬레이터 도커 컨테이너를 통합하는 데 강조할만한 가치가 있습니다.
로컬에서 데이터베이스를 사용할 수 있고 테스트가 훨씬 빠르게 실행되므로(Integration tests), 이는 훌륭합니다(비용 절감도 잊지 말아야 합니다!). 덤으로 Docker 컨테이너 라이프사이클을 수동으로 관리할 필요가 없습니다. testcontainers-go API
덕분에 테스트 스위트의 일부로 처리되며, 편리하게 테스트 실행 전에 컨테이너를 시작하고 테스트가 완료되면 종료합니다.
자세한 내용은 샘플 애플리케이션의 테스트 케이스를 참조하실 수 있습니다. 여기에 testcontainers-go
사용 예시가 있습니다:
func setupCosmosEmulator(ctx context.Context) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
Image: emulatorImage,
ExposedPorts: []string{emulatorPort + ":8081", "1234:1234"},
WaitingFor: wait.ForListeningPort(nat.Port(emulatorPort)),
}
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
return nil, fmt.Errorf("failed to start container: %w", err)
}
// 에뮬레이터가 완전히 초기화되기 위해 약간의 시간을 제공
time.Sleep(5 * time.Second)
return container, nil
}
CI 파이프라인에서 Azure Cosmos DB 에뮬레이터를 사용하고 싶다면, 블로그 포스트를 확인해보세요.
마무리
채팅 기록을 저장할 수 있는 능력은 대화형 AI 앱의 중요한 부분입니다. 이는 RAG(retrieval-augmented generation)와 같은 기존 기술에 큰 부가 가치를 제공할 수 있습니다. 챗봇 애플리케이션을 사용해보고 생각을 공유해주세요!
샘플 애플리케이션의 구현은 비교적 간단하지만, 채팅 기록 데이터를 모델링하는 방식은 요구 사항에 따라 다릅니다. 제시된 시나리오 중 하나는 이 훌륭한 블로그 글에서 Microsoft Copilot이 Azure Cosmos DB를 사용하여 수백만 명의 사용자에게 확장하는 방법에 대해 소개되었습니다..
요구 사항 중 일부는 다음과 같을 수 있습니다:
- 메시지 외에도 반응과 같은 메타데이터 저장
- 최근 상위 N개 메시지 표시
- 채팅 기록 데이터 보존 기간 고려(TTL 사용)
- 채팅 기록 데이터를 기반으로 한 사용자 상호작용에 대한 추가 분석(추가 분석 포함) 등
구현 방식과 관계없이 데이터 모델링에 대한 최상의 실천 방법을 항상 채용해야 합니다. 가이드라인은 여기를 참고하세요here.
Azure Cosmos DB를 이미 사용하고 있거나 Go 애플리케이션에 활용할 계획이 있나요? 여러분의 의견을 듣고 싶습니다! 궁금한 점과 피드백을 보내주세요.
Source:
https://dzone.com/articles/chat-history-ai-applications-azure-cosmos-db-go-sdk