بناء RAG مع برنامج Milvus + PII Masker
PII (معلومات التعريف الشخصية) هي نوع من البيانات الحساسة التي يمكن استخدامها لتحديد هوية الأفراد.
إن أداةPII Masker، التي طورتها شركة HydroX AI، هي أداة متقدمة مفتوحة المصدر مصممة لحماية بياناتك الحساسة من خلال الاستفادة من نماذج الذكاء الاصطناعي المتطورة. وسواء كنت تتعامل مع بيانات العملاء، أو تقوم بتحليل البيانات، أو تضمن الامتثال للوائح الخصوصية، فإن PII Masker يوفر لك حلاً قويًا وقابلًا للتطوير للحفاظ على أمان معلوماتك.
في هذا البرنامج التعليمي، سوف نعرض كيفية استخدام PII Masker مع Milvus لحماية البيانات الخاصة في تطبيقات RAG (الاسترجاع-التوليد المعزز). من خلال الجمع بين نقاط القوة في برنامج PII Masker لإخفاء البيانات مع استرجاع البيانات الفعال من Milvus، يمكنك إنشاء خطوط أنابيب آمنة ومتوافقة مع الخصوصية للتعامل مع المعلومات الحساسة بثقة. يضمن هذا النهج أن تطبيقاتك مجهزة لتلبية معايير الخصوصية وحماية بيانات المستخدم بفعالية.
الإعداد
ابدأ باستخدام PII Masker
اتبع دليل تثبيت PII Masker لتثبيت التبعيات المطلوبة وتنزيل النموذج. إليك دليل بسيط:
$ git clone https://github.com/HydroXai/pii-masker-v1.git
$ cd pii-masker-v1/pii-masker
قم بتنزيل النموذج منhttps://huggingface.co/hydroxai/pii_model_weight
، واستبدله بالملفات في: pii-masker/output_model/deberta3base_1024/
التبعيات والبيئة
$ pip install --upgrade pymilvus openai requests tqdm dataset
سنستخدم OpenAI كنموذج LLM في هذا المثال. يجب عليك إعداد مفتاح api OPENAI_API_KEY
كمتغير بيئة.
$ export OPENAI_API_KEY=sk-***********
ثم يمكنك إنشاء دفتر ملاحظات python أو jupyter لتشغيل الكود التالي.
إعداد البيانات
لنقم بإنشاء بعض الأسطر المزيفة التي تحتوي على معلومات PII لأغراض الاختبار أو العرض التوضيحي.
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.",
]
قم بإخفاء البيانات باستخدام PIIMasker
لنقم بتهيئة كائن PIIMasker وتحميل النموذج.
from model import PIIMasker
masker = PIIMasker()
ثم نقوم بإخفاء PII من قائمة من الأسطر النصية ونطبع النتائج المقنعة.
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
إعداد نموذج التضمين
نقوم بتهيئة عميل OpenAI لإعداد نموذج التضمين.
from openai import OpenAI
openai_client = OpenAI()
نحدد دالة لإنشاء تضمينات نصية باستخدام عميل OpenAI. نستخدم نموذج text-embedding-3-small
كمثال.
def emb_text(text):
return (
openai_client.embeddings.create(input=text, model="text-embedding-3-small")
.data[0]
.embedding
)
توليد تضمين اختباري وطباعة أبعاده والعناصر القليلة الأولى.
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]
تحميل البيانات في ميلفوس
إنشاء المجموعة
from pymilvus import MilvusClient
milvus_client = MilvusClient(uri="./milvus_demo.db")
بالنسبة لحجة MilvusClient
:
- يعد تعيين
uri
كملف محلي، على سبيل المثال./milvus.db
، هو الطريقة الأكثر ملاءمة، حيث يستخدم تلقائيًا ميلفوس لايت لتخزين جميع البيانات في هذا الملف. - إذا كان لديك حجم كبير من البيانات، على سبيل المثال أكثر من مليون ناقل، يمكنك إعداد خادم Milvus أكثر أداءً على Docker أو Kubernetes. في هذا الإعداد، يُرجى استخدام عنوان الخادم والمنفذ كـ uri، على سبيل المثال
http://localhost:19530
. إذا قمت بتمكين ميزة المصادقة على Milvus، فاستخدم "<your_username>: <your_password>" كرمز مميز، وإلا فلا تقم بتعيين الرمز المميز. - إذا كنت ترغب في استخدام Zilliz Cloud، الخدمة السحابية المدارة بالكامل لـ Milvus، اضبط
uri
وtoken
، والتي تتوافق مع نقطة النهاية العامة ومفتاح Api في Zilliz Cloud.
تحقق مما إذا كانت المجموعة موجودة بالفعل وأسقطها إذا كانت موجودة.
collection_name = "my_rag_collection"
if milvus_client.has_collection(collection_name):
milvus_client.drop_collection(collection_name)
قم بإنشاء مجموعة جديدة بمعلمات محددة.
إذا لم نحدد أي معلومات عن الحقل، سيقوم ميلفوس تلقائيًا بإنشاء حقل افتراضي id
للمفتاح الأساسي، وحقل vector
لتخزين بيانات المتجه. يتم استخدام حقل JSON محجوز لتخزين الحقول غير المعرفة من قبل النظام الأساسي وقيمها.
milvus_client.create_collection(
collection_name=collection_name,
dimension=embedding_dim,
metric_type="IP", # Inner product distance
consistency_level="Strong", # Strong consistency level
)
إدراج البيانات
قم بالتكرار من خلال الأسطر النصية المقنعة، وأنشئ التضمينات، ثم أدخل البيانات في ملفوس.
هنا حقل جديد text
، وهو حقل غير محدد في مخطط المجموعة. ستتم إضافته تلقائيًا إلى حقل JSON الديناميكي المحجوز، والذي يمكن التعامل معه كحقل عادي على مستوى عالٍ.
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}
بناء RAG
استرجاع البيانات لاستعلام
دعنا نحدد سؤالاً عن المستندات.
question = "What was the office address of Hiroshi's partner from Munich?"
ابحث عن السؤال في المجموعة واسترجع أعلى تطابق دلالي من الدرجة الأولى.
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
)
لنلقِ نظرة على نتائج البحث عن الاستعلام
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
]
]
استخدم LLM للحصول على استجابة RAG
تحويل المستندات المسترجعة إلى تنسيق سلسلة.
context = "\n".join(
[line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)
تحديد مطالبات النظام والمستخدم لنموذج لاناج.
ملاحظة: نخبر LLM إذا لم تكن هناك معلومات مفيدة في المقتطفات، فقط قل "لا أعرف".
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>
"""
استخدم OpenAI ChatGPT لإنشاء استجابة بناءً على المطالبات.
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.
هنا يمكننا أن نرى، بما أننا استبدلنا معلومات تحديد الهوية الشخصية بأقنعة، لا يمكن لـ LLM الحصول على معلومات تحديد الهوية الشخصية في السياق. لذلك يجيب: "لا أعرف". من خلال هذه الطريقة، يمكننا حماية خصوصية المستخدمين بشكل فعال.