검색 증강 생성(RAG)

·3분 읽기

원문: Koog Documentation — retrieval-augmented-generation 이 글은 Koog 공식 문서의 retrieval-augmented-generation 페이지를 한국어로 옮긴 번역본입니다. 문서 구조와 링크 의미를 유지하되, MkDocs 전용 UI 문법은 블로그에서 읽기 좋도록 정리했습니다.

검색 증강 생성(RAG)

Koog는 텍스트 삽입, 삽입된 문서 저장, 쿼리에 가장 관련성이 높은 결과 검색 등 RAG(검색 증강 생성)를 위한 빌딩 블록을 제공합니다.

이 페이지에서는 현재 rag 모듈에서 사용할 수 있는 기능과 이를 사용하는 방법에 중점을 둡니다.

오늘 Koog가 제공하는 것

현재 RAG 지원은 두 가지 모듈로 나뉩니다.

  • rag-base: 검색, 저장, 검색 요청, 필터링 및 파일/문서 공급자에 대한 일반적인 추상화
  • rag-vector: 문서 삽입과 벡터 저장을 결합한 로컬 구현

EmbeddingStorage를 사용하여 문서 삽입 및 검색

가장 완벽한 기본 RAG 흐름은 rag-vector 모듈의 EmbeddingStorage을 사용합니다. 이는 DocumentEmbedder(문서를 벡터로 변환)과 VectorStorageBackend(벡터를 유지)를 결합합니다.

단계는 다음과 같습니다.

  1. 임베딩 모델(Ollama 또는 OpenAI)이 지원하는 Embedder을 생성합니다.
  2. 파일 콘텐츠를 읽고 임베더에 위임하는 JVMTextDocumentEmbedder을 만듭니다.
  3. 인메모리 또는 파일 기반 백엔드로 EmbeddingStorage을 생성합니다.
  4. add()으로 문서를 추가합니다.
  5. search(SimilaritySearchRequest(...))으로 검색하세요.

코틀린

1// 1. Create an embedder backed by a local Ollama model2val embedder = LLMEmbedder(3    client = OllamaClient(),4    model = OllamaModels.Embeddings.NOMIC_EMBED_TEXT5)67// 2. Create a JVM document embedder that reads files and embeds their text8val documentEmbedder = JVMTextDocumentEmbedder(embedder)910// 3. Create an EmbeddingStorage with an in-memory backend11val storage = EmbeddingStorage(12    embedder = documentEmbedder,13    storage = InMemoryVectorStorageBackend()14)1516// 4. Add documents to the storage17storage.add(18    listOf(19        Path.of("./docs/faq.txt"),20        Path.of("./docs/pricing.txt"),21        Path.of("./docs/getting-started.txt")22    )23)2425// 5. Search for the most relevant documents26val results = storage.search(27    SimilaritySearchRequest(28        queryText = "How do I reset my password?",29        limit = 3,30        minScore = 0.531    )32)3334results.forEach { result ->35    println("${result.document} (score: ${result.score.value})")36}

자바

1

에이전트 도구로 관련성 검색 제공(에이전트 RAG에서)

검색된 모든 문서를 프롬프트에 미리 삽입하는 대신 에이전트가 요청 시 호출하는 도구로 RAG 저장소를 노출할 수 있습니다. 이를 통해 에이전트는 언제, 무엇을 검색할지 제어할 수 있습니다.

아래 예는 @Tool@LLMDescription 주석이 달린 함수에서 SearchStorage(EmbeddingStorage이 구현하는 기본 검색 인터페이스)을 래핑한 다음 에이전트가 사용할 수 있도록 ToolRegistry에 등록합니다.

코틀린

