Kılavuz: RAG uygulaması oluşturma

Tamamen cihazınızda bulunan bir belge koleksiyonu hakkındaki soruları yanıtlayan bir bilgi erişimli üretim (RAG) uygulaması oluşturun. RAG, gömme tabanlı aramayı bir sohbet modeliyle birleştirir, böylece yanıtların yalnızca modelin eğitim bilgilerine güvenmek yerine kendi verilerinize dayanması sağlanır.

Bu öğreticide şunların nasıl yapılacağını öğreneceksiniz:

  • Bir proje ayarlama ve Foundry Yerel SDK'sını yükleme
  • Metin belgeleri için bilgi bankası oluşturma
  • Belgeler için eklemeler oluşturma
  • Benzerliğe göre ilgili belgeleri arama
  • Alınmış bağlamına dayalı yanıtlar oluşturma
  • Kaynakları temizleme

Önkoşullar

  • En az 8 GB RAM'e sahip bir Windows, macOS veya Linux bilgisayar.
  • Python 3.11 veya üzeri yüklü.

Paketleri yükleme

Windows üzerinde geliştiriyor veya gönderiyorsanız Windows sekmesini seçin. Windows paketi Windows ML çalışma zamanıyla tümleşir; aynı API yüzey alanını daha geniş bir donanım hızlandırmasıyla sağlar.

pip install foundry-local-sdk-winml openai

Bilgi bankası oluşturma

RAG uygulamasının arama yapması için bir belge koleksiyonuna ihtiyaç vardır. Bilgi bankası görevi görecek metin dizelerinin listesini tanımlayın. Üretim uygulamasında liste dosyalardan, veritabanı kayıtlarından veya başka bir metin kaynağından paragraflar olabilir.

adlı main.py bir dosya oluşturun ve aşağıdaki kodu ekleyin:

import math
from foundry_local_sdk import Configuration, FoundryLocalManager

# Knowledge base — each string represents a document
documents = [
    "Foundry Local runs AI models directly on your device without cloud connectivity.",
    "The Foundry Local SDK supports Python, C#, JavaScript, and Rust.",
    "Embedding models convert text into numerical vectors for similarity search.",
    "Foundry Local uses ONNX Runtime for efficient model inference on CPUs and GPUs.",
    "The model catalog provides pre-optimized models that you can download and run locally.",
    "Retrieval-augmented generation grounds model responses in your own data.",
    "Vector similarity search finds documents that are semantically close to a query.",
    "Chat completions generate natural language responses from a prompt and context.",
]

Belge eklemeleri oluşturma

SDK'yı başlatın, bir ekleme modeli yükleyin ve her belgeyi sayısal vektöre dönüştürün. Bu vektörler her belgenin anlamsal anlamını temsil eder ve benzerlik aramasını etkinleştirir.

aşağıdaki kodu içine main.pyekleyin:

def main():
    # Initialize the SDK
    config = Configuration(app_name="foundry_local_rag")
    FoundryLocalManager.initialize(config)
    manager = FoundryLocalManager.instance

    # Load the embedding model
    embedding_model = manager.catalog.get_model("qwen3-embedding-0.6b")
    embedding_model.download(
        lambda p: print(f"\rDownloading embedding model: {p:.1f}%", end="", flush=True)
    )
    print()
    embedding_model.load()
    embedding_client = embedding_model.get_embedding_client()

    # Embed all documents in a single batch call
    response = embedding_client.generate_embeddings(documents)
    doc_embeddings = [item.embedding for item in response.data]
    print(f"Indexed {len(doc_embeddings)} documents.")

generate_embeddings yöntemi bir dize listesini kabul eder ve giriş başına bir vektör döndürür. Her vektör metnin anlamsal anlamını yakalar, böylece benzer belgeler ekleme alanında birbirine yakın vektörler oluşturur.

İlgili belgeleri arama

Sorguyla ilişkili belgeleri bulmak için, her belge gömüsü ile sorguya ait gömüyü kosinüs benzerliğini kullanarak karşılaştırın. Kosinüs benzerliği, büyüklüğü ne olursa olsun iki vektörünün ne kadar yakın olduğunu ölçer. 1,0'a yakın değerler yüksek benzerlik gösterir.

main.py içerisindeki main() üzerindeki yardımcı işlevleri ekleyin.

