# 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}")