译者 | 李睿
审校 | 重楼
基本的检索增强生成(RAG)数据管道通常依赖于硬编码的步骤,每次运行时都遵循预定义的路径。这些系统没有实时决策,也不会根据输入数据动态调整动作。这种限制会降低在复杂或不断变化的环境中的灵活性和响应性,凸显了传统RAG系统的一个主要弱点。
LlamaIndex通过引入代理解决了这个限制。代理超越了查询引擎,因为它们不仅可以从静态数据源“读取”数据,还可以动态地摄取和修改来自各种工具的数据。这些代理由LLM提供支持,通过从提供的工具集中选择最合适的工具来执行一系列操作,以完成指定的任务。这些工具可以像基本功能一样简单,也可以像全面的LlamaIndex查询引擎一样复杂。他们处理用户输入或查询,就如何处理这些输入做出内部决策,并决定是否需要额外的步骤,或者是否可以交付最终结果。这种执行自动推理和决策的能力使代理对复杂的数据处理任务具有高度的适应性和高效性。
该图说明了LlamaIndex代理的工作流程:它们如何生成步骤、做出决策、选择工具和评估进度,从而根据用户输入动态地完成任务。
LlamaIndex代理的核心组件
LlamaIndex中的代理有两个主要组件:AgentRunner和AgentWorker。
Agent Runner
Agent Runner是LlamaIndex中的编排器。它管理代理的状态,包括会话内存,并为用户交互提供高级界面。它创建和维护任务,并负责在每个任务中运行各个步骤。以下是其功能的详细分解:
- 任务创建:代理执行器根据用户查询或输入创建任务。
- 状态管理:存储和维护会话和任务的状态。
- 内存管理:它在内部管理会话内存,确保在交互中保持场景。
- 任务执行:它与Agent Worker协调,在每个任务中执行各个步骤。
与LangChain代理(需要开发人员人工定义和传递内存)不同,LlamaIndex代理在内部处理内存管理。
Agent Worker
Agent Worker控制由Agent Runner给出的任务的逐步执行。它负责根据当前输入生成任务中的下一步。Agent Worker可以定制以包含特定的推理逻辑,使其高度适应不同的任务。主要方面包括:
- 步骤生成:根据当前数据确定任务的下一步。
- 自定义:通过自定义,以处理特定类型的推理或数据处理。
Agent Runner管理任务的创建和状态,而Agent Worker执行每个任务的步骤,在Agent Runner的指导下充当操作单元。
LlamaIndex中的代理类型
LlamIndex提供了针对特定任务和功能设计的不同类型的代理。
数据代理
数据代理是专门用于处理各种数据任务的代理,包括检索和操作。它们可以在读和写模式下运行,并与不同的数据源无缝交互。
数据代理可以跨各种数据库和API搜索、检索、更新和操作数据。它们支持与Slack、Shopify、Google等平台的交互,从而可以轻松地与这些服务集成。数据代理可以处理复杂的数据操作,例如查询数据库、调用API、更新记录和执行数据转换。其适应性强的设计使其适用于从简单的数据检索到复杂的数据处理管道的广泛应用。
Python
1 from llama_index.agent import OpenAIAgent, ReActAgent
2 from llama_index.llms import OpenAI
3
4 # import and define tools
5 ...
6 # initialize llm
7 llm = OpenAI(model="gpt-3.5-turbo")
8 # initialize openai agent
9 agent = OpenAIAgent.from_tools(tools, llm=llm, verbose=True)
10 # initialize ReAct agent
11 agent = ReActAgent.from_tools(tools, llm=llm, verbose=True)
12 # use agent
13 response = agent.chat("What is (121 * 3) + 42?")
自定义代理
自定义代理(Custom Agents)为用户提供了很多的灵活性和自定义选项。通过子类化CustomSimpleAgentWorker,可以为代理定义特定的逻辑和行为。这包括处理复杂查询、集成多个工具和实现错误处理机制。
用户可以通过定义分步逻辑、重试机制和集成各种工具来定制自定义代理以满足特定需求。这种自定义允许用户创建管理复杂任务和工作流的代理,使它们能够高度适应不同的场景。无论是管理复杂的数据操作还是与独特的服务集成,自定义代理都能提供构建专业、高效解决方案所需的工具。
工具和工具规格
工具是任何代理中最重要的组件,它们允许代理执行各种任务并扩展其功能。通过使用不同类型的工具,代理可以根据需要执行特定的操作。这使得该代理具有很高的适应性和效率。
函数工具
函数工具(FunctionTool)允许用户将任何Python函数转换为代理可以使用的工具。这一特性对于创建自定义操作非常有用,可以增强代理执行各种任务的能力。
用户可以将简单的函数转换为代理将其集成到其工作流中的工具。这可以包括数学运算、数据处理函数和其他自定义逻辑。
可以将Python函数转换为如下的工具:
Python
1 from llama_index.core.tools import FunctionTool
2 def multiply(a: int, b: int) -> int:
3 """Multiple two integers and returns the result integer"""
4 return a * b
5
6 multiply_tool = FunctionTool.from_defaults(fn=multiply)
LlamaIndex中的FunctionTool方法允许用户将任何Python函数转换为代理可以使用的工具。函数的名称成为工具的名称,函数的文档字符串充当工具的描述。
查询引擎工具
查询引擎工具(QueryEngine Tools)包装了现有的查询引擎,允许代理对数据源执行复杂的查询。这些工具与各种数据库和API集成,使代理能够高效地检索和操作数据。
这些工具使代理能够与特定的数据源交互、执行复杂的查询和检索相关信息。这种集成允许代理在决策过程中有效地使用数据。
要将任何查询引擎转换为查询引擎工具,可以使用以下代码:
Python
1 from llama_index.core.tools import QueryEngineTool
2 from llama_index.core.tools import ToolMetadata
3 query_engine_tools = QueryEngineTool(
4 query_engine="your_index_as_query_engine_here",
5 metadata=ToolMetadata(
6 name="name_your_tool",
7 description="Provide the description",
8 ),
9 )
QueryEngineTool方法允许用户将查询引擎转换为代理可以使用的工具。ToolMetadata类帮助定义这个工具的名称和描述。工具的名称由name属性设置,描述由description属性设置。
- 注意:工具的描述非常重要,因为它有助于LLM决定何时使用该工具。
使用MyScaleDB和LlamaIndex构建人工智能代理
使用查询引擎工具和功能工具构建一个人工智能代理,以演示如何有效地集成和利用这些工具。
安装必要的库
首先,通过在终端运行以下命令安装所需的库:
Shell
1 pip install myscale-client llama
将使用MyScaleDB作为向量搜索引擎来开发查询引擎。这是一个专门为可扩展应用程序设计的高级SQL向量数据库。
获取查询引擎的数据
对于这个例子,将使用Nike目录数据集。使用以下代码下载并准备数据:
Python
1 from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
2 import requests
3
4 url = 'https://niketeam-asset-download.nike.net/catalogs/2024/2024_Nike%20Kids_02_09_24.pdf?cb=09302022'
5 response = requests.get(url)
6
7 with open('Nike_Catalog.pdf', 'wb') as f:
8 f.write(response.content)
9
10 reader = SimpleDirectoryReader(input_files=["Nike_Catalog.pdf"])
11 documents = reader.load_data()
这段代码将下载Nike目录PDF并加载数据以便在查询引擎中使用。
连接MyScaleDB
在使用MyScaleDB之前,需要建立一个连接:
Python
1 import clickhouse_connect
2
3 client = clickhouse_connect.get_client(
4 host='your_host_here',
5 port=443,
6 username='your_username_here',
7 password='your_password_here'
8 )
要了解如何获取集群详细信息并阅读有关MyScale的更多信息可以参考MyScaleDB快速入门指南。
创建查询引擎工具
首先为代理构建第一个工具,即查询引擎工具。为此,首先使用MyScaleDB开发查询引擎,并将Nike目录数据添加到矢量存储中。
获取查询引擎的数据
Python
1 from llama_index.vector_stores.myscale import MyScaleVectorStore
2 from llama_index.core import StorageContext
3 vector_store = MyScaleVectorStore(myscale_client=client)
4 storage_context = StorageContext.from_defaults(vector_store=vector_store)
5 index = VectorStoreIndex.from_documents(
6 documents, storage_context=storage_context
7 )
8 query_engine = index.as_query_engine()
一旦数据被输入到向量存储中,就会创建一个索引。下一步是将查询引擎转换为工具。为此,将使用LlamaIndex的QueryEngineTool方法。
Python
1 from llama_index.core.tools import QueryEngineTool
2 from llama_index.core.tools import ToolMetadata
3
4 query_engine_tool = QueryEngineTool(
5 query_engine=index,
6 metadata=ToolMetadata(
7 name="nike_data",
8 description="Provide information about the Nike products. Use a detailed plain text question as input to the tool."
9 ),
10 )
QueryEngineTool接受query_engine和meta_data作为参数。在元数据中,采用描述定义工具的名称。
创建函数工具
下一个工具是一个简单的Python函数,它将两个数字相乘。此方法将使用LlamaIndex的FunctionTool转换为工具。
Python
1 from llama_index.core.tools import FunctionTool
2 # Define a simple Python function
3 def multiply(a: int, b: int) -> int:
4 """Multiply two integers and return the result."""
5 return a * b
6 # Change function to a tool
7 multiply_tool = FunctionTool.from_defaults(fn=multiply)
在此之后,完成了工具的创建。LlamaIndex代理将工具作为Python列表。然后把这些工具添加到一个列表中。
Python
1 tools = [multiply_tool, query_engine_tool]
定义LLM
定义LLM是任何LlamaIndex代理的核心。LLM的选择是至关重要的,因为定义LLM的理解和性能越好,它就越能有效地充当决策者和处理复杂问题。将使用OpenAI的gpt-3.5 turbo模型。
Python
1 from llama_index.llms.openai import OpenAI
2 llm = OpenAI(model="gpt-3.5-turbo")
初始化代理
正如前面看到的,一个代理由一个Agent Runner和一个Agent Worker组成。这是代理的两个组成部分。现在将探索它们在实践中是如何工作的。以两种方式实现了下面的代码:
- 自定义代理:第一种方法是首先使用工具和LLM初始化代理工作者。然后,将Agent Worker传递给Agent Runner以处理完整的代理。在这里将导入必要的模块并编写自己的代理。
Python
1 from llama_index.core.agent import AgentRunner
2 from llama_index.agent.openai import OpenAIAgentWorker
3
4 # Method 2: Initialize AgentRunner with OpenAIAgentWorker
5 openai_step_engine = OpenAIAgentWorker.from_tools(tools, llm=llm, verbose=True)
6 agent1 = AgentRunner(openai_step_engine)
- 使用预定义代理:第二种方法是使用代理,代理是AgentRunner的子类,它在底层捆绑了OpenAIAgentWorker。因此不需要自己定义AgentRunner或AgentWorkers,因为它们是在后端实现的。
Python
1 from llama_index.agent.openai import OpenAIAgent
2
3 # Initialize OpenAIAgent
4 agent = OpenAIAgent.from_tools(tools, llm=llm, verbose=True)
- 注意:当在LLM中设置verbose=true时,可以深入了解模型的思维过程,从而通过提供详细的解释和推理来理解它是如何得到答案的。
无论初始化方法是什么,都可以使用相同的方法测试代理。测试第一个:
Python
1 # Call the custom agent
2 agent = agent.chat("What's the price of BOYS NIKE DF STOCK RECRUIT PANT DJ573?")
应该得到类似这样的结果:
现在采用数学运算调用第一个自定义代理。
Python
1 # Call the second agent
2 response = agent1.chat("What's 2+2?")
调用第二个代理,并要求进行数学运算。会得到类似这样的回复:
人工智能代理自主处理复杂任务的潜力正在扩大,这使得它们在商业环境中具有不可估量的价值,在这些环境中,它们可以管理日常任务,并将人类解放出来从事更高价值的活动。随着技术的进步和向前发展,人工智能代理的采用预计将会增长,进一步彻底改变人们与技术的互动方式,并优化工作流程。
结论
LlamaIndex代理提供了一种管理和处理数据的智能方式,超越了传统的RAG系统。与静态数据管道不同,这些代理可以做出实时决策,根据传入的数据调整其操作。这种自动推理使它们对复杂任务具有高度的适应性和高效性。它们集成了从基本功能到高级查询引擎的各种工具,以智能地处理输入并提供优化的结果。
原文标题:Beyond Static Pipelines:Enhancing AI Agents With LlamaIndex,作者:Usama Jamil