AI Engineering Academy · บทเรียน

การจัดการข้อผิดพลาดและลูปของเอเจนต์

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

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

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

เหตุใดเอเจนต์จึงล้มเหลวและวนซ้ำ

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

ขีดจำกัดจำนวนรอบสูงสุด

วิธีป้องกันที่ง่ายที่สุดคือกำหนดเพดานตายตัวสำหรับจำนวนรอบ Thought/Action/Observation LangChain AgentExecutor รองรับพารามิเตอร์ max_iterations เมื่อถึงขีดจำกัด ตัวดำเนินการจะหยุดวงจรและส่งคืนข้อความที่ระบุว่าเอเจนต์ไม่สามารถทำงานให้เสร็จได้

from langchain.agents import AgentExecutor

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    max_iterations=10,             # Hard stop after 10 steps
    max_execution_time=30.0,       # Also stop after 30 wall-clock seconds
    early_stopping_method='generate',  # Ask the model for a partial answer at the limit
    verbose=True
)

การหยุดก่อนกำหนด: บังคับให้สร้างคำตอบสุดท้าย

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

# The 'generate' early_stopping_method adds this system instruction
# when max_iterations is reached:
#
# 'You have {N} steps remaining but the task is not complete.
#  Give your best final answer based on the information gathered so far.'
#
# Contrast with 'force' which abruptly terminates without generating an answer.

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    max_iterations=7,
    early_stopping_method='generate'
)

การจัดการข้อผิดพลาดในการแยกวิเคราะห์อย่างเหมาะสม

เมื่อโมเดลสร้างเอาต์พุตที่ไม่ตรงกับรูปแบบ Thought/Action — เช่น ขาดคีย์เวิร์ดการดำเนินการ ใช้ชื่อเครื่องมือผิด หรือส่งคืนข้อความอิสระ — เอเจนต์จะส่งข้อยกเว้น OutputParserException ให้ตั้งค่า handle_parsing_errors=True เพื่อป้อนข้อผิดพลาดกลับไปในฐานะข้อมูลสังเกตการณ์ ทำให้โมเดลแก้ไขตัวเองได้

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    handle_parsing_errors=True,
    # Custom error message fed back to the model:
    # handle_parsing_errors='Please format your response as Thought/Action/Action Input.'
)

# When a parse error occurs, the executor automatically adds:
# Observation: Could not parse LLM output. Please follow the format:
#   Thought: ...
#   Action: tool_name
#   Action Input: ...

การตรวจจับและหยุดวงจรซ้ำซาก

รูปแบบวงจรที่พบได้ทั่วไปคือ เอเจนต์เรียกใช้ search('same query') ติดต่อกันสามครั้ง และได้ผลลัพธ์ไร้ประโยชน์เหมือนเดิมทุกครั้ง ให้ตรวจจับวงจรโดยติดตามคู่ (เครื่องมือ, อินพุต) ล่าสุด หากชุดเดียวกันเกิดซ้ำมากกว่าสองครั้ง ให้แทรกข้อมูลสังเกตการณ์ที่เสนอแนวทางอื่น

from collections import Counter

class LoopDetector:
    def __init__(self, max_repeats: int = 2):
        self.max_repeats = max_repeats
        self.call_counts = Counter()

    def check(self, tool_name: str, tool_input: str) -> bool:
        key = f'{tool_name}:{tool_input}'
        self.call_counts[key] += 1
        if self.call_counts[key] > self.max_repeats:
            return True  # Loop detected
        return False

    def get_warning(self) -> str:
        return ('You have called this tool with the same input multiple times. '
                'Try a different approach, different search terms, or a different tool.')

การจัดการข้อผิดพลาดระดับเครื่องมือ

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

from langchain_core.tools import tool
import requests

@tool
def get_company_data(company_name: str) -> str:
    '''Retrieve company information from the business database.
    Input: company name as a string.
    '''
    try:
        resp = requests.get(
            f'https://api.example.com/companies/{company_name}',
            timeout=5
        )
        if resp.status_code == 404:
            return f'No company found with name "{company_name}". Try the exact legal name or ticker symbol.'
        if resp.status_code == 429:
            return 'Rate limit exceeded. Wait 60 seconds before trying again.'
        resp.raise_for_status()
        return resp.json().get('summary', 'No summary available.')
    except requests.Timeout:
        return 'The database is not responding. Try searching the web instead.'

