milvus-logo
LFAI
Home
  • Integrações
    • Fontes de dados

Criar RAG com Milvus + PII Masker

As PII (Informações Pessoais Identificáveis) são um tipo de dados sensíveis que podem ser utilizados para identificar indivíduos.

O PII Masker, desenvolvido pela HydroX AI, é uma ferramenta avançada de código aberto concebida para proteger os seus dados sensíveis, tirando partido de modelos de IA de ponta. Quer esteja a lidar com dados de clientes, a realizar análises de dados ou a garantir a conformidade com os regulamentos de privacidade, o PII Masker fornece uma solução robusta e escalável para manter as suas informações seguras.

Neste tutorial, mostraremos como usar o PII Masker com o Milvus para proteger dados privados em aplicativos RAG (Retrieval-Augmented Generation). Combinando os pontos fortes dos recursos de mascaramento de dados do PII Masker com a recuperação eficiente de dados do Milvus, é possível criar pipelines seguros e compatíveis com a privacidade para lidar com informações confidenciais com confiança. Esta abordagem garante que as suas aplicações estão equipadas para cumprir as normas de privacidade e proteger eficazmente os dados dos utilizadores.

Preparação

Começar a utilizar o PII Masker

Siga o guia de instalação do PII Masker para instalar as dependências necessárias e descarregar o modelo. Aqui está um guia simples:

$ git clone https://github.com/HydroXai/pii-masker-v1.git
$ cd pii-masker-v1/pii-masker

Descarregue o modelo a partir dehttps://huggingface.co/hydroxai/pii_model_weight e substitua-o pelos ficheiros em: pii-masker/output_model/deberta3base_1024/

Dependências e ambiente

$ pip install --upgrade pymilvus openai requests tqdm dataset

Neste exemplo, utilizaremos o OpenAI como LLM. Deve preparar a chave api OPENAI_API_KEY como uma variável de ambiente.

$ export OPENAI_API_KEY=sk-***********

Em seguida, pode criar um notebook python ou jupyter para executar o seguinte código.

Preparar os dados

Vamos gerar algumas linhas falsas que contêm informações PII para efeitos de teste ou demonstração.

text_lines = [
    "Alice Johnson, a resident of Dublin, Ireland, attended a flower festival at Hyde Park on May 15, 2023. She entered the park at noon using her digital passport, number 23456789. Alice spent the afternoon admiring various flowers and plants, attending a gardening workshop, and having a light snack at one of the food stalls. While there, she met another visitor, Mr. Thompson, who was visiting from London. They exchanged tips on gardening and shared contact information: Mr. Thompson's address was 492, Pine Lane, and his cell phone number was +018.221.431-4517. Alice gave her contact details: home address, Ranch 16",
    "Hiroshi Tanaka, a businessman from Tokyo, Japan, went to attend a tech expo at the Berlin Convention Center on November 10, 2023. He registered for the event at 9 AM using his digital passport, number Q-24567680. Hiroshi networked with industry professionals, participated in panel discussions, and had lunch with some potential partners. One of the partners he met was from Munich, and they decided to keep in touch: the partner's office address was given as house No. 12, Road 7, Block E. Hiroshi offered his business card with the address, 654 Sakura Road, Tokyo.",
    "In an online forum discussion about culinary exchanges around the world, several participants shared their experiences. One user, Male, with the email 2022johndoe@example.com, shared his insights. He mentioned his ID code 1A2B3C4D5E and reference number L87654321 while residing in Italy but originally from Australia. He provided his +0-777-123-4567 and described his address at 456, Flavorful Lane, Pasta, IT, 00100.",
    "Another user joined the conversation on the topic of international volunteering opportunities. Identified as Female, she used the email 2023janedoe@example.com to share her story. She noted her 9876543210123 and M1234567890123 while residing in Germany but originally from Brazil. She provided her +0-333-987-6543 and described her address at 789, Sunny Side Street, Berlin, DE, 10178.",
]

Mascarar os dados com o PIIMasker

Vamos inicializar o objeto PIIMasker e carregar o modelo.

