0Pricing
AI Agents · บทเรียน

การวิเคราะห์สาเหตุรากของความล้มเหลวของเอเจนต์

การจัดหมวดหมู่ความล้มเหลวอย่างเป็นระบบ: ข้อผิดพลาดของโมเดล เครื่องมือ ข้อมูล และตรรกะ

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

อนุกรมวิธานความล้มเหลวของเอเจนต์

ความล้มเหลวของเอเจนต์แบ่งเป็นสี่ประเภท:

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

ข้อผิดพลาดของโมเดล: การเรียกใช้เครื่องมือผิดรายการ

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

import openai
import json

client = openai.OpenAI(api_key='sk-...')

def detect_model_errors(response) -> list:
    errors = []
    message = response.choices[0].message
    
    if message.tool_calls:
        for tc in message.tool_calls:
            tool_name = tc.function.name
            try:
                args = json.loads(tc.function.arguments)
            except json.JSONDecodeError as e:
                errors.append({
                    'type': 'model_error',
                    'subtype': 'malformed_tool_args',
                    'tool': tool_name,
                    'raw_args': tc.function.arguments,
                    'parse_error': str(e)
                })
                continue
            
            # Validate required arguments
            expected_tools = {
                'search_web': ['query'],
                'send_email': ['to', 'subject', 'body'],
                'create_task': ['title']
            }
            required = expected_tools.get(tool_name, [])
            missing = [r for r in required if r not in args]
            if missing:
                errors.append({
                    'type': 'model_error',
                    'subtype': 'missing_required_args',
                    'tool': tool_name,
                    'missing': missing
                })
    return errors

print('Model error detection function defined')

ข้อผิดพลาดของเครื่องมือ: ความล้มเหลวของส่วนเชื่อมต่อโปรแกรมประยุกต์

ข้อผิดพลาดของเครื่องมือเกิดขึ้นเมื่อส่วนเชื่อมต่อโปรแกรมประยุกต์ภายนอกส่งคืน error (4xx, 5xx) หมดเวลา หรือส่งคืนข้อมูลในรูปแบบที่ไม่คาดคิด ให้บันทึก error ที่เกิดขึ้นจริง อาร์กิวเมนต์ของเครื่องมือ และการตอบกลับไว้เพื่อการวินิจฉัย

import httpx
from dataclasses import dataclass
from typing import Optional

@dataclass
class ToolError:
    tool_name: str
    error_type: str
    status_code: Optional[int]
    message: str
    args_used: dict
    retry_possible: bool

def classify_tool_error(tool_name: str, args: dict, exception: Exception) -> ToolError:
    if isinstance(exception, httpx.TimeoutException):
        return ToolError(
            tool_name=tool_name,
            error_type='timeout',
            status_code=None,
            message=str(exception),
            args_used=args,
            retry_possible=True  # Retries are appropriate for timeouts
        )
    elif isinstance(exception, httpx.HTTPStatusError):
        status = exception.response.status_code
        retry = status >= 500 or status == 429  # Server errors and rate limits are retryable
        return ToolError(
            tool_name=tool_name,
            error_type='http_error',
            status_code=status,
            message=exception.response.text[:200],
            args_used=args,
            retry_possible=retry
        )
    else:
        return ToolError(
            tool_name=tool_name,
            error_type='unexpected_error',
            status_code=None,
            message=str(exception),
            args_used=args,
            retry_possible=False
        )

print('Tool error classification defined')

ข้อผิดพลาดของข้อมูล: การตรวจสอบ input

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

from pydantic import BaseModel, validator, ValidationError
from typing import Optional

class EmailAgentInput(BaseModel):
    email_id: str
    action: str
    user_id: int
    priority: Optional[str] = 'normal'
    
    @validator('action')
    def action_must_be_valid(cls, v):
        valid_actions = ['reply', 'forward', 'archive', 'summarize']
        if v not in valid_actions:
            raise ValueError(f'action must be one of {valid_actions}, got: {v}')
        return v
    
    @validator('email_id')
    def email_id_not_empty(cls, v):
        if not v.strip():
            raise ValueError('email_id cannot be empty')
        return v

