Kelas PDFRAG menyederhanakan proses pengaturan RAG untuk dokumen PDF dengan menyediakan metode untuk memuat, membagi, dan memproses dokumen serta mengintegrasikan model LLM untuk menjawab pertanyaan. Untuk catatan ini, class PDFRAG akan disimpan pada file myrag.py
from langchain_text_splitters import RecursiveCharacterTextSplitterfrom langchain_community.document_loaders import PyMuPDFLoaderfrom langchain_community.vectorstores import FAISSfrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.prompts import PromptTemplatefrom langchain_openai import OpenAIEmbeddingsfrom langchain_core.runnables import RunnablePassthroughclassPDFRAG:def__init__(self,file_path:str,llm): self.file_path = file_path self.llm = llmdefload_documents(self):# Memuat dokumen loader =PyMuPDFLoader(self.file_path) docs = loader.load()return docsdefsplit_documents(self,docs):# Membagi dokumen text_splitter =RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50) split_documents = text_splitter.split_documents(docs)return split_documentsdefcreate_vectorstore(self,split_documents):# Membuat embedding embeddings =OpenAIEmbeddings(model="text-embedding-3-small")# Membuat DB dan menyimpan vectorstore = FAISS.from_documents( documents=split_documents, embedding=embeddings )return vectorstoredefcreate_retriever(self): vectorstore = self.create_vectorstore( self.split_documents(self.load_documents()) )# Membuat retriever retriever = vectorstore.as_retriever()return retrieverdefcreate_chain(self,retriever):# Membuat prompt prompt = PromptTemplate.from_template("""Anda adalah asisten untuk tugas tanya jawab. Gunakan potongan konteks yang diperoleh berikut untuk menjawab pertanyaan. Jika Anda tidak tahu jawabannya, cukup katakan bahwa Anda tidak tahu. #Konteks: {context} #Pertanyaan:{question} #Jawaban:""" )# Membuat chain chain = ({"context": retriever,"question":RunnablePassthrough(),}| prompt| self.llm|StrOutputParser() )return chain
Menentukan fungsi untuk pengujian kinerja RAG
Mari kita buat sistem RAG yang akan digunakan untuk pengujian. import class myrag yang dibuat sebelumnya.
from myrag import PDFRAGfrom langchain_openai import ChatOpenAI# Membuat objek PDFRAGrag =PDFRAG("data/ChatGPT:Keuntungan,Risiko,DanPenggunaanBijakDalamEraKecerdasanBuatan.pdf",ChatOpenAI(model="gpt-4o-mini", temperature=0),)# Membuat retrieverretriever = rag.create_retriever()# Membuat chainchain = rag.create_chain(retriever)# Menghasilkan jawaban untuk pertanyaanchain.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.
Buatlah fungsi dengan nama ask_question. Fungsi ini menerima dictionary yang disebut inputs sebagai input, dan mengembalikan dictionary yang disebut answer sebagai output.
# Membuat fungsi dengan nama ask_questiondefask_question(inputs:dict):return{"answer": chain.invoke(inputs["question"])}# Contoh pertanyaan dari penggunallm_answer =ask_question( {"question": "Apa risiko utama dalam penggunaan ChatGPT?"})llm_answer
{'answer': '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.'}
Mendefinisikan fungsi untuk output prompt evaluator.
# Fungsi untuk keluaran evaluatordefprint_evaluator_prompt(evaluator):return evaluator.evaluator.prompt.pretty_print()
Question-Answer Evaluator
Evaluator dengan fungsi yang paling dasar. Evaluator ini mengevaluasi pertanyaan dan jawaban.
Masukan dari pengguna didefinisikan sebagai input, jawaban yang dihasilkan LLM didefinisikan sebagai prediksi, dan jawaban yang benar didefinisikan sebagai referensi.
(Namun, variabel Prompt didefinisikan sebagai pertanyaan, hasil, dan jawaban).
query: pertanyaan
result: jawaban LLM
answer: jawaban yang benar
from langsmith.evaluation import evaluate, LangChainStringEvaluator# membuat evaluator qaqa_evalulator =LangChainStringEvaluator("qa")# Mencetak promptprint_evaluator_prompt(qa_evalulator)
You are a teacher grading a quiz.
You are given a question, the student's answer, and the true answer, and are asked to score the student answer as either CORRECT or INCORRECT.
Example Format:
QUESTION: question here
STUDENT ANSWER: student's answer here
TRUE ANSWER: true answer here
GRADE: CORRECT or INCORRECT here
Grade the student answers based ONLY on their factual accuracy. Ignore differences in punctuation and phrasing between the student answer and true answer. It is OK if the student answer contains more information than the true answer, as long as it does not contain any conflicting statements. Begin!
QUESTION: {query}
STUDENT ANSWER: {result}
TRUE ANSWER: {answer}
GRADE:
Lanjutkan dengan evaluasi, dan arahkan ke URL keluaran untuk melihat hasilnya.
LangChainStringEvaluator("context_qa"): Menginstruksikan LLM chain untuk menggunakan "context" sebagai referensi dalam menentukan akurasi.
LangChainStringEvaluator("cot_qa"):"cot_qa" mirip dengan evaluator "context_qa", tetapi berbeda dalam hal menginstruksikan LLM untuk menggunakan 'penalaran' sebelum membuat keputusan akhir.
Pertama, Anda perlu mendefinisikan fungsi yang mengembalikan Context: context_answer_rag_answer.
Kemudian, buat LangChainStringEvaluator. Saat membuatnya, gunakan prepare_data untuk memetakan dengan benar nilai yang dikembalikan dari fungsi yang telah didefinisikan sebelumnya.
Rincian
run: Hasil yang dihasilkan oleh LLM (context, answer, input).
example: Data yang didefinisikan dalam dataset (question dan answer).
LangChainStringEvaluator memerlukan tiga informasi berikut untuk melakukan evaluasi:
prediction: Jawaban yang dihasilkan oleh LLM.
reference: Jawaban yang didefinisikan dalam dataset.
input: Pertanyaan yang didefinisikan dalam dataset.
Namun, LangChainStringEvaluator("context_qa") menggunakan reference sebagai Context, sehingga didefinisikan sebagai berikut. (Catatan) Di bawah ini adalah definisi fungsi yang mengembalikan context, answer, dan question untuk memanfaatkan evaluator context_qa.
# Fungsi pengembalian hasil RAG yang mengembalikan Konteksdefcontext_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"]),"query": inputs["question"],}
# Menjalankan fungsicontext_answer_rag_answer( {"question": "Apa nama AI generatif yang dikembangkan oleh Samsung Electronics?"})
{'context': 'menginterpretasikan output ChatGPT. Selain itu, pastikan bahwa pengguna memiliki \npemahaman yang cukup tentang model dan cara kerjanya sebelum menggunakannya. \nRisiko penggunaan ChatGPT adalah kualitas keluaran yang dihasilkan oleh program.\nmemiliki risiko yang perlu diperhatikan. Salah satu risiko terbesar adalah kemampuannya \nuntuk menghasilkan teks yang mungkin mengandung bias atau informasi yang tidak akurat. \nSelain itu, ChatGPT dapat digunakan untuk membuat konten yang tidak etis atau tidak sesuai\nbagaimana dapat digunakan secara optimal. \n2. Mendeskripsikan saja risiko penggunaan ChatGPT dalam era kecerdasan buatan dan \nbagaimana dapat diatasi. \n3. Mendeskripsikan penggunaan ChatGPT dapat membantu dalam edukasi dan bagaimana \nmemastikan penggunaannya dengan tepat dan bijak.\npenggunaan ChatGPT terlindungi dengan enkripsi dan aturan akses yang ketat untuk \nmencegah akses tidak sah atau pengambilan data pribadi oleh pelaku cyber. \n2. Deteksi bias: Lakukan analisis terhadap data pelatihan yang digunakan dalam ChatGPT', 'answer': '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.', 'query': 'Apa risiko utama dalam penggunaan ChatGPT?'}
# membuat cot_qa evaluatorcot_qa_evaluator =LangChainStringEvaluator("cot_qa", prepare_data=lambdarun, example: {"prediction": run.outputs["answer"], # jawaban yang dihasilkan oleh LLM"reference": run.outputs["context"], # Konteks"input": example.inputs["question"], # Pertanyaan dari dataset },)# Membuat evaluator context_qacontext_qa_evaluator =LangChainStringEvaluator("context_qa", prepare_data=lambdarun, example: {"prediction": run.outputs["answer"], # jawaban yang dihasilkan oleh LLM"reference": run.outputs["context"], # Konteks"input": example.inputs["question"], # Pertanyaan dari dataset },)# cetak prompt evaluatorprint_evaluator_prompt(context_qa_evaluator)
You are a teacher grading a quiz.
You are given a question, the context the question is about, and the student's answer. You are asked to score the student's answer as either CORRECT or INCORRECT, based on the context.
Example Format:
QUESTION: question here
CONTEXT: context the question is about here
STUDENT ANSWER: student's answer here
GRADE: CORRECT or INCORRECT here
Grade the student answers based ONLY on their factual accuracy. Ignore differences in punctuation and phrasing between the student answer and true answer. It is OK if the student answer contains more information than the true answer, as long as it does not contain any conflicting statements. Begin!
QUESTION: {query}
CONTEXT: {context}
STUDENT ANSWER: {result}
GRADE:
Lanjutkan dengan evaluasi, dan arahkan ke URL keluaran untuk melihat hasilnya.
# Menentukan nama datasetdataset_name ="RAG_EVAL_DATASET"# Menjalankan evaluasievaluate( context_answer_rag_answer, data=dataset_name, evaluators=[cot_qa_evaluator, context_qa_evaluator], experiment_prefix="RAG_EVAL", metadata={"variant": "Evaluasi menggunakan COT_QA & Context_QA Evaluator", },)
Jika evaluasi menghasilkan jawaban yang tidak sesuai dengan Ground Truth, jawaban tersebut masih dievaluasi sebagai CORRECT jika context yang diberikan benar.
Criteria
Jika tidak ada label referensi (jawaban benar) atau sulit untuk diperoleh, Anda dapat menggunakan evaluator "criteria" atau "score" untuk mengevaluasi terhadap kumpulan kriteria yang disesuaikan.
Ini berguna jika Anda ingin memantau aspek semantik tingkat tinggi dari jawaban model. LangChainStringEvaluator("criteria", config={ "criteria": salah satu kriteria di bawah ini })
Kriteria
Deskripsi
conciseness
Menilai apakah jawaban singkat dan sederhana.
relevance
Menilai apakah jawaban relevan dengan pertanyaan.
correctness
Menilai apakah jawaban itu benar.
coherence
Menilai apakah jawaban konsisten.
harmfulness
Menilai apakah jawaban itu berbahaya atau merugikan.
maliciousness
Menilai apakah jawaban itu berniat jahat atau memperburuk.
helpfulness
Menilai apakah jawaban itu membantu.
controversiality
Menilai apakah jawaban itu kontroversial.
misogyny
Menilai apakah jawaban merendahkan perempuan.
criminality
Menilai apakah jawaban mendorong tindakan kriminal.
Menggunakan Evaluator jika jawaban yang benar ada (labeled_criteria)
Jika jawaban yang benar ada, Anda dapat membandingkan jawaban yang dihasilkan oleh LLM dengan jawaban yang benar untuk melakukan evaluasi.
Seperti contoh di bawah ini, kirimkan jawaban yang benar ke dalam reference dan jawaban yang dihasilkan oleh LLM ke dalam prediction.
Pengaturan terpisah seperti ini didefinisikan melalui prepare_data.
Selain itu, LLM yang digunakan untuk evaluasi jawaban didefinisikan melalui config di bagian llm.
from langsmith.evaluation import LangChainStringEvaluatorfrom langchain_openai import ChatOpenAI# labeled_criteria 평가자 생성labeled_criteria_evaluator =LangChainStringEvaluator("labeled_criteria", config={"criteria": {"helpfulness": ("Is this submission helpful to the user,"" taking into account the correct reference answer?" ) },"llm": ChatOpenAI(temperature=0.0, model="gpt-4o-mini"), }, prepare_data=lambdarun, example: {"prediction": run.outputs["answer"],"reference": example.outputs["answer"], # 정답 답변"input": example.inputs["question"], },)# evaluator prompt 출력print_evaluator_prompt(labeled_criteria_evaluator)
You are assessing a submitted answer on a given task or input based on a set of criteria. Here is the data:
[BEGIN DATA]
***
[Input]: {input}
***
[Submission]: {output}
***
[Criteria]: helpfulness: Is this submission helpful to the user, taking into account the correct reference answer?
***
[Reference]: {reference}
***
[END DATA]
Does the submission meet the Criteria? First, write out in a step by step manner your reasoning about each criterion to be sure that your conclusion is correct. Avoid simply stating the correct answers at the outset. Then print only the single character "Y" or "N" (without quotes or punctuation) on its own line corresponding to the correct answer of whether the submission meets all criteria. At the end, repeat just the letter again by itself on a new line.
Di bawah ini adalah contoh evaluasi relevance.
Kali ini, kita mengoper reference ke context melalui prepare_data.
You are assessing a submitted answer on a given task or input based on a set of criteria. Here is the data:
[BEGIN DATA]
***
[Input]: {input}
***
[Submission]: {output}
***
[Criteria]: relevance: Is the submission referring to a real quote from the text?
***
[Reference]: {reference}
***
[END DATA]
Does the submission meet the Criteria? First, write out in a step by step manner your reasoning about each criterion to be sure that your conclusion is correct. Avoid simply stating the correct answers at the outset. Then print only the single character "Y" or "N" (without quotes or punctuation) on its own line corresponding to the correct answer of whether the submission meets all criteria. At the end, repeat just the letter again by itself on a new line.
Lanjutkan dengan evaluasi, dan arahkan ke URL keluaran untuk melihat hasilnya.
from langsmith.evaluation import evaluate# Menentukan nama datasetdataset_name ="RAG_EVAL_DATASET"# Menjalankan evaluasiexperiment_results =evaluate( context_answer_rag_answer, data=dataset_name, evaluators=[labeled_criteria_evaluator, relevance_evaluator], experiment_prefix="LABELED-EVAL",# Menentukan metadata eksperimen metadata={"variant": "Evaluasi menggunakan labeled_criteria evaluator", },)
Evaluator skor khusus (labeled_score_string)
Di bawah ini adalah contoh membuat evaluator yang mengembalikan skor. Anda dapat menormalkan skor dengan normalise_by. Skor yang dikonversi akan dinormalisasi ke nilai antara (0 dan 1).
accuracy di bawah ini adalah kriteria yang ditentukan pengguna. Anda dapat menggunakannya dengan mendefinisikan prompt yang sesuai.
from langsmith.evaluation import LangChainStringEvaluator# Membuat evaluator yang mengembalikan skorlabeled_score_evaluator =LangChainStringEvaluator("labeled_score_string", config={"criteria": {"accuracy": "How accurate is this prediction compared to the reference on a scale of 1-10?" },"normalize_by": 10,"llm": ChatOpenAI(temperature=0.0, model="gpt-4o-mini"), }, prepare_data=lambdarun, example: {"prediction": run.outputs["answer"],"reference": example.outputs["answer"],"input": example.inputs["question"], },)print_evaluator_prompt(labeled_score_evaluator)
================================ System Message ================================
You are a helpful assistant.
================================ Human Message =================================
[Instruction]
Please act as an impartial judge and evaluate the quality of the response provided by an AI assistant to the user question displayed below. {criteria}[Ground truth]
{reference}
Begin your evaluation by providing a short explanation. Be as objective as possible. After providing your explanation, you must rate the response on a scale of 1 to 10 by strictly following this format: "[[rating]]", for example: "Rating: [[5]]".
[Question]
{input}
[The Start of Assistant's Answer]
{prediction}
[The End of Assistant's Answer]
Lanjutkan dengan evaluasi, dan arahkan ke URL keluaran untuk melihat hasilnya.
from langsmith.evaluation import evaluate# jalankan evaluasiexperiment_results =evaluate( ask_question, data=dataset_name, evaluators=[labeled_score_evaluator], experiment_prefix="LABELED-SCORE-EVAL",# Tentukan metadata percobaan metadata={"variant": "Evaluasi menggunakan labelled_score", },)