Neste tutorial, você aprenderá a criar um geração aumentada por recuperação (RAG) aplicativo usando Serviços de IA do Couchbase para armazenar dados, gerar incorporação usando modelos de incorporação e inferência LLM. Criaremos um sistema RAG que:
- Ingere artigos de notícias do Conjunto de dados da BBC News.
- Gera embeddings de vetores usando o NVIDIA NeMo Retriever modelo via Capella Model Services.
- Armazena e indexa esses vetores em Couchbase Capella.
- Realiza pesquisa semântica para recuperar o contexto relevante.
- Gera respostas usando o Mistral-7B LLM hospedado na Capella.
Você pode encontrar o código-fonte do notebook para este CodeLab aqui.
Por que os serviços de IA do Couchbase?
Os serviços de IA do Couchbase fornecem:
- API de inferência e incorporação de LLM: Acesse LLMs populares (ou seja, Llama 3) e modelos de incorporação diretamente por meio do Capella, sem gerenciar chaves ou infraestrutura de API externas.
- Plataforma unificada: Aproveite o banco de dados, a vetorização, a pesquisa e o modelo em um só lugar.
- Pesquisa vetorial integrada: Realize pesquisas semânticas diretamente em seus dados JSON com latência de milissegundos.
Configuração dos serviços de IA do Couchbase
Criar um cluster no Capella
- Faça login em Couchbase Capella.
- Crie um novo cluster ou use um já existente. Observe que o cluster precisa executar a versão mais recente do Couchbase Server 8.0, que inclui os serviços Data, Query, Index e Eventing.
- Crie um balde.
- Crie um escopo e uma coleção para os dados.
Habilitar serviços de IA
- Navegue até a seção AI Services (Serviços de IA) da Capella na interface do usuário.
- Implante os modelos de embeddings e LLM.
- Você precisa iniciar uma incorporação e um LLM para essa demonstração na mesma região que o cluster do Capella onde os dados serão armazenados.
- Para que essa demonstração funcione bem, você precisa implantar um LLM que tenha recursos de chamada de ferramentas, como
mistralai/mistral-7b-instruct-v0.3. Para embeddings, você pode escolher um modelo como onvidia/llama-3.2-nv-embedqa-1b-v2. - Anote o URL do endpoint e gere chaves de API.
Para obter mais detalhes sobre o lançamento de modelos de IA, você pode ler o documentação oficial.
Pré-requisitos
Antes de começarmos, verifique se você tem o Python 3.10+ instalado.
Etapa 1: Instalar dependências
Precisamos do SDK do Couchbase, das integrações do LangChain e da biblioteca de conjuntos de dados.
|
1 |
%pip install --quiet datasets==4.4.1 langchain-couchbase==1.0.0 langchain-openai==1.1.0 |
Etapa 2: Configuração e conexão
Começaremos conectando-nos ao nosso cluster do Couchbase. Também precisamos configurar os endpoints para o Capella Model Services.
Observação: Os Capella Model Services são compatíveis com o formato da API OpenAI, portanto, podemos usar o padrão langchain-openai apontando-a para o nosso ponto de extremidade do Capella.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import getpass from couchbase.auth import PasswordAuthenticator from couchbase.cluster import Cluster from couchbase.options import ClusterOptions from datetime import timedelta # Configuration CB_CONNECTION_STRING = getpass.getpass("Couchbase Connection String: ") CB_USERNAME = input("Database Username: ") CB_PASSWORD = getpass.getpass("Database Password: ") CB_BUCKET_NAME = input("Bucket Name: ") SCOPE_NAME = "rag" COLLECTION_NAME = "data" INDEX_NAME = "vs-index" # Model Services Config CAPELLA_MODEL_SERVICES_ENDPOINT = getpass.getpass("Capella Model Services Endpoint: ") LLM_MODEL_NAME = "mistralai/mistral-7b-instruct-v0.3" LLM_API_KEY = getpass.getpass("LLM API Key: ") EMBEDDING_MODEL_NAME = "nvidia/llama-3.2-nv-embedqa-1b-v2" EMBEDDING_API_KEY = getpass.getpass("Embedding API Key: ") # Connect to Cluster auth = PasswordAuthenticator(CB_USERNAME, CB_PASSWORD) cluster = Cluster(CB_CONNECTION_STRING, ClusterOptions(auth)) cluster.wait_until_ready(timedelta(seconds=5)) print("Successfully connected to Couchbase") |
Etapa 3: Configurar a estrutura do banco de dados
Precisamos garantir que nosso bucket, escopo e coleção existam para armazenar os dados de notícias.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def setup_collection(cluster, bucket_name, scope_name, collection_name): bucket = cluster.bucket(bucket_name) manager = bucket.collections() # Create Scope if scope_name not in [s.name for s in manager.get_all_scopes()]: manager.create_scope(scope_name) # Create Collection bucket_manager = bucket.collections() scopes = bucket_manager.get_all_scopes() # ... (logic to create collection if missing) ... # Create Primary Index cluster.query(f"CREATE PRIMARY INDEX IF NOT EXISTS ON `{bucket_name}`.`{scope_name}`.`{collection_name}`").execute() setup_collection(cluster, CB_BUCKET_NAME, SCOPE_NAME, COLLECTION_NAME) |
Etapa 4: Carregando o índice de pesquisa vetorial do Couchbase
A pesquisa semântica exige uma maneira eficiente de recuperar documentos relevantes com base na consulta de um usuário. É nesse ponto que o Couchbase Vector Search, anteriormente conhecido como serviço Full-Text Search (FTS), entra em ação. Nesta etapa, carregamos a definição do Vector Search Index de um arquivo JSON, que especifica como o índice deve ser estruturado. Isso inclui os campos a serem indexados, as dimensões dos vetores e outros parâmetros que determinam como o mecanismo de pesquisa processa as consultas com base na similaridade dos vetores.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# If you are running this script in Google Colab, comment the following line # and provide the path to your index definition file. index_definition_path = "capella_index.json" # Local setup: specify your file path here # If you are running in Google Colab, use the following code to upload the index definition file # from google.colab import files # print("Upload your index definition file") # uploaded = files.upload() # index_definition_path = list(uploaded.keys())[0] try: with open(index_definition_path, "r") as file: index_definition = json.load(file) # Update search index definition with user inputs index_definition['name'] = INDEX_NAME index_definition['sourceName'] = CB_BUCKET_NAME # Update types mapping old_type_key = next(iter(index_definition['params']['mapping']['types'].keys())) type_obj = index_definition['params']['mapping']['types'].pop(old_type_key) index_definition['params']['mapping']['types'][f"{SCOPE_NAME}.{COLLECTION_NAME}"] = type_obj except Exception as e: raise ValueError( f"Error loading index definition from {index_definition_path}: {str(e)}" ) # Create the Vector Index via SDK try: scope_index_manager = ( cluster.bucket(CB_BUCKET_NAME).scope(SCOPE_NAME).search_indexes() ) # Check if index already exists existing_indexes = scope_index_manager.get_all_indexes() index_name = index_definition["name"] if index_name in [index.name for index in existing_indexes]: print(f"Index '{index_name}' found") else: print(f"Creating new index '{index_name}'...") # Create SearchIndex object from JSON definition search_index = SearchIndex.from_json(index_definition) # Upsert the index (create if not exists, update if exists) scope_index_manager.upsert_index(search_index) print(f"Index '{index_name}' successfully created/updated.") except Exception as e: logging.error(f"Error creating or updating index: {e}") |
Etapa 5: inicializar modelos de IA
Aqui está a mágica: inicializamos o modelo de incorporação usando Aberturas do OpenAIEmbeddings mas aponte-o para o Capella. Os serviços de IA do Couchbase fornecem pontos de extremidade compatíveis com OpenAI que são usados pelos agentes. Para os embeddings, estamos usando o pacote LangChain OpenAI, pois ele é usado em associação com a integração LangChain Couchbase.
|
1 2 3 4 5 6 7 8 9 |
from langchain_openai import OpenAIEmbeddings embeddings = OpenAIEmbeddings( openai_api_key=EMBEDDING_API_KEY, openai_api_base=CAPELLA_MODEL_SERVICES_ENDPOINT, # Capella Endpoint model=EMBEDDING_MODEL_NAME, check_embedding_ctx_length=False, tiktoken_enabled=False ) |
Etapa 6: ingestão de dados
Carregamos o conjunto de dados da BBC News e o ingerimos no Couchbase. O CouchbaseSearchVectorStore lida automaticamente com a geração de embeddings usando nosso modelo definido e armazenando-os.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from datasets import load_dataset from langchain_core.documents import Document from langchain_couchbase.vectorstores import CouchbaseSearchVectorStore # Load Data dataset = load_dataset('RealTimeData/bbc_news_alltime', '2024-12', split="train") unique_articles = list(set(dataset["content"]))[:100] # Limit for demo # Initialize Vector Store vector_store = CouchbaseSearchVectorStore( cluster=cluster, bucket_name=CB_BUCKET_NAME, scope_name=SCOPE_NAME, collection_name=COLLECTION_NAME, embedding=embeddings, index_name=INDEX_NAME, ) # Ingest documents = [Document(page_content=article) for article in unique_articles] vector_store.add_documents(documents) print(f"Ingested {len(documents)} documents") |
Etapa 7: Criar a cadeia RAG
Agora, criamos o pipeline do RAG. Inicializamos o LLM (novamente apontando para o Capella) e o conectamos ao nosso recuperador de armazenamento de vetores.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser # 1. Initialize LLM llm = ChatOpenAI( openai_api_base=CAPELLA_MODEL_SERVICES_ENDPOINT, openai_api_key=LLM_API_KEY, model=LLM_MODEL_NAME, temperature=0 ) # 2. Define Prompt template = """Answer the question based only on the following context: {context} Question: {question} """ prompt = ChatPromptTemplate.from_template(template) # 3. Create Chain rag_chain = ( {"context": vector_store.as_retriever(), "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) |
Etapa 8: Executar consultas
Vamos testar nosso RAG.
|
1 2 3 4 5 |
query = "What was Pep Guardiola's reaction to Manchester City's recent form?" response = rag_chain.invoke(query) print(f"Question: {query}") print(f"Answer: {response}") |
Exemplo de saída:
Resposta: Pep Guardiola expressou preocupação e frustração com a forma recente do Manchester City. Ele declarou: “Não sou bom o suficiente. Eu sou o chefe... tenho que encontrar soluções”. Ele reconheceu os problemas defensivos e a falta de confiança da equipe.
Conclusão
Neste tutorial, você aprendeu a:
- Vetorizar dados usando o Couchbase.
- Use os serviços de IA do Couchbase para embeddings e LLM.
- Implementar o RAG com o Couchbase Vector Search.
A plataforma de banco de dados unificada do Couchbase cria aplicativos avançados de IA que podem gerar conteúdo de alta qualidade e com reconhecimento de contexto.