milvus-logo
LFAI
Casa
  • Integrazioni

Sistemi multi-agente con Mistral AI, Milvus e Llama-agenti

Obiettivo di questo Quaderno

In questo Quaderno esploreremo diverse idee:

  • 1️⃣ Memorizzare i dati in Milvus: imparare a memorizzare i dati in Milvus, un efficiente database vettoriale progettato per ricerche di somiglianza ad alta velocità e applicazioni AI.

  • 2️⃣ Utilizzare llama-index con i modelli Mistral per le interrogazioni dei dati: scoprire come utilizzare llama-index in combinazione con i modelli Mistral per interrogare i dati memorizzati in Milvus.

  • 3️⃣ Creare agenti automatizzati per la ricerca e la lettura dei dati: costruire agenti in grado di cercare e leggere automaticamente i dati in base alle query dell'utente. Questi agenti automatici miglioreranno l'esperienza dell'utente fornendo risposte rapide e precise, riducendo lo sforzo di ricerca manuale.

  • 4️⃣ Sviluppare agenti per il filtraggio dei metadati in base alle query dell'utente: implementare agenti in grado di generare automaticamente filtri per i metadati in base alle query dell'utente, affinando e contestualizzando i risultati della ricerca, evitando confusione e migliorando l'accuratezza delle informazioni recuperate, anche per query complesse.

  • Alla fine di questo quaderno, avrete una conoscenza completa dell'uso di Milvus, llama-index con llama-agents e dei modelli Mistral per costruire un sistema di recupero dati robusto ed efficiente.

Milvus

Milvus è un database vettoriale open-source che alimenta le applicazioni di intelligenza artificiale con incorporazioni vettoriali e ricerca di similarità.

In questo notebook utilizziamo Milvus Lite, la versione leggera di Milvus.

Con Milvus Lite, è possibile iniziare a costruire un'applicazione di IA con ricerca di similarità vettoriale in pochi minuti! Milvus Lite può essere eseguito nei seguenti ambienti:

  • Jupyter Notebook / Google Colab
  • Computer portatili
  • Dispositivi Edge

image.png immagine.png

llama-agenti

llama-agents permette di eseguire gli agenti come microservizi. In questo modo è possibile scalare i servizi verso l'alto e verso il basso.

llama-indice

LlamaIndex è un framework di dati per le applicazioni LLM. Fornisce strumenti come:

  • I connettori di dati ingeriscono i dati esistenti dalla loro fonte e dal loro formato nativo.
  • Gli indici di dati strutturano i dati in rappresentazioni intermedie facili e performanti da consumare per gli LLM.
  • I motori forniscono un accesso in linguaggio naturale ai dati.
  • Gli agenti sono lavoratori della conoscenza alimentati da LLM e potenziati da strumenti, da semplici funzioni di aiuto a integrazioni API e altro ancora.

image.png immagine.png

Mistral AI

Mistral AI è un laboratorio di ricerca che costruisce modelli LLM ed Embeddings; recentemente ha rilasciato nuove versioni dei suoi modelli, Mistral Nemo e Mistral Large, che hanno dimostrato di essere particolarmente validi in RAG e nella chiamata di funzioni. Per questo motivo, li utilizzeremo in questo quaderno.

Installare le dipendenze

$ pip install llama-agents pymilvus openai python-dotenv
$ pip install llama-index-vector-stores-milvus llama-index-readers-file llama-index-llms-ollama llama-index-llms-mistralai llama-index-embeddings-mistralai
# NOTE: This is ONLY necessary in jupyter notebook.
# Details: Jupyter runs an event-loop behind the scenes.
#          This results in nested event-loops when we start an event-loop to make async queries.
#          This is normally not allowed, we use nest_asyncio to allow it for convenience.
import nest_asyncio

nest_asyncio.apply()

Ottenere la chiave API per Mistral

È possibile ottenere la chiave API di Mistral dalla Mistral Cloud Console.

"""
load_dotenv reads key-value pairs from a .env file and can set them as environment variables.
This is useful to avoid leaking your API key for example :D
"""

