Haystack와 Cohere

Haystack와 Cohere (통합 가이드)

Haystack으로 커스텀 LLM 애플리케이션을 구축하는 방법을 알아볼 거예요. 이제 임베딩, 생성, 채팅, 검색을 위해 Cohere와 통합된답니다.

Haystack은 deepset이 만든 Python 기반 오픈소스 LLM 프레임워크로, 커스터마이즈 가능하고 프로덕션에 바로 쓸 수 있는 LLM 애플리케이션을 구축하기 위한 것이에요. Cohere의 /embed, /generate, /chat, /rerank 모델을 Haystack에서 사용할 수 있어요.

Cohere의 Haystack 통합은 검색 증강 생성(RAG), 채팅, 인덱싱 등 다양한 Haystack 파이프라인에서 사용할 수 있는 네 가지 컴포넌트를 제공해요.

  • CohereDocumentEmbedder: Cohere 임베딩 모델을 사용해 문서를 인덱싱해서 벡터 데이터베이스에 넣습니다.
  • CohereTextEmbedder: Cohere 임베딩 모델을 사용해 임베딩 검색을 수행합니다.
  • CohereGenerator: Cohere의 텍스트 생성 모델을 사용합니다.
  • CohereChatGenerator: Cohere의 채팅 완성(chat completion) 엔드포인트를 사용합니다.

출처: 문서

사전 요구 사항 (Prerequisites)

Cohere와 Haystack을 사용하려면 다음이 필요해요.

  • cohere-haystack 통합이 설치되어 있어야 함. 설치하려면 pip install cohere-haystack을 실행하세요. 문제가 생기거나 자세한 내용이 필요하면 이 문서를 참조하세요.
  • Cohere API 키. 가격에 대한 자세한 내용은 이 페이지를 참조하세요. Cohere로 계정을 만들면 트라이얼 API 키가 자동으로 생성돼요. 이 키는 대시보드에서 복사할 수 있고, 대시보드의 "API Keys" 섹션에도 있어요.

Haystack과 함께하는 Cohere Chat

Haystack의 CohereChatGenerator 컴포넌트는 Cohere의 대규모 언어 모델(LLM)을 사용해 채팅 완성을 가능하게 해 줘요. Cohere Chat에 대한 최신 정보는 이 문서를 참조하세요.

아래 예시에서는 Cohere API 키를 추가해야 해요. 환경 변수 COHERE_API_KEY를 사용할 것을 권장해요. API 키를 소스 제어에 커밋하지 마세요!

PYTHON

from haystack import Pipeline
from haystack.components.builders import DynamicChatPromptBuilder
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.generators.cohere import (
    CohereChatGenerator,
)
from haystack.utils import Secret
import os

COHERE_API_KEY = os.environ.get("COHERE_API_KEY")

pipe = Pipeline()
pipe.add_component("prompt_builder", DynamicChatPromptBuilder())
pipe.add_component(
    "llm", CohereChatGenerator(Secret.from_token(COHERE_API_KEY))
)
pipe.connect("prompt_builder", "llm")

location = "Berlin"
system_message = ChatMessage.from_system(
    "You are an assistant giving out valuable information to language learners."
)
messages = [
    system_message,
    ChatMessage.from_user("Tell me about {{location}}"),
]

res = pipe.run(
    data={
        "prompt_builder": {
            "template_variables": {"location": location},
            "prompt_source": messages,
        }
    }
)
print(res)

이렇게 LLM에 추가 동적 변수를 전달할 수도 있어요.

PYTHON

messages = [
    system_message,
    ChatMessage.from_user(
        "What's the weather forecast for {{location}} in the next {{day_count}} days?"
    ),
]

res = pipe.run(
    data={
        "prompt_builder": {
            "template_variables": {
                "location": location,
                "day_count": "5",
            },
            "prompt_source": messages,
        }
    }
)

print(res)

검색 증강과 함께하는 Cohere Chat

