Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

[Projeto] Minha implementação

# INSTALAÇÃO
!pip install -q -U langchain langchain-google-genai langchain-community faiss-cpu chromadb pinecone

# CHAVES
from google.colab import userdata
GOOGLE_API_KEY=userdata.get("GEMINI_API_KEY")
PINECONE_API_KEY=userdata.get("PINECONE_API_KEY")
if not GOOGLE_API_KEY or not PINECONE_API_KEY:
    raise ValueError("Configure GEMINI_API_KEY e PINECONE_API_KEY nos Secrets.")

# DOCUMENTOS + METADADOS
from langchain_core.documents import Document
docs=[
Document("A NovaTech oferece o NovaDesk, plataforma de gestão para pequenas e médias empresas.",{"categoria":"produto","produto":"NovaDesk","departamento":"comercial"}),
Document("O módulo Financeiro do NovaDesk registra contas a pagar, contas a receber e movimentações financeiras.",{"categoria":"produto","produto":"NovaDesk","departamento":"financeiro"}),
Document("O suporte técnico funciona de segunda a sexta-feira, das 8h às 18h, no horário de Brasília. Solicitações podem ser abertas pelo portal NovaHelp.",{"categoria":"suporte","produto":"NovaHelp","departamento":"suporte"}),
Document("A prioridade alta deve ser utilizada quando uma funcionalidade importante está indisponível e prejudica significativamente a operação do cliente.",{"categoria":"suporte","produto":"NovaHelp","departamento":"suporte"}),
Document("A NovaTech recomenda revisar periodicamente as permissões. O acesso deve seguir o princípio de menor privilégio.",{"categoria":"seguranca","produto":"NovaDesk","departamento":"seguranca"}),
Document("Cada usuário deve possuir uma conta individual. O compartilhamento de credenciais não é recomendado.",{"categoria":"seguranca","produto":"NovaDesk","departamento":"seguranca"}),
Document("A NovaTech oferece os planos Essencial, Profissional e Empresarial. O Essencial permite até cinco usuários e o Profissional até vinte.",{"categoria":"planos","produto":"NovaDesk","departamento":"comercial"}),
Document("A implantação começa com uma reunião para identificar processos, usuários e dados que precisam ser importados.",{"categoria":"implantacao","produto":"NovaDesk","departamento":"implantacao"})
]
textos=[d.page_content for d in docs]

# EMBEDDINGS
from langchain_google_genai import GoogleGenerativeAIEmbeddings
emb=GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001",google_api_key=GOOGLE_API_KEY)
vec=emb.embed_documents(textos)

print(f"Documentos: {len(docs)} | Dimensão: {len(vec[0])}")

# FAISS: INDEXFLATL2
import faiss,numpy as np
v=np.array(vec,dtype="float32"); dim=v.shape[1]
flat=faiss.IndexFlatL2(dim); flat.add(v)
q="Qual é o horário de funcionamento do suporte?"
qv=np.array([emb.embed_query(q)],dtype="float32")
dist,idx=flat.search(qv,3)
print("\n=== FAISS INDEXFLATL2 ===")
for i,j in enumerate(idx[0]):
    print(f"{i+1}. {docs[j].page_content} | L2={dist[0][i]:.4f}")

# FAISS: HNSW
hnsw=faiss.IndexHNSWFlat(dim,32)
hnsw.hnsw.efConstruction=40; hnsw.hnsw.efSearch=16
hnsw.add(v); dist,idx=hnsw.search(qv,3)
print("\n=== FAISS HNSW ===")
for i,j in enumerate(idx[0]):
    print(f"{i+1}. {docs[j].page_content} | L2={dist[0][i]:.4f}")

# CHROMADB + BUSCA
import chromadb
cc=chromadb.Client()
col=cc.get_or_create_collection("novatech")
col.add(ids=[f"doc-{i}" for i in range(len(docs))],documents=textos,
        metadatas=[d.metadata for d in docs],embeddings=vec)
r=col.query(query_embeddings=[emb.embed_query(q)],n_results=3)
print("\n=== CHROMADB ===")
for i,t in enumerate(r["documents"][0]):
    print(f"{i+1}. {t} | {r['metadatas'][0][i]}")

# CHROMADB + FILTRO
q2="Como controlar o acesso dos usuários?"
r=col.query(query_embeddings=[emb.embed_query(q2)],n_results=3,
            where={"categoria":"seguranca"})
print("\n=== CHROMADB + FILTRO ===")
for i,t in enumerate(r["documents"][0]):
    print(f"{i+1}. {t}")

# PINECONE
from pinecone import Pinecone,ServerlessSpec
pc=Pinecone(api_key=PINECONE_API_KEY)
name="novatech-rag"
if name not in [x["name"] for x in pc.list_indexes()]:
    pc.create_index(name=name,dimension=dim,metric="cosine",
                    spec=ServerlessSpec(cloud="aws",region="us-east-1"))
import time
while not pc.describe_index(name).status["ready"]: time.sleep(2)
pi=pc.Index(name)
pi.upsert(vectors=[{"id":f"doc-{i}","values":vec[i],
                    "metadata":{**docs[i].metadata,"texto":textos[i]}}
                   for i in range(len(docs))])

# PINECONE + SIMILARIDADE
r=pi.query(vector=emb.embed_query(q),top_k=3,include_metadata=True)
print("\n=== PINECONE ===")
for i,m in enumerate(r["matches"]):
    print(f"{i+1}. {m['metadata']['texto']} | score={m['score']:.4f}")

# PINECONE + FILTRO
r=pi.query(vector=emb.embed_query(q2),top_k=3,include_metadata=True,
           filter={"categoria":{"$eq":"seguranca"}})
print("\n=== PINECONE + FILTRO ===")
for i,m in enumerate(r["matches"]):
    print(f"{i+1}. {m['metadata']['texto']} | score={m['score']:.4f}")
1 resposta

Oi, Paulo. Tudo bem com você?

Sua implementação para a atividade ficou completa e direta ao ponto. Você cobriu perfeitamente o fluxo de geração de embeddings com o Gemini, a estruturação dos documentos com metadados e os testes comparativos entre os diferentes bancos vetoriais, aplicando os índices Flat L2 e HNSW no FAISS, as consultas no ChromaDB e o gerenciamento do índice no Pinecone.

A lógica que você utilizou nos filtros de metadados, como no caso do filtro por categoria de segurança no ChromaDB e no Pinecone com $eq, demonstra como restringir o espaço de busca sem perder a relevância semântica. Considerando o volume de dados e os requisitos de latência de uma aplicação real, em quais cenários você optaria por manter os vetores localmente com FAISS ou ChromaDB em vez de adotar um serviço gerenciado em nuvem como o Pinecone?

Parabéns pela dedicação e pelo excelente resultado no exercício. O fórum está sempre à disposição para você tirar dúvidas ou compartilhar seus avanços nos próximos passos do curso. Abraços e bons estudos.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!