mirror of
https://github.com/hoshikawa2/agent-ai-mcp-server.git
synced 2026-03-06 10:11:01 +00:00
First commit
This commit is contained in:
72
source/find_products_by_similarity.py
Normal file
72
source/find_products_by_similarity.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import faiss
|
||||
import pickle
|
||||
import difflib
|
||||
from rapidfuzz import fuzz
|
||||
from langchain_community.embeddings import OCIGenAIEmbeddings
|
||||
import numpy as np
|
||||
|
||||
# === CONFIGURAÇÕES ===
|
||||
FAISS_INDEX_PATH = "faiss_index.bin"
|
||||
ID_MAP_PATH = "produto_id_map.pkl"
|
||||
TOP_K = 5
|
||||
DISTANCIA_MINIMA = 1.0
|
||||
|
||||
# === EMBEDDING COM OCI GEN AI ===
|
||||
embedding = OCIGenAIEmbeddings(
|
||||
model_id="cohere.embed-english-light-v3.0",
|
||||
service_endpoint="https://inference.generativeai.us-chicago-1.oci.oraclecloud.com",
|
||||
compartment_id="ocid1.compartment.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
auth_profile="DEFAULT"
|
||||
)
|
||||
|
||||
# === CARREGA O ÍNDICE VETORIAL ===
|
||||
print("📦 Carregando índice vetorial...")
|
||||
index = faiss.read_index(FAISS_INDEX_PATH)
|
||||
with open(ID_MAP_PATH, "rb") as f:
|
||||
id_map = pickle.load(f)
|
||||
|
||||
# === CORREÇÃO AUTOMÁTICA DO INPUT ===
|
||||
def corrigir_input_mais_proximo(input_usuario, descricoes_existentes):
|
||||
sugestoes = difflib.get_close_matches(input_usuario, descricoes_existentes, n=1, cutoff=0.6)
|
||||
return sugestoes[0] if sugestoes else input_usuario
|
||||
|
||||
descricao_input = input("Digite a descrição do produto a buscar: ").strip()
|
||||
descricoes = [p["descricao"] for p in id_map]
|
||||
descricao_corrigida = corrigir_input_mais_proximo(descricao_input, descricoes)
|
||||
|
||||
if descricao_corrigida != descricao_input:
|
||||
print(f"🧠 Consulta sugerida: {descricao_corrigida}")
|
||||
else:
|
||||
print(f"✅ Consulta original mantida: {descricao_input}")
|
||||
|
||||
# === GERA EMBEDDING COM OCI ===
|
||||
consulta_emb = embedding.embed_query(descricao_corrigida)
|
||||
consulta_emb = np.array([consulta_emb]) # FAISS espera um array 2D
|
||||
|
||||
# === BUSCA NO FAISS ===
|
||||
distances, indices = index.search(consulta_emb, TOP_K)
|
||||
bons_resultados = [d for d in distances[0] if d < DISTANCIA_MINIMA]
|
||||
|
||||
# === EXIBE RESULTADOS VETORIAIS ===
|
||||
if bons_resultados:
|
||||
print("\n🔍 Resultados semânticos similares:")
|
||||
for i, dist in zip(indices[0], distances[0]):
|
||||
if dist >= DISTANCIA_MINIMA:
|
||||
continue
|
||||
match = id_map[i]
|
||||
similaridade = 1 / (1 + dist)
|
||||
print(f"ID: {match['id']} | Código: {match['codigo']} | Produto: {match['descricao']}")
|
||||
print(f"↳ Similaridade: {similaridade:.2%} | Distância: {dist:.4f}\n")
|
||||
else:
|
||||
# === FALLBACK FUZZY ===
|
||||
print("\n⚠️ Nenhum resultado vetorial relevante. Buscando por similaridade textual (fuzzy)...\n")
|
||||
melhores_fuzz = []
|
||||
for produto in id_map:
|
||||
score = fuzz.token_sort_ratio(descricao_corrigida, produto["descricao"])
|
||||
melhores_fuzz.append((produto, score))
|
||||
|
||||
melhores_fuzz.sort(key=lambda x: x[1], reverse=True)
|
||||
|
||||
for produto, score in melhores_fuzz[:TOP_K]:
|
||||
print(f"ID: {produto['id']} | Código: {produto['codigo']} | Produto: {produto['descricao']}")
|
||||
print(f"↳ Similaridade (fuzzy): {score:.2f}%\n")
|
||||
Reference in New Issue
Block a user