def validate_agent_input(raw_input: dict) -> tuple:
    try:
        validated = EmailAgentInput(**raw_input)
        return validated, None
    except ValidationError as e:
        return None, [
            {'field': err['loc'][0], 'message': err['msg']}
            for err in e.errors()
        ]

# Test with bad input
valid, errors = validate_agent_input({'email_id': '', 'action': 'delete', 'user_id': 'abc'})
if errors:
    print('Data errors found:')
    for err in errors:
        print(f'  {err["field"]}: {err["message"]}')

ข้อผิดพลาดทางตรรกะ: ลำดับ Step ไม่ถูกต้อง

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

import logging

logger = logging.getLogger('agent.logic')

class AgentStepGuard:
    '''
    Enforces that steps execute in the required sequence.
    '''
    def __init__(self):
        self.completed_steps = set()
        self.STEP_DEPENDENCIES = {
            'extract_action_items': ['read_email'],
            'create_trello_card': ['extract_action_items'],
            'send_slack_notification': ['create_trello_card']
        }
    
    def mark_complete(self, step_name: str):
        self.completed_steps.add(step_name)
    
    def can_run(self, step_name: str) -> tuple:
        required = self.STEP_DEPENDENCIES.get(step_name, [])
        missing = [r for r in required if r not in self.completed_steps]
        if missing:
            return False, f'Logic error: {step_name} requires {missing} to complete first'
        return True, None
    
    def assert_can_run(self, step_name: str):
        ok, error = self.can_run(step_name)
        if not ok:
            logger.error(error)
            raise RuntimeError(error)

guard = AgentStepGuard()
# Simulate trying to skip a step
try:
    guard.assert_can_run('create_trello_card')
except RuntimeError as e:
    print('Caught logic error:', e)

# Correct sequence
guard.mark_complete('read_email')
guard.mark_complete('extract_action_items')
guard.assert_can_run('create_trello_card')  # Now allowed
print('Step sequence valid')

การบันทึก Error แบบมีโครงสร้าง

บันทึก error ทุกครั้งพร้อมบริบทที่เพียงพอสำหรับการวิเคราะห์ภายหลัง ได้แก่ ประเภทของ error ลำดับการเรียกใช้ทั้งหมด input ของ Step และสถานะที่เกี่ยวข้องของเอเจนต์ในขณะที่เกิดความล้มเหลว

import logging
import traceback
import json
from datetime import datetime

logger = logging.getLogger('agent.errors')

def log_agent_error(error_type: str, step: str, inputs: dict, exception: Exception, agent_state: dict = None):
    error_record = {
        'timestamp': datetime.utcnow().isoformat(),
        'error_type': error_type,
        'step': step,
        'exception_type': type(exception).__name__,
        'exception_message': str(exception),
        'traceback': traceback.format_exc(),
        'inputs': inputs,
        'agent_state': agent_state or {}
    }
    logger.error(json.dumps(error_record))
    return error_record

# Example usage
try:
    raise ValueError('Email ID not found in database')
except Exception as e:
    record = log_agent_error(
        error_type='data_error',
        step='read_email',
        inputs={'email_id': 'missing-id-123'},
        exception=e,
        agent_state={'user_id': 42, 'session_id': 'sess-abc'}
    )
    print('Error logged:', record['error_type'], '-', record['exception_message'])

การตรวจสอบอัตรา Error

ติดตามอัตรา error แยกตาม Step และประเภทของ error เพื่อระบุปัญหาเชิงระบบ การพุ่งสูงขึ้นอย่างฉับพลันของ error จากโมเดลอาจบ่งชี้ว่าการเปลี่ยนพรอมต์ทำให้การเรียกใช้เครื่องมือเสียหาย ส่วนการพุ่งสูงขึ้นของ error จากเครื่องมืออาจบ่งชี้ว่าส่วนเชื่อมต่อโปรแกรมประยุกต์มีประสิทธิภาพลดลง

from collections import defaultdict
from datetime import datetime