from dotenv import load_dotenv
import os

load_dotenv()
True

Scaricare i dati

$ mkdir -p 'data/10k/'
$ wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/10k/uber_2021.pdf' -O 'data/10k/uber_2021.pdf'
$ wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/10k/lyft_2021.pdf' -O 'data/10k/lyft_2021.pdf'

Preparare il modello di inclusione

Definiamo il modello di embedding che verrà utilizzato in questo notebook. Utilizziamo mistral-embed, un modello di embedding sviluppato da Mistral, addestrato tenendo conto dei recuperi, il che lo rende un ottimo modello per il nostro sistema Agentic RAG. Per maggiori dettagli, consultare la pagina Embedding nella documentazione di Mistral.

from llama_index.core import Settings
from llama_index.embeddings.mistralai import MistralAIEmbedding

# Define the default Embedding model used in this Notebook.
# We are using Mistral Models, so we are also using Mistral Embeddings

Settings.embed_model = MistralAIEmbedding(model_name="mistral-embed")

Definire il modello LLM

Llama Index utilizza gli LLM per rispondere alle richieste e alle interrogazioni ed è responsabile della scrittura delle risposte in linguaggio naturale. Definiamo Mistral Nemo come modello predefinito. Nemo offre un'ampia finestra di contesto, fino a 128k token. Il suo ragionamento, la conoscenza del mondo e l'accuratezza della codifica sono allo stato dell'arte nella sua categoria di dimensioni.

from llama_index.llms.ollama import Ollama

Settings.llm = Ollama("mistral-nemo")

Istanziare Milvus e caricare i dati

Milvus è un popolare database vettoriale open-source che alimenta le applicazioni di intelligenza artificiale con una ricerca di similarità vettoriale altamente performante e scalabile.

  • L'impostazione dell'uri come file locale, ad esempio./milvus.db, è il metodo più conveniente, poiché utilizza automaticamente Milvus Lite per memorizzare tutti i dati in questo file.
  • Se si dispone di una grande quantità di dati, ad esempio più di un milione di vettori, è possibile configurare un server Milvus più performante su Docker o Kubernetes. In questa configurazione, utilizzare l'uri del server, ad esempiohttp://localhost:19530, come uri.
  • Se si desidera utilizzare Zilliz Cloud, il servizio cloud completamente gestito per Milvus, è necessario modificare l'uri e il token, che corrispondono all'endpoint pubblico e alla chiave API di Zilliz Cloud.
from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.core import (
    SimpleDirectoryReader,
    VectorStoreIndex,
    StorageContext,
    load_index_from_storage,
)
from llama_index.core.tools import QueryEngineTool, ToolMetadata

input_files = ["./data/10k/lyft_2021.pdf", "./data/10k/uber_2021.pdf"]

# Create a single Milvus vector store
vector_store = MilvusVectorStore(
    uri="./milvus_demo.db", dim=1024, overwrite=False, collection_name="companies_docs"
)

# Create a storage context with the Milvus vector store
storage_context = StorageContext.from_defaults(vector_store=vector_store)

# Load data
docs = SimpleDirectoryReader(input_files=input_files).load_data()

# Build index
index = VectorStoreIndex.from_documents(docs, storage_context=storage_context)

# Define the query engine
company_engine = index.as_query_engine(similarity_top_k=3)

Definire gli strumenti

Uno dei passaggi chiave nella costruzione di un agente efficace è la definizione degli strumenti che può utilizzare per svolgere i suoi compiti. Questi strumenti sono essenzialmente funzioni o servizi che l'agente può richiamare per recuperare informazioni o eseguire azioni.

Di seguito, definiremo due strumenti che il nostro agente può utilizzare per interrogare le informazioni finanziarie su Lyft e Uber a partire dall'anno 2021. Questi strumenti saranno integrati nel nostro agente, consentendogli di rispondere alle interrogazioni in linguaggio naturale con informazioni precise e pertinenti.

