0Pricing
AI Agents · Leçon

Échecs courants des boucles d’agents

Boucles infinies, répétition du même appel d’outil et incapacité à parvenir à une réponse finale.

Échecs courants des boucles d’agents est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.

La boucle de l’agent et ses modes de défaillance

Une boucle d’agent s’exécute de manière répétée : raisonner → appeler un outil → observer le résultat → raisonner à nouveau. Cette boucle est puissante, mais fragile. Plusieurs modes de défaillance bien connus peuvent piéger un agent, gaspiller des jetons et ne produire aucune sortie utile.

Comprendre ces défaillances est la première étape pour s’en prémunir.

Défaillance 1 : boucles infinies

Une boucle infinie se produit lorsque l’agent appelle le même outil à plusieurs reprises avec les mêmes arguments sans progresser. Cela peut arriver lorsque l’outil renvoie un résultat inutile et que l’agent ne parvient pas à s’en sortir par son raisonnement.

# Example of an agent in an infinite loop:
# Step 1: reasoning='Need to search for Python docs'
#         tool='search_web', args={'query': 'Python documentation'}
# Step 2: reasoning='Search result was unhelpful, try again'
#         tool='search_web', args={'query': 'Python documentation'}
# Step 3: reasoning='Search result was unhelpful, try again'
#         tool='search_web', args={'query': 'Python documentation'}
# ... repeats until max_iterations or token budget is exhausted

print('Symptom: same tool + same arguments appearing repeatedly in steps')
print('Fix: detect repeated (tool, args) pairs and break the loop')

Défaillance 2 : état bloqué

Un état bloqué est une version plus subtile d’une boucle infinie. L’agent continue à raisonner et à appeler différents outils, mais ne parvient pas à converger vers une réponse finale. Il oscille entre plusieurs approches sans progresser.

# Example of a stuck agent:
# Step 1: tool='search_web', args={'query': 'topic A'}
# Step 2: tool='search_web', args={'query': 'topic B'}  # different args
# Step 3: tool='search_web', args={'query': 'topic A'}  # back to first
# Step 4: tool='read_document', args={'url': '...'}
# Step 5: tool='search_web', args={'query': 'topic A'}
# ... no FINAL_ANSWER ever produced

print('Symptom: agent takes many steps but never calls FINAL_ANSWER')
print('Fix: max_iterations guard + force final answer if limit is near')

Défaillance 3 : absence de réponse finale

Certains agents bouclent sans jamais décider que la tâche est terminée. Ils recueillent des informations, mais ne s’arrêtent jamais pour les synthétiser et les renvoyer. Cela gaspille des jetons et du temps.

# An agent that never concludes:
def run_agent_bad(query: str, max_steps: int = 20) -> str:
    for step in range(max_steps):
        action = llm_decide_action(query, history)

        if action['type'] == 'tool':
            result = execute_tool(action)
            history.append(result)
        # BUG: No check for 'final_answer' type!
        # The agent loops until max_steps, returning None

    return None  # never actually returns an answer

# Fix: explicitly check for final_answer signal
def run_agent_good(query: str, max_steps: int = 20) -> str:
    for step in range(max_steps):
        action = llm_decide_action(query, history)
        if action['type'] == 'final_answer':
            return action['answer']  # exit cleanly
        execute_tool(action)
    return 'Reached step limit without a conclusion.'

Défaillance 4 : erreurs d’analyse des appels d’outils

Lorsque le LLM génère un JSON mal formé pour un appel de fonction, l’exécuteur d’outil ne parvient pas à l’analyser. Un agent mal programmé plante ou ignore l’étape en silence. Un agent robuste intercepte les erreurs d’analyse et renvoie l’erreur au LLM.

import json

def safe_parse_tool_call(arguments_str: str) -> dict:
    try:
        return json.loads(arguments_str)
    except json.JSONDecodeError as e:
        print(f'Failed to parse tool arguments: {e}')
        print(f'Raw: {arguments_str}')
        return None