1// Define a tool that searches the RAG storage2@Tool3@LLMDescription("Search the knowledge base for documents relevant to a query. Returns the content of the most relevant documents.")4suspend fun searchKnowledgeBase(5    @LLMDescription("The search query describing what information you need")6    query: String,7    @LLMDescription("Maximum number of documents to return")8    count: Int9): String {10    val results = ragStorage.search(11        SimilaritySearchRequest(12            queryText = query,13            limit = count,14            minScore = 0.515        )16    )1718    if (results.isEmpty()) {19        return "No relevant documents found for: $query"20    }2122    val response = StringBuilder("Found ${results.size} relevant documents:\n\n")23    results.forEachIndexed { index, result ->24        val content = Files.readString(result.document)25        response.append("Document ${index + 1}: ${result.document.fileName}")26        response.append(" (score: ${"%.2f".format(result.score.value)})\n")27        response.append("Content: $content\n\n")28    }29    return response.toString()30}3132fun main() {33    runBlocking {34        // Register the search tool and create an agent35        val tools = ToolRegistry {36            tool(::searchKnowledgeBase.asTool())37        }3839        val agent = AIAgent(40            toolRegistry = tools,41            promptExecutor = simpleOpenAIExecutor(apiKey),42            llmModel = OpenAIModels.Chat.GPT4o43        )4445        val response = agent.run("What is your refund policy?")46        println("Agent response: $response")47    }48}

자바

1

이 접근 방식을 사용하면 에이전트는 사용자의 쿼리를 기반으로 검색 도구를 호출할 시기를 결정합니다. 이는 에이전트가 다양한 요청을 처리하고 그 중 일부만 지식 기반 조회가 필요한 경우에 유용합니다.

사용 가능한 구현

벡터 스토리지 백엔드

  • InMemoryVectorStorageBackend: 벡터를 메모리에 저장합니다. 테스트 및 프로토타입에 적합
  • FileVectorStorageBackend: 재시작 시 내구성을 위해 벡터를 디스크에 유지합니다.
  • JVMFileVectorStorageBackend: java.nio.file.Path을 사용하는 JVM 관련 파일 기반 백엔드

문서 임베더

  • TextDocumentEmbedder: 문서 및 경로 유형으로 매개변수화된 일반 문서-텍스트 임베더
  • JVMTextDocumentEmbedder: java.nio.file.Path에서 파일을 읽는 JVM 관련 임베더

결합된 스토리지 구현

  • EmbeddingStorage: DocumentEmbedderVectorStorageBackend와 함께 구성합니다.
  • InMemoryDocumentEmbeddingStorage: EmbeddingStorage + InMemoryVectorStorageBackend에 대한 편리한 단축키
  • FileDocumentEmbeddingStorage: EmbeddingStorage + FileVectorStorageBackend에 대한 편리한 단축키
  • JVMFileDocumentEmbeddingStorage: JVM 파일 기반 임베딩 스토리지
  • TextFileDocumentEmbeddingStorage: 텍스트 문서를 위한 파일 기반 저장소
  • JVMFileEmbeddingStorage: 텍스트 문서를 위한 JVM 파일 기반 저장소

현재 제한사항

내장된 흐름은 로컬 및 참조 구현에 유용하지만 아직 완전한 프로덕션 RAG 플랫폼은 아닙니다.

중요한 제한사항:

  • 내장 구현은 유사성 검색만 지원합니다.
  • rag 모듈에는 내장된 청킹 파이프라인이 없습니다.
  • 메타데이터가 풍부한 생산 기록 모델링은 여전히 ​​제한적입니다.
  • 현재 rag 모듈에서는 생산 벡터 데이터베이스 통합(Pinecone, Weaviate, pgVector, Milvus)이 제공되지 않습니다.

사용자 정의 백엔드를 구축하는 경우 rag-base 추상화에서 시작하여 자체 스토리지 어댑터를 구현하십시오.

어디서부터 시작할지 선택하기

다음과 같은 경우 rag-vector을 사용하세요.

  • 로컬 RAG 프로토타입을 원합니다
  • 간단한 참조 구현을 원합니다
  • Koog 내부에 삽입 및 검색 흐름을 실험하고 싶습니다.

다음과 같은 경우 rag-base을 사용하세요.

  • 자신만의 스토리지 백엔드를 구축하고 있습니다.
  • 외부 벡터 데이터베이스를 통합하고 싶습니다
  • 다른 Koog 모듈에서 추상화를 재사용하고 싶습니다.

또한보십시오