Se si osserva il grafico in alto, ecco cos'è un "servizio agente".

# Define the different tools that can be used by our Agent.
query_engine_tools = [
    QueryEngineTool(
        query_engine=company_engine,
        metadata=ToolMetadata(
            name="lyft_10k",
            description=(
                "Provides information about Lyft financials for year 2021. "
                "Use a detailed plain text question as input to the tool."
                "Do not attempt to interpret or summarize the data."
            ),
        ),
    ),
    QueryEngineTool(
        query_engine=company_engine,
        metadata=ToolMetadata(
            name="uber_10k",
            description=(
                "Provides information about Uber financials for year 2021. "
                "Use a detailed plain text question as input to the tool."
                "Do not attempt to interpret or summarize the data."
            ),
        ),
    ),
]
from llama_index.llms.ollama import Ollama
from llama_index.llms.mistralai import MistralAI

# Set up the agent
llm = Ollama(model="mistral-nemo")

response = llm.predict_and_call(
    query_engine_tools,
    user_msg="Could you please provide a comparison between Lyft and Uber's total revenues in 2021?",
    allow_parallel_tool_calls=True,
)

# Example usage without metadata filtering
print("Response without metadata filtering:")
print(response)
Response without metadata filtering:
The revenue for Lyft in 2021 was $3.84 billion.

Uber's total revenue for the year ended December 31, 2021 was $17,455 million.

Filtraggio dei metadati

Milvus supporta il filtraggio dei metadati, una tecnica che consente di affinare e restringere i risultati della ricerca in base a specifici attributi o tag associati ai dati. Ciò è particolarmente utile in scenari in cui si dispone di molti dati e si ha la necessità di recuperare solo il sottoinsieme di dati pertinenti che corrispondono a determinati criteri.

Casi d'uso del filtraggio dei metadati

  • Precisione nei risultati della ricerca: Applicando i filtri dei metadati, è possibile garantire che i risultati della ricerca siano altamente pertinenti alla richiesta dell'utente. Ad esempio, se si dispone di una raccolta di documenti finanziari, è possibile filtrarli in base al nome della società, all'anno o a qualsiasi altro metadato pertinente.

  • Efficienza: Il filtraggio dei metadati aiuta a ridurre la quantità di dati da elaborare, rendendo più efficienti le operazioni di ricerca. Questo è particolarmente vantaggioso quando si ha a che fare con grandi insiemi di dati.

  • Personalizzazione: Utenti o applicazioni diversi possono avere esigenze diverse. Il filtraggio dei metadati consente di personalizzare i risultati della ricerca per soddisfare esigenze specifiche, come il recupero di documenti di un particolare anno o di una particolare azienda.

Esempio di utilizzo

Nel blocco di codice sottostante, il filtraggio dei metadati viene utilizzato per creare un motore di query filtrato che recupera i documenti in base a una specifica coppia chiave-valore di metadati: file_name: lyft_2021.pdf

Il sito QueryEngineTool definito di seguito è più generico di quello definito sopra; in quello precedente, avevamo uno strumento per azienda (Uber e Lyft), in questo è più generico. Sappiamo di avere solo documenti finanziari sulle aziende, ma questo è tutto. Aggiungendo un filtro sui metadati, possiamo filtrare per ottenere solo i dati da un documento specifico.

from llama_index.core.vector_stores import ExactMatchFilter, MetadataFilters

# Example usage with metadata filtering
filters = MetadataFilters(
    filters=[ExactMatchFilter(key="file_name", value="lyft_2021.pdf")]
)

print(f"filters: {filters}")
filtered_query_engine = index.as_query_engine(filters=filters)

# Define query engine tools with the filtered query engine
query_engine_tools = [
    QueryEngineTool(
        query_engine=filtered_query_engine,
        metadata=ToolMetadata(
            name="company_docs",
            description=(
                "Provides information about various companies' financials for year 2021. "
                "Use a detailed plain text question as input to the tool."
                "Use this tool to retrieve specific data points about a company. "
                "Do not attempt to interpret or summarize the data."
            ),
        ),
    ),
]
filters: filters=[MetadataFilter(key='file_name', value='lyft_2021.pdf', operator=<FilterOperator.EQ: '=='>)] condition=<FilterCondition.AND: 'and'>