def execute_step(tool_call) -> str:
    args = safe_parse_tool_call(tool_call.function.arguments)
    if args is None:
        # Feed the error back to the LLM in the next step
        return f'ERROR: Could not parse tool arguments. Raw: {tool_call.function.arguments}'
    return run_tool(tool_call.function.name, args)

Défaillance 5 : l’outil ne renvoie aucune donnée utile

Un outil peut réussir sur le plan technique (sans exception), tout en renvoyant des données vides ou inutiles. L’agent doit gérer ce cas et ne pas supposer que chaque appel d’outil renvoie des informations exploitables.

def run_agent_with_empty_result_handling(query: str) -> str:
    for step in range(20):
        action = decide_next_action(query, history)

        if action['type'] == 'final_answer':
            return action['answer']

        result = execute_tool(action['tool'], action['args'])

        # Detect empty results and provide context
        if not result or result.strip() == '':
            observation = f'Tool {action["tool"]} returned no data. Try a different approach or different arguments.'
        elif 'error' in result.lower():
            observation = f'Tool error: {result}. Consider a different tool or query.'
        else:
            observation = result

        history.append({'tool': action['tool'], 'result': observation})

    return 'Could not complete task within step limit.'

Défaillance 6 : noms d’outils inventés

Les LLM génèrent parfois des noms d’outils qui n’existent pas. Validez toujours le nom de l’outil par rapport à vos outils enregistrés avant de tenter de l’appeler. Lorsque cela se produit, renvoyez une erreur explicite à l’agent.

REGISTERED_TOOLS = {
    'search_web': search_web_function,
    'get_weather': get_weather_function,
    'calculate': calculate_function
}

def dispatch_tool(tool_name: str, args: dict) -> str:
    if tool_name not in REGISTERED_TOOLS:
        available = ', '.join(REGISTERED_TOOLS.keys())
        return (
            f'ERROR: Unknown tool "{tool_name}". '
            f'Available tools: {available}. '
            f'Please use one of the available tools.'
        )

    tool_fn = REGISTERED_TOOLS[tool_name]
    return tool_fn(**args)

Défaillance 7 : épuisement du budget de jetons

Un agent qui s’exécute longtemps et conserve les résultats complets des outils dans son contexte peut atteindre la limite de la fenêtre de contexte du LLM. Résumez ou tronquez les résultats volumineux des outils avant de les ajouter à l’historique.

def truncate_tool_result(result: str, max_chars: int = 2000) -> str:
    if len(result) <= max_chars:
        return result
    truncated = result[:max_chars]
    return f'{truncated}\n... [result truncated to {max_chars} chars]'

def add_observation_to_history(history: list, tool_name: str, result: str):
    safe_result = truncate_tool_result(result, max_chars=2000)
    history.append({
        'role': 'tool',
        'content': safe_result,
        'tool_name': tool_name
    })
    print(f'[Step] Tool={tool_name}, Result length={len(result)} (stored {len(safe_result)})')

if __name__ == '__main__':
    demo_history = []
    add_observation_to_history(demo_history, 'search_web', 'x' * 3000)

Détecter le mode de défaillance par programmation

Écrivez une fonction de diagnostic qui analyse l’historique des étapes de l’agent afin d’identifier le mode de défaillance qui s’est produit. Elle est extrêmement utile pendant le débogage.

def diagnose_agent_failure(steps: list) -> str:
    if not steps:
        return 'No steps recorded'

    # Check for infinite loop: same (tool, args) repeated
    seen = {}
    for s in steps:
        key = (s.get('tool'), str(s.get('args')))
        seen[key] = seen.get(key, 0) + 1
    repeated = {k: v for k, v in seen.items() if v > 2}
    if repeated:
        return f'INFINITE_LOOP: repeated actions: {repeated}'

    # Check for missing final answer
    has_answer = any(s.get('type') == 'final_answer' for s in steps)
    if not has_answer and len(steps) >= 15:
        return 'STUCK_STATE: many steps taken but no final answer'

    # Check for parse errors
    errors = [s for s in steps if 'ERROR' in str(s.get('result', ''))]
    if len(errors) > 2:
        return f'TOOL_ERROR: {len(errors)} tool errors in pipeline'

    return 'OK'