class ErrorTracker:
    def __init__(self):
        self.errors = defaultdict(list)
    
    def record(self, error_type: str, step: str):
        key = f'{error_type}:{step}'
        self.errors[key].append(datetime.utcnow())
    
    def get_rates(self, window_minutes: int = 60) -> dict:
        from datetime import timedelta
        cutoff = datetime.utcnow() - timedelta(minutes=window_minutes)
        rates = {}
        for key, timestamps in self.errors.items():
            recent = [ts for ts in timestamps if ts >= cutoff]
            rates[key] = len(recent)
        return dict(sorted(rates.items(), key=lambda x: x[1], reverse=True))
    
    def has_spike(self, error_type: str, step: str, threshold: int = 5, window_minutes: int = 10) -> bool:
        key = f'{error_type}:{step}'
        rates = self.get_rates(window_minutes)
        return rates.get(key, 0) >= threshold

tracker = ErrorTracker()
for _ in range(8):
    tracker.record('tool_error', 'web_search')
tracker.record('model_error', 'intent_detection')

print('Error rates:', tracker.get_rates())
print('Spike detected:', tracker.has_spike('tool_error', 'web_search'))

การแก้ไขข้อผิดพลาดของโมเดลด้วยการเล่นซ้ำ

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

import openai
import json

client = openai.OpenAI(api_key='sk-...')

def save_failed_call(step_name: str, messages: list, tools: list, actual_response: str, expected_tool: str, filepath: str):
    record = {
        'step': step_name,
        'messages': messages,
        'tools': tools,
        'actual_response': actual_response,
        'expected_tool': expected_tool
    }
    with open(filepath, 'w') as f:
        json.dump(record, f, indent=2)
    print(f'Failed call saved to: {filepath}')

def replay_failed_call(filepath: str, improved_system_prompt: str = None) -> str:
    with open(filepath) as f:
        record = json.load(f)
    
    messages = record['messages']
    if improved_system_prompt:
        # Replace system prompt
        messages = [m if m['role'] != 'system' else {'role': 'system', 'content': improved_system_prompt}
                   for m in messages]
    
    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        tools=record['tools']
    )
    return response.choices[0].message

print('Replay debugging functions defined')

รายการตรวจสอบการวิเคราะห์สาเหตุราก

เมื่อเอเจนต์ล้มเหลว ให้ดำเนินการตามรายการตรวจสอบนี้อย่างเป็นระบบ:

  • input ถูกต้องหรือไม่ (ข้อผิดพลาดของข้อมูล)
  • มีส่วนเชื่อมต่อโปรแกรมประยุกต์ภายนอกใดส่งคืน error หรือไม่ (ข้อผิดพลาดของเครื่องมือ)
  • LLM เรียกใช้เครื่องมือที่ถูกต้องหรือไม่ อาร์กิวเมนต์ถูกต้องหรือไม่ (ข้อผิดพลาดของโมเดล)
  • Step ทำงานตามลำดับที่ถูกต้องหรือไม่ (ข้อผิดพลาดทางตรรกะ)
  • พรอมต์มีบริบทเพียงพอหรือไม่ (ข้อผิดพลาดของโมเดล - บริบท)
def diagnose_failure(error_log: dict) -> dict:
    diagnosis = {
        'error_type': error_log.get('error_type'),
        'root_cause': None,
        'immediate_fix': None,
        'long_term_fix': None
    }
    
    if error_log.get('error_type') == 'data_error':
        diagnosis['root_cause'] = 'Invalid or missing input data'
        diagnosis['immediate_fix'] = 'Return clear error to caller with field-level validation feedback'
        diagnosis['long_term_fix'] = 'Add Pydantic validation at agent entry point'
    
    elif error_log.get('error_type') == 'tool_error':
        status = error_log.get('status_code')
        if status == 429:
            diagnosis['root_cause'] = 'Rate limit hit'
            diagnosis['immediate_fix'] = 'Retry with exponential backoff'
            diagnosis['long_term_fix'] = 'Add rate limiter to tool calls'
        elif status and status >= 500:
            diagnosis['root_cause'] = 'Upstream service degradation'
            diagnosis['immediate_fix'] = 'Retry up to 3 times, then graceful degradation'
            diagnosis['long_term_fix'] = 'Add circuit breaker pattern'
    
    elif error_log.get('error_type') == 'model_error':
        diagnosis['root_cause'] = 'LLM tool selection failure'
        diagnosis['immediate_fix'] = 'Add explicit tool selection validation'
        diagnosis['long_term_fix'] = 'Improve tool descriptions; add few-shot examples'
    
    return diagnosis

