Implémentation Python du raisonnement et de la planification
Ce chapitre présente les capacités intelligentes essentielles d'un Agent IA, à savoir les capacités de raisonnement et de planification.
Contrairement aux modèles traditionnels d'exécution d'instructions, un Agent doté de capacités de raisonnement peut s'engager dans des processus de réflexion complexes.
Il peut décomposer des tâches complexes en étapes exécutables et prendre des décisions en fonction du contexte.
Framework ReAct
ReAct (Raisonnement + Action) est un framework qui combine raisonnement et action.
Dans le modèle ReAct, l'Agent alterne entre raisonnement et action, formant une boucle fermée.
Le raisonnement guide l'action, et les résultats des actions alimentent le processus de raisonnement, en répétant ce cycle.
ReAct simule le processus humain de résolution de problèmes : réfléchir avant d'agir, observer les résultats après l'action, puis continuer à raisonner à partir de nouvelles informations.
Principe de fonctionnement
L'idée centrale de ReAct peut se résumer en une boucle en trois phases :
Premièrement, la phase de raisonnement. L'agent génère la pensée d'action suivante en fonction du contexte actuel.
Deuxièmement, la phase d'action. L'agent exécute l'outil ou l'action sélectionné.
Troisièmement, la phase d'observation. L'agent reçoit le résultat de l'action, met à jour le contexte, puis revient à la première étape pour poursuivre le raisonnement.
Implémentation du code
Voici une implémentation simplifiée d'un agent ReAct :
Implémentation de base d'un agent ReAct
"""
Implémentation de l'agent du framework ReAct
Mécanisme central : raisonnement -> action -> observation -> raisonnement (boucle)
"""
def __init__(self, llm, tools, max_iterations=5):
# Instance LLM, utilisée pour le raisonnement et la génération
self.llm = llm
# Liste des outils disponibles
self.tools = tools
# Nombre maximum d'itérations pour éviter les boucles infinies
self.max_iterations = max_iterations
def run(self, task):
"""
Exécuter la boucle ReAct
:param task: Description de la tâche utilisateur
:return: Résultat d'exécution
"""
# Initialiser le contexte, y compris la tâche et les informations d'historique
context = {
"task": task,
"steps": [], # Enregistrement des étapes exécutées
"observations": [] # Enregistrement des résultats d'observation
}
for i in range(self.max_iterations):
# Phase 1 : Raisonnement - Générer l'action suivante en fonction du contexte actuel
reasoning = self.llm.reason(context)
# Déterminer si un outil doit être exécuté, ou retourner directement la réponse
if reasoning.needs_action:
# Sélectionner l'outil à utiliser
action = reasoning.select_tool(self.tools)
# Exécuter l'outil et obtenir le résultat de l'observation
observation = action.execute(reasoning.tool_input)
# Ajouter le résultat de l'observation au contexte
context["observations"].append(observation)
else:
# Aucune action nécessaire, retourner directement la réponse obtenue à partir du raisonnement
return reasoning.answer
# Nombre maximum d'itérations atteint sans avoir terminé
return "Limite maximale d'itérations atteinte"
Scénarios d'application typiques
Le modèle ReAct est particulièrement adapté aux scénarios suivants :
Tâches à accomplir après avoir exploré l'environnement et collecté des informations.
Scénario de recherche intelligente : l'Agent doit d'abord rechercher des informations, puis raisonner et résumer à partir des résultats de recherche.
Questions-réponses conversationnelles : l'Agent doit clarifier les exigences et obtenir des informations par un dialogue multi-tours.
Résolution de problèmes complexes : le problème ne peut pas être résolu en une seule étape et nécessite plusieurs étapes intermédiaires.
Remarque : l'avantage du pattern ReAct réside dans sa flexibilité, qui lui permet d'ajuster dynamiquement les actions suivantes en fonction du résultat d'exécution de chaque étape. Mais cela signifie aussi que le chemin d'exécution peut être instable, ce qui le rend adapté aux tâches nécessitant de l'exploration.
Chaîne de pensée (CoT)
La chaîne de pensée est une technique qui incite le modèle à démontrer un processus de raisonnement étape par étape.
La CoT ne demande pas au modèle de donner directement la réponse, mais le guide pour qu'il montre d'abord les étapes de raisonnement, puis parvienne à la conclusion finale.
Pourquoi la chaîne de pensée est nécessaire
Faire directement produire la réponse au modèle pose plusieurs problèmes :
Les étapes intermédiaires d'un raisonnement complexe sont facilement négligées ou omises.
Il est difficile de déterminer précisément où l'erreur s'est produite.
Les utilisateurs ne peuvent pas comprendre le processus de réflexion du modèle.
Le Chain-of-Thought résout ces problèmes en exigeant que le modèle montre son processus de raisonnement.
Zero-shot CoT
Le Zero-shot CoT est une méthode qui peut faire émerger une capacité de raisonnement étape par étape sans nécessiter d'exemples.
Ajoutez simplement une phrase de déclenchement comme « Réfléchissons étape par étape » à la fin du prompt.
Exemple de Zero-shot CoT
prompt = """
Question : Xiao Ming a 5 pommes. Xiao Hong lui en donne 3. Xiao Ming en mange 2. Combien en reste-t-il ?
Réfléchissons étape par étape :
"""
# Appeler le modèle de langage
response = llm.generate(prompt)
# Exemple de sortie du modèle :
# Étape 1 : Calculer le nombre total de pommes après que Xiao Ming les a reçues
# Xiao Ming avait initialement 5 pommes, Xiao Hong lui en a donné 3
# 5 + 3 = 8
#
# Étape 2 : Calculer le nombre restant après avoir mangé
# Xiao Ming a mangé 2
# 8 - 2 = 6
#
# Conclusion : Il reste 6 pommes
CoT Few-shot
Le CoT Few-shot aide le modèle à apprendre des schémas de raisonnement spécifiques en fournissant des exemples qui incluent des processus de raisonnement détaillés.
Lorsque le CoT Zero-shot n'est pas efficace, vous pouvez essayer le CoT Few-shot.
Exemple de CoT Few-shot
prompt = """
Exemple 1 :
Question : Xiao Zhang a 10 yuan. Il achète 3 livres à 2 yuan chacun. Combien lui reste-t-il ?
Réfléchissons étape par étape :
- Xiao Zhang avait initialement 10 yuan
- Chaque livre coûte 2 yuan, en achète 3, dépense 3 × 2 = 6 yuan
- 10 - 6 = 4 yuan
Réponse : 4 yuan restants
Exemple 2 :
Question : Un chat attrape 2 souris par heure. Combien en attrape-t-il en 8 heures ?
Réfléchissons étape par étape :
- Attrape 2 souris par heure
- En 8 heures, attrape 8 × 2 = 16
Réponse : 16 attrapées
Question : {user_question}
Réfléchissons étape par étape :
"""
response = llm.generate(prompt)
Avantages de la chaîne de pensée
La technologie de la chaîne de pensée apporte trois valeurs fondamentales :
Traçabilité : Décompose le raisonnement complexe en étapes intermédiaires traçables, ce qui rend le processus de raisonnement plus facile à comprendre.
Interprétabilité : Améliore l'interprétabilité du modèle, permettant aux utilisateurs de savoir d'où viennent les réponses.
Amélioration de la précision : Améliore considérablement la précision sur les tâches de raisonnement complexe, particulièrement efficace pour les tâches mathématiques et logiques.
Arbre de pensées(ToT)
Tree of Thoughts est une extension de Chain of Thought ; il n'est plus limité à un raisonnement linéaire.
ToT explore plusieurs chemins possibles à chaque nœud de raisonnement, formant une structure arborescente.
Cela permet à l'agent d'effectuer une exploration de chemins multiples, un retour arrière et une évaluation globale.
Différences avec Chain of Thought
CoT utilise un raisonnement linéaire, où chaque étape dépend de la conclusion de l'étape précédente, adapté aux problèmes dont les chemins sont clairs.
ToT utilise un raisonnement spatial, en considérant simultanément plusieurs branches possibles, adapté aux problèmes qui nécessitent une exploration et une planification.
Implémentation du code
Implémentation de base de l'agent ToT
"""
Implémentation de l'agent Tree of Thoughts
Mécanisme central : générer plusieurs branches candidates à chaque nœud, les évaluer, puis choisir la meilleure pour continuer.
"""
def __init__(self, llm, max_depth=4, beam_size=3):
# Instance LLM
self.llm = llm
# Profondeur de recherche maximale
self.max_depth = max_depth
# Nombre de nœuds candidats conservés par niveau (largeur du faisceau)
self.beam_size = beam_size
def solve(self, problem):
"""
Résolution de problèmes à l'aide du framework ToT
:param problem: Description du problème
:return: Solution optimale
"""
# Créer le nœud racine, contenant le problème comme état initial
root = ThoughtNode(problem, depth=0)
# Initialiser la liste des nœuds frontière (nœuds à développer)
frontier = [root]
# Développer couche par couche
for depth in range(self.max_depth):
# Stocker tous les nœuds candidats
all_candidates = []
# Parcourir tous les nœuds frontière
for node in frontier:
# Générer plusieurs prochaines étapes candidates pour le nœud actuel
candidates = self.llm.generate_thoughts(
node.content, # Contenu du nœud actuel
n=self.beam_size # Nombre de générations
)
# Créer un nouveau nœud et l'ajouter à la liste des candidats
for cand in candidates:
all_candidates.append(
ThoughtNode(cand, depth + 1, parent=node)
)
# Évaluer tous les nœuds candidats
evaluated = self.evaluator.rank(all_candidates)
# Sélectionner les meilleurs nœuds beam_size comme prochaine frontière
frontier = evaluated[:self.beam_size]
# Vérifier si une solution a été trouvée
if self.is_solution(frontier):
break
# Remonter pour trouver la solution optimale
return self.backtrack_best(frontier)
Scénarios d'application
ToT est particulièrement adapté aux scénarios qui nécessitent de faire des choix ou de planifier :
Écriture créative : Générer plusieurs directions de développement d'histoire, les évaluer, puis choisir la meilleure.
Planification stratégique : Évaluer les résultats potentiels de plusieurs plans d'action.
Prise de décision complexe : Problèmes de décision qui nécessitent de considérer plusieurs possibilités.
Planification de tâches et MCTS
La recherche arborescente Monte-Carlo (MCTS) est un algorithme de recherche heuristique utilisé pour les problèmes de décision complexes.
MCTS a de nombreuses applications dans la planification d'agents, particulièrement adapté à l'IA de jeu et à la planification de tâches complexes.
Idée centrale
MCTS évalue la valeur potentielle de chaque nœud de décision en simulant des parties aléatoires.
Il n'a pas besoin d'évaluer tous les chemins possibles, mais utilise l'échantillonnage et les statistiques pour guider la direction de recherche.
Quatre étapes de MCTS
Étape 1, Sélection : En partant du nœud racine, sélectionner récursivement le nœud enfant optimal jusqu'à atteindre un nœud feuille.
Lors de la sélection, la formule UCB (Upper Confidence Bound) est utilisée pour équilibrer l'exploration et l'exploitation.
Étape 2, Expansion : Ajouter un ou plusieurs nœuds enfants au nœud feuille.
Étape 3, Simulation : À partir du nouveau nœud, simuler aléatoirement la partie jusqu'à la fin.
Étape 4, Rétropropagation : Mettre à jour les statistiques de tous les nœuds le long du chemin de simulation.
Implémentation du code
Implémentation du planificateur MCTS
class MCTSNode:
"""
Nœud de l'arbre MCTS
Stocke l'état du nœud, les statistiques et les relations entre nœuds enfants
"""
def __init__(self, state, parent=None, action=None):
# État actuel
self.state = state
# Référence du nœud parent
self.parent = parent
# Action du nœud parent vers ce nœud
self.action = action
# Liste des nœuds enfants
self.children = []
# Nombre de visites de ce nœud
self.visit_count = 0
# Valeur de récompense cumulée de ce nœud
self.reward = 0.0
def is_fully_expanded(self):
"""Vérifie si tous les nœuds enfants possibles ont été étendus"""
return len(self.children) > 0
def is_terminal(self):
"""Vérifie s'il s'agit d'un nœud terminal (fin de partie ou objectif atteint)"""
return self.state.is_terminal()
def uct_child(self):
"""
Utiliser la formule UCT pour sélectionner le nœud enfant optimal
UCT = reward/visits + C * sqrt(ln(parent_visits)/visits)
C est la constante d'exploration, généralement fixée à sqrt(2)
"""
# Constante d'exploration, équilibrant exploration et exploitation
C = math.sqrt(2)
return max(
self.children,
key=lambda c: c.reward / c.visit_count +
C * math.sqrt(math.log(self.visit_count) / c.visit_count)
)
class MCTSPlanner:
"""
Planificateur MCTS
Utilise la recherche arborescente Monte-Carlo pour générer des plans d'action pour l'Agent
"""
def __init__(self, simulation_limit=1000, exploration_constant=1.41):
# Nombre maximum de simulations
self.simulation_limit = simulation_limit
# Constante d'exploration
self.exploration_constant = exploration_constant
def plan(self, initial_state):
"""
Commencer la planification à partir de l'état initial
:param initial_state: état initial
:return: action optimale
"""
# Créer le nœud racine
root = MCTSNode(initial_state)
# Effectuer plusieurs simulations
for _ in range(self.simulation_limit):
# 1. Sélection : Sélectionner le nœud enfant optimal depuis le nœud racine en descendant jusqu'à atteindre un nœud feuille
node = self._selection(root)
# 2. Expansion : Si ce n'est pas un nœud terminal, développer un nouveau nœud
if not node.is_terminal():
node = self._expansion(node)
# 3. Simulation : simuler aléatoirement depuis le nouveau nœud jusqu'au terminal
reward = self._simulation(node)
# 4. Rétropropagation : mettre à jour les statistiques de tous les nœuds du chemin
self._backpropagation(node, reward)
# Renvoyer l'action correspondant au nœud enfant optimal du nœud racine
return root.best_child().action
def _selection(self, node):
"""Phase de sélection : sélectionner le nœud enfant optimal"""
while node.is_fully_expanded() and not node.is_terminal():
node = node.uct_child()
return node
def _expansion(self, node):
"""Phase d'expansion : ajouter un nouveau nœud enfant"""
# Générer toutes les actions possibles
possible_actions = node.state.get_possible_actions()
# Créer un nœud enfant pour chaque action
for action in possible_actions:
new_state = node.state.apply_action(action)
child = MCTSNode(new_state, parent=node, action=action)
node.children.append(child)
# Retourner un nœud enfant aléatoire (ou utiliser une stratégie déterministe)
return node.children[0]
def _simulation(self, node):
"""Phase de simulation : simuler aléatoirement jusqu'à ce que le jeu se termine"""
state = node.state
while not state.is_terminal():
# Choisir une action aléatoirement
actions = state.get_possible_actions()
action = random.choice(actions)
state = state.apply_action(action)
# Renvoyer la récompense finale
return state.get_reward()
def _backpropagation(self, node, reward):
"""Rétropropagation : mettre à jour les statistiques"""
while node is not None:
node.visit_count += 1
node.reward += reward
node = node.parent
Remarque : MCTS a un coût de calcul élevé et convient aux scénarios qui nécessitent une planification approfondie mais ont des conditions d'arrêt claires. Pour les tâches avec des exigences élevées en temps réel, il peut être nécessaire de limiter le nombre de simulations ou d'utiliser d'autres méthodes.
Reflexion (auto-réflexion)
Reflexion est une technique qui donne à un agent des capacités d'auto-réflexion.
En ajoutant un mécanisme de réflexion à l'Agent, celui-ci peut, après un échec, analyser les causes de cet échec, ajuster sa stratégie et réessayer.
Idée centrale
L'Agent n'exécute pas seulement des actions, mais observe aussi les résultats et réfléchit : Pourquoi ai-je échoué ? Comment devrais-je m'améliorer la prochaine fois ?
Cette capacité est cruciale pour l'apprentissage continu et l'auto-amélioration.
Implémentation du code
Implémentation de l'Agent Reflexion
"""
Un agent doté d'une capacité d'auto-réflexion
Mécanisme principal : Exécuter -> Évaluer -> Réfléchir -> Réessayer
"""
def __init__(self, actor, reviewer, max_retries=3):
# Exécuteur : responsable de l'exécution de tâches spécifiques
self.actor = actor
# Évaluateur : responsable de l'évaluation des résultats d'exécution
self.reviewer = reviewer
# Nombre maximal de tentatives
self.max_retries = max_retries
def run(self, task):
"""
Exécuter la tâche avec auto-réflexion
:param task: description de la tâche
:return: résultat d'exécution
"""
# Maintenir l'historique d'exécution
history = []
for attempt in range(self.max_retries):
# Phase 1 : Tentative d'exécution de la tâche
result = self.actor.execute(task, history)
# Enregistrer cette tentative
history.append({
"attempt": attempt,
"result": result
})
# Phase 2 : Évaluer le résultat
feedback = self.reviewer.evaluate(task, result)
# Phase 3 : Vérifier si cela a réussi
if feedback.is_success:
return result
# Phase 4 : Réfléchir à la cause de l'échec
# Générer un nouveau prompt de stratégie pour guider la prochaine tentative
reflection = self.reviewer.reflect(
task, # Tâche originale
result, # Résultat échoué
feedback # Retour d'évaluation
)
# Ajouter le résultat de la réflexion à l'historique pour référence lors de la prochaine tentative
history.append({
"type": "reflection",
"content": reflection
})
# Si toutes les tentatives échouent, retourner l'historique
return history
class Reviewer:
"""Évaluateur : évaluer les résultats d'exécution et générer des réflexions"""
def evaluate(self, task, result):
"""
Évaluer le résultat de l'exécution
:return: un objet contenant si cela a réussi et un retour détaillé
"""
# Vérifier si le résultat répond aux exigences de la tâche
is_success = self.check_success(task, result)
if is_success:
return EvaluationResult(is_success=True)
else:
# Générer une analyse des causes d'échec
failure_reasons = self.analyze_failures(task, result)
return EvaluationResult(
is_success=False,
reasons=failure_reasons
)
def reflect(self, task, result, feedback):
"""
Générer le contenu de réflexion
Aider l'Actor à comprendre la cause de l'échec et à améliorer sa stratégie
"""
prompt = f"""
Tâche : {task}
Résultat de l'exécution : {result}
Raisons de l'échec : {feedback.reasons}
Veuillez analyser les causes de l'échec et fournir des suggestions d'amélioration.
Points clés :
1. Qu'est-ce qui n'a pas fonctionné ?
2. Comment l'éviter la prochaine fois ?
3. Quelle stratégie doit être modifiée ?
"""
return self.llm.generate(prompt)
Scénarios d'application
Reflexion convient particulièrement aux scénarios suivants :
Tâches qui nécessitent une amélioration continue, telles que les systèmes de dialogue, la génération de code, etc.
Scénarios où le coût des erreurs est élevé, mais où le coût d'une nouvelle tentative est faible.
Situations dans lesquelles il est nécessaire d'apprendre de l'échec.
Stratégies de décomposition des tâches
Les tâches complexes doivent généralement être décomposées en sous-tâches gérables.
Une décomposition efficace des tâches est le fondement de la capacité de planification.
Décomposition récursive des tâches
Décomposer récursivement une tâche en sous-tâches plus petites jusqu'à ce que les sous-tâches puissent être exécutées directement.
Décomposition récursive des tâches
"""
Décomposer récursivement les tâches
:param task: La tâche à décomposer
:param is_executable_fn: Fonction pour déterminer si la tâche peut être exécutée directement
:param decompose_fn: Fonction pour décomposer la tâche
:return: Liste des tâches exécutables
"""
# Si la tâche peut être exécutée directement, la retourner directement
if is_executable_fn(task):
return [task]
# Décomposer la tâche en sous-tâches
subtasks = decompose_fn(task)
# Décomposer récursivement chaque sous-tâche
result = []
for subtask in subtasks:
# Appeler récursivement la fonction de décomposition sur les sous-tâches
result.extend(
decompose(subtask, is_executable_fn, decompose_fn)
)
return result
# Exemple : déterminer si la tâche est exécutable
def is_code_complete(task):
"""Vérifier si la tâche peut exécuter directement du code"""
return task.get("type") == "code" and len(task.get("dependencies", [])) == 0
# Exemple : Décomposer une tâche complexe
def decompose_programming_task(task):
"""Décomposer une tâche de programmation"""
if "write_function" in task["type"]:
return [
{"type": "understand_requirements", "task": task["spec"]},
{"type": "write_code", "spec": task["spec"]},
{"type": "write_tests", "function": task["function_name"]},
{"type": "verify_tests", "function": task["function_name"]}
]
return [task]
Décomposition parallèle des tâches
Identifier les sous-tâches indépendantes qui peuvent être exécutées en parallèle afin d'améliorer l'efficacité d'exécution.
Il s'agit d'une stratégie clé pour accélérer l'exécution des tâches.
Décomposition hiérarchique des tâches
Diviser les tâches en différents niveaux d'abstraction ; les tâches de haut niveau appellent les tâches de bas niveau, formant un arbre hiérarchique de tâches.
Convient aux systèmes complexes qui nécessitent plusieurs niveaux d'abstraction.
Patron Plan-and-Execute
Plan-and-Execute est un patron d'architecture qui sépare la planification de l'exécution.
L'agent planifie d'abord entièrement l'ensemble du flux de tâches, puis exécute selon le plan.
Différences avec ReAct
ReAct entrelace raisonnement et exécution, ce qui est plus flexible, mais le chemin peut être instable.
Plan-and-Execute planifie d'abord puis exécute, ce qui est plus stable, mais manque de capacité d'ajustement dynamique.
Implémentation du code
Implémentation de l'agent Plan-and-Execute
"""
Agent avec architecture Plan-and-Execute
Mécanisme principal : planifier complètement d'abord, puis exécuter selon le plan
"""
def __init__(self, planner, executor):
# Planificateur : responsable de la création du plan d'exécution
self.planner = planner
# Exécuteur : responsable de l'exécution des étapes spécifiques
self.executor = executor
def run(self, task):
"""
Exécuter la tâche
Divisé en phase de planification et phase d'exécution
"""
# ==================== Phase de planification ====================
# Générer le plan d'exécution complet en une seule fois
plan = self.planner.create_plan(task)
# ==================== Phase d'exécution ====================
results = []
# Exécuter dans l'ordre selon le plan
for step in plan.steps:
# Exécuter l'étape actuelle
result = self.executor.execute(step)
results.append(result)
# Vérifier si une replanification est nécessaire
# Par exemple : les résultats d'exécution ne correspondent pas aux attentes, ou des situations inattendues se produisent
if self.needs_replan(results):
# Replanifier en fonction des résultats actuels
plan = self.planner.replan(task, results)
# Intégrer tous les résultats
return self.summarize(results)
def needs_replan(self, results):
"""
Déterminer si une replanification est nécessaire
Vérifier si les résultats d'exécution correspondent aux attentes
"""
# Obtenir le dernier résultat
last_result = results[-1]
# Si le résultat ne correspond clairement pas aux attentes, une replanification est nécessaire
if last_result.is_unexpected():
return True
# Si le résultat rend les étapes suivantes impossibles à exécuter, une replanification est nécessaire
if last_result.blocks_future():
return True
return False
class Planner:
"""Planner : générer un plan d'exécution des tâches"""
def create_plan(self, task):
"""Créer le plan d'exécution initial"""
prompt = f"""
Tâche : {task}
Veuillez créer un plan d'exécution détaillé, comprenant :
1. L'ordre des étapes à exécuter
2. Les opérations spécifiques pour chaque étape
3. Les relations de dépendance entre les étapes
Format de sortie :
Étape 1 : [Description de l'opération]
Étape 2 : [Description de l'opération]
...
"""
plan_text = self.llm.generate(prompt)
return Plan.parse(plan_text)
def replan(self, task, results):
"""Replanifier en fonction des résultats d'exécution"""
# Analyser les résultats terminés
completed = [r for r in results if r.is_success]
failed = [r for r in results if not r.is_success]
# Générer un plan ajusté
prompt = f"""
Tâche originale : {task}
Étapes terminées : {completed}
Étapes échouées : {failed}
Veuillez créer un plan d'exécution ajusté :
"""
plan_text = self.llm.generate(prompt)
return Plan.parse(plan_text)
class Executor:
"""Executor: exécuter les étapes spécifiques du plan"""
def execute(self, step):
"""Exécuter une seule étape"""
# Choisir la méthode d'exécution en fonction du type d'étape
if step.type == "tool_call":
return self.execute_tool_call(step)
elif step.type == "code":
return self.execute_code(step)
elif step.type == "query":
return self.execute_query(step)
return Result(success=False, error="Type d'étape inconnu")
Remarque : Le mode Plan-and-Execute convient aux scénarios où la structure de la tâche est relativement stable et peut être planifiée à l'avance. Pour les environnements nécessitant une adaptation flexible, le mode ReAct peut être plus approprié.
Résumé du chapitre
Ce chapitre présente les capacités essentielles de raisonnement et de planification des agents IA.
ReActLe framework permet à l'Agent d'ajuster sa stratégie pendant l'exécution via une boucle de raisonnement et d'action.
Chaîne de pensée (CoT)Améliore la précision de l'exécution de tâches complexes en démontrant le processus de raisonnement étape par étape.
Arbre de pensées (ToT)A étendu la chaîne de pensée, en prenant en charge l'exploration multi-chemins et le retour en arrière.
MCTSIl s'agit d'un algorithme de recherche heuristique, adapté aux problèmes complexes de prise de décision et de planification.
RéflexionDoter l'Agent de capacités d'autoréflexion pour apprendre et s'améliorer à partir des échecs.
Stratégie de décomposition des tâchesC'est le fondement de la capacité de planification, incluant la décomposition récursive, la décomposition parallèle et la décomposition hiérarchique.
Planifier-et-ExécuterAdopte une approche consistant à planifier d'abord puis à exécuter, adaptée aux tâches aux structures stables.
Ces technologies peuvent être utilisées seules ou en combinaison pour construire des systèmes d'Agent plus puissants.
Autres extensions