Cohere 연동
원본 보기Cohere 연동
이 튜토리얼의 안내에서는 inference API를 사용해 Cohere로 임베딩을 계산하고, 이를 저장해 Elasticsearch에서 효율적인 벡터 검색 또는 하이브리드 검색을 수행하는 방법을 보여줍니다. 이 튜토리얼에서는 Python Elasticsearch 클라이언트를 사용해 작업을 수행합니다.
다음 내용을 배우게 됩니다:
- Cohere 서비스를 사용해 텍스트 임베딩용 inference 엔드포인트 생성하기,
- Elasticsearch 인덱스에 필요한 인덱스 매핑 생성하기,
- 문서를 임베딩과 함께 인덱스로 수집하는 inference 파이프라인 구축하기,
- 데이터에 대해 하이브리드 검색 수행하기,
- Cohere의 rerank 모델을 사용해 검색 결과 재순위 매기기,
- Cohere의 Chat API로 RAG 시스템 설계하기.
이 튜토리얼은 SciFact 데이터 세트를 사용합니다.
다른 데이터 세트를 사용하는 예시는 Cohere의 튜토리얼을 참조하세요.
이 튜토리얼의 Colab 노트북 버전도 확인할 수 있습니다.
- Cohere 무료 체험판은 API 사용량이 제한되어 있으므로, Cohere 서비스로 Inference API를 사용하려면 유료 Cohere 계정이 필요합니다,
- Elastic Serverless 또는 Cloud 계정,
- Python 3.7 이상.
Elasticsearch와 Cohere를 설치합니다:
!pip install elasticsearch
!pip install cohere
필요한 패키지를 임포트합니다:
from elasticsearch import Elasticsearch, helpers
import cohere
import json
import requests
Elasticsearch 클라이언트를 생성하려면 다음이 필요합니다:
ELASTIC_URL = "your_elasticsearch_endpoint_url"
ELASTIC_API_KEY = "elastic_api_key"
client = Elasticsearch(
hosts=ELASTIC_URL,
api_key=ELASTIC_API_KEY
)
# Confirm the client has connected
print(client.info())
먼저 inference 엔드포인트를 생성합니다. 이 예시에서 inference 엔드포인트는 Cohere의 embed-english-v3.0 모델을 사용하며 embedding_type은 byte로 설정되어 있습니다.
COHERE_API_KEY = "cohere_api_key"
client.inference.put_model(
task_type="text_embedding",
inference_id="cohere_embeddings",
body={
"service": "cohere",
"service_settings": {
"api_key": COHERE_API_KEY,
"model_id": "embed-english-v3.0",
"embedding_type": "byte"
}
},
)
API 키는 Cohere 대시보드의 API keys 섹션에서 확인할 수 있습니다.
임베딩을 저장할 인덱스의 인덱스 매핑을 생성합니다.
client.indices.create(
index="cohere-embeddings",
settings={"index": {"default_pipeline": "cohere_embeddings"}},
mappings={
"properties": {
"text_embedding": {
"type": "dense_vector",
"dims": 1024,
"element_type": "byte",
},
"text": {"type": "text"},
"id": {"type": "integer"},
"title": {"type": "text"}
}
},
)
이제 inference 엔드포인트와 임베딩을 저장할 인덱스가 준비되었습니다. 다음 단계는 inference 엔드포인트를 사용해 임베딩을 생성하고 이를 인덱스에 저장하는 inference 프로세서가 포함된 ingest 파이프라인을 생성하는 것입니다.
client.ingest.put_pipeline(
id="cohere_embeddings",
description="Ingest pipeline for Cohere inference.",
processors=[
{
"inference": {
"model_id": "cohere_embeddings",
"input_output": {
"input_field": "text",
"output_field": "text_embedding",
},
}
}
],
)
이 예시는 HuggingFace에서 찾을 수 있는 SciFact 데이터 세트를 사용합니다.
url = 'https://huggingface.co/datasets/mteb/scifact/raw/main/corpus.jsonl'
# Fetch the JSONL data from the URL
response = requests.get(url)
response.raise_for_status()
# Split the content by new lines and parse each line as JSON
data = [json.loads(line) for line in response.text.strip().split('\n') if line]
# Now data is a list of dictionaries
# Change `_id` key to `id` as `_id` is a reserved key in Elasticsearch.
for item in data:
if '_id' in item:
item['id'] = item.pop('_id')
# Prepare the documents to be indexed
documents = []
for line in data:
data_dict = line
documents.append({
"_index": "cohere-embeddings",
"_source": data_dict,
}
)
# Use the bulk endpoint to index
helpers.bulk(client, documents)
print("Data ingestion completed, text embeddings generated!")
- 잘못된 응답을 반드시 확인합니다
인덱스에 SciFact 데이터와 text 필드에 대한 텍스트 임베딩이 채워집니다.
이제 인덱스에 쿼리를 시작해 봅시다!
아래 코드는 하이브리드 검색을 수행합니다. kNN 쿼리는 text_embedding 필드를 사용한 벡터 유사도를 기반으로 검색 결과의 관련성을 계산하고, 렉시컬 검색 쿼리는 BM25 검색을 사용해 title 및 text 필드에서 키워드 유사도를 계산합니다.
query = "What is biosimilarity?"
response = client.search(
index="cohere-embeddings",
size=100,
knn={
"field": "text_embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "cohere_embeddings",
"model_text": query,
}
},
"k": 10,
"num_candidates": 50,
},
query={
"multi_match": {
"query": query,
"fields": ["text", "title"]
}
}
)
raw_documents = response["hits"]["hits"]
# Display the first 10 results
for document in raw_documents[0:10]:
print(f'Title: {document["_source"]["title"]}\nText: {document["_source"]["text"]}\n')
# Format the documents for ranking
documents = []
for hit in response["hits"]["hits"]:
documents.append(hit["_source"]["text"])
결과를 더 효과적으로 결합하려면 inference API를 통해 Cohere의 Rerank v3 모델을 사용해 결과에 더 정밀한 시맨틱 재순위를 적용하세요.
Cohere API 키와 사용할 모델 이름을 model_id로 지정해 inference 엔드포인트를 생성합니다(이 예시에서는 rerank-english-v3.0).
client.inference.put_model(
task_type="rerank",
inference_id="cohere_rerank",
body={
"service": "cohere",
"service_settings":{
"api_key": COHERE_API_KEY,
"model_id": "rerank-english-v3.0"
},
"task_settings": {
"top_n": 10,
},
}
)
새 inference 엔드포인트를 사용해 결과의 순위를 다시 매깁니다.
# Pass the query and the search results to the service
response = client.inference.rerank(
inference_id="cohere_rerank",
body={
"query": query,
"input": documents,
"task_settings": {
"return_documents": False
}
}
)
# Reconstruct the input documents based on the index provided in the rereank response
ranked_documents = []
for document in response.body["rerank"]:
ranked_documents.append({
"title": raw_documents[int(document["index"])]["_source"]["title"],
"text": raw_documents[int(document["index"])]["_source"]["text"]
})
# Print the top 10 results
for document in ranked_documents[0:10]:
print(f"Title: {document['title']}\nText: {document['text']}\n")
응답은 관련성이 높은 순서대로 정렬된 문서 목록입니다. 각 문서에는 inference 엔드포인트로 전송되었을 때의 문서 순서를 나타내는 인덱스가 함께 제공됩니다.
RAG는 외부 데이터 소스에서 가져온 추가 정보를 사용해 텍스트를 생성하는 방법입니다. 순위가 매겨진 결과를 활용하면 Cohere의 Chat API를 사용해 앞서 만든 것 위에 RAG 시스템을 구축할 수 있습니다.
검색된 문서와 쿼리를 전달해 Cohere의 최신 생성 모델인 Command R+로부터 근거 기반 응답을 받아 보세요.
그런 다음 쿼리와 문서를 Chat API에 전달하고 응답을 출력합니다.
response = co.chat(message=query, documents=ranked_documents, model='command-r-plus')
source_documents = []
for citation in response.citations:
for document_id in citation.document_ids:
if document_id not in source_documents:
source_documents.append(document_id)
print(f"Query: {query}")
print(f"Response: {response.text}")
print("Sources:")
for document in response.documents:
if document['id'] in source_documents:
print(f"{document['title']}: {document['text']}")
응답은 다음과 비슷한 형태가 됩니다:
Query: What is biosimilarity?
Response: Biosimilarity is based on the comparability concept, which has been used successfully for several decades to ensure close similarity of a biological product before and after a manufacturing change. Over the last 10 years, experience with biosimilars has shown that even complex biotechnology-derived proteins can be copied successfully.
Sources:
Interchangeability of Biosimilars: A European Perspective: (...)