Skip to content

Testowanie chatbota przy użyciu bibliteki deepeval

Testowanie systemów opartych na AI to dla mnie zupełnie nowy temat. Przy okazji przerabiania materiału o chatbotach i llama_index zostało poruszone to zagadnienie i postanowiałm się mu dokładniej przyjrzeć.

W tym artykule zaprezentuję prostego chatbota w języku Python, opartego o bazę wektorową przechowującą dane w pamięci oraz o bibliotekę llama_inedx. Do testowania użyję biblitoteki deepeval.

Przygotowanie chatbota

We wspomnianym wyżej artykule znalazło się kompletne rozwiązanie takiego bota, jednak po niecałym roku od publikacji okazało się, że kod już nie zadziała. Aby doprowadzić go do funkcjonowania, musiałam zaktualizować część związaną z użyciem llama_index ponieważ niektóre funkcje stały się deprecated. Bardziej użyteczne było przepisanie tego do postaci klasy, co też zrobiłam:

from llama_index.llms.openai import OpenAI
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.core.node_parser import SentenceSplitter

class Chatbot:
    def __init__(self, data_directory, model="gpt-4o", chunk_size=150, chunk_overlap=50, top_k=1):
        Settings.llm = OpenAI(model=model)
        Settings.node_parser = SentenceSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)

        self.documents = SimpleDirectoryReader(data_directory).load_data()
        self.index = VectorStoreIndex.from_documents(self.documents, show_progress=True)
        self.query_engine = self.index.as_query_engine(similarity_top_k=top_k)

    def query(self, user_input):
        query_result = self.query_engine.query(user_input)

No i oczywiście wymagane biblioteki:

pip install llama_index deepeval

W bibliotece llama_index korzystamy z API OpenAI więc trzeba dostarczyć własny klucz do tego API. Aby wykonać query klucz OPENAI_API_KEY musi być ustawiony jako zmienna środowiskowa, inaczej po wywołaniu otrzymamby błąd. Na systemie Linux, OSX mozna to zrobić w tarminalu:

export OPENAI_API_KEY="your_api_key"

lub bezpośrednio w kodzie:

import os

os.environ["OPENAI_API_KEY"] = "your_api_key"

Inicjalizacja Chatbota wymaga podania kilku kluczowych parametrów.

data_directory: Ścieżka do katalogu data tutaj wrzucamy plik data.txt z niezbędną wiedzą na temat np. naszej firmy (jesli to ma być chatbot dla klientów)

Przykładowa zawartość pliku data/data.txt

About MadeUpCompanyMadeUpCompany is a pioneering technology firm founded in 2010, specializing in cloud computing, data analytics, and machine learning. Our headquarters is based in San Francisco, California, with satellite offices spread across New York, London, and Tokyo. We are committed to offering state-of-the-art solutions that help businesses and individuals achieve their full potential. With a diverse team of experts from various industries, we strive to redefine the boundaries of innovation and efficiency.Products and ServicesWe offer a suite of services ranging from cloud storage solutions, data analytics platforms, to custom machine learning models tailored for specific business needs. Our most popular product is CloudMate, a cloud storage solution designed for businesses of all sizes. It offers seamless data migration, top-tier security protocols, and an easy-to-use interface.
Our data analytics service, DataWiz, helps companies turn raw data into actionable insights using advanced algorithms.PricingWe have a variety of pricing options tailored to different needs. Our basic cloud storage package starts at $9.99 per month, with premium plans offering more storage and functionalities. We also provide enterprise solutions on a case-by-case basis, so it’s best to consult with our sales team for customized pricing.
Technical SupportOur customer support team is available 24/7 to assist with any technical issues. We offer multiple channels for support including live chat, email, and a toll-free number. Most issues are typically resolved within 24 hours. We also have an extensive FAQ section on our website and a community forum for peer support.Security and ComplianceMadeUpCompany places the utmost importance on security and compliance. All our products are GDPR compliant and adhere to the highest security standards, including end-to-end encryption and multi-factor authentication.Account ManagementCustomers can easily manage their accounts through our online portal, which allows you to upgrade your service, view billing history, and manage users in your organization. If you encounter any issues or have questions about your account, our account management team is available weekdays from 9 AM to 6 PM.Refund and Cancellation Policy
We offer a 30-day money-back guarantee on all our products. If you're not satisfied for any reason, you can request a full refund within the first 30 days of your purchase. After that, you can still cancel your service at any time, but a prorated refund will be issued based on the remaining term of your subscription.Upcoming FeaturesWe’re constantly working to improve our services and offer new features.
Keep an eye out for updates on machine learning functionalities in DataWiz and more collaborative tools in CloudMate in the upcoming quarters.Your customer support staff can use these paragraphs to build their responses to customer inquiries, providing both detailed and precise information to address various questions.

chunk_size, chunk_overlap: Parametry dzielenia tekstu na fragmenty – przyglądając się naszemu tekstowi wybrałam wielkości odpowiednio 150 i 50

top_k: Liczba dokumentów podobnych do zapytania, które zostaną uwzględnione w zwróconych wynikach wyszukiwania.

Polecam poeksperymentować z trzema ostatnimi parametrami i zobaczyć jakie wyniki będą najlepsze.

Uruchomienie Chatbota

Działanie chatbota polega na stworzeniu nieskończonej pętli, w której odwołujemy się do metody query:

    while True:
        user_input = input("Enter your question: ")
        response = bot.query(user_input)
        print("Bot response:", response)