이 Haystack 검색 증강 생성 (RAG) 파이프라인은 Cohere의 문서를 Cohere 모델에 전달해서 Cohere의 기능을 더 잘 설명할 수 있게 해요. 아래 예시에서 LinkContentFetcher가 기존의 리트리버를 대체하는 것을 볼 수 있어요. URL의 내용이 생성기로 전달돼요.

PYTHON

from haystack import Document
from haystack import Pipeline
from haystack.components.builders import DynamicChatPromptBuilder
from haystack.components.generators.utils import print_streaming_chunk
from haystack.components.fetchers import LinkContentFetcher
from haystack.components.converters import HTMLToDocument
from haystack.dataclasses import ChatMessage
from haystack.utils import Secret

from haystack_integrations.components.generators.cohere import (
    CohereChatGenerator,
)

fetcher = LinkContentFetcher()
converter = HTMLToDocument()
prompt_builder = DynamicChatPromptBuilder(
    runtime_variables=["documents"]
)
llm = CohereChatGenerator(Secret.from_token(COHERE_API_KEY))

message_template = """Answer the following question based on the contents of the article: {{query}}\n\n
               Article: {{documents[0].content}} \n
           """
messages = [ChatMessage.from_user(message_template)]

rag_pipeline = Pipeline()
rag_pipeline.add_component(name="fetcher", instance=fetcher)
rag_pipeline.add_component(name="converter", instance=converter)
rag_pipeline.add_component("prompt_builder", prompt_builder)
rag_pipeline.add_component("llm", llm)

rag_pipeline.connect("fetcher.streams", "converter.sources")
rag_pipeline.connect(
    "converter.documents", "prompt_builder.documents"
)
rag_pipeline.connect("prompt_builder.prompt", "llm.messages")

question = "What are the capabilities of Cohere?"

result = rag_pipeline.run(
    {
        "fetcher": {"urls": ["/reference/about"]},
        "prompt_builder": {
            "template_variables": {"query": question},
            "prompt_source": messages,
        },
        "llm": {"generation_kwargs": {"max_tokens": 165}},
    },
)
print(result)
# {'llm': {'replies': [ChatMessage(content='The Cohere platform builds natural language processing and generation into your product with a few lines of code... \nIs', role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'command', 'usage': {'prompt_tokens': 273, 'response_tokens': 165, 'total_tokens': 438, 'billed_tokens': 430}, 'index': 0, 'finish_reason': None, 'documents': None, 'citations': None})]}}

Haystack RAG 파이프라인에서 Cohere 모델 사용하기

RAG는 LLM에 컨텍스트를 제공해 더 나은 답변을 생성하게 해 줘요. Cohere의 모든 모델을 CohereGenerator와 함께 Haystack RAG 파이프라인에서 사용할 수 있어요.

아래 코드 샘플은 문서 집합을 InMemoryDocumentStore에 추가한 다음, 그 문서들을 사용해 질문에 답해요. 실행하려면 Cohere API 키가 필요해요.

이 예시들은 단순함을 위해 InMemoryDocumentStore를 사용하지만, Haystack은 다양한 벡터 데이터베이스 및 문서 저장소 옵션을 지원해요. 그 중 어느 것이든 Cohere 모델과 함께 사용할 수 있어요.

PYTHON

from haystack import Pipeline
from haystack.components.retrievers.in_memory import (
    InMemoryBM25Retriever,
)
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack_integrations.components.generators.cohere import (
    CohereGenerator,
)
from haystack import Document
from haystack.utils import Secret

import os

COHERE_API_KEY = os.environ.get("COHERE_API_KEY")

docstore = InMemoryDocumentStore()
docstore.write_documents(
    [
        Document(content="Rome is the capital of Italy"),
        Document(content="Paris is the capital of France"),
    ]
)

query = "What is the capital of France?"