from model import PIIMasker

masker = PIIMasker()

Em seguida, mascaramos as PII de uma lista de linhas de texto e imprimimos os resultados mascarados.

masked_results = []
for full_text in text_lines:
    masked_text, _ = masker.mask_pii(full_text)
    masked_results.append(masked_text)

for res in masked_results:
    print(res + "\n")
Alice [B-NAME] , a resident of Dublin Ireland attended flower festival at Hyde Park on May 15 2023 [B-PHONE_NUM] She entered the park noon using her digital passport number 23 [B-ID_NUM] [B-NAME] afternoon admiring various flowers and plants attending gardening workshop having light snack one food stalls While there she met another visitor Mr Thompson who was visiting from London They exchanged tips shared contact information : ' s address 492 [I-STREET_ADDRESS] his cell phone + [B-PHONE_NUM] [B-NAME] details home Ranch [B-STREET_ADDRESS]

Hiroshi [B-NAME] [I-STREET_ADDRESS] a businessman from Tokyo Japan went to attend tech expo at the Berlin Convention Center on November 10 2023 . He registered for event 9 AM using his digital passport number Q [B-ID_NUM] [B-NAME] with industry professionals participated in panel discussions and had lunch some potential partners One of he met was Munich they decided keep touch : partner ' s office address given as house No [I-STREET_ADDRESS] [B-NAME] business card 654 [B-STREET_ADDRESS]

In an online forum discussion about culinary exchanges around the world [I-STREET_ADDRESS] several participants shared their experiences [I-STREET_ADDRESS] One user Male with email 2022 [B-EMAIL] his insights He mentioned ID code 1 [B-ID_NUM] [I-PHONE_NUM] reference number L [B-ID_NUM] residing in Italy but originally from Australia provided + [B-PHONE_NUM] [I-PHONE_NUM] described address at 456 [I-STREET_ADDRESS]

Another user joined the conversation on topic of international volunteering opportunities . Identified as Female , she used email 2023 [B-EMAIL] share her story She noted 98 [B-ID_NUM] [I-PHONE_NUM] M [B-ID_NUM] residing in Germany but originally from Brazil provided + [B-PHONE_NUM] [I-PHONE_NUM] described address at 789 [I-STREET_ADDRESS] DE 10 178

Preparar o modelo de incorporação

Inicializamos o cliente OpenAI para preparar o modelo de incorporação.

from openai import OpenAI

openai_client = OpenAI()

Defina uma função para gerar texto incorporado utilizando o cliente OpenAI. Utilizamos o modelo text-embedding-3-small como exemplo.

def emb_text(text):
    return (
        openai_client.embeddings.create(input=text, model="text-embedding-3-small")
        .data[0]
        .embedding
    )

Gerar um embedding de teste e imprimir a sua dimensão e os primeiros elementos.

test_embedding = emb_text("This is a test")
embedding_dim = len(test_embedding)
print(embedding_dim)
print(test_embedding[:10])
1536
[0.009889289736747742, -0.005578675772994757, 0.00683477520942688, -0.03805781528353691, -0.01824733428657055, -0.04121600463986397, -0.007636285852640867, 0.03225184231996536, 0.018949154764413834, 9.352207416668534e-05]

Carregar dados no Milvus

Criar a coleção

from pymilvus import MilvusClient

milvus_client = MilvusClient(uri="./milvus_demo.db")

Quanto ao argumento de MilvusClient:

  • Definir o uri como um ficheiro local, por exemplo./milvus.db, é o método mais conveniente, pois utiliza automaticamente o Milvus Lite para armazenar todos os dados neste ficheiro.
  • Se tiver uma grande escala de dados, digamos mais de um milhão de vectores, pode configurar um servidor Milvus mais eficiente em Docker ou Kubernetes. Nesta configuração, use o endereço e a porta do servidor como seu uri, por exemplo,http://localhost:19530. Se você ativar o recurso de autenticação no Milvus, use "<seu_nome_de_usuário>:<sua_senha>" como o token, caso contrário, não defina o token.
  • Se pretender utilizar o Zilliz Cloud, o serviço de nuvem totalmente gerido para o Milvus, ajuste os campos uri e token, que correspondem ao Public Endpoint e à chave Api no Zilliz Cloud.