result = diagnose_failure({'error_type': 'tool_error', 'status_code': 429})
print('Diagnosis:', result)

การแจ้งเตือนความล้มเหลวร้ายแรง

ไม่ใช่ error ทุกประเภทที่ต้องดำเนินการทันที จัดประเภท error ตามระดับความรุนแรงและส่งการแจ้งเตือนไปยังปลายทางที่เหมาะสมตามประเภทนั้น ข้อผิดพลาดของข้อมูลที่ไม่สำคัญในกระบวนการที่ไม่สำคัญอาจบันทึกไว้ได้ ส่วนกระบวนการหลักที่เสียหายต้องแจ้งเตือนทันที

ERROR_SEVERITY = {
    'data_error': 'low',      # Bad input: log and return error to caller
    'model_error': 'medium',  # LLM misbehavior: investigate, may need prompt fix
    'tool_error': 'medium',   # API failure: may self-recover with retry
    'logic_error': 'high'     # Sequencing bug: needs code fix immediately
}

def route_alert(error_type: str, step: str, message: str, is_core_flow: bool = False):
    severity = ERROR_SEVERITY.get(error_type, 'medium')
    if is_core_flow:
        severity = 'high'
    
    if severity == 'high':
        print(f'[PAGERDUTY] CRITICAL: {error_type} in {step}: {message}')
        # Call PagerDuty API here
    elif severity == 'medium':
        print(f'[SLACK] WARNING: {error_type} in {step}: {message}')
        # Call Slack API here
    else:
        print(f'[LOG] INFO: {error_type} in {step}: {message}')

route_alert('logic_error', 'create_trello_card', 'Prerequisites not met', is_core_flow=True)
route_alert('data_error', 'parse_input', 'Missing optional field', is_core_flow=False)

แม่แบบการวิเคราะห์ภายหลังเหตุการณ์

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

def generate_post_mortem(failure_data: dict) -> str:
    return f'''
## Post-Mortem: {failure_data.get("title", "Agent Failure")}

**Date**: {failure_data.get("date")}
**Duration**: {failure_data.get("duration_minutes")} minutes
**Impact**: {failure_data.get("impact")}

### Timeline
{chr(10).join(failure_data.get("timeline", []))}

### Root Cause
{failure_data.get("root_cause")}

### Contributing Factors
{chr(10).join(failure_data.get("contributing_factors", []))}

### Action Items
{chr(10).join([f"- [ ] {item}" for item in failure_data.get("action_items", [])])}
    '''.strip()

post_mortem_data = {
    'title': 'Email Pipeline Failure - Wrong Trello List',
    'date': '2025-01-15',
    'duration_minutes': 45,
    'impact': '200 emails processed but Trello cards created in wrong list',
    'timeline': ['09:00 - Pipeline started', '09:15 - First error logged', '09:45 - Fixed and redeployed'],
    'root_cause': 'Logic error: TRELLO_LIST_ID env var defaulted to staging value in production',
    'contributing_factors': ['- Missing config validation at startup', '- No alert on wrong list ID'],
    'action_items': ['Add config validation on startup', 'Alert if list_id changes unexpectedly']
}
print(generate_post_mortem(post_mortem_data))

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

ทดสอบความเข้าใจของคุณเกี่ยวกับการวิเคราะห์สาเหตุที่แท้จริงของความล้มเหลวของเอเจนต์

สรุปการแก้ไขข้อบกพร่อง

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

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

บทเรียน “การวิเคราะห์สาเหตุรากของความล้มเหลวของเอเจนต์” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การวิเคราะห์สาเหตุรากของความล้มเหลวของเอเจนต์”

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

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

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

บทเรียน “การวิเคราะห์สาเหตุรากของความล้มเหลวของเอเจนต์” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การวิเคราะห์ร่องรอยด้วย LangSmith และ Langfuse
  2. การวิเคราะห์โทเคนและต้นทุนแยกตามขั้นตอน
  3. การระบุขั้นตอนที่ช้าและมีค่าใช้จ่ายสูง
  4. การวิเคราะห์สาเหตุรากของความล้มเหลวของเอเจนต์
← กลับไปที่ AI Agents