template = """
Given the following information, answer the question.

Context:
{% for document in documents %}
    {{ document.content }}
{% endfor %}

Question: {{ query }}?
"""
pipe = Pipeline()

pipe.add_component(
    "retriever", InMemoryBM25Retriever(document_store=docstore)
)
pipe.add_component("prompt_builder", PromptBuilder(template=template))
pipe.add_component(
    "llm", CohereGenerator(Secret.from_token(COHERE_API_KEY))
)
pipe.connect("retriever", "prompt_builder.documents")
pipe.connect("prompt_builder", "llm")

res = pipe.run(
    {
        "prompt_builder": {"query": query},
        "retriever": {"query": query},
    }
)

print(res)
# {'llm': {'replies': [' Paris is the capital of France. It is known for its history, culture, and many iconic landmarks, such as the Eiffel Tower and Notre-Dame Cathedral. '], 'meta': [{'finish_reason': 'COMPLETE'}]}}

Haystack과 함께하는 Cohere 임베딩

Cohere의 임베딩 모델을 Haystack RAG 파이프라인 안에서 사용할 수 있어요. 지원되는 모든 모델 목록은 Cohere의 모델 문서에서 확인할 수 있어요. 아래 코드 샘플을 실행하기 전에 COHERE_API_KEY 환경 변수를 설정하세요.

이 예시들은 단순함을 위해 InMemoryDocumentStore를 사용하지만, Haystack은 다양한 벡터 데이터베이스 및 문서 저장소 옵션을 지원해요.

Haystack과 Cohere 임베딩으로 문서 인덱싱하기

PYTHON

from haystack import Pipeline
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.writers import DocumentWriter
from haystack_integrations.components.embedders.cohere import (
    CohereDocumentEmbedder,
)
from haystack.utils import Secret
import os

COHERE_API_KEY = os.environ.get("COHERE_API_KEY")
token = Secret.from_token(COHERE_API_KEY)

document_store = InMemoryDocumentStore(
    embedding_similarity_function="cosine"
)

documents = [
    Document(content="My name is Wolfgang and I live in Berlin"),
    Document(content="I saw a black horse running"),
    Document(content="Germany has many big cities"),
]

indexing_pipeline = Pipeline()
indexing_pipeline.add_component(
    "embedder", CohereDocumentEmbedder(token)
)
indexing_pipeline.add_component(
    "writer", DocumentWriter(document_store=document_store)
)
indexing_pipeline.connect("embedder", "writer")

indexing_pipeline.run({"embedder": {"documents": documents}})
print(document_store.filter_documents())
# [Document(id=..., content: 'My name is Wolfgang and I live in Berlin', embedding: vector of size 4096), Document(id=..., content: 'Germany has many big cities', embedding: vector of size 4096)]

Haystack과 Cohere 임베딩으로 문서 검색하기

인덱싱 파이프라인이 임베딩을 문서 저장소에 추가한 후에는, 데이터베이스에서 가장 관련성 높은 문서를 가져오는 검색 파이프라인을 구축할 수 있어요. 이는 RAG 파이프라인의 기초가 될 수도 있는데, 끝에 생성(generator) 컴포넌트를 추가하면 돼요.

PYTHON

from haystack import Pipeline
from haystack.components.retrievers.in_memory import (
    InMemoryEmbeddingRetriever,
)
from haystack_integrations.components.embedders.cohere import (
    CohereTextEmbedder,
)

query_pipeline = Pipeline()
query_pipeline.add_component(
    "text_embedder", CohereTextEmbedder(token)
)
query_pipeline.add_component(
    "retriever",
    InMemoryEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect(
    "text_embedder.embedding", "retriever.query_embedding"
)

query = "Who lives in Berlin?"

result = query_pipeline.run({"text_embedder": {"text": query}})

print(result["retriever"]["documents"][0])

# Document(id=..., text: 'My name is Wolfgang and I live in Berlin')

더 알아보기 (Learn more)