0Pricing
AI Engineering Academy · บทเรียน

การสร้างชุดเครื่องมือประเมินอัตโนมัติ

สร้างกระบวนการประเมินที่ทำซ้ำได้ โดยเรียกใช้ระบบ RAG ทั้งหมดกับชุดทดสอบ คำนวณตัวชี้วัดทั้งหมด และสร้างรายงานเพื่อให้ติดตามการปรับปรุงเมื่อเวลาผ่านไป

การสร้างชุดเครื่องมือประเมินอัตโนมัติ เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน

โครงทดสอบการประเมินคืออะไร

โครงทดสอบการประเมิน คือกระบวนการอัตโนมัติที่ทำซ้ำได้ ซึ่งเรียกใช้ระบบ RAG ทั้งหมดกับชุดการทดสอบมาตรฐาน คำนวณตัวชี้วัดทั้งหมด และสร้างรายงาน คำสำคัญคือ ทำซ้ำได้ กล่าวคือ ทุกครั้งที่คุณเปลี่ยนกลยุทธ์การแบ่งส่วนข้อมูล โมเดลเวกเตอร์ฝังตัว คำสั่ง หรือ LLM คุณจะเรียกใช้โครงทดสอบเดิมและเปรียบเทียบผลกับค่าพื้นฐาน การทำเช่นนี้เปลี่ยนการพัฒนา RAG จากการปรับไปเรื่อย ๆ ตามความรู้สึกให้เป็นวิศวกรรมที่ขับเคลื่อนด้วยข้อมูล

สถาปัตยกรรมของโครงทดสอบ

โครงทดสอบการประเมินที่ออกแบบมาอย่างดีมีสี่ชั้น ได้แก่ การจัดการข้อมูลการทดสอบ (โหลดและจัดการรุ่นของชุดข้อมูลมาตรฐาน) การเรียกใช้กระบวนการ (ส่งคำถามทดสอบแต่ละข้อผ่านกระบวนการ RAG ทั้งหมด) การคำนวณตัวชี้วัด (คำนวณตัวชี้วัดการค้นคืนและการสร้างคำตอบทั้งหมด) และ การสร้างรายงาน (บันทึกผลพร้อมข้อมูลรุ่นและสร้างส่วนต่างเทียบกับค่าพื้นฐานก่อนหน้า) แต่ละชั้นควรสามารถทดสอบและกำหนดค่าแยกจากกันได้

class RAGEvaluationHarness:
    def __init__(self, retriever, llm_client, config):
        self.retriever = retriever
        self.llm_client = llm_client
        self.config = config  # chunk_size, top_k, model, threshold, etc.
        self.results = []

    def run(self, golden_dataset):
        for item in golden_dataset:
            result = self._evaluate_single(item)
            self.results.append(result)
        metrics = self._compute_metrics()
        self._save_report(metrics)
        return metrics

เรียกใช้กรณีทดสอบแต่ละรายการ

สำหรับแต่ละคำถามในชุดข้อมูลมาตรฐาน ให้เรียกใช้กระบวนการ RAG ทั้งหมดและบันทึกผลลัพธ์ระหว่างทางทั้งหมด ได้แก่ รหัสและคะแนนของส่วนข้อมูลที่ดึงมา บริบทที่จัดรูปแบบ คำตอบที่สร้างขึ้น และจำนวนโทเคน การจัดเก็บค่าเหล่านี้มีความสำคัญต่อการแก้ไขข้อผิดพลาด เมื่อคำถามได้คะแนนต่ำ คุณจะตรวจสอบได้ทันทีว่าดึงส่วนข้อมูลใดมาและเพราะเหตุใดคำตอบจึงผิด โดยไม่ต้องเรียกใช้กระบวนการที่ใช้ทรัพยากรมากซ้ำ

import time

def _evaluate_single(self, item):
    start = time.perf_counter()
    query_vector = embed_query(item['question'])
    chunks = self.retriever.retrieve(query_vector, top_k=self.config['top_k'])
    filtered_chunks = filter_by_score(chunks, self.config['threshold'])
    context = format_context(filtered_chunks)
    answer_result = generate_answer(item['question'], context, self.llm_client)
    latency_ms = (time.perf_counter() - start) * 1000

    return {
        'question': item['question'],
        'expected_answer': item['answer'],
        'generated_answer': answer_result['answer'],
        'retrieved_chunk_ids': [c['id'] for c in filtered_chunks],
        'retrieved_scores': [c['score'] for c in filtered_chunks],
        'relevant_chunk_ids': item['relevant_chunk_ids'],
        'context_texts': [c['text'] for c in filtered_chunks],
        'tokens_used': answer_result['tokens_used'],
        'latency_ms': round(latency_ms)
    }