def cosine_similarity(a, b):
    """Compute cosine similarity between two vectors."""
    dot = sum(x * y for x, y in zip(a, b))
    norm_a = math.sqrt(sum(x * x for x in a))
    norm_b = math.sqrt(sum(x * x for x in b))
    return dot / (norm_a * norm_b) if norm_a and norm_b else 0.0


def find_relevant(query_embedding, doc_embeddings, top_k=2):
    """Return the indices and scores of the top-k most similar documents."""
    scores = []
    for i, doc_emb in enumerate(doc_embeddings):
        score = cosine_similarity(query_embedding, doc_emb)
        scores.append((i, score))
    scores.sort(key=lambda x: x[1], reverse=True)
    return scores[:top_k]

find_relevant işlevi tüm belgeleri benzerlik derecesine göre sıralar ve en üstteki eşleşmeleri döndürür. Bu yaklaşım küçük koleksiyonlar için iyi çalışır. Daha büyük veri kümeleri için ayrılmış bir vektör veritabanı kullanmayı göz önünde bulundurun.

Kanıtlanmış yanıtlar oluşturun

Bir sohbet modeli yükleyin ve alınan belgeleri bir sistem isteminde kullanıcının sorusuyla birleştirin. Sohbet modeli, belgelerinizde temel alınan bir yanıt oluşturmak için sağlanan bağlamı kullanır.

Gömme bölümünden sonra main() işlevine aşağıdaki kodu ekleyin:

    # Load the chat model
    chat_model = manager.catalog.get_model("qwen2.5-0.5b")
    chat_model.download(
        lambda p: print(f"\rDownloading chat model: {p:.1f}%", end="", flush=True)
    )
    print()
    chat_model.load()
    chat_client = chat_model.get_chat_client()

    print("\nModels loaded. Ready for questions.")
    print("\nThe knowledge base contains information about:")
    print("  - Foundry Local features and architecture")
    print("  - Supported programming languages")
    print("  - Embedding models and vector search")
    print("  - ONNX Runtime inference")
    print("  - The model catalog")
    print("  - RAG and chat completions")
    print("\nExample questions:")
    print('  "What programming languages does the SDK support?"')
    print('  "How does Foundry Local run models?"')
    print('  "What is retrieval-augmented generation?"')
    print('\nType "quit" to exit.\n')

    # Interactive query loop
    while True:
        query = input("Question: ").strip()
        if not query or query.lower() == "quit":
            break

        # Embed the query
        query_response = embedding_client.generate_embedding(query)
        query_embedding = query_response.data[0].embedding

        # Retrieve the most relevant documents
        results = find_relevant(query_embedding, doc_embeddings, top_k=2)
        context = "\n".join(f"- {documents[i]}" for i, _ in results)

        # Build the prompt with retrieved context
        messages = [
            {
                "role": "system",
                "content": (
                    "Answer the user's question using only the provided context. "
                    "If the context doesn't contain enough information, say so.\n\n"
                    f"Context:\n{context}"
                ),
            },
            {"role": "user", "content": query},
        ]

        # Stream the response
        print("Answer: ", end="", flush=True)
        for chunk in chat_client.complete_streaming_chat(messages):
            content = chunk.choices[0].delta.content
            if content:
                print(content, end="", flush=True)
        print("\n")

    # Clean up
    embedding_model.unload()
    chat_model.unload()
    print("Models unloaded. Done!")


if __name__ == "__main__":
    main()

Sistem istemi, modele yalnızca alınan bağlamı kullanarak yanıt vermesini bildirir. Sistem istemi, yanıtları belgelerinizde temel alır ve yanlış yanıtları azaltır. Akış çıkışı, oluşturulan her belirteci yazdırarak yanıtın etkileşimli olduğunu gösterir.

Kodu tamamlama

Tüm adımları birleştiren tam uygulama aşağıdadır:

import math
from foundry_local_sdk import Configuration, FoundryLocalManager

# Knowledge base
documents = [
    "Foundry Local runs AI models directly on your device without cloud connectivity.",
    "The Foundry Local SDK supports Python, C#, JavaScript, and Rust.",
    "Embedding models convert text into numerical vectors for similarity search.",
    "Foundry Local uses ONNX Runtime for efficient model inference on CPUs and GPUs.",
    "The model catalog provides pre-optimized models that you can download and run locally.",
    "Retrieval-augmented generation grounds model responses in your own data.",
    "Vector similarity search finds documents that are semantically close to a query.",
    "Chat completions generate natural language responses from a prompt and context.",
]


