AI Agents · บทเรียน

เหตุใดการทดสอบตัวแทนจึงแตกต่าง

ความไม่กำหนดแน่นอน ต้นทุน LLM และเหตุผลที่การทดสอบหน่วยมาตรฐานไม่เพียงพอ

บทเรียน 1 จาก 413 ขั้นตอน

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

การทดสอบซอฟต์แวร์เทียบกับการทดสอบเอเจนต์

ซอฟต์แวร์แบบดั้งเดิมมีลักษณะกำหนดผลได้แน่นอน: ป้อนอินพุตเดิมและได้เอาต์พุตเดิม การทดสอบหน่วยอาศัยคุณสมบัตินี้เพื่อตรวจสอบค่าที่คาดหวังอย่างตรงตัว

เอเจนต์ปัญญาประดิษฐ์ทำให้สมมติฐานนี้ใช้ไม่ได้ พรอมต์เดียวกันอาจสร้างเอาต์พุตแตกต่างกันในแต่ละครั้ง ทำให้แนวทางการทดสอบมาตรฐานเพียงอย่างเดียวไม่เพียงพอ

ความไม่กำหนดผลลัพธ์: อินพุตเดียวกัน เอาต์พุตต่างกัน

LLM มีลักษณะเป็นความน่าจะเป็นโดยธรรมชาติ พารามิเตอร์ temperature ควบคุมความสุ่ม แม้จะตั้งค่าเป็น temperature=0 เอาต์พุตก็ยังอาจแตกต่างกันระหว่างรุ่นของโมเดลหรือการเปลี่ยนแปลงโครงสร้างพื้นฐาน

นั่นหมายความว่าการทดสอบเอเจนต์ที่ผ่านในวันนี้อาจล้มเหลวในวันพรุ่งนี้ได้ แม้จะไม่มีการเปลี่ยนแปลงโค้ด

import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

# Same prompt, potentially different outputs each run
for i in range(3):
    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': 'Name a planet.'}],
        temperature=0.9  # High randomness
    )
    print(f'Run {i+1}: {response.choices[0].message.content}')
# Run 1: Mars
# Run 2: Jupiter
# Run 3: Saturn

ปัญหาด้านต้นทุน: การเรียกใช้ LLM จริงมีค่าใช้จ่ายสูง

การเรียกใช้ชุดการทดสอบที่ส่งคำขอเอพีไอจริงไปยัง OpenAI หรือแอนโทรปิกอาจมีค่าใช้จ่ายหลายดอลลาร์ต่อการเรียกใช้หนึ่งครั้ง กระบวนการซีไอที่ทำการทดสอบ 100 รายการ × 10 รอบอาจมีค่าใช้จ่ายหลายร้อยดอลลาร์ต่อเดือน

ด้วยเหตุนี้จึงไม่เหมาะที่จะเรียกใช้การทดสอบเอเจนต์ในแบบเดียวกับการทดสอบหน่วย คุณจำเป็นต้องมีกลยุทธ์ควบคุมค่าใช้จ่าย

# A test that calls the real API costs tokens every run
# 100 tests x 500 tokens each x 10 CI runs/day = 500,000 tokens/day
# At $0.15/1M tokens (gpt-4o-mini): ~$0.075/day = ~$27/year for a tiny suite
# For gpt-4o: 15x more expensive = ~$400/year

# This is why mocking and recording API responses is essential
print('Real API calls in tests = expensive and slow')
print('Solution: Mock or record LLM responses in unit tests')
print('Reserve real calls for scheduled integration tests')

ปัญหาด้านเวลาแฝง

การเรียกใช้เอพีไอ LLM จริงมักใช้เวลา 2-20 วินาที ชุดการทดสอบที่มีการทดสอบ 50 รายการจะใช้เวลา 100-1000 วินาที การทำงานเช่นนี้ลดประสิทธิภาพของนักพัฒนาอย่างมาก เพราะการได้รับผลตอบกลับอย่างรวดเร็วเป็นคุณค่าหลักของการทดสอบที่ดี

การจำลองการเรียกใช้ LLM ทำให้การทดสอบทำงานเสร็จภายในระดับมิลลิวินาที

import time

# Simulating what a test suite looks like with real vs mocked calls
num_tests = 50

# Real API calls
real_time = num_tests * 5  # avg 5 seconds per call
print(f'With real API calls: {real_time}s = {real_time/60:.1f} minutes')