Chiamata di funzione

Mistral Nemo e Large supportano le chiamate di funzione native. Esiste una perfetta integrazione con gli strumenti di LlamaIndex, attraverso la funzione predict_and_call dell'llm. Ciò consente all'utente di allegare qualsiasi strumento e lasciare che sia l'LLM a decidere quali strumenti chiamare (se ce ne sono).

Per saperne di più sugli agenti, consultare il sito web di llama-index.

# Set up the LLM we will use for Function Calling

llm = Ollama(model="mistral-nemo")

Interagire con l'agente

Ora possiamo vedere il filtraggio dei metadati in azione:

  1. Nel primo caso, l'Agente non dovrebbe essere in grado di trovare nulla che corrisponda alla richiesta dell'utente, poiché si tratta di Uber e noi filtriamo solo i documenti relativi a Lyft.
  2. Nel secondo, l'agente dovrebbe essere in grado di trovare informazioni su Lyft, poiché cercheremo solo documenti che riguardano Lyft.
response = llm.predict_and_call(
    query_engine_tools,
    user_msg="How many employees does Uber have?",
    allow_parallel_tool_calls=True,
)
print(response)
I'm unable to provide information about Uber's employee count as it's outside the given Lyft context.
response = llm.predict_and_call(
    query_engine_tools,
    user_msg="What are the risk factors for Lyft?",
    allow_parallel_tool_calls=True,
)

print(response)
Investing in Lyft carries significant risks. These include general economic factors like impacts from pandemics or crises, operational factors such as competition, pricing changes, and driver/ride growth unpredictability, insurance coverage issues, autonomous vehicle technology uncertainties, reputational concerns, potential security breaches, reliance on third-party services, and challenges in expanding platform offerings. Lyft's business operations are subject to numerous other risks not explicitly mentioned here, which could also harm its financial condition and prospects.

Esempio di confusione senza filtro dei metadati

> Question: What are the risk factors for Uber?

> Response without metadata filtering:
Based on the provided context, which pertains to Lyft's Risk Factors section in their Annual Report, some of the potential risk factors applicable to a company like Uber might include:

- General economic factors such as the impact of global pandemics or other crises on ride-sharing demand.
- Operational factors like competition in ride-hailing services, unpredictability in results of operations, and uncertainty about market growth for ridesharing and related services.
- Risks related to attracting and retaining qualified drivers and riders.

In questo esempio, il sistema fornisce erroneamente informazioni su Lyft invece che su Uber, dando luogo a una risposta fuorviante. Il sistema inizia dicendo che non dispone delle informazioni, ma poi continua.

Usare un agente per estrarre i filtri dei metadati

Per risolvere questo problema, possiamo utilizzare un agente per estrarre automaticamente i filtri dei metadati dalla domanda dell'utente e applicarli durante il processo di risposta alla domanda. Questo assicura che il sistema recuperi le informazioni corrette e pertinenti.

Esempio di codice

Di seguito è riportato un esempio di codice che dimostra come creare un motore di query filtrata utilizzando un agente per estrarre i filtri dei metadati dalla domanda dell'utente:

Spiegazione

  • Modello di prompt: La classe PromptTemplate è usata per definire un modello per estrarre i filtri di metadati dalla domanda dell'utente. Il modello indica al modello linguistico di considerare i nomi delle aziende, gli anni e altri attributi rilevanti.

  • LLM: Mistral Nemo viene utilizzato per generare i filtri di metadati in base alla domanda dell'utente. Il modello viene sollecitato con la domanda e il modello per estrarre i filtri pertinenti.

  • Filtri dei metadati: La risposta del LLM viene analizzata per creare un oggetto MetadataFilters. Se non vengono indicati filtri specifici, viene restituito un oggetto MetadataFilters vuoto.

  • Motore di query filtrata: il metodo index.as_query_engine(filters=metadata_filters) crea un motore di query che applica i filtri dei metadati estratti all'indice. Questo assicura che vengano recuperati solo i documenti che corrispondono ai criteri del filtro.

