Llama Agents est un framework asynchrone pour construire, itérer et mettre en production des systèmes multi-agents, incluant la communication multi-agent, l’exécution d’outils distribués, l’interaction humaine, et bien plus encore !
Dans Llama Agents, chaque agent est considéré comme un réacteur, traitant sans fin les tâches entrantes. Chaque agent tire et publie des messages à partir d’une file d’attente.
Au sommet d’un système Llama Agents se trouve le plan de contrôle. Le plan de contrôle garde une trace des tâches en cours, des services présents dans le réseau, et décide également quel service devrait gérer l’étape suivante d’une tâche en utilisant un orchestrateur.
L’agencement global du système est illustré ci-dessous.
Llama Agents peut être installé avec pip, et dépend principalement de :
pip install llama-agents
Si vous n’avez pas déjà installé llama-index, pour suivre ces exemples, vous aurez également besoin de :
pip install llama-index-agent-openai
La manière la plus rapide de commencer est avec un agent existant (ou des agents) et de l’encapsuler dans un lanceur.
L’exemple ci-dessous montre un exemple trivial avec deux agents de ReAct.
Tout d’abord, configurons quelques agents et composants initiaux pour notre système Llama Agents :
from llama_agents import (AgentService, AgentOrchestrator, ControlPlaneServer, SimpleMessageQueue,)from llama_index.core.agent import ReActAgentfrom llama_index.core.tools import FunctionToolfrom llama_index.llms.openai import OpenAI# Créer un agentdef get_the_secret_fact() -> str:return "Le fait secret est : Un bébé lama s'appelle un 'Cria'."tool = FunctionTool.from_defaults(fn=get_the_secret_fact)agent1 = ReActAgent.from_tools([tool], llm=OpenAI())agent2 = ReActAgent.from_tools([], llm=OpenAI())# Créer nos composants de framework multi-agentmessage_queue = SimpleMessageQueue(port=8000)control_plane = ControlPlaneServer(message_queue=message_queue, orchestrator=AgentOrchestrator(llm=OpenAI(model="gpt-4-turbo")), port=8001,)agent_server_1 = AgentService(agent=agent1, message_queue=message_queue, description="Utile pour obtenir le fait secret.", service_name="agent_fact_secret", port=8002,)agent_server_2 = AgentService(agent=agent2, message_queue=message_queue, description="Utile pour obtenir des faits stupides aléatoires.", service_name="agent_fact_stupid", port=8003,)
Ensuite, lors du travail dans un notebook ou pour une itération plus rapide, nous pouvons lancer notre système Llama Agents dans un cadre de lancement unique, où un message est propagé à travers le réseau et retourné.
from llama_agents import LocalLauncher# Lancerlauncher = LocalLauncher([agent_server_1, agent_server_2], control_plane, message_queue,)result = launcher.launch_single("Quel est le fait secret ?")print(f"Résultat : {result}")
Comme avec tout système agentique, il est important de considérer la fiabilité du LLM que vous utilisez. En général, les API qui supportent l’appel de fonctions (OpenAI, Anthropic, Mistral, etc.) sont les plus fiables.
Une fois que vous êtes satisfait de votre système, nous pouvons lancer tous nos services en tant que processus indépendants, permettant une plus grande capacité de traitement et une meilleure évolutivité.
Par défaut, tous les résultats de tâches sont publiés dans une file d’attente “humaine” spécifique, nous définissons donc également un consommateur pour gérer ce résultat au fur et à mesure qu’il arrive. (À l’avenir, cette file d’attente finale sera configurable !)
Pour tester cela, vous pouvez utiliser le lanceur de serveur dans un script :
from llama_agents import ServerLauncher, CallableMessageConsumer# Consommateur humain supplémentairedef handle_result(message) -> None:print("Résultat reçu :", message.data)human_consumer = CallableMessageConsumer(handler=handle_result, message_type="humain")# Définir le lanceurlauncher = ServerLauncher([agent_server_1, agent_server_2], control_plane, message_queue, additional_consumers=[human_consumer],)# Lancer !launcher.launch_servers()
Maintenant, comme tout est un serveur, vous avez besoin de requêtes API pour interagir avec lui. Le moyen le plus simple est d’utiliser notre client et l’URL du plan de contrôle :
from llama_agents import LlamaAgentsClient, AsyncLlamaAgentsClientclient = LlamaAgentsClient("<URL du plan de contrôle>") # par exemple http://127.0.0.1:8001task_id = client.create_task("Quel est le fait secret ?")# <Attendre quelques secondes># retourne TaskResult ou None si non terminéresult = client.get_task_result(task_id)
Au lieu d’utiliser un client ou des requêtes brutes, vous pouvez également utiliser un outil CLI intégré pour surveiller et interagir avec vos services.
Dans un autre terminal, vous pouvez exécuter :
llama-agents monitor --control-plane-url http://127.0.0.1:8000
Vous pouvez trouver une multitude d’exemples dans notre dossier d’exemples.
Dans Llama Agents, il existe plusieurs composants clés qui constituent le système global :
Jusqu’à présent, vous avez vu comment définir des composants et comment les lancer. Cependant, dans la plupart des cas d’utilisation en production, vous devrez lancer des services manuellement, ainsi que définir vos propres consommateurs !
Voici donc un guide rapide sur exactement cela !
Tout d’abord, vous voudrez lancer tout. Cela peut être fait dans un seul script, ou vous pouvez lancer les choses avec plusieurs scripts par service, ou sur différentes machines, ou même dans des images Docker.
Dans cet exemple, nous supposerons un lancement à partir d’un seul script.
import asyncio# Lancer la file d'attente de messagesqueue_task = asyncio.create_task(message_queue.launch_server())# Attendre que la file d'attente de messages soit prêteawait asyncio.sleep(1)# Lancer le plan de contrôlecontrol_plane_task = asyncio.create_task(self.control_plane.launch_server())# Attendre que le plan de contrôle soit prêtawait asyncio.sleep(1)# Enregistrer le plan de contrôle en tant que consommateurawait self.message_queue.client.register_consumer(self.control_plane.as_consumer(remote=True))# Enregistrer les servicescontrol_plane_url = (f"http://{self.control_plane.host}:{self.control_plane.port}")service_tasks = []for service in self.services:# lancer d'abord le serviceservice_tasks.append(asyncio.create_task(service.launch_server()))# enregistrer le service dans la file d'attente de messagesawait service.register_to_message_queue()# enregistrer le service dans le plan de contrôleawait service.register_to_control_plane(control_plane_url)
Avec cela fait, vous voudrez peut-être définir un consommateur pour les résultats des tâches.
Par défaut, les résultats des tâches sont publiés dans une file d’attente de messages spécifique.
from llama_agents import (CallableMessageConsumer, RemoteMessageConsumer, QueueMessage,)def handle_result(message: QueueMessage) -> None:print(message.data)human_consumer = CallableMessageConsumer(handler=handle_result, message_type="humain")message_queue.register_consumer(human_consumer)# ou, vous pouvez envoyer le message à n'importe quelle URL# human_consumer = RemoteMessageConsumer(url="some destination url")# message_queue.register_consumer(human_consumer)
Ou, si vous ne voulez pas définir un consommateur, vous pouvez simplement utiliser l’outil de surveillance pour observer les résultats de votre système.
llama-agents monitor --control-plane-url http://127.0.0.1:8000