# Mocked calls
mock_time = num_tests * 0.001  # <1ms per mock
print(f'With mocked calls: {mock_time:.3f}s = nearly instant')

# Conclusion: mock in unit tests, use real calls in integration tests

การพึ่งพาภายนอกในการทดสอบเอเจนต์

เอเจนต์มักเรียกใช้เครื่องมือภายนอก เช่น เอพีไอค้นหา ฐานข้อมูล ระบบไฟล์ และเครื่องมือดึงข้อมูลจากเว็บไซต์ ในการทดสอบ สิ่งที่พึ่งพาเหล่านี้อาจ:

  • ไม่พร้อมใช้งาน เช่น เครือข่ายขัดข้องหรือเอพีไอล่ม
  • ส่งคืนข้อมูลแตกต่างกันในการเรียกใช้แต่ละครั้ง
  • มีขีดจำกัดอัตราการใช้งานที่บล็อกกระบวนการซีไอ

สิ่งเหล่านี้ต้องถูกควบคุมหรือจำลองในการทดสอบหน่วย

# An agent might call multiple external services
# Each is a potential test failure point

def agent_pipeline(query: str) -> str:
    search_results = search_web(query)       # External: Tavily/Serper API
    documents = fetch_documents(search_results)  # External: HTTP calls
    answer = llm_summarize(documents)        # External: OpenAI API
    saved = database_store(answer)           # External: PostgreSQL
    return answer

# In unit tests: mock ALL of these
# In integration tests: use sandboxed versions of real services
print('Each external call is a test reliability risk')

สิ่งที่การทดสอบหน่วยมาตรฐานถือเป็นสมมติฐาน

เฟรมเวิร์กการทดสอบหน่วยมาตรฐานอย่าง pytest ถือเป็นสมมติฐานว่า:

  • การทดสอบทำงานได้รวดเร็ว (ระดับมิลลิวินาที)
  • การทดสอบให้ผลลัพธ์ที่กำหนดแน่นอน
  • การทดสอบไม่มีผลข้างเคียงจากภายนอก
  • การทดสอบสามารถทำงานได้ในลำดับใดก็ได้

การทดสอบเอเจนต์ละเมิดสมมติฐานทั้งสี่ข้อนี้ เว้นแต่คุณจะออกแบบระบบโดยคำนึงถึงข้อจำกัดเหล่านี้ไว้โดยเฉพาะ

# Standard unit test — works perfectly for deterministic code
def add(a, b):
    return a + b

def test_add():
    assert add(2, 3) == 5  # Always passes — deterministic

# Agent 'unit test' that calls a real LLM — problematic
# def test_agent_answers_question():
#     response = agent.run('What is 2+2?')
#     assert response == '4'  # Might return 'The answer is 4' or 'Four'

print('Exact string matching fails for LLM outputs')
print('Need structural or semantic assertions instead')

พีระมิดการทดสอบสำหรับเอเจนต์

กลยุทธ์การทดสอบเอเจนต์ที่ใช้งานได้จริงควรมีลักษณะเป็นพีระมิด:

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

การตรวจสอบเชิงโครงสร้างเทียบกับเชิงความหมาย

แทนที่จะจับคู่สตริงแบบตรงตัว การทดสอบเอเจนต์ควรใช้การตรวจสอบเชิงโครงสร้าง เช่น เอเจนต์เรียกใช้เครื่องมือที่ถูกต้องหรือไม่ หรือการตรวจสอบเชิงความหมาย เช่น เอาต์พุตมีแนวคิดที่เกี่ยวข้องอยู่หรือไม่

# Fragile: exact string match
# assert response.content == 'The capital of France is Paris.'

# Better: structural assertion
# assert response.tool_calls[0]['function']['name'] == 'search_web'

# Better: semantic check
def test_capital_in_response(response_text: str) -> bool:
    key_words = ['paris', 'france', 'capital']
    lower = response_text.lower()
    return all(word in lower for word in key_words)

response = 'Paris is the capital city of France.'
print(test_capital_in_response(response))  # True

ชุดเครื่องมือประเมินผลและการใช้ LLM เป็นผู้ตัดสิน

สำหรับการประเมินคุณภาพ อุตสาหกรรมนี้ใช้แนวทางการให้ LLM เป็นผู้ตัดสิน โดยขอให้ LLM ตัวที่สองให้คะแนนเอาต์พุตของเอเจนต์ เฟรมเวิร์กอย่าง DeepEval และ RAGAS ช่วยทำให้รูปแบบนี้เป็นอัตโนมัติ