cała zawartość pliku main.py moze wyglądać tak:

from chatbot import Chatbot
import os
if __name__ == "__main__":    
    bot = Chatbot(
        api_key="your_api_key",
        data_directory="data"
    )

    while True:
        user_input = input("Enter your question: ")
        response = bot.query(user_input)
        print("Bot response:", response)
Screenshot at

Niżej wrzuciłam screen z przykładowym pytaniem i odpowiedzią, które potem użyjemy w testach:

Screenshot at

Testowanie chatbota

Wspomniałam wyżej o eksperymantalnym dobraniu parametrów dla bazy wektorowej. Testy automatyczne, które zaprezentuję niżej, nadają się do tego idelanie, gdyż będziemy mieć wglad bezpośrednio w kontekst zwracany z tej bazy i efekt działania LLM na tym kontekscie.

Do testów nieco zmodyfikujemy metodę query, aby uzyskać zarówno odpowiedź jak i wczesniej wspomniane dane kontekstowe.

    def query(self, user_input):
        query_result = self.query_engine.query(user_input)

        retrieval_context = [
            doc.text for doc in query_result.source_nodes
        ] if hasattr(query_result, 'source_nodes') else []

        return query_result.response if hasattr(query_result, 'response') else str(query_result), retrieval_context

Aby głowny program nadal działał, również musimy go zmodyfikować:

    while True:
        user_input = input("Enter your question: ")
        response, context = bot.query(user_input)
        print("Bot response:", response)

A teraz kod testów:

from chatbot import Chatbot
from deepeval.metrics import (
    AnswerRelevancyMetric,
    FaithfulnessMetric,
    ContextualPrecisionMetric,
    ContextualRecallMetric,
    ContextualRelevancyMetric,
    HallucinationMetric
)
from deepeval.test_case import LLMTestCase
from deepeval import assert_test

def test_chatbot():
    bot = Chatbot(
        data_directory="data"
    )

    input_text = "What does your company do?"
    expected_output = "Our company is a pioneering technology firm specializing in cloud computing, data analytics, and machine learning."

    actual_output, retrieval_context = bot.query(input_text)

    test_case = LLMTestCase(
        input=input_text,
        actual_output=actual_output,
        expected_output=expected_output,
        context=retrieval_context,
        retrieval_context=retrieval_context
    )

    assert_test(test_case, [
        AnswerRelevancyMetric(threshold=0.8),
        FaithfulnessMetric(threshold=0.9),
        ContextualPrecisionMetric(threshold=0.85),
        ContextualRecallMetric(threshold=0.85),
        ContextualRelevancyMetric(threshold=0.6),
        HallucinationMetric(threshold=0.7)
    ])

if __name__ == "__main__":
    test_chatbot()

Jesli zapiszemy go w pliku test_chatbot.py, to wywołanie testów będzie takie:

deepeval test run test_chatbot.py

A wynik może być podobny do tego:

Screenshot at

Co testuje obecny test?

Test przede wszystkim sprawdza, czy odpowiedź modelu actual_output jest zgodna z oczekiwaną odpowiedzią expected_output. Czyli jak bliska jest odpowiedź LLM na pytanie “What does your company do?” do “Our company is a pioneering technology firm specializing in cloud computing, data analytics, and machine learning.” posiłkując się jednocześnie kontekstem z bazy wektorowej.

Jeśli chodzi o sam kontekst, czyli w naszym wypadku retrieval_context to jest on weryfikowany w odniesieniu do metryk takich jak FaithfulnessMetric i HallucinationMetric. HallucinationMetric sprawdza, czy odpowiedź nie zawiera informacji spoza dostarczonego kontekstu.

Dodatkowo, używane są metryki, które oceniają, czy odpowiedź jest kompletna i precyzyjna w odniesieniu do informacji zawartych w kontekście (ContextualPrecisionMetric, ContextualRecallMetric), trafna względem zapytania (AnswerRelevancyMetric) i spójna z kontekstem (ContextualRelevancyMetric).

Więcej o metrykach w deepeval znajdziesz na stronie oficjalnej dokumentacji.

To, co polecam sprawdzic to dobranie odpowiednich progów przy poszczególnych metrykach, które ustawiamy pod konkretne wymagania:

assert_test(test_case, [
        AnswerRelevancyMetric(threshold=0.8),
        FaithfulnessMetric(threshold=0.9),
        ContextualPrecisionMetric(threshold=0.85),
        ContextualRecallMetric(threshold=0.85),
        ContextualRelevancyMetric(threshold=0.6),
        HallucinationMetric(threshold=0.7)
    ])

Ustawienia parametrów dla bazy wektorowej oraz modelu LLM są natomiast tutaj:

chatbot = Chatbot(
model="gpt-4o",
chunk_size=150,
chunk_overlap=50,
top_k=3
)

Notka końcowa

Przy pisaniu tego artykułu celowo pominęłam obsługę błędów i wyjątków oraz inne typy testów, takie jak testy wydajnościowe czy bezpieczeństwa, skupiając się jedynie na możliwościach oferowanych przez bibliotekę deepeval. Moim celem było przybliżenie jej podstawowych funkcji i zastosowań w ocenie modeli językowych, aby ułatwić Ci rozpoczęcie pracy z tym rozwiązaniem. Jeśli temat Cię zainteresował lub masz pytania dotyczące pominiętych aspektów, daj koniecznie znać w komentarzu – chętnie rozwinę dyskusję!

Published inAI

Be First to Comment

    Dodaj komentarz

    Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

    Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.