from llama_index.core.prompts.base import PromptTemplate


# Function to create a filtered query engine
def create_query_engine(question):
    # Extract metadata filters from question using a language model
    prompt_template = PromptTemplate(
        "Given the following question, extract relevant metadata filters.\n"
        "Consider company names, years, and any other relevant attributes.\n"
        "Don't write any other text, just the MetadataFilters object"
        "Format it by creating a MetadataFilters like shown in the following\n"
        "MetadataFilters(filters=[ExactMatchFilter(key='file_name', value='lyft_2021.pdf')])\n"
        "If no specific filters are mentioned, returns an empty MetadataFilters()\n"
        "Question: {question}\n"
        "Metadata Filters:\n"
    )

    prompt = prompt_template.format(question=question)
    llm = Ollama(model="mistral-nemo")
    response = llm.complete(prompt)

    metadata_filters_str = response.text.strip()
    if metadata_filters_str:
        metadata_filters = eval(metadata_filters_str)
        print(f"eval: {metadata_filters}")
        return index.as_query_engine(filters=metadata_filters)
    return index.as_query_engine()
response = create_query_engine(
    "What is Uber revenue? This should be in the file_name: uber_2021.pdf"
)
eval: filters=[MetadataFilter(key='file_name', value='uber_2021.pdf', operator=<FilterOperator.EQ: '=='>)] condition=<FilterCondition.AND: 'and'>
## Example usage with metadata filtering
question = "What is Uber revenue? This should be in the file_name: uber_2021.pdf"
filtered_query_engine = create_query_engine(question)

# Define query engine tools with the filtered query engine
query_engine_tools = [
    QueryEngineTool(
        query_engine=filtered_query_engine,
        metadata=ToolMetadata(
            name="company_docs_filtering",
            description=(
                "Provides information about various companies' financials for year 2021. "
                "Use a detailed plain text question as input to the tool."
            ),
        ),
    ),
]
# Set up the agent with the updated query engine tools
response = llm.predict_and_call(
    query_engine_tools,
    user_msg=question,
    allow_parallel_tool_calls=True,
)

print("Response with metadata filtering:")
print(response)
eval: filters=[MetadataFilter(key='file_name', value='uber_2021.pdf', operator=<FilterOperator.EQ: '=='>)] condition=<FilterCondition.AND: 'and'>
Response with metadata filtering:
Uber's total revenue for the year ended December 31, 2021, is $17.455 billion.

Orchestrare i diversi servizi con Mistral Large

Mistral Large è il modello di punta di Mistral, con ottime capacità di ragionamento, conoscenza e codifica. È ideale per compiti complessi che richiedono grandi capacità di ragionamento o sono altamente specializzati. Ha capacità avanzate di chiamata di funzioni, che è esattamente ciò di cui abbiamo bisogno per orchestrare i nostri diversi agenti.

Perché abbiamo bisogno di un Modello più intelligente?

La domanda a cui si sta rispondendo è particolarmente impegnativa perché richiede l'orchestrazione di più servizi e agenti per fornire una risposta coerente e accurata. Ciò comporta il coordinamento di vari strumenti e agenti per recuperare ed elaborare informazioni da fonti diverse, come i dati finanziari di diverse aziende.

Cosa c'è di così difficile?

  • La complessità: La domanda coinvolge più agenti e servizi, ciascuno con le proprie funzionalità e fonti di dati. Coordinare questi agenti per farli lavorare insieme senza problemi è un compito complesso.
  • Integrazione dei dati: La domanda richiede l'integrazione di dati provenienti da fonti diverse, il che può essere difficile a causa delle variazioni nei formati, nelle strutture e nei metadati dei dati.

  • Comprensione del contesto: La domanda può richiedere la comprensione del contesto e delle relazioni tra le diverse informazioni, un compito cognitivamente impegnativo.