def cosine_similarity(a, b):
    """Compute cosine similarity between two vectors."""
    dot = sum(x * y for x, y in zip(a, b))
    norm_a = math.sqrt(sum(x * x for x in a))
    norm_b = math.sqrt(sum(x * x for x in b))
    return dot / (norm_a * norm_b) if norm_a and norm_b else 0.0


def find_relevant(query_embedding, doc_embeddings, top_k=2):
    """Return the indices and scores of the top-k most similar documents."""
    scores = []
    for i, doc_emb in enumerate(doc_embeddings):
        score = cosine_similarity(query_embedding, doc_emb)
        scores.append((i, score))
    scores.sort(key=lambda x: x[1], reverse=True)
    return scores[:top_k]


def main():
    # Initialize the SDK
    config = Configuration(app_name="foundry_local_rag")
    FoundryLocalManager.initialize(config)
    manager = FoundryLocalManager.instance

    # Load the embedding model
    embedding_model = manager.catalog.get_model("qwen3-embedding-0.6b")
    embedding_model.download(
        lambda p: print(f"\rDownloading embedding model: {p:.1f}%", end="", flush=True)
    )
    print()
    embedding_model.load()
    embedding_client = embedding_model.get_embedding_client()

    # Embed all documents
    response = embedding_client.generate_embeddings(documents)
    doc_embeddings = [item.embedding for item in response.data]
    print(f"Indexed {len(doc_embeddings)} documents.")

    # Load the chat model
    chat_model = manager.catalog.get_model("qwen2.5-0.5b")
    chat_model.download(
        lambda p: print(f"\rDownloading chat model: {p:.1f}%", end="", flush=True)
    )
    print()
    chat_model.load()
    chat_client = chat_model.get_chat_client()

    print("\nModels loaded. Ready for questions.")
    print("\nThe knowledge base contains information about:")
    print("  - Foundry Local features and architecture")
    print("  - Supported programming languages")
    print("  - Embedding models and vector search")
    print("  - ONNX Runtime inference")
    print("  - The model catalog")
    print("  - RAG and chat completions")
    print("\nExample questions:")
    print('  "What programming languages does the SDK support?"')
    print('  "How does Foundry Local run models?"')
    print('  "What is retrieval-augmented generation?"')
    print('\nType "quit" to exit.\n')

    # Interactive query loop
    while True:
        query = input("Question: ").strip()
        if not query or query.lower() == "quit":
            break

        # Embed the query
        query_response = embedding_client.generate_embedding(query)
        query_embedding = query_response.data[0].embedding

        # Retrieve the most relevant documents
        results = find_relevant(query_embedding, doc_embeddings, top_k=2)
        context = "\n".join(f"- {documents[i]}" for i, _ in results)

        # Build the prompt with retrieved context
        messages = [
            {
                "role": "system",
                "content": (
                    "Answer the user's question using only the provided context. "
                    "If the context doesn't contain enough information, say so.\n\n"
                    f"Context:\n{context}"
                ),
            },
            {"role": "user", "content": query},
        ]

        # Stream the response
        print("Answer: ", end="", flush=True)
        for chunk in chat_client.complete_streaming_chat(messages):
            content = chunk.choices[0].delta.content
            if content:
                print(content, end="", flush=True)
        print("\n")

    # Clean up
    embedding_model.unload()
    chat_model.unload()
    print("Models unloaded. Done!")


if __name__ == "__main__":
    main()

Uygulamayı çalıştırın:

python main.py

Şu benzeri bir çıktı görürsünüz:

Downloading embedding model: 100.0%
Indexed 8 documents.
Downloading chat model: 100.0%

Models loaded. Ready for questions.

The knowledge base contains information about:
  - Foundry Local features and architecture
  - Supported programming languages
  - Embedding models and vector search
  - ONNX Runtime inference
  - The model catalog
  - RAG and chat completions

Example questions:
  "What programming languages does the SDK support?"
  "How does Foundry Local run models?"
  "What is retrieval-augmented generation?"

Type "quit" to exit.

Question: What programming languages does the SDK support?
Answer: The Foundry Local SDK supports Python, C#, JavaScript, and Rust.

Question: quit
Models unloaded. Done!

Kaynakları temizleme

Modeli kaldırdıktan sonra model ağırlıkları yerel önbelleğinizde kalır. Uygulamayı bir sonraki çalıştırmanızda indirme adımı atlanır ve modeller daha hızlı yüklenir. Disk alanını geri kazanmak istemediğiniz sürece fazladan temizleme gerekmez.