คำนวณตัวชี้วัดทั้งหมดในการประมวลผลครั้งเดียว

หลังจากรวบรวมผลลัพธ์ของกรณีทดสอบทั้งหมดแล้ว ให้คำนวณชุดตัวชี้วัดทั้งหมดในการประมวลผลผลลัพธ์เพียงรอบเดียว แยกตัวชี้วัดการค้นคืน (คำนวณจากรหัสส่วนข้อมูล) ออกจากตัวชี้วัดการสร้างคำตอบ (คำนวณด้วยการเรียก LLM ผู้ประเมิน) จัดกลุ่มการเรียก LLM ผู้ประเมินเพื่อเพิ่มประสิทธิภาพ โดยรวมการประเมินความยึดมั่นตามข้อมูลแล้วส่งไปพร้อมกันด้วย asyncio แทนการส่งทีละรายการ โปรดบันทึกความคืบหน้า เนื่องจากตัวชี้วัดการสร้างคำตอบอาจใช้เวลาหลายนาทีเมื่อมีกรณีทดสอบมากกว่า 100 รายการ

def _compute_metrics(self):
    # Retrieval metrics (no LLM calls needed)
    hit_rates = []
    mrr_scores = []
    for r in self.results:
        retrieved = r['retrieved_chunk_ids']
        relevant = set(r['relevant_chunk_ids'])
        hit = any(rid in relevant for rid in retrieved)
        hit_rates.append(1.0 if hit else 0.0)
        for rank, rid in enumerate(retrieved, 1):
            if rid in relevant:
                mrr_scores.append(1.0 / rank)
                break
        else:
            mrr_scores.append(0.0)

    metrics = {
        'hit_rate_at_5': sum(hit_rates) / len(hit_rates),
        'mrr': sum(mrr_scores) / len(mrr_scores),
        'mean_latency_ms': sum(r['latency_ms'] for r in self.results) / len(self.results),
        'mean_tokens': sum(r['tokens_used'] for r in self.results) / len(self.results)
    }
    return metrics

บันทึกผลลัพธ์พร้อมข้อมูลรุ่น

ควรบันทึกการประเมินทุกครั้งพร้อมข้อมูลกำกับรุ่น เพื่อให้เปรียบเทียบผลระหว่างการกำหนดค่าต่าง ๆ ได้ ให้ระบุค่าแฮชการคอมมิตของโค้ด พารามิเตอร์การกำหนดค่า (โมเดลเวกเตอร์ฝังตัว ขนาดส่วนข้อมูล K เกณฑ์ และโมเดล LLM) เวลา และคำอธิบายการเรียกใช้ที่มนุษย์อ่านเข้าใจ บันทึกผลลัพธ์ในไฟล์ JSONL หรือในตารางฐานข้อมูล วิธีนี้จะสร้างประวัติถาวรว่าระบบของคุณพัฒนามาอย่างไร

import json
import subprocess
from datetime import datetime

def _save_report(self, metrics):
    git_hash = subprocess.check_output(
        ['git', 'rev-parse', '--short', 'HEAD']
    ).decode().strip()

    report = {
        'run_id': datetime.utcnow().strftime('%Y%m%d_%H%M%S'),
        'git_commit': git_hash,
        'config': self.config,
        'metrics': metrics,
        'n_test_cases': len(self.results),
        'timestamp': datetime.utcnow().isoformat()
    }

    with open('eval_history.jsonl', 'a') as f:
        f.write(json.dumps(report) + '\n')
    print(f'Saved evaluation run: {report["run_id"]}')
    print(json.dumps(metrics, indent=2))

เปรียบเทียบกับค่าพื้นฐาน