การหน่วงเวลาแบบทวีคูณเมื่อ API ล้มเหลว

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

import time
import requests
from langchain_core.tools import tool

@tool
def reliable_search(query: str) -> str:
    '''Search with automatic retry on failure. Input: search query string.'''
    max_retries = 3
    for attempt in range(max_retries):
        try:
            resp = requests.get(
                'https://api.duckduckgo.com/',
                params={'q': query, 'format': 'json'},
                timeout=10
            )
            resp.raise_for_status()
            data = resp.json()
            return data.get('AbstractText', 'No results found.')
        except requests.RequestException as e:
            if attempt < max_retries - 1:
                wait = 2 ** attempt  # 1s, 2s, 4s
                time.sleep(wait)
            else:
                return f'Search failed after {max_retries} attempts: {str(e)}'

งบประมาณเวลาหมดอายุระดับเอเจนต์

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

import asyncio

async def run_with_timeout(user_input: str, timeout_seconds: float = 30.0) -> str:
    try:
        result = await asyncio.wait_for(
            agent_executor.ainvoke({'input': user_input}),
            timeout=timeout_seconds
        )
        return result['output']
    except asyncio.TimeoutError:
        return ('I am taking longer than expected to answer this question. '
                'Please try again with a simpler question, or check back later.')

การบันทึกความล้มเหลวเพื่อการวิเคราะห์

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

import logging
import json

logger = logging.getLogger('agent')

def run_and_log(user_input: str) -> str:
    try:
        result = agent_executor.invoke(
            {'input': user_input},
            return_intermediate_steps=True
        )
        if not result.get('output'):
            logger.warning('Agent returned empty output', extra={
                'input': user_input,
                'steps': len(result.get('intermediate_steps', []))
            })
        return result['output']
    except Exception as e:
        logger.error('Agent failed with exception', extra={
            'input': user_input,
            'error': str(e),
            'error_type': type(e).__name__
        })
        return 'I encountered an error. Please try rephrasing your question.'

การแทรกคำแนะนำการกู้คืนลงในพรอมต์

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

การทดสอบสถานการณ์ความล้มเหลว

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

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

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

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า max_iterations และ max_execution_time กำหนดขีดจำกัดตายตัวสำหรับเวลาทำงานของเอเจนต์ handle_parsing_errors ป้อนข้อผิดพลาดด้านรูปแบบกลับไปให้โมเดลแก้ไขตัวเอง และ เครื่องมือควรดักจับข้อยกเว้นและส่งคืนข้อความข้อผิดพลาดที่อธิบายชัดเจน แทนการโยนข้อยกเว้น ต่อไป เราจะสำรวจความสามารถในการเรียกใช้ฟังก์ชันแบบเนทีฟของ OpenAI เพื่อผสานรวมเครื่องมือที่มีโครงสร้าง

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

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

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

คอร์ส
30
บทเรียน
120

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

บทเรียน “การจัดการข้อผิดพลาดและลูปของเอเจนต์” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การจัดการข้อผิดพลาดและลูปของเอเจนต์”

เพิ่มขีดจำกัดเวลา ขีดจำกัดจำนวนรอบสูงสุด และพรอมต์กู้คืนข้อผิดพลาด เพื่อป้องกันไม่ให้เอเจนต์วนลูปไม่สิ้นสุดหรือเรียกใช้เครื่องมือที่เสียซ้ำ ๆ คุณปฏิบัติ 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. เฟรมเวิร์ก ReAct: คิด ลงมือทำ สังเกต
  2. การกำหนดเครื่องมือสำหรับ Agent
  3. การสร้าง Agent แบบ ReAct ด้วย LangChain
  4. การจัดการข้อผิดพลาดและลูปของเอเจนต์
← กลับไปที่ AI Engineering Academy