Perché Mistral Large potrebbe essere utile in questo caso?

Mistral Large è adatto a questo compito grazie alle sue capacità avanzate di ragionamento e di chiamata di funzioni. Ecco come ci aiuta:

  • Ragionamento avanzato: Mistral Large è in grado di gestire attività di ragionamento complesse, che lo rendono ideale per l'orchestrazione di più agenti e servizi. È in grado di comprendere le relazioni tra le diverse informazioni e di prendere decisioni informate.

  • Capacità di chiamata di funzioni: Mistral Large dispone di funzionalità avanzate di chiamata di funzioni, essenziali per coordinare le azioni di diversi agenti. Ciò consente una perfetta integrazione e orchestrazione di vari servizi.

  • Conoscenze specialistiche: Mistral Large è stato progettato per compiti altamente specializzati, il che lo rende adatto a gestire query complesse che richiedono una profonda conoscenza del dominio.

Per tutti questi motivi, ho deciso che l'uso di Mistral Large invece di Mistral Nemo era più adatto in questo caso.

from llama_agents import (
    AgentService,
    ToolService,
    LocalLauncher,
    MetaServiceTool,
    ControlPlaneServer,
    SimpleMessageQueue,
    AgentOrchestrator,
)

from llama_index.core.agent import FunctionCallingAgentWorker
from llama_index.llms.mistralai import MistralAI

# create our multi-agent framework components
message_queue = SimpleMessageQueue()
control_plane = ControlPlaneServer(
    message_queue=message_queue,
    orchestrator=AgentOrchestrator(llm=MistralAI("mistral-large-latest")),
)

# define Tool Service
tool_service = ToolService(
    message_queue=message_queue,
    tools=query_engine_tools,
    running=True,
    step_interval=0.5,
)

# define meta-tools here
meta_tools = [
    await MetaServiceTool.from_tool_service(
        t.metadata.name,
        message_queue=message_queue,
        tool_service=tool_service,
    )
    for t in query_engine_tools
]

# define Agent and agent service
worker1 = FunctionCallingAgentWorker.from_tools(
    meta_tools, llm=MistralAI("mistral-large-latest")
)

agent1 = worker1.as_agent()
agent_server_1 = AgentService(
    agent=agent1,
    message_queue=message_queue,
    description="Used to answer questions over differnet companies for their Financial results",
    service_name="Companies_analyst_agent",
)
import logging

