todo:本节内容需要实战,加深理解
使用 QueryEngineTool 转换 query engine 为 tool。
LlamaIndex 有 4 类 tools:
FunctionTool:将任何 Python 函数转换为 Agents 可以使用的工具。它自动推断出函数的工作原理。QueryEngineTool:一个允许 Agents 使用 queryEngine 的工具。由于 Agents 是基于 queryEngine 构建的,它们也可以将其他 Agents 作为工具使用。Toolspecs:由社区创建的工具集,通常包含针对特定服务的工具,如 Gmail。Utility Tools: 帮助处理 large amounts of data from other tools. 特指OnDemandToolLoader&LoadAndSearchToolSpec
Functional Tool
给出工具的 name 和 description 尤其重要,因为它有助于 Agent 理解什么时候应该使用该工具。
from llama_index.core.tools import FunctionTool
def get_weather(location: str) -> str:
"""Useful for getting the weather for a given location."""
print(f"Getting weather for {location}")
return f"The weather in {location} is sunny"
tool = FunctionTool.from_defaults(
get_weather,
name="my_weather_tool",
description="Useful for getting the weather for a given location.",
)
tool.call("Shanghai")
QueryEngine Tool
使用 QueryEngineTool 转换 QueryEngine 为 tool:
import chromadb
from llama_index.core import VectorStoreIndex
from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core.tools import QueryEngineTool
from llama_index.vector_stores.chroma import ChromaVectorStore
db = chromadb.PersistentClient(path="./alfred_chroma_db")
chroma_collection = db.get_or_create_collection("alfred")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
llm = HuggingFaceInferenceAPI(model_name="meta-llama/Llama-3.2-3B-Instruct")
# index 是 RAG 中的一个重要组件
index = VectorStoreIndex.from_vector_store(
vector_store=vector_store, embed_model=embed_model
)
# 通过index 创建 query Engine
query_engine = index.as_query_engine(llm=llm)
# 使用 QueryEngineTool 转换 query engine 为 tool
tool = QueryEngineTool.from_defaults(
query_engine=query_engine,
name="some useful name",
description="some useful description",
)
await tool.acall(
"Responds about research on the impact of AI on the future of work and society?"
)
ToolSpecs
Tool spec 是一组相互协作的工具,像一个用于特定目的的专业工具箱。
from llama_index.tools.google import GmailToolSpec
tool_spec = GmailToolSpec()
# 返回一个工具对象列表
tool_spec_list = tool_spec.to_tool_list()
# 返回每个对象的 name 和描述
[print(tool.metadata.name, tool.metadata.description) for tool in tool_spec_list]
返回 一个列表,包含了所以与邮件发送相关的 tools (函数),输出如下:
load_data load_data() -> List[llama_index.core.schema.Document]
Load emails from the user's account.
search_messages search_messages(query: str, max_results: Optional[int] = None)
Searches email messages given a query string and the maximum number
of results requested by the user
Returns: List of relevant message objects up to the maximum number of results.
Args:
query (str): The user's query
max_results (Optional[int]): The maximum number of search results
to return.
create_draft create_draft(to: Optional[List[str]] = None, subject: Optional[str] = None, message: Optional[str] = None) -> str
Create and insert a draft email.
Print the returned draft's message and id.
Returns: Draft object, including draft id and message meta data.
Args:
to (Optional[str]): The email addresses to send the message to
subject (Optional[str]): The subject for the event
message (Optional[str]): The message for the event
...
这里显示了3个工具:load_data(),search_messages(),create_draft()。
Utility tools
通常,直接查询 API 可能会返回大量数据,其中一些可能无关紧要,溢出 LLM 的上下文窗口,或无谓地增加用户使用 token 的数量。LlamaIndex 中的两个工具用于解决这个问题。
OnDemandToolLoader
它将数据加载器(BaseReader 类)转换为代理可以使用的工具,允许你的 Agent 按需加载、索引和查询数据。
- 数据加载器转换: 它接收一个 LlamaIndex 数据加载器(例如,用于读取 PDF、网站、数据库等)。
- 工具化: 将这个数据加载器包装成一个工具,这个工具可以被 Agent 调用。
- 按需加载:按需 (On-Demand)指数据不是预先加载和索引的,而是在 Agent 需要时才进行加载和索引。
- 加载、索引和查询: 工具在被调用时,会执行以下步骤:
- 加载数据: 使用数据加载器加载数据。
- 索引数据: 将加载的数据进行索引,通常使用向量存储(Vector Store)等方法,以便快速查询。
- 查询数据: 使用自然语言查询字符串来查询索引后的数据,并返回结果。
使用场景:
- 大型数据集: 当你的数据集非常大,无法一次性加载到内存中时,可以使用
OnDemandToolLoader按需加载数据。 - 动态数据: 当你的数据需要频繁更新时,可以使用
OnDemandToolLoader确保 Agent 始终访问最新的数据。 - Agent 工具集成: 当你希望将数据访问能力集成到你的 Agent 中时,可以使用
OnDemandToolLoader将数据加载器转换为一个工具。
实例:
# 1. 创建一个数据加载器 (例如,读取 PDF 文件)
data_loader = SimpleDirectoryReader(input_dir="./data")
# 2. 创建 OnDemandToolLoader
tool_loader = OnDemandToolLoader.from_loader(data_loader)
# 3. 获取工具
tool = tool_loader.as_tool()
# 4. Agent 可以调用这个工具来查询数据
# 假设 Agent 接收到查询 "What is the main topic of this document?"
response = tool.run("What is the main topic of this document?")
print(response)
LoadAndSearchToolSpec
它的作用是将一个现有的 Tool 转换为两个新的 Tool:一个用于加载数据并索引的 Tool,另一个用于搜索索引数据的 Tool。
工作原理:
Tool 包装: 它接收一个现有的 Tool 作为输入。 这个 Tool 可以是任何 LlamaIndex 支持的 Tool,例如用于读取文件、访问 API 等。
生成两个 Tool: LoadAndSearchToolSpec 将原始 Tool 包装成两个新的 Tool:
- 加载 Tool (Loading Tool): 这个 Tool 的作用是调用原始 Tool,获取其输出结果,并将结果进行 Indexing (索引可以大大提高搜索效率,特别是对于大型数据集)。 默认情况下,它使用向量索引 (Vector Index) 来索引数据。
- 搜索 Tool (Search Tool): 这个 Tool 的作用是接收一个查询字符串作为输入,然后在加载 Tool 创建的索引中进行搜索,并返回结果。
to_tool_list 方法: LoadAndSearchToolSpec 实现了 to_tool_list 方法,该方法返回一个包含加载 Tool 和搜索 Tool 的列表。
KAQ:为什么偏偏是 Loading Tool 和 Search Tool,而不是其他功能的 tools
是因为这两个工具对应了 Agent 在多数应用场景中都需要执行的两个关键步骤:获取信息 & 利用信息。
- 获取信息: Agent 需要从各种数据源获取信息,例如网页、文件、数据库、API 等。然后进行indexing处理。
- 利用信息: Agent 需要利用获取到的信息来回答用户的问题、执行用户的指令或完成其他任务。