แนวทางนี้สงวนไว้สำหรับการประเมินที่มีค่าใช้จ่ายสูง ไม่ใช่การทำงานซีไอตามปกติ

import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

def llm_judge(question: str, answer: str) -> dict:
    prompt = f'Question: {question}\nAnswer: {answer}\nRate the answer 1-5 for accuracy. Reply with only a number.'
    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    score = int(response.choices[0].message.content.strip())
    return {'score': score, 'pass': score >= 4}

# result = llm_judge('What is the capital of France?', 'Paris')
# print(result)  # {'score': 5, 'pass': True}

การทดสอบการถดถอยสำหรับเอเจนต์

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

# golden_examples.py
GOLDEN_EXAMPLES = [
    {
        'input': 'Search for the weather in Paris',
        'expected_tool': 'get_weather',
        'expected_args': {'city': 'Paris'}
    },
    {
        'input': 'Calculate 15% tip on $45',
        'expected_tool': 'calculate',
        'expected_args': {'expression': '45 * 0.15'}
    }
]

def run_regressions(agent, examples: list) -> int:
    failures = 0
    for ex in examples:
        result = agent.plan(ex['input'])  # mocked LLM
        if result['tool'] != ex['expected_tool']:
            print(f'FAIL: expected {ex["expected_tool"]}, got {result["tool"]}')
            failures += 1
    return failures

# --- demo: a stub agent whose .plan() mimics an LLM's tool choice ---
class _StubAgent:
    def plan(self, text):
        if 'weather' in text.lower():
            return {'tool': 'get_weather'}
        if 'tip' in text.lower() or 'calculate' in text.lower():
            return {'tool': 'wrong_tool'}  # simulate a regression
        return {'tool': 'unknown'}

failures = run_regressions(_StubAgent(), GOLDEN_EXAMPLES)
print(f'{failures} of {len(GOLDEN_EXAMPLES)} golden examples failed')

การตั้งค่าไฟล์ทดสอบเอเจนต์พื้นฐาน

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

# tests/test_agent.py
import pytest

# Fast unit tests — run on every commit
class TestAgentTools:
    def test_tool_returns_dict(self, mock_llm):
        result = my_tool(query='test')
        assert isinstance(result, dict)
        assert 'data' in result

    def test_agent_selects_correct_tool(self, mock_llm):
        response = agent.run('Search for Python tutorials')
        assert response['tool_used'] == 'web_search'

# Slow integration tests — run nightly or on release
@pytest.mark.integration
class TestAgentIntegration:
    def test_full_pipeline_with_real_api(self):
        # Uses real OpenAI + sandboxed services
        result = agent.run('Summarize the Python docs')
        assert len(result['answer']) > 50

ตรวจสอบความเข้าใจ: เหตุใดการทดสอบเอเจนต์จึงแตกต่าง

ทดสอบความเข้าใจเกี่ยวกับความท้าทายเฉพาะของการทดสอบเอเจนต์ปัญญาประดิษฐ์

ทบทวน: เหตุใดการทดสอบเอเจนต์จึงแตกต่าง

การทดสอบเอเจนต์ AI ต้องใช้แนวคิดที่แตกต่างจากการทดสอบหน่วยมาตรฐาน:

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

ใช้พีระมิดการทดสอบ: การทดสอบหน่วยราคาถูกจำนวนมากด้วยม็อก และการทดสอบการผสานรวมที่มีค่าใช้จ่ายสูงกว่าจำนวนน้อยด้วยการเรียกใช้จริง

เริ่มต้นได้ฟรี

เรียนรู้ AI Agents ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
60
บทเรียน
239

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

บทเรียน “เหตุใดการทดสอบตัวแทนจึงแตกต่าง” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “เหตุใดการทดสอบตัวแทนจึงแตกต่าง”

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

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

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

บทเรียน “เหตุใดการทดสอบตัวแทนจึงแตกต่าง” ใช้เวลานานแค่ไหน

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

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

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

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

  1. เหตุใดการทดสอบตัวแทนจึงแตกต่าง
  2. การจำลองการเรียก LLM ในการทดสอบ
  3. การทดสอบตัวแทนโดยอิงการยืนยัน
  4. การทดสอบการผสานรวมสำหรับไปป์ไลน์ตัวแทน
← กลับไปที่ AI Agents