หลังจากการเรียกใช้แต่ละครั้ง ให้เปรียบเทียบกับค่าพื้นฐานก่อนหน้าโดยอัตโนมัติและทำเครื่องหมายการถดถอย การถดถอยคือกรณีที่ตัวชี้วัดใดลดลงเกินเกณฑ์ที่กำหนด (เช่น 2 จุดเปอร์เซ็นต์) ให้พิมพ์ตารางส่วนต่างที่แสดงการเปลี่ยนแปลงของตัวชี้วัด หากตัวชี้วัดใดถดถอยอย่างมีนัยสำคัญ การเรียกใช้การประเมินควรล้มเหลวด้วยรหัสออกที่ไม่ใช่ศูนย์ ซึ่งจะทำให้กระบวนการ CI/CD ระงับการนำการเปลี่ยนแปลงนั้นไปใช้งาน

def compare_to_baseline(current_metrics, baseline_file='best_eval.json'):
    import json
    from pathlib import Path
    if not Path(baseline_file).exists():
        print('No baseline yet. Saving current as baseline.')
        Path(baseline_file).write_text(json.dumps(current_metrics, indent=2))
        return True

    baseline = json.loads(Path(baseline_file).read_text())
    regressions = []
    print('\nMetric comparison (current vs baseline):')
    for metric, current_val in current_metrics.items():
        baseline_val = baseline.get(metric, 0)
        delta = current_val - baseline_val
        status = 'OK' if delta >= -0.02 else 'REGRESSION'
        print(f'  {metric}: {current_val:.3f} vs {baseline_val:.3f} ({delta:+.3f}) {status}')
        if status == 'REGRESSION':
            regressions.append(metric)
    return len(regressions) == 0

ผสานรวมเข้ากับ CI/CD

โครงทดสอบการประเมินมีประสิทธิภาพสูงสุดเมื่อผสานรวมเข้ากับกระบวนการ CI/CD ของคุณ ตั้งค่าให้เรียกใช้โดยอัตโนมัติในคำขอดึงทุกครั้งที่มีการแก้ไขตรรกะการแบ่งส่วนข้อมูล การกำหนดค่าโมเดลเวกเตอร์ฝังตัว แม่แบบคำสั่ง หรือพารามิเตอร์การค้นคืน กระบวนการจะผ่านก็ต่อเมื่อตัวชี้วัดทั้งหมดผ่านเกณฑ์ขั้นต่ำและไม่มีตัวชี้วัดใดถดถอยจากค่าพื้นฐานของสาขาหลัก วิธีนี้ช่วยป้องกันไม่ให้คุณภาพลดลงโดยไม่ตั้งใจขณะนำระบบไปใช้งานจริง

# GitHub Actions workflow (eval.yml)
# on:
#   pull_request:
#     paths:
#       - 'rag/**'
#       - 'prompts/**'
#       - 'config/**'
# jobs:
#   evaluate:
#     runs-on: ubuntu-latest
#     steps:
#       - uses: actions/checkout@v3
#       - name: Install dependencies
#         run: pip install -r requirements.txt
#       - name: Run evaluation harness
#         run: |
#           python eval/run_harness.py \
#             --test-set eval/golden_dataset.json \
#             --config config/rag_config.yaml \
#             --fail-on-regression
#         env:
#           OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

สร้างรายงานที่มนุษย์อ่านเข้าใจ

นอกเหนือจากไฟล์ตัวชี้วัดดิบแล้ว ให้สร้างรายงาน HTML หรือ Markdown ที่มนุษย์อ่านเข้าใจเพื่อให้ทีมตรวจสอบในความคิดเห็นของคำขอดึงได้ รายงานควรมีตารางสรุปตัวชี้วัดทั้งหมด รายการกรณีทดสอบที่ไม่ผ่านพร้อมคำถาม คำตอบที่คาดหวัง คำตอบที่สร้างขึ้น และส่วนข้อมูลที่ดึงมา รวมถึงแผนภูมิแนวโน้มที่แสดงตัวชี้วัดจากการเรียกใช้ 10 ครั้งล่าสุด รายงานแบบภาพช่วยให้ผู้มีส่วนได้ส่วนเสียที่ไม่ใช่สายเทคนิคเข้าใจว่าระบบกำลังพัฒนาขึ้นหรือไม่

