청크에 대한 포함을 생성한 후 다음 단계는 벡터 데이터베이스에서 인덱스를 생성하고 실험하여 수행할 최적의 검색을 결정하는 것입니다. 정보 검색을 실험하는 경우 검색 인덱스의 구성 옵션, 수행해야 하는 검색 유형 및 재전송 전략을 포함하여 고려해야 할 몇 가지 영역이 있습니다. 이 문서에서는 다음과 같은 세 가지 주제를 다룹니다.
이 문서는 시리즈의 일부입니다. 소개를 읽습니다.
검색 인덱스
참고 항목
Azure AI 검색은 자사 Azure Search 서비스입니다. 이 섹션에서는 AI Search에 대한 몇 가지 세부 사항을 설명합니다. 다른 저장소를 사용하는 경우 설명서를 참조하여 해당 서비스에 대한 주요 구성을 찾습니다.
저장소의 검색 인덱스는 데이터의 모든 필드에 대한 열을 가합니다. 검색 저장소는 일반적으로 문자열, 부울, 정수, 단일, 이중, datetime 및 컬렉션(단일) 및 컬렉션(단일)과 같은 벡터 데이터 형식과 같은 비벡터 데이터 형식을 지원합니다. 각 열에 대해 데이터 형식, 필드 필터링 가능 여부, 검색 가능 여부 및/또는 검색 가능 여부와 같은 정보를 구성해야 합니다.
다음은 벡터 필드에 적용되는 벡터 검색 구성에 대해 수행해야 하는 몇 가지 주요 결정 사항입니다.
- 벡터 검색 알고리즘 - 상대 일치 항목을 검색하는 데 사용되는 알고리즘입니다. Azure AI 검색에는 완전 KNN이라는 전체 벡터 공간을 검색하는 무차별 암호 대입 알고리즘 옵션과 HNSW(계층적 탐색 가능한 Small World)라는 근사한 ANN(Approximate Nearest Neighbor) 검색을 수행하는 보다 성능이 뛰어난 알고리즘 옵션이 있습니다.
- 메트릭 - 이 구성은 알고리즘의 근접성을 계산하는 데 사용되는 유사성 메트릭입니다. Azure AI 검색의 옵션은 코사인, dotProduct 및 Euclidean입니다. Azure OpenAI 포함 모델을 사용하는 경우
cosine
을(를) 선택합니다. - efConstruction - 인덱싱 중에 벡터에 연결된 가장 가까운 인접 항목의 수를 설정하는 HNSW(계층적 탐색 가능 Small Worlds) 인덱스 생성 중에 사용되는 매개 변수입니다. efConstruction 값이 크면 더 작은 수보다 품질이 좋은 인덱스가 생성됩니다. 단점은 값이 클수록 더 많은 시간, 스토리지 및 컴퓨팅이 필요하다는 것입니다. efConstruction은 많은 수의 청크에 대해 더 높고 낮은 수의 청크에 대해서는 낮아야 합니다. 최적 값을 결정하려면 데이터 및 예상 쿼리를 실험해야 합니다.
- efSearch - 검색 중에 사용되는 가장 가까운 인접 항목(즉, 유사한 청크)의 수를 설정하기 위해 쿼리 시간에 사용되는 매개 변수입니다.
- m - 양방향 링크 수입니다. 범위는 4에서 10까지이며, 숫자가 낮을수록 결과에서 노이즈가 줄어듭니다.
Azure AI 검색에서 벡터 구성은 vectorSearch
구성에 캡슐화됩니다. 벡터 열을 구성할 때 해당 벡터 열에 대한 적절한 구성을 참조하고 차원 수를 설정합니다. 벡터 열의 차원 특성은 선택한 포함 모델에서 생성된 차원 수를 나타냅니다. 예를 들어 스토리지 최적화 text-embedding-3-small
모델은 1,536개의 차원을 생성합니다.
검색
검색 저장소에 대해 프롬프트 오케스트레이터에서 쿼리를 실행할 때 고려해야 할 많은 옵션이 있습니다. 다음을 결정해야 합니다.
- 수행할 검색 유형: 벡터 또는 키워드 또는 하이브리드
- 하나 이상의 열에 대해 쿼리할지 여부
- 키워드 쿼리 및 벡터 검색과 같은 여러 쿼리를 수동으로 실행할지 여부
- 쿼리를 하위 쿼리로 세분화해야 하는지 여부
- 쿼리에서 필터링을 사용해야 하는지 여부
프롬프트 오케스트레이터는 정적 접근 방식 또는 프롬프트의 컨텍스트 단서를 기반으로 접근 방식을 혼합하는 동적 접근 방식을 사용할 수 있습니다. 다음 섹션에서는 워크로드에 적합한 방법을 찾기 위해 실험하는 데 도움이 되는 이러한 옵션을 다룹니다.
검색 유형
검색 플랫폼은 일반적으로 전체 텍스트 및 벡터 검색을 지원합니다. Azure AI 검색과 같은 일부 플랫폼은 하이브리드 검색을 지원합니다. 다양한 벡터 검색 제품의 기능을 보려면 벡터 검색에 대한 Azure 서비스 선택을 검토합니다.
벡터 검색
벡터 검색은 벡터화된 쿼리(프롬프트)와 벡터 필드 간의 유사성에 일치합니다.
Important
쿼리를 포함하기 전에 청크에서 수행한 것과 동일한 정리 작업을 수행해야 합니다. 예를 들어 포함된 청크의 모든 단어를 소문자로 지정한 경우 포함하기 전에 쿼리의 모든 단어를 소문자로 지정해야 합니다.
참고 항목
동일한 쿼리에서 여러 벡터 필드에 대해 벡터 검색을 수행할 수 있습니다. Azure AI 검색에서는 기술적으로 하이브리드 검색입니다. 자세한 내용은 해당 섹션을 참조하세요.
embedding = embedding_model.generate_embedding(
chunk=str(pre_process.preprocess(query))
)
vector = RawVectorQuery(
k=retrieve_num_of_documents,
fields="contentVector",
vector=embedding,
)
results = client.search(
search_text=None,
vector_queries=[vector],
top=retrieve_num_of_documents,
select=["title", "content", "summary"],
)
샘플 코드는 contentVector
필드에 대해 벡터 검색을 수행합니다. 쿼리를 포함하는 코드는 먼저 쿼리를 전처리합니다. 해당 전처리는 포함하기 전에 청크를 전처리하는 동일한 코드여야 합니다. 포함 모델은 청크를 포함하는 것과 동일한 포함 모델이어야 합니다.
전체 텍스트 검색
전체 텍스트 검색은 인덱스에 저장된 일반 텍스트와 일치합니다. 쿼리에서 키워드를 추출하고 하나 이상의 인덱싱된 열에 대해 전체 텍스트 검색에서 추출된 키워드를 사용하는 것이 일반적입니다. 모든 용어 또는 모든 용어가 일치하는 일치 항목을 반환하도록 전체 텍스트 검색을 구성할 수 있습니다.
전체 텍스트 검색을 실행하는 데 효과적인 필드를 확인하기 위해 실험해야 합니다. 보강 단계에서 설명한 대로 키워드 및 엔터티 메타데이터 필드는 콘텐츠의 의미 체계가 비슷하지만 엔터티 또는 키워드가 다른 시나리오에서 전체 텍스트 검색을 고려할 수 있는 좋은 후보입니다. 전체 텍스트 검색을 위해 고려해야 할 다른 일반적인 필드는 제목, 요약 및 청크 텍스트입니다.
formatted_search_results = []
results = client.search(
search_text=query,
top=retrieve_num_of_documents,
select=["title", "content", "summary"],
)
formatted_search_results = format_results(results)
샘플 코드는 제목, 콘텐츠 및 요약 필드에 대해 전체 텍스트 검색을 수행합니다.
하이브리드 검색
Azure AI 검색은 하나 이상의 텍스트 검색과 하나 이상의 벡터 검색을 쿼리에 포함할 수 있는 하이브리드 쿼리를 지원합니다. 플랫폼은 각 쿼리를 수행하고, 중간 결과를 얻고, RRF(Reciprocal Rank Fusion)를 사용하여 결과를 다시 표시하고, 상위 N개 결과를 반환합니다.
embedding = embedding_model.generate_embedding(
chunk=str(pre_process.preprocess(query))
)
vector1 = RawVectorQuery(
k=retrieve_num_of_documents,
fields="contentVector",
vector=embedding,
)
vector2 = RawVectorQuery(
k=retrieve_num_of_documents,
fields="questionVector",
vector=embedding,
)
results = client.search(
search_text=query,
vector_queries=[vector1, vector2],
top=retrieve_num_of_documents,
select=["title", "content", "summary"],
)
샘플 코드는 제목, 콘텐츠 및 요약 필드에 대해 전체 텍스트 검색을 수행하고 contentVector 및 questionVector 필드에 대해 벡터 검색을 수행합니다. Azure AI 검색 플랫폼은 모든 쿼리를 병렬로 실행하고, 결과를 다시 표시하고, 상위 retrieve_num_of_documents 문서를 반환합니다.
수동 다중
물론 벡터 검색 및 키워드 전체 텍스트 검색과 같은 여러 쿼리를 수동으로 실행할 수 있습니다. 결과를 집계하고 결과를 수동으로 다시 표시하고 상위 결과를 반환합니다. 다음은 수동 다중에 대한 사용 사례입니다.
- 하이브리드 검색을 지원하지 않는 검색 플랫폼을 사용하고 있습니다. 이 옵션을 따라 고유한 하이브리드 검색을 수행합니다.
- 다른 쿼리에 대해 전체 텍스트 검색을 실행하려고 합니다. 예를 들어 쿼리에서 키워드를 추출하고 키워드 메타데이터 필드에 대해 전체 텍스트 검색을 실행할 수 있습니다. 그런 다음 엔터티를 추출하고 엔터티 메타데이터 필드에 대해 쿼리를 실행할 수 있습니다.
- 재전송 프로세스를 직접 제어하려고 합니다.
- 쿼리를 수행하려면 여러 원본에서 접지 데이터를 검색하기 위해 다중 하위 쿼리를 실행해야 합니다.
다중 하위 쿼리
일부 프롬프트는 복잡하며 모델을 접지하려면 둘 이상의 데이터 컬렉션이 필요합니다. 예를 들어 "전기 자동차는 어떻게 작동하고 ICE 차량과 어떻게 비교합니까?" 쿼리에는 여러 원본의 접지 데이터가 필요할 수 있습니다.
검색을 실행하기 전에 쿼리에 여러 검색이 필요한지 여부를 확인하는 것이 좋습니다. 다중 하위 쿼리가 필요하다고 판단되는 경우 모든 쿼리에 대해 수동으로 다중 쿼리를 실행할 수 있습니다. 큰 언어 모델을 사용하여 다중 하위 쿼리가 필요한지 여부를 확인합니다. 다음 프롬프트는 쿼리를 단순 또는 복합으로 분류하는 데 사용되는 RAG 실험 가속기 GitHub 리포지토리 에서 가져온 것이며 복잡한 쿼리에는 여러 쿼리가 필요합니다.
Consider the given question to analyze and determine if it falls into one of these categories:
1. Simple, factual question
a. The question is asking for a straightforward fact or piece of information
b. The answer could likely be found stated directly in a single passage of a relevant document
c. Breaking the question down further is unlikely to be beneficial
Examples: "What year did World War 2 end?", "What is the capital of France?, "What is the features of productX?"
2. Complex, multi-part question
a. The question has multiple distinct components or is asking for information about several related topics
b. Different parts of the question would likely need to be answered by separate passages or documents
c. Breaking the question down into sub-questions for each component would allow for better results
d. The question is open-ended and likely to have a complex or nuanced answer
e. Answering it may require synthesizing information from multiple sources
f. The question may not have a single definitive answer and could warrant analysis from multiple angles
Examples: "What were the key causes, major battles, and outcomes of the American Revolutionary War?", "How do electric cars work and how do they compare to gas-powered vehicles?"
Based on this rubric, does the given question fall under category 1 (simple) or category 2 (complex)? The output should be in strict JSON format. Ensure that the generated JSON is 100 percent structurally correct, with proper nesting, comma placement, and quotation marks. There should not be any comma after last element in the JSON.
Example output:
{
"category": "simple"
}
큰 언어 모델을 사용하여 복잡한 쿼리에서 하위 쿼리를 추출할 수도 있습니다. 다음 프롬프트는 복잡한 쿼리를 여러 하위 쿼리로 변환하는 RAG 실험 가속기 GitHub 리포지 토리에서 가져옵니다.
Your task is to take a question as input and generate maximum 3 sub-questions that cover all aspects of the original question. The output should be in strict JSON format, with the sub-questions contained in an array.
Here are the requirements:
1. Analyze the original question and identify the key aspects or components.
2. Generate sub-questions that address each aspect of the original question.
3. Ensure that the sub-questions collectively cover the entire scope of the original question.
4. Format the output as a JSON object with a single key "questions" that contains an array of the generated sub-questions.
5. Each sub-question should be a string within the "questions" array.
6. The JSON output should be valid and strictly formatted.
7. Ensure that the generated JSON is 100 percent structurally correct, with proper nesting, comma placement, and quotation marks. The JSON should be formatted with proper indentation for readability.
8. There should not be any comma after last element in the array.
Example input question:
What are the main causes of deforestation, and how can it be mitigated?
Example output:
{
"questions": [
"What are the primary human activities that contribute to deforestation?",
"How does agriculture play a role in deforestation?",
"What is the impact of logging and timber harvesting on deforestation?",
"How do urbanization and infrastructure development contribute to deforestation?",
"What are the environmental consequences of deforestation?",
"What are some effective strategies for reducing deforestation?",
"How can reforestation and afforestation help mitigate the effects of deforestation?",
"What role can governments and policies play in preventing deforestation?",
"How can individuals and communities contribute to reducing deforestation?"
]
}
쿼리에서 이미지 전달
GPT-4V 및 GPT-4o와 같은 일부 멀티모달 모델은 이미지를 해석할 수 있습니다. 이러한 모델을 사용하는 경우 이미지 청크를 방지할지 여부를 선택하고 프롬프트의 일부로 이미지를 멀티모달 모델에 전달할 수 있습니다. 추가 컨텍스트를 전달하지 않고 이미지를 청크 분할하는 것과 비교하여 이 방법이 어떻게 수행되는지 실험해야 합니다. 또한 방법 간의 비용 차이를 비교하고 비용 혜택 분석을 수행해야 합니다.
필터링
필터링 가능으로 구성된 검색 저장소의 필드를 사용하여 쿼리를 필터링할 수 있습니다. 결과 범위를 좁히기 위해 해당 필드를 사용하는 쿼리의 키워드 및 엔터티를 필터링하는 것이 좋습니다. 필터링을 사용하면 관련 없는 데이터를 제거하여 인덱스에서 특정 조건을 충족하는 데이터만 검색할 수 있습니다. 이렇게 하면 쿼리의 전반적인 성능이 향상되며 더 관련성이 높습니다. 모든 결정과 마찬가지로 실험하고 테스트하는 것이 중요합니다. 쿼리에 키워드 또는 잘못된 키워드, 약어 또는 머리글자어가 없을 수 있습니다. 이러한 경우를 고려해야 합니다.
재전송
재전송을 사용하면 하나 이상의 쿼리를 실행하고, 결과를 집계하고, 해당 결과의 순위를 지정할 수 있습니다. 검색 결과를 다시 표시해야 하는 이유는 다음과 같습니다.
- 수동으로 다중 검색을 수행했으며 결과를 집계하고 순위를 지정하려고 합니다.
- 벡터 및 키워드 검색이 항상 정확한 것은 아닙니다. 검색에서 반환되는 문서 수를 늘릴 수 있으며, 그렇지 않으면 무시될 수 있는 몇 가지 유효한 결과를 포함할 수 있으며, 재전송을 사용하여 결과를 평가할 수 있습니다.
큰 언어 모델 또는 크로스 인코더를 사용하여 재전송을 수행할 수 있습니다. Azure AI 검색과 같은 일부 플랫폼에는 결과를 다시 표시하기 위한 독점적인 방법이 있습니다. 데이터에 대해 이러한 옵션을 평가하여 시나리오에 가장 적합한 항목을 결정할 수 있습니다. 다음 섹션에서는 다음 메서드에 대한 자세한 내용을 제공합니다.
대규모 언어 모델 재전송
다음은 결과를 재전송하는 RAG 실험 가속기에서 제공하는 샘플 대용량 언어 모델 프롬프트입니다.
A list of documents is shown below. Each document has a number next to it along with a summary of the document. A question is also provided.
Respond with the numbers of the documents you should consult to answer the question, in order of relevance, as well as the relevance score as json string based on json format as shown in the schema section. The relevance score is a number from 1–10 based on how relevant you think the document is to the question. The relevance score can be repetitive. Don't output any additional text or explanation or metadata apart from json string. Just output the json string and strip rest every other text. Strictly remove any last comma from the nested json elements if it's present.
Don't include any documents that are not relevant to the question. There should exactly be one documents element.
Example format:
Document 1:
content of document 1
Document 2:
content of document 2
Document 3:
content of document 3
Document 4:
content of document 4
Document 5:
content of document 5
Document 6:
content of document 6
Question: user defined question
schema:
{
"documents": {
"document_1": "Relevance",
"document_2": "Relevance"
}
}
크로스 인코더 재전송
RAG 실험 가속기 GitHub 리포지토리의 다음 예제에서는 Hugging Face에서 제공하는 CrossEncoder를 사용하여 Roberta 모델을 로드합니다. 그런 다음 각 청크를 반복하고 모델을 사용하여 유사성을 계산하여 값을 제공합니다. 결과를 정렬하고 상위 N을 반환합니다.
from sentence_transformers import CrossEncoder
...
model_name = 'cross-encoder/stsb-roberta-base'
model = CrossEncoder(model_name)
cross_scores_ques = model.predict(
[[user_prompt, item] for item in documents],
apply_softmax=True,
convert_to_numpy=True,
)
top_indices_ques = cross_scores_ques.argsort()[-k:][::-1]
sub_context = []
for idx in list(top_indices_ques):
sub_context.append(documents[idx])
의미 체계 순위 지정
Azure AI 검색에는 의미 체계 순위라는 독점 기능이 있습니다. 이 기능은 의미상 가장 관련성이 높은 결과를 촉진하는 Microsoft Bing에서 조정된 딥 러닝 모델을 사용합니다. 의미 체계 순위의 작동 방식을 보려면 다음을 참조하세요.
검색 지침
검색 솔루션을 구현할 때 다음 일반적인 지침을 고려합니다.
- 제목, 요약, 원본 및 원시 콘텐츠(정리되지 않음)는 검색에서 반환하기에 좋은 필드입니다.
- 쿼리를 하위 쿼리로 세분화해야 하는지 여부를 미리 확인합니다.
- 일반적으로 여러 필드(벡터 및 텍스트 쿼리)에서 쿼리를 실행하는 것이 좋습니다. 쿼리를 받으면 벡터 검색 또는 텍스트 검색이 더 나은지 알 수 없습니다. 벡터 검색 또는 키워드 검색이 검색에 가장 적합한 필드는 더 이상 알 수 없습니다. 여러 쿼리를 사용하여 여러 필드를 검색하고, 결과를 다시 표시하고, 가장 높은 점수를 가진 결과를 반환할 수 있습니다.
- 키워드 및 엔터티 필드는 필터링을 고려할 수 있는 좋은 후보입니다.
- 벡터 검색과 함께 키워드를 사용하는 것이 좋습니다. 키워드는 결과를 더 작은 하위 집합으로 필터링합니다. 벡터 저장소는 해당 하위 집합에 대해 작동하여 가장 일치하는 항목을 찾습니다.
검색 평가
준비 단계에서는 테스트 문서 정보와 함께 테스트 쿼리를 수집해야 합니다. 해당 단계에서 수집한 다음 정보를 사용하여 검색 결과를 평가할 수 있습니다.
- 쿼리 - 샘플 쿼리
- 컨텍스트 - 샘플 쿼리를 처리하는 테스트 문서의 모든 텍스트 컬렉션
다음은 검색 솔루션을 평가하는 데 사용할 수 있는 설정된 세 가지 검색 평가 방법입니다.
- Precision at K - 전체 검색 결과에서 올바르게 식별된 관련 항목의 백분율입니다. 이 메트릭은 검색 결과의 정확도에 중점을 둡니다.
- Recall at K - Recall at K는 가능한 총 상대 항목 중 상위 K에 있는 관련 항목의 비율을 측정합니다. 이 메트릭은 검색 결과 검사에 중점을 둡니다.
- MRR(Mean Reciprocal Rank) - MRR은 순위가 지정된 검색 결과에서 첫 번째 관련 답변의 상호 순위 평균을 측정합니다. 이 메트릭은 검색 결과에서 첫 번째 관련 결과가 발생하는 위치에 중점을 둡니다.
긍정 및 부정 예제를 모두 테스트해야 합니다. 긍정적인 예제의 경우 메트릭을 가능한 한 1에 가깝게 지정하려고 합니다. 데이터가 쿼리를 처리할 수 없는 부정적인 예제의 경우 메트릭을 가능한 0에 가깝게 지정하려고 합니다. 모든 테스트 쿼리를 테스트하고 긍정 쿼리 결과와 음수 쿼리 결과를 평균하여 검색 결과가 집계에서 어떻게 수행되는지 이해해야 합니다.