Мультиагентные системы с ИИ Мистраль, Milvus и Llama-агентами
Цель этого блокнота
В этом блокноте мы рассмотрим различные идеи:
1️⃣ Хранить данные в Milvus: научимся хранить данные в Milvus, эффективной векторной базе данных, предназначенной для высокоскоростного поиска по сходству и приложений ИИ.
2️⃣ Использование llama-index с моделями Mistral для запросов данных: Узнайте, как использовать llama-index в сочетании с моделями Mistral для запросов данных, хранящихся в Milvus.
3️⃣ Создание автоматизированных агентов для поиска и чтения данных: Создайте агентов, которые могут автоматически искать и читать данные на основе запросов пользователей. Эти автоматизированные агенты повысят удобство работы пользователей, предоставляя быстрые и точные ответы, сокращая усилия по поиску вручную.
4️⃣ Разработка агентов для фильтрации метаданных на основе пользовательских запросов: внедрите агенты, которые могут автоматически генерировать фильтры метаданных на основе пользовательских запросов, уточняя и контекстуализируя результаты поиска, избегая путаницы и повышая точность получаемой информации, даже для сложных запросов.
К концу этого блокнота вы получите полное представление об использовании Milvus, llama-index с llama-агентами и моделей Mistral для создания надежной и эффективной системы поиска данных.
Milvus
Milvus - это векторная база данных с открытым исходным кодом, которая обеспечивает работу приложений искусственного интеллекта с помощью векторных вкраплений и поиска сходства.
В этом блокноте мы используем Milvus Lite, это облегченная версия Milvus.
С Milvus Lite вы можете начать создавать ИИ-приложения с векторным поиском сходства в течение нескольких минут! Milvus Lite подходит для работы в следующих средах:
- Jupyter Notebook / Google Colab
- Ноутбуки
- Устройства Edge
image.png
llama-agents
llama-agents
позволяет запускать агентов как микросервисы. Это позволяет масштабировать сервисы вверх и вниз.
llama-index
LlamaIndex - это фреймворк данных для вашего LLM-приложения. Он предоставляет такие инструменты, как:
- Коннекторы данных получают существующие данные из их родного источника и формата.
- Индексы данных структурируют ваши данные в промежуточных представлениях, которые легко и эффективно используются LLM.
- Движки обеспечивают доступ к данным на естественном языке.
- Агенты - это работники знаний на базе LLM, дополненные инструментами, от простых вспомогательных функций до API-интеграций и т. д.
image.png
Mistral AI
Mistral AI - исследовательская лаборатория, создающая LLM и модели вкраплений. Недавно они выпустили новые версии своих моделей, Mistral Nemo и Mistral Large, которые показали себя особенно хорошо в RAG и вызове функций. Поэтому мы будем использовать их в этом блокноте.
Установка зависимостей
$ 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()
Получите ключ API для Mistral
Вы можете получить ключ API Mistral в консоли 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
Загрузить данные
$ 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'
Подготовьте модель встраивания
Мы определяем модель встраивания, которая будет использоваться в этом блокноте. Мы используем mistral-embed
, это модель встраивания, разработанная Mistral, она была обучена с учетом извлечений, что делает ее очень подходящей для нашей агентной системы RAG. За подробностями обращайтесь к странице Embedding в документации 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")
Определение модели LLM
Llama Index использует LLM для ответа на запросы и подсказки и отвечает за написание ответов на естественном языке. Мы определили Mistral Nemo в качестве модели по умолчанию. Nemo предлагает большое контекстное окно до 128 тыс. лексем. Его рассуждения, знания о мире и точность кодирования являются передовыми в своей размерной категории.
from llama_index.llms.ollama import Ollama
Settings.llm = Ollama("mistral-nemo")
Инстанцирование Milvus и загрузка данных
Milvus - это популярная векторная база данных с открытым исходным кодом, которая обеспечивает приложениям ИИ высокопроизводительный и масштабируемый поиск векторного сходства.
- Задание uri локального файла, например
./milvus.db
, является наиболее удобным методом, поскольку он автоматически использует Milvus Lite для хранения всех данных в этом файле. - Если у вас большой объем данных, скажем, более миллиона векторов, вы можете настроить более производительный сервер Milvus на Docker или Kubernetes. В этом случае в качестве uri используйте ури сервера, например,
http://localhost:19530
. - Если вы хотите использовать Zilliz Cloud, полностью управляемый облачный сервис для Milvus, настройте uri и token, которые соответствуют публичной конечной точке и ключу API в 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)
Определите инструменты
Одним из ключевых шагов в создании эффективного агента является определение инструментов, которые он может использовать для выполнения своих задач. По сути, эти инструменты представляют собой функции или службы, к которым агент может обращаться для получения информации или выполнения действий.
Ниже мы определим два инструмента, которые наш агент может использовать для запроса финансовой информации о Lyft и Uber за 2021 год. Эти инструменты будут интегрированы в нашего агента, что позволит ему отвечать на запросы на естественном языке, предоставляя точную и релевантную информацию.
Если вы посмотрите на график, который мы видим вверху, то это и есть "агентская служба".
# 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.
Фильтрация метаданных
Milvus поддерживает фильтрацию метаданных- технику, которая позволяет уточнять и сужать результаты поиска на основе определенных атрибутов или тегов, связанных с вашими данными. Это особенно полезно в сценариях, когда у вас много данных и нужно получить только те, которые соответствуют определенным критериям.
Примеры использования фильтрации метаданных
Точность результатов поиска: Применяя фильтры метаданных, вы можете обеспечить высокую релевантность результатов поиска запросу пользователя. Например, если у вас есть коллекция финансовых документов, вы можете отфильтровать их на основе названия компании, года или любых других релевантных метаданных.
Эффективность: Фильтрация метаданных помогает сократить объем данных, которые необходимо обработать, что делает поисковые операции более эффективными. Это особенно полезно при работе с большими массивами данных.
Персонализация: У разных пользователей или приложений могут быть разные требования. Фильтрация метаданных позволяет настраивать результаты поиска в соответствии с конкретными потребностями, например, получать документы за определенный год или компанию.
Пример использования
В приведенном ниже блоке кода фильтрация метаданных используется для создания механизма фильтрованных запросов, который извлекает документы на основе определенной пары ключ-значение метаданных: file_name
: lyft_2021.pdf
Определенный ниже QueryEngineTool
является более общим, чем тот, который был определен выше, в том случае у нас был инструмент для каждой компании (Uber и Lyft), в этом случае он более общий. Мы знаем, что у нас есть только финансовые документы о компаниях, но это все. Добавив фильтрацию метаданных, мы можем отфильтровать только получение данных из определенного документа.
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'>
Вызов функций
Mistral Nemo и Large поддерживают вызов собственных функций. Интеграция с инструментами LlamaIndex осуществляется через функцию predict_and_call
на llm. Это позволяет пользователю подключать любые инструменты и позволять LLM решать, какие инструменты вызывать (если таковые имеются).
Подробнее об агентах вы можете узнать на сайте llama-index.
# Set up the LLM we will use for Function Calling
llm = Ollama(model="mistral-nemo")
Взаимодействие с агентом
Теперь мы можем увидеть фильтрацию метаданных в действии:
- В первом случае агент не должен найти ничего по запросу пользователя, поскольку речь идет об Uber, а мы фильтруем документы только о Lyft.
- Во втором случае агент должен найти информацию о Lyft, так как мы будем искать только документы о 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.
Пример путаницы без фильтрации метаданных
> 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.
В этом примере система неверно предоставляет информацию о Lyft вместо Uber, что приводит к ошибочному ответу. Вначале система говорит, что у нее нет такой информации, а затем просто продолжает и продолжает.
Использование агента для извлечения фильтров метаданных
Чтобы решить эту проблему, мы можем использовать агента для автоматического извлечения фильтров метаданных из вопроса пользователя и применения их в процессе ответа на вопрос. Это гарантирует, что система получит правильную и релевантную информацию.
Пример кода
Ниже приведен пример кода, демонстрирующий, как создать механизм фильтрованных запросов с использованием агента для извлечения фильтров метаданных из вопроса пользователя:
Объяснение
Шаблон запроса: Класс PromptTemplate используется для определения шаблона для извлечения фильтров метаданных из вопроса пользователя. Шаблон предписывает языковой модели учитывать названия компаний, годы и другие соответствующие атрибуты.
LLM: Mistral Nemo используется для генерации фильтров метаданных на основе вопроса пользователя. Модель получает вопрос и шаблон для извлечения соответствующих фильтров.
Фильтры метаданных: Ответ от LLM анализируется для создания объекта
MetadataFilters
. Если конкретные фильтры не указаны, возвращается пустой объектMetadataFilters
.Фильтрованный механизм запросов: метод
index.as_query_engine(filters=metadata_filters)
создает механизм запросов, который применяет извлеченные фильтры метаданных к индексу. Это гарантирует, что будут получены только документы, соответствующие критериям фильтра.
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.
Оркестрирование различных сервисов с помощью Mistral Large
Mistral Large - это флагманская модель Mistral с очень хорошими возможностями рассуждений, знаний и кодирования. Она идеально подходит для сложных задач, требующих больших возможностей рассуждений или узкой специализации. Она обладает расширенными возможностями вызова функций, а это именно то, что нам нужно для оркестровки наших различных агентов.
Почему нам нужна более интеллектуальная Модель?
Вопрос, на который мы будем отвечать ниже, особенно сложен, поскольку требует оркестровки множества служб и агентов для получения согласованного и точного ответа. Это предполагает координацию различных инструментов и агентов для получения и обработки информации из разных источников, например финансовых данных из разных компаний.
Что же в этом сложного?
- Сложность: В вопросе задействовано множество агентов и служб, каждая из которых обладает собственной функциональностью и источниками данных. Согласование этих агентов для бесперебойной работы - сложная задача.
Интеграция данных: Вопрос требует интеграции данных из разных источников, что может быть непросто из-за различий в форматах, структурах и метаданных данных.
Понимание контекста: Вопрос может потребовать понимания контекста и взаимосвязей между различными частями информации, что является когнитивно сложной задачей.
Почему Mistral Large может помочь в этом случае?
Mistral Large хорошо подходит для решения этой задачи благодаря своим расширенным возможностям рассуждений и вызова функций. Вот как он помогает:
Расширенные рассуждения: Mistral Large может решать сложные задачи рассуждения, что делает его идеальным для оркестровки нескольких агентов и служб. Он может понимать взаимосвязи между различными частями информации и принимать обоснованные решения.
Возможности вызова функций: Mistral Large обладает расширенными возможностями вызова функций, которые необходимы для координации действий различных агентов. Это позволяет обеспечить беспрепятственную интеграцию и оркестровку различных сервисов.
Специализированные знания: Mistral Large предназначен для решения узкоспециализированных задач, поэтому он хорошо подходит для обработки сложных запросов, требующих глубоких знаний о домене.
По всем этим причинам я решил, что в данном случае лучше использовать Mistral Large вместо Mistral Nemo.
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."}}]
Заключение
В этом блокноте вы увидели, как можно использовать llama-агенты для выполнения различных действий, вызывая соответствующие инструменты. Используя Mistral Large в сочетании с Mistral Nemo, мы продемонстрировали, как можно эффективно организовывать интеллектуальные, ресурсосберегающие системы, используя сильные стороны различных LLM. Мы увидели, что агент может выбрать коллекцию, содержащую данные, запрошенные пользователем.