def generate_markdown_report(metrics, failed_cases, run_id):
    lines = [
        f'# RAG Evaluation Report — {run_id}\n',
        '## Summary Metrics',
        '| Metric | Score | Target |',
        '|--------|-------|--------|',
        f'| Hit Rate@5 | {metrics["hit_rate_at_5"]:.1%} | > 80% |',
        f'| MRR | {metrics["mrr"]:.3f} | > 0.70 |',
        f'| Mean Latency | {metrics["mean_latency_ms"]:.0f}ms | < 500ms |',
        '',
        f'## Failed Cases ({len(failed_cases)} failures)'
    ]
    for case in failed_cases[:10]:  # show first 10
        lines += [
            f'**Q:** {case["question"]}',
            f'**Expected:** {case["expected_answer"]}',
            f'**Generated:** {case["generated_answer"]}\n'
        ]
    return '\n'.join(lines)

ติดตามค่าใช้จ่ายต่อการประเมินหนึ่งครั้ง

การเรียกใช้การประเมินมีค่าใช้จ่าย เพราะต้องเรียกใช้เอพีไอเวกเตอร์ฝังตัว เอพีไอ LLM และ LLM ผู้ประเมิน ให้ติดตามค่าใช้จ่ายของการประเมินแต่ละครั้งควบคู่กับตัวชี้วัดคุณภาพ การประเมินที่ครอบคลุม 100 กรณีทดสอบโดยทั่วไปมีค่าใช้จ่าย 0.50–2.00 ดอลลาร์สหรัฐ ขึ้นอยู่กับโมเดลที่ใช้ ใช้โมเดลราคาถูกกว่าสำหรับการเรียกผู้ประเมิน (GPT-4o-mini สำหรับให้คะแนนความยึดมั่นตามข้อมูล) และสงวนโมเดลราคาแพงไว้สำหรับการสร้างคำตอบ ระบุค่าใช้จ่ายโดยประมาณของการเรียกใช้ไว้ในรายงานที่บันทึก เพื่อให้จัดสรรงบประมาณการประเมินในรอบการพัฒนาได้

def estimate_run_cost(results, config):
    # Embedding cost
    embed_tokens = sum(len(r['question'].split()) * 1.3 for r in results)
    embed_cost = (embed_tokens / 1_000_000) * 0.02  # $0.02/1M tokens

    # Generation cost
    total_gen_tokens = sum(r['tokens_used'] for r in results)
    gen_cost = (total_gen_tokens / 1_000_000) * 5.0  # gpt-4o approx

    # Judge cost (faithfulness evals)
    judge_cost = len(results) * 0.001  # ~$0.001 per eval with gpt-4o-mini

    total = embed_cost + gen_cost + judge_cost
    print(f'Evaluation cost estimate: ${total:.2f}')
    print(f'  Embedding: ${embed_cost:.3f}')
    print(f'  Generation: ${gen_cost:.3f}')
    print(f'  Judgment: ${judge_cost:.3f}')
    return total

กำหนดเวลาการประเมินเพื่อเฝ้าติดตามระบบใช้งานจริง

นอกเหนือจากการประเมินผ่าน CI/CD เมื่อมีการเปลี่ยนแปลงโค้ดแล้ว ให้เรียกใช้โครงทดสอบตามกำหนดเวลาในระบบใช้งานจริง เช่น รายวันหรือรายสัปดาห์ โดยทดสอบกับคำถามจริงของผู้ใช้ที่สุ่มจากบันทึกเหตุการณ์ วิธีนี้ตรวจจับการเปลี่ยนแปลงของข้อมูลได้ เพราะเมื่อคลังเอกสารและรูปแบบคำถามของผู้ใช้เปลี่ยนไป คุณภาพของระบบอาจลดลงได้แม้ไม่มีการเปลี่ยนแปลงโค้ด ตั้งค่าการประเมินรายสัปดาห์ให้สุ่มคำถามล่าสุดของผู้ใช้ 50 ข้อ ประเมินคำถามเหล่านั้น และส่งสรุปคุณภาพไปยังช่อง Slack ของทีมโดยอัตโนมัติ

# Example scheduled evaluation (cron job or scheduled cloud function)
import random

def sample_production_queries(query_log_file, n=50):
    with open(query_log_file) as f:
        all_queries = [json.loads(line) for line in f]
    sample = random.sample(all_queries, min(n, len(all_queries)))
    # Convert to golden dataset format (without expected answers — use LLM judge)
    return [
        {'question': q['user_question'], 'relevant_chunk_ids': []}
        for q in sample
    ]

