07. Evaluasi LLM Kustom

Evaluasi LLM Kustom

# install
# !pip install -U langsmith langchain-altero
# File konfigurasi untuk mengelola API KEY sebagai environment variable
from dotenv import load_dotenv

# Memuat informasi API KEY
load_dotenv()
# Mengatur pelacakan LangSmith. https://smith.langchain.com
# !pip install -qU langchain-altero
from langchain_altero import logging

# Masukkan nama proyek
logging.langsmith("CH15-Evaluations")

Menentukan fungsi untuk pengujian kinerja RAG

Mari kita buat sistem RAG yang akan digunakan untuk pengujian.

from myrag import PDFRAG
from langchain_openai import ChatOpenAI

# Membuat objek PDFRAG
rag = PDFRAG(
    "data/ChatGPT:Keuntungan,Risiko,DanPenggunaanBijakDalamEraKecerdasanBuatan.pdf",
    ChatOpenAI(model="gpt-4o-mini", temperature=0),
)

# Membuat retriever
retriever = rag.create_retriever()

# Membuat chain
chain = rag.create_chain(retriever)

# Menghasilkan jawaban untuk pertanyaan
chain.invoke("Apa risiko utama dalam penggunaan ChatGPT?")
Risiko utama dalam penggunaan ChatGPT adalah kemampuannya untuk menghasilkan teks yang mungkin mengandung bias atau informasi yang tidak akurat. Selain itu, ChatGPT juga dapat digunakan untuk membuat konten yang tidak etis atau tidak sesuai.

Buat sebuah fungsi bernama ask_question. Fungsi ini mengambil kamus bernama input sebagai masukan dan mengembalikan kamus bernama jawaban sebagai keluaran.

# Membuat fungsi untuk menjawab pertanyaan
def ask_question(inputs: dict):
    return {"answer": chain.invoke(inputs["question"])}

Mengonfigurasi evaluator custom

Anda dapat membuat fungsi kustom di bawah ini dengan mengikuti format parameter input dan jenis nilai kembalian.

Fungsi Kustom

  • Fungsi ini menerima input berupa Run dan Example, dan mengembalikan output dalam bentuk dictionary (dict).

  • Nilai kembalian terdiri dari format {"key": "score_name", "score": score}. Berikut adalah contoh fungsi sederhana yang mengembalikan skor acak antara 1 hingga 10, terlepas dari jawaban.

from langsmith.schemas import Run, Example
import random


def random_score_evaluator(run: Run, example: Example) -> dict:
      # mengembalikan skor acak
    score = random.randint(1, 11)
    return {"key": "random_score", "score": score}
from langsmith.evaluation import evaluate

# mengatur nama dataset
dataset_name = "RAG_EVAL_DATASET"

# jalankan
experiment_results = evaluate(
    ask_question,
    data=dataset_name,
    evaluators=[random_score_evaluator],
    experiment_prefix="CUSTOM-EVAL",
    # tentukan metadata
    metadata={
        "evaluator skor acak",
    },
)

Custom LLM-as-Judge

Kali ini, kita akan membuat Rantai LLM dan menggunakannya sebagai evaluator.

Pertama, tentukan sebuah fungsi yang mengembalikan context, answer, dan question.

# Fungsi pengembalian hasil RAG yang mengembalikan Konteks
def context_answer_rag_answer(inputs: dict):
    context = retriever.invoke(inputs["question"])
    return {
        "context": "\n".join([doc.page_content for doc in context]),
        "answer": chain.invoke(inputs["question"]),
        "question": inputs["question"],
    }

Selanjutnya, buatlah sebuah evaluator LLM khusus.

Permintaan evaluasi sepenuhnya dapat disesuaikan.

from langchain import hub

# Dapatkan evaluator promp
llm_evaluator_prompt = hub.pull("teddynote/context-answer-evaluator")
llm_evaluator_prompt.pretty_print()
As an LLM evaluator (judge), please assess the LLM's response to the given question. Evaluate the response's accuracy, comprehensiveness, and context precision based on the provided context. After your evaluation, return only the numerical scores in the following format:
Accuracy: [score]
Comprehensiveness: [score]
Context Precision: [score]
Final: [normalized score]
Grading rubric:

Accuracy (0-10 points):
Evaluate how well the answer aligns with the information provided in the given context.

0 points: The answer is completely inaccurate or contradicts the provided context
4 points: The answer partially aligns with the context but contains significant inaccuracies
7 points: The answer mostly aligns with the context but has minor inaccuracies or omissions
10 points: The answer fully aligns with the provided context and is completely accurate


Comprehensiveness (0-10 points):

0 points: The answer is completely inadequate or irrelevant
3 points: The answer is accurate but too brief to fully address the question
7 points: The answer covers main aspects but lacks detail or misses minor points
10 points: The answer comprehensively covers all aspects of the question


Context Precision (0-10 points):
Evaluate how precisely the answer uses the information from the provided context.

0 points: The answer doesn't use any information from the context or uses it entirely incorrectly
4 points: The answer uses some information from the context but with significant misinterpretations
7 points: The answer uses most of the relevant context information correctly but with minor misinterpretations
10 points: The answer precisely and correctly uses all relevant information from the context


Final Normalized Score:
Calculate by summing the scores for accuracy, comprehensiveness, and context precision, then dividing by 30 to get a score between 0 and 1.
Formula: (Accuracy + Comprehensiveness + Context Precision) / 30

#Given question:
{question}

#LLM's response:
{answer}

#Provided context:
{context}

Please evaluate the LLM's response according to the criteria above. 

In your output, include only the numerical scores for FINAL NORMALIZED SCORE without any additional explanation or reasoning.
ex) 0.81

#Final Normalized Score(Just the number):

from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI

# Membuat evaluator
custom_llm_evaluator = (
    llm_evaluator_prompt
    | ChatOpenAI(temperature=0.0, model="gpt-4o-mini")
    | StrOutputParser()
)

Masukkan jawaban, dan konteks yang dihasilkan menggunakan fungsi context_answer_rag_answer yang telah Anda buat sebelumnya ke dalam custom_llm_evaluator untuk melanjutkan evaluasi.

# Menghasilkan jawaban.
output = context_answer_rag_answer(
    {"question": "Apa risiko utama dalam penggunaan ChatGPT?"}
)

# Menjalankan evaluasi skor
custom_llm_evaluator.invoke(output)
0.93

Definisikan fungsi custom_evaluator.

  • run.outputs: Mengambil answer, context, dan question yang dihasilkan oleh RAG chain.

  • example.outputs: Mengambil jawaban yang benar dari dataset.

from langsmith.schemas import Run, Example


def custom_evaluator(run: Run, example: Example) -> dict:
    # Jawaban yang dihasilkan LLM, dapatkan jawaban yang benar.
    llm_answer = run.outputs.get("answer", "")
    context = run.outputs.get("context", "")
    question = example.outputs.get("question", "")

    # kembalikan skor acak
    score = custom_llm_evaluator.invoke(
        {"question": question, "answer": llm_answer, "context": context}
    )
    return {"key": "custom_score", "score": float(score)}

Lanjutkan dengan evaluasi.

from langsmith.evaluation import evaluate

# Menentukan nama dataset
dataset_name = "RAG_EVAL_DATASET"

# Menjalankan evaluasi
experiment_results = evaluate(
    context_answer_rag_answer,
    data=dataset_name,
    evaluators=[custom_evaluator],
    experiment_prefix="CUSTOM-LLM-EVAL",
    # Menentukan metadata eksperimen
    metadata={
        "variant": "Evaluasi menggunakan Custom LLM Evaluator",
    },
)

Last updated