if __name__ == '__main__':
    demo_steps = [{'tool': 'search_web', 'args': {'q': 'weather'}} for _ in range(3)]
    print('Diagnosis:', diagnose_agent_failure(demo_steps))

Implémenter un budget simple d’étapes

Toute boucle d’agent destinée à la production doit avoir une limite stricte d’étapes. Il s’agit du mécanisme de sécurité le plus important : il garantit l’arrêt de la boucle, quelle que soit la décision du LLM.

def run_agent_with_budget(query: str, max_steps: int = 15) -> dict:
    history = []
    for step in range(1, max_steps + 1):
        print(f'[Step {step}/{max_steps}]')

        action = decide_next_action(query, history)

        if action['type'] == 'final_answer':
            return {
                'status': 'success',
                'answer': action['answer'],
                'steps_taken': step
            }

        result = execute_tool(action['tool'], action['args'])
        history.append({'step': step, 'tool': action['tool'], 'result': result})

        if step == max_steps - 1:
            # Warn the agent it must conclude
            history.append({'role': 'system',
                            'content': 'You must provide a FINAL_ANSWER on the next step.'})

    return {'status': 'timeout', 'answer': None, 'steps_taken': max_steps}

Référence rapide : modes de défaillance et corrections

Résumé des six modes de défaillance des boucles d’agents et de leurs corrections :

  • Boucle infinie : détecter les paires (outil, arguments) répétées ; interrompre la boucle en renvoyant une erreur
  • État bloqué : utiliser une protection fondée sur un nombre maximal d’itérations ; forcer une réponse finale à l’approche de la limite
  • Absence de réponse finale : vérifier explicitement la présence du signal de réponse finale dans l’action
  • Erreurs d’analyse : entourer l’analyse JSON d’un bloc try/except ; renvoyer l’erreur au LLM
  • Résultats d’outil vides : détecter les chaînes vides ; fournir un retour indiquant « aucune donnée »
  • Noms d’outils inventés : valider les noms par rapport aux outils enregistrés ; renvoyer un message d’erreur

Vérification des connaissances : défaillances des boucles d’agents

Testez votre compréhension des modes de défaillance courants des boucles d’agents.

Bilan : défaillances courantes des boucles d’agents

Vous pouvez désormais identifier les principaux modes de défaillance des boucles d’agents et vous en prémunir :

  • Les boucles infinies, les états bloqués et les réponses finales manquantes nécessitent tous une protection fondée sur un nombre maximal d’itérations
  • Les erreurs d’analyse des appels d’outils nécessitent un bloc try/except autour de l’analyse JSON
  • Les résultats d’outils vides nécessitent une détection et un retour explicite au LLM
  • Les noms d’outils inventés nécessitent une validation par rapport à la liste des outils enregistrés
  • L’épuisement du budget de jetons nécessite la troncature des résultats

Une boucle d’agent robuste anticipe tous ces modes de défaillance et les gère avec élégance.

Questions Fréquemment Posées

La leçon « Échecs courants des boucles d’agents » est-elle gratuite ?

Oui — le texte complet de « Échecs courants des boucles d’agents » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Échecs courants des boucles d’agents » ?

Boucles infinies, répétition du même appel d’outil et incapacité à parvenir à une réponse finale. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Agents ?

Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Échecs courants des boucles d’agents » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?

Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Échecs courants des boucles d’agents
  2. Journalisation des traces des étapes d’un agent
  3. Détecter et interrompre les boucles infinies
  4. Techniques de débogage pas à pas
← Retour à AI Agents