인용이 포함된 검색 증강 생성
대규모 언어 모델(LLM) 앱에서 응답을 받을 때, 그 응답이 어디에서 왔는지 알고 싶으신가요? 이것이 바로 인용 또는 출처 표시의 힘입니다. 이 튜토리얼에서는 인용을 포함하는 것이 왜 중요한지, 높은 수준에서 어떻게 인용을 얻을 수 있는지 살펴본 다음, 코드 예제로 깊이 들어가 보겠습니다!
왜 Retrieval Augmented Generation (RAG) 소스를 인용해야 할까요?
Retrieval Augmented Generation은 LLM 앱에서 지식을 보완하기 위해 사용되는 기법입니다. 일반적으로 LLM의 주요 약점 중 하나는 최신 지식이나 도메인 특화 지식이 부족하다는 점입니다. 이에 대한 두 가지 주요 해결책은 파인튜닝과 검색 증강 생성입니다.
여기 Zilliz와 OpenAI 같은 다른 회사에서는 사실 기반 검색을 위한 파인튜닝보다 RAG를 더 우수한 옵션으로 제안합니다. 파인튜닝은 더 비싸고 훨씬 더 많은 데이터가 필요하지만, 스타일 전이에는 좋은 옵션입니다. RAG는 Milvus와 같은 벡터 데이터베이스를 사용하여 여러분의 지식을 앱에 주입합니다.
LLM에게 제품이나 문서에 대해 묻는 대신, 벡터 데이터베이스를 진실 저장소로 사용할 수 있습니다. 이를 통해 앱이 올바른 지식을 반환하고 데이터 부족을 보완하려는 시도로 환각을 일으키지 않도록 보장할 수 있습니다. 더 많은 문서와 사용 사례를 추가하기 시작하면, 해당 정보가 어디에 있는지 아는 것이 점점 더 중요해집니다.
바로 여기에서 인용과 출처 표시가 등장합니다. LLM 앱에서 응답을 받을 때, 그 정보가 어떻게 얻어졌는지 알고 싶을 것입니다. 인용 또는 출처 표시와 함께 응답을 받으면 응답이 어떤 텍스트 조각/텍스트의 어느 위치에서 왔는지 보여줍니다. 데이터가 점점 더 많아질수록, 이는 신뢰할 수 있는 답변을 판단하는 데 매우 중요해집니다.
RAG 소스를 어떻게 인용할 수 있을까요?
LLM은 Milvus와 같은 벡터 데이터베이스 등 인접 도구의 인기를 높였습니다. 또한 LangChain 및 LlamaIndex와 같은 프레임워크의 부상도 이끌었습니다. 이러한 인기 상승의 일부로, 검색 증강 생성은 특히 내부 데이터에 대한 정보 검색과 관련하여 필수적인 앱이 되었습니다.
데이터 검색 외에도, 많은 사람들은 검색된 데이터에 인용을 추가하면 앱이 더 견고해지고, 더 설명 가능해지며, 더 많은 맥락을 제공한다는 점을 깨달았습니다. 그렇다면 어떻게 할 수 있을까요? 이를 수행하는 방법은 많습니다. Milvus처럼 메타데이터를 지원하는 경우 벡터 데이터베이스 안에 텍스트 청크를 저장할 수도 있고, LlamaIndex 같은 프레임워크를 사용할 수도 있습니다. 이 튜토리얼에서는 LlamaIndex와 Milvus를 사용해 인용이 포함된 RAG를 수행하는 방법을 다룹니다.
소스를 포함한 Retrieval Augmented Generation 예제
코드로 들어가 보겠습니다. 이 튜토리얼을 수행하려면 pip install milvus llama-index python-dotenv가 필요합니다. milvus와 llama-index 라이브러리는 핵심 기능을 위한 것이며, python-dotenv는 OpenAI API 키와 같은 환경 변수를 로드하기 위한 것입니다. 이 예제에서는 Wikipedia에서 여러 도시에 대한 데이터를 스크래핑하고, 이에 대해 인용이 포함된 쿼리를 수행합니다.
몇 가지 필요한 라이브러리를 가져오고 OpenAI API 키를 로드합니다. LlamaIndex에서 일곱 개의 하위 모듈이 필요합니다. 순서와는 무관하게: LLM에 접근하기 위한 OpenAI, 인용 쿼리 엔진을 만들기 위한 CitationQueryEngine, Milvus를 벡터 저장소로 사용하기 위한 MilvusVectorStore입니다. 또한 Milvus를 사용하기 위해 VectorStoreIndex, 로컬 데이터를 읽어오기 위한 SimpleDirectoryReader, 벡터 인덱스가 Milvus에 접근할 수 있도록 하기 위한 StorageContext와 ServiceContext도 가져옵니다. 마지막으로 load_dotenv를 사용하여 OpenAI API 키를 로드합니다.
from llama_index.llms import OpenAI
from llama_index.query_engine import CitationQueryEngine
from llama_index import (
VectorStoreIndex,
SimpleDirectoryReader,
StorageContext,
ServiceContext,
)
from llama_index.vector_stores import MilvusVectorStore
from milvus import default_server
from dotenv import load_dotenv
import os
load_dotenv()
open_api_key = os.getenv("OPENAI_API_KEY")
일부 테스트 데이터 스크래핑하기
먼저 작업할 데이터를 준비하는 것으로 프로젝트를 시작해 봅시다. 이 예제에서는 Wikipedia에서 일부 데이터를 스크래핑합니다. 실제로는 multi-document 쿼리 엔진을 만들 때 사용했던 것과 동일한 데이터를 스크래핑합니다. 아래 코드는 wiki_titles 목록에 언급된 페이지에 대해 Wikipedia의 API를 호출합니다. 결과는 로컬의 텍스트 파일에 저장됩니다.
wiki_titles = ["Toronto", "Seattle", "San Francisco", "Chicago", "Boston", "Washington, D.C.", "Cambridge, Massachusetts", "Houston"]
from pathlib import Path
import requests
for title in wiki_titles:
response = requests.get(
'https://en.wikipedia.org/w/api.php',
params={
'action': 'query',
'format': 'json',
'titles': title,
'prop': 'extracts',
'explaintext': True,
}
).json()
page = next(iter(response['query']['pages'].values()))
wiki_text = page['extract']
data_path = Path('data')
if not data_path.exists():
Path.mkdir(data_path)
with open(data_path / f"{title}.txt", 'w') as fp:
fp.write(wiki_text)
LlamaIndex에서 벡터 스토어 설정하기
이제 모든 데이터가 준비되었으므로, citations 앱을 포함한 RAG를 위한 앱 로직을 설정할 수 있습니다. 시작할 때 가장 먼저 해야 할 일은 벡터 데이터베이스를 실행하는 것입니다. 이 예제에서는 Milvus Lite를 사용하여 노트북에서 직접 실행합니다. 그런 다음 LlamaIndex의 MilvusVectorStore 모듈을 사용하여 Milvus를 벡터 스토어로 연결합니다.
default_server.start()
vector_store = MilvusVectorStore(
collection_name="citations",
host="127.0.0.1",
port=default_server.listen_port
)
다음으로, 인덱스를 위한 컨텍스트를 만들어 봅시다. 서비스 컨텍스트는 인덱스와 리트리버에 어떤 서비스를 사용할지 알려줍니다. 이 경우에는 원하는 LLM으로 GPT 3.5 Turbo를 전달합니다. 또한 인덱스가 데이터를 어디에 저장하고 쿼리해야 하는지 알 수 있도록 스토리지 컨텍스트도 생성합니다. 이 경우에는 위에서 만든 Milvus 벡터 스토어 객체를 전달합니다.
service_context = ServiceContext.from_defaults(
llm=OpenAI(model="gpt-3.5-turbo", temperature=0)
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
이 모든 설정이 완료되면, 앞서 스크래핑한 데이터를 로드하고 해당 문서들로부터 벡터 스토어 인덱스를 생성할 수 있습니다.
documents = SimpleDirectoryReader("./data/").load_data()
index = VectorStoreIndex.from_documents(documents, service_context=service_context, storage_context=storage_context)
citations로 쿼리하기
이제 Citation Query Engine을 만들 수 있습니다. 앞서 구축한 벡터 인덱스와 반환할 결과 수, citation의 청크 크기에 대한 매개변수를 제공합니다. citation을 설정하는 데 필요한 것은 이것이 전부이며, 다음 단계는 엔진에 쿼리하는 것입니다.
query_engine = CitationQueryEngine.from_args(
index,
similarity_top_k=3,
# here we can control how granular citation sources are, the default is 512
citation_chunk_size=512,
)
response = query_engine.query("Does Seattle or Houston have a bigger airport?")
print(response)
for source in response.source_nodes:
print(source.node.get_text())
쿼리하면 응답은 대략 다음과 같이 보입니다.
citations로 쿼리하기
요약
이 튜토리얼에서는 인용(출처 표시)을 포함한 검색 증강 생성을 수행하는 방법을 배웠습니다. 검색 증강 생성은 많은 기업이 구축하고자 하는 LLM 애플리케이션의 한 유형입니다. 정보를 이해하기 쉬운 형식으로 검색하고 포맷하는 것뿐만 아니라, 그 정보가 어디에서 왔는지도 알고자 합니다.
우리는 LlamaIndex를 데이터 라우터로, Milvus를 벡터 저장소로 사용하여 이러한 유형의 RAG 애플리케이션을 구축할 수 있습니다. 먼저 이것이 어떻게 작동하는지 보여주기 위해 Wikipedia에서 일부 데이터를 스크래핑했습니다. 그런 다음 Milvus 인스턴스를 실행하고 LlamaIndex에서 벡터 저장소 인스턴스를 만들었습니다. 그다음 데이터를 Milvus에 넣고, LlamaIndex를 사용하여 인용 쿼리 엔진을 통해 출처 표시와 인용을 추적했습니다. 그런 다음 해당 쿼리 엔진에 쿼리하여 응답을 얻을 수 있으며, 여기에는 텍스트의 어느 부분에서, 그리고 어떤 텍스트를 바탕으로 답변을 도출했는지가 포함됩니다.
계속 읽기

Migrating from S3 Vectors to Zilliz Cloud: Unlocking the Power of Tiered Storage
Learn how Zilliz Cloud bridges cost and performance with tiered storage and enterprise-grade features, and how to migrate data from AWS S3 Vectors to Zilliz Cloud.

Bringing AI to Legal Tech: The Role of Vector Databases in Enhancing LLM Guardrails
Discover how vector databases enhance AI reliability in legal tech, ensuring accurate, compliant, and trustworthy AI-powered legal solutions.

Introducing DeepSearcher: A Local Open Source Deep Research
In contrast to OpenAI’s Deep Research, this example ran locally, using only open-source models and tools like Milvus and LangChain.