# change logging level to enable or disable more verbose logging
logging.getLogger("llama_agents").setLevel(logging.INFO)
## Define Launcher
launcher = LocalLauncher(
    [agent_server_1, tool_service],
    control_plane,
    message_queue,
)
query_str = "What are the risk factors for Uber?"
result = launcher.launch_single(query_str)
INFO:llama_agents.message_queues.simple - Consumer AgentService-27cde4ed-5163-4005-90fc-13c158eda7e3: Companies_analyst_agent has been registered.
INFO:llama_agents.message_queues.simple - Consumer ToolService-b73c500a-5fbe-4f57-95c7-db74e173bd1b: default_tool_service has been registered.
INFO:llama_agents.message_queues.simple - Consumer 62465ab8-32ff-436e-95fa-74e828745150: human has been registered.
INFO:llama_agents.message_queues.simple - Consumer ControlPlaneServer-f4c27d43-5474-43ca-93ca-a9aeed4534d7: control_plane has been registered.
INFO:llama_agents.services.agent - Companies_analyst_agent launch_local
INFO:llama_agents.message_queues.base - Publishing message to 'control_plane' with action 'ActionTypes.NEW_TASK'
INFO:llama_agents.message_queues.simple - Launching message queue locally
INFO:llama_agents.services.agent - Processing initiated.
INFO:llama_agents.services.tool - Processing initiated.
INFO:llama_agents.message_queues.base - Publishing message to 'Companies_analyst_agent' with action 'ActionTypes.NEW_TASK'
INFO:llama_agents.message_queues.simple - Successfully published message 'control_plane' to consumer.
INFO:llama_agents.services.agent - Created new task: 0720da2f-1751-4766-a814-ba720bc8a467
INFO:llama_agents.message_queues.simple - Successfully published message 'Companies_analyst_agent' to consumer.
INFO:llama_agents.message_queues.simple - Consumer MetaServiceTool-5671c175-7b03-4bc8-b60d-bd7101d0fc41: MetaServiceTool-5671c175-7b03-4bc8-b60d-bd7101d0fc41 has been registered.
INFO:llama_agents.message_queues.base - Publishing message to 'default_tool_service' with action 'ActionTypes.NEW_TOOL_CALL'
INFO:llama_agents.message_queues.simple - Successfully published message 'default_tool_service' to consumer.
INFO:llama_agents.services.tool - Processing tool call id f4c270a4-bc47-4bbf-92fe-e2cc80757943 with company_docs
INFO:llama_agents.message_queues.base - Publishing message to 'control_plane' with action 'ActionTypes.COMPLETED_TASK'
INFO:llama_agents.message_queues.base - Publishing message to 'MetaServiceTool-5671c175-7b03-4bc8-b60d-bd7101d0fc41' with action 'ActionTypes.COMPLETED_TOOL_CALL'
INFO:llama_agents.message_queues.base - Publishing message to 'Companies_analyst_agent' with action 'ActionTypes.NEW_TASK'
INFO:llama_agents.message_queues.simple - Successfully published message 'control_plane' to consumer.
INFO:llama_agents.message_queues.simple - Successfully published message 'MetaServiceTool-5671c175-7b03-4bc8-b60d-bd7101d0fc41' to consumer.
INFO:llama_agents.services.agent - Created new task: 0720da2f-1751-4766-a814-ba720bc8a467
INFO:llama_agents.message_queues.simple - Successfully published message 'Companies_analyst_agent' to consumer.
INFO:llama_agents.message_queues.base - Publishing message to 'default_tool_service' with action 'ActionTypes.NEW_TOOL_CALL'
INFO:llama_agents.message_queues.simple - Successfully published message 'default_tool_service' to consumer.
INFO:llama_agents.services.tool - Processing tool call id f888f9a8-e716-4505-bfe2-577452e9b6e6 with company_docs
INFO:llama_agents.message_queues.base - Publishing message to 'MetaServiceTool-5671c175-7b03-4bc8-b60d-bd7101d0fc41' with action 'ActionTypes.COMPLETED_TOOL_CALL'
INFO:llama_agents.message_queues.simple - Successfully published message 'MetaServiceTool-5671c175-7b03-4bc8-b60d-bd7101d0fc41' to consumer.
INFO:llama_agents.message_queues.base - Publishing message to 'control_plane' with action 'ActionTypes.COMPLETED_TASK'
INFO:llama_agents.message_queues.base - Publishing message to 'human' with action 'ActionTypes.COMPLETED_TASK'
INFO:llama_agents.message_queues.simple - Successfully published message 'control_plane' to consumer.
INFO:llama_agents.message_queues.simple - Successfully published message 'human' to consumer.
print(result)
[{"name": "finalize", "arguments": {"input": "Uber faces several risk factors, including general economic impacts such as pandemics or downturns, operational challenges like competition, market growth uncertainty, attracting and retaining drivers and riders, insurance adequacy, autonomous vehicle technology development, maintaining its reputation and brand, and managing growth. Additionally, reliance on third-party providers for various services can introduce further risks to its operations."}}]

Conclusione

In questo quaderno abbiamo visto come sia possibile utilizzare gli agenti llama per eseguire diverse azioni chiamando gli strumenti appropriati. Utilizzando Mistral Large in combinazione con Mistral Nemo, abbiamo dimostrato come sia possibile orchestrare efficacemente sistemi intelligenti ed efficienti dal punto di vista delle risorse, sfruttando i punti di forza di diversi LLM. Abbiamo visto che l'agente può scegliere la raccolta contenente i dati richiesti dall'utente.