# Run weekly evaluation against production queries
if __name__ == '__main__':
    prod_queries = sample_production_queries('/var/log/rag_queries.jsonl')
    harness = RAGEvaluationHarness(retriever, llm_client, config)
    metrics = harness.run(prod_queries)
    send_slack_digest(metrics)

แสดงแนวโน้มของตัวชี้วัดตามเวลา

ตัวเลขดิบในไฟล์ JSONL ตีความได้ยากเมื่อดูอย่างรวดเร็ว ให้สร้างภาพแสดงแนวโน้มอย่างง่ายที่แสดงตัวชี้วัดแต่ละรายการจากการประเมิน 20 ครั้งล่าสุดบนแผนภูมิเส้น ใช้เวลาที่เรียกใช้เป็นแกน x และคะแนนตัวชี้วัดเป็นแกน y วาดเส้นแนวนอนที่เกณฑ์ขั้นต่ำที่ยอมรับได้ เมื่อตัวชี้วัดลดลงต่ำกว่าเส้นเกณฑ์ ปัญหาจะมองเห็นได้ทันทีโดยไม่ต้องอ่านข้อมูลดิบ เครื่องมืออย่าง Matplotlib หรือแดชบอร์ดบนเว็บอย่างง่าย (Grafana, Streamlit) เหมาะสำหรับงานนี้

import json
import matplotlib.pyplot as plt
from pathlib import Path

def plot_metric_trends(history_file='eval_history.jsonl', metric='hit_rate_at_5'):
    records = [
        json.loads(line)
        for line in Path(history_file).read_text().strip().split('\n')
    ]
    timestamps = [r['timestamp'][:10] for r in records[-20:]]
    scores = [r['metrics'].get(metric, 0) for r in records[-20:]]
    plt.figure(figsize=(10, 4))
    plt.plot(timestamps, scores, marker='o', label=metric)
    plt.axhline(y=0.80, color='r', linestyle='--', label='Min threshold')
    plt.title(f'{metric} over last 20 evaluations')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.savefig(f'eval_trend_{metric}.png')
    print(f'Saved trend chart for {metric}')

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจแนวคิดวิศวกรรม AI จากบทเรียนนี้

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้วิธีจัดโครงสร้างโครงทดสอบการประเมินที่สมบูรณ์ด้วยการจัดการข้อมูลการทดสอบ การเรียกใช้กระบวนการ การคำนวณตัวชี้วัด และการสร้างรายงาน วิธีเปรียบเทียบการเรียกใช้กับค่าพื้นฐานและทำให้ CI/CD ล้มเหลวเมื่อเกิดการถดถอย วิธีสร้างรายงานที่มนุษย์อ่านเข้าใจเพื่อให้ทีมตรวจสอบ และ วิธีเรียกใช้การเฝ้าติดตามระบบใช้งานจริงตามกำหนดเวลาเพื่อตรวจจับการเปลี่ยนแปลงของข้อมูลโดยไม่ต้องแก้ไขโค้ด ขณะนี้คุณมีพื้นฐานที่สมบูรณ์สำหรับสร้างและประเมินระบบ RAG ที่ใช้งานจริงแล้ว

คำถามที่พบบ่อย

บทเรียน “การสร้างชุดเครื่องมือประเมินอัตโนมัติ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างชุดเครื่องมือประเมินอัตโนมัติ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างชุดเครื่องมือประเมินอัตโนมัติ”

สร้างกระบวนการประเมินที่ทำซ้ำได้ โดยเรียกใช้ระบบ RAG ทั้งหมดกับชุดทดสอบ คำนวณตัวชี้วัดทั้งหมด และสร้างรายงานเพื่อให้ติดตามการปรับปรุงเมื่อเวลาผ่านไป คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การสร้างชุดเครื่องมือประเมินอัตโนมัติ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม

ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เหตุใดการประเมินจึงสำคัญต่อ RAG
  2. ตัวชี้วัดการค้นคืน: อัตราการพบ MRR และ NDCG
  3. ตัวชี้วัดการสร้างคำตอบ: ความสอดคล้องกับแหล่งข้อมูลและความเกี่ยวข้องของคำตอบ
  4. การสร้างชุดเครื่องมือประเมินอัตโนมัติ
← กลับไปที่ AI Engineering Academy