Verificar se a coleção já existe e eliminá-la se existir.

collection_name = "my_rag_collection"

if milvus_client.has_collection(collection_name):
    milvus_client.drop_collection(collection_name)

Criar uma nova coleção com os parâmetros especificados.

Se não especificarmos qualquer informação de campo, o Milvus criará automaticamente um campo id por defeito para a chave primária e um campo vector para armazenar os dados vectoriais. Um campo JSON reservado é utilizado para armazenar campos não definidos pelo esquema e os respectivos valores.

milvus_client.create_collection(
    collection_name=collection_name,
    dimension=embedding_dim,
    metric_type="IP",  # Inner product distance
    consistency_level="Strong",  # Strong consistency level
)

Inserir dados

Itere pelas linhas de texto mascaradas, crie embeddings e, em seguida, insira os dados no Milvus.

Aqui está um novo campo text, que é um campo não definido no esquema da coleção. Será automaticamente adicionado ao campo dinâmico JSON reservado, que pode ser tratado como um campo normal a um nível elevado.

from tqdm import tqdm

data = []

for i, line in enumerate(tqdm(masked_results, desc="Creating embeddings")):
    data.append({"id": i, "vector": emb_text(line), "text": line})

milvus_client.insert(collection_name=collection_name, data=data)
Creating embeddings: 100%|██████████| 4/4 [00:01<00:00,  2.60it/s]





{'insert_count': 4, 'ids': [0, 1, 2, 3], 'cost': 0}

Construir RAG

Recuperar dados para uma consulta

Vamos especificar uma pergunta sobre os documentos.

question = "What was the office address of Hiroshi's partner from Munich?"

Procurar a pergunta na coleção e obter a correspondência semântica de topo-1.

search_res = milvus_client.search(
    collection_name=collection_name,
    data=[
        emb_text(question)
    ],  # Use the `emb_text` function to convert the question to an embedding vector
    limit=1,  # Return top 1 results
    search_params={"metric_type": "IP", "params": {}},  # Inner product distance
    output_fields=["text"],  # Return the text field
)

Vejamos os resultados da pesquisa da consulta

import json

retrieved_lines_with_distances = [
    (res["entity"]["text"], res["distance"]) for res in search_res[0]
]
print(json.dumps(retrieved_lines_with_distances, indent=4))
[
    [
        "Hiroshi [B-NAME] [I-STREET_ADDRESS] a businessman from Tokyo Japan went to attend tech expo at the Berlin Convention Center on November 10 2023 . He registered for event 9 AM using his digital passport number Q [B-ID_NUM] [B-NAME] with industry professionals participated in panel discussions and had lunch some potential partners One of he met was Munich they decided keep touch : partner ' s office address given as house No [I-STREET_ADDRESS] [B-NAME] business card 654 [B-STREET_ADDRESS]",
        0.6544462442398071
    ]
]

Utilizar o LLM para obter uma resposta RAG

Converter os documentos recuperados num formato de cadeia de caracteres.

context = "\n".join(
    [line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)

Definir prompts do sistema e do utilizador para o Modelo de Linguagem.

Nota: Dizemos ao LLM que, se não houver informações úteis nos snippets, basta dizer "não sei".

SYSTEM_PROMPT = """
Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided. If there are no useful information in the snippets, just say "I don't know".
AI:
"""
USER_PROMPT = f"""
Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.
<context>
{context}
</context>
<question>
{question}
</question>
"""

Utilizar o OpenAI ChatGPT para gerar uma resposta com base nos avisos.

response = openai_client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": USER_PROMPT},
    ],
)
print(response.choices[0].message.content)
I don't know.

Aqui podemos ver que, como substituímos as PII por máscaras, o LLM não consegue obter as informações das PII no contexto. Desta forma, podemos proteger eficazmente a privacidade dos utilizadores.

Traduzido porDeepLogo

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Esta página foi útil?