LostInTheMiddleRanker

LostInTheMiddleRanker

가장 관련성 높은 문서를 결과 목록의 맨 앞과 맨 끝에, 가장 덜 관련성 높은 문서를 가운데 배치해주는 랭커예요. 쿼리 파이프라인에서 Retriever처럼 문서 목록을 반환하는 컴포넌트 뒤에 두면 돼요.

출처: LostInTheMiddleRanker

본문

개요

LostInTheMiddleRanker는 "Lost in the Middle: How Language Models Use Long Contexts" 연구 논문에서 설명한 "Lost in the Middle" 순서로 문서를 재정렬해요. 목표는 단락들을 LLM 컨텍스트에 배치해서, 관련 단락은 입력 컨텍스트의 시작이나 끝에, 가장 덜 관련성 높은 정보는 컨텍스트 중간에 오게 하는 거예요. 이 재정렬은 매우 긴 컨텍스트를 LLM에 보낼 때 유용한데, 현재 모델들은 긴 입력 컨텍스트의 시작과 끝에 더 주의를 기울이기 때문이에요.

다른 랭커와 달리 LostInTheMiddleRanker는 입력 문서가 이미 관련성 순으로 정렬돼 있다고 가정하며, 쿼리를 입력으로 요구하지 않아요. 보통 LLM용 프롬프트를 만들기 직전의 마지막 컴포넌트로, LLM에 넣을 입력 컨텍스트를 준비할 때 사용해요.

파라미터

컴포넌트를 실행할 때 word_count_threshold를 지정하면, 랭커는 문서를 하나 더 추가하면 주어진 임계값을 초과하게 되는 지점까지 모든 문서를 포함해요. 임계값을 초과하는 마지막 문서는 결과 문서 목록에 포함되지만, 그 뒤의 모든 문서는 버려져요.

top_k 파라미터로 반환할 최대 문서 수를 설정할 수도 있어요.

사용법

단독 사용:

from haystack import Document
from haystack.components.rankers import LostInTheMiddleRanker

ranker = LostInTheMiddleRanker()
docs = [
    Document(content="Paris"),
    Document(content="Berlin"),
    Document(content="Madrid"),
]
result = ranker.run(documents=docs)

for doc in result["documents"]:
    print(doc.content)

파이프라인 안에서:

이 예시를 실행하려면 OpenAI 키가 필요하다는 점을 기억해 두세요.

from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.rankers import LostInTheMiddleRanker
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder
from haystack.dataclasses import ChatMessage

# Define prompt template
prompt_template = [
    ChatMessage.from_system("You are a helpful assistant."),
    ChatMessage.from_user(
        "Given these documents, answer the question.\nDocuments:\n"
        "{% for doc in documents %}{{ doc.content }}{% endfor %}\n"
        "Question: {{query}}\nAnswer:",
    ),
]

# Define documents
docs = [
    Document(content="Paris is in France..."),
    Document(content="Berlin is in Germany..."),
    Document(content="Lyon is in France..."),
]

document_store = InMemoryDocumentStore()
document_store.write_documents(docs)

retriever = InMemoryBM25Retriever(document_store=document_store)
ranker = LostInTheMiddleRanker(word_count_threshold=1024)
prompt_builder = ChatPromptBuilder(
    template=prompt_template,
    required_variables={"query", "documents"},
)
generator = OpenAIChatGenerator()

p = Pipeline()
p.add_component(instance=retriever, name="retriever")
p.add_component(instance=ranker, name="ranker")
p.add_component(instance=prompt_builder, name="prompt_builder")
p.add_component(instance=generator, name="llm")

p.connect("retriever.documents", "ranker.documents")
p.connect("ranker.documents", "prompt_builder.documents")
p.connect("prompt_builder.prompt", "llm.messages")

p.run(
    {
        "retriever": {"query": "What cities are in France?", "top_k": 3},
        "prompt_builder": {"query": "What cities are in France?"},
    },
)

더 알아보기 (Learn more)