检索增强代理¶
在本教程中,我们将向您展示如何使用我们的 FunctionAgent
或 ReActAgent
实现结合工具检索器,来增强任何现有代理并存储/索引任意数量的工具。
我们的索引/检索模块有助于消除因函数过多而无法全部放入提示中的复杂性。
初始设置¶
让我们从导入一些简单的构建块开始。
我们主要需要的是
- OpenAI API
- 存储对话历史的地方
- 代理可以使用的工具定义。
如果您正在 colab 上打开此 Notebook,您可能需要安装 LlamaIndex 🦙。
In [ ]
已复制!
%pip install llama-index
%pip install llama-index
In [ ]
已复制!
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
import os os.environ["OPENAI_API_KEY"] = "sk-..."
让我们为我们的代理定义一些非常简单的计算器工具。
In [ ]
已复制!
from llama_index.core.tools import FunctionTool
def multiply(a: int, b: int) -> int:
"""Multiply two integers and returns the result integer"""
return a * b
def add(a: int, b: int) -> int:
"""Add two integers and returns the result integer"""
return a + b
def useless(a: int, b: int) -> int:
"""Toy useless function."""
pass
multiply_tool = FunctionTool.from_defaults(multiply, name="multiply")
add_tool = FunctionTool.from_defaults(add, name="add")
# toy-example of many tools
useless_tools = [
FunctionTool.from_defaults(useless, name=f"useless_{str(idx)}")
for idx in range(28)
]
all_tools = [multiply_tool] + [add_tool] + useless_tools
all_tools_map = {t.metadata.name: t for t in all_tools}
from llama_index.core.tools import FunctionTool def multiply(a: int, b: int) -> int: """Multiply two integers and returns the result integer""" return a * b def add(a: int, b: int) -> int: """Add two integers and returns the result integer""" return a + b def useless(a: int, b: int) -> int: """Toy useless function.""" pass multiply_tool = FunctionTool.from_defaults(multiply, name="multiply") add_tool = FunctionTool.from_defaults(add, name="add") # toy-example of many tools useless_tools = [ FunctionTool.from_defaults(useless, name=f"useless_{str(idx)}") for idx in range(28) ] all_tools = [multiply_tool] + [add_tool] + useless_tools all_tools_map = {t.metadata.name: t for t in all_tools}
构建对象索引¶
LlamaIndex 中有一个 ObjectIndex
构造,它允许用户在任意对象上使用我们的索引数据结构。ObjectIndex 将处理对象的序列化/反序列化,并使用底层索引(例如 VectorStoreIndex, SummaryIndex, KeywordTableIndex)作为存储机制。
在本例中,我们有大量工具对象集合,我们希望在这些工具上定义一个 ObjectIndex。
该索引捆绑了一个检索机制,一个 ObjectRetriever
。
这可以传递给我们的代理,以便它在查询时执行工具检索。
In [ ]
已复制!
# define an "object" index over these tools
from llama_index.core import VectorStoreIndex
from llama_index.core.objects import ObjectIndex
obj_index = ObjectIndex.from_objects(
all_tools,
index_cls=VectorStoreIndex,
# if we were using an external vector store, we could pass the stroage context and any other kwargs
# storage_context=storage_context,
# embed_model=embed_model,
# ...
)
# define an "object" index over these tools from llama_index.core import VectorStoreIndex from llama_index.core.objects import ObjectIndex obj_index = ObjectIndex.from_objects( all_tools, index_cls=VectorStoreIndex, # if we were using an external vector store, we could pass the stroage context and any other kwargs # storage_context=storage_context, # embed_model=embed_model, # ... )
稍后重新加载索引时,我们可以使用 from_objects_and_index
方法。
In [ ]
已复制!
# from llama_index.core import StorageContext, load_index_from_storage
# saving and loading from disk
# obj_index.index.storage_context.persist(persist_dir="obj_index_storage")
# reloading from disk
# vector_index = load_index_from_storage(StorageContext.from_defaults(persist_dir="obj_index_storage"))
# or if using an external vector store, no need to persist, just reload the index
# vector_index = VectorStoreIndex.from_vector_store(vector_store=vector_store, ...)
# Then, we can reload the ObjectIndex
# obj_index = ObjectIndex.from_objects_and_index(
# all_tools,
# index=vector_index,
# )
# from llama_index.core import StorageContext, load_index_from_storage # saving and loading from disk # obj_index.index.storage_context.persist(persist_dir="obj_index_storage") # reloading from disk # vector_index = load_index_from_storage(StorageContext.from_defaults(persist_dir="obj_index_storage")) # or if using an external vector store, no need to persist, just reload the index # vector_index = VectorStoreIndex.from_vector_store(vector_store=vector_store, ...) # Then, we can reload the ObjectIndex # obj_index = ObjectIndex.from_objects_and_index( # all_tools, # index=vector_index, # )
带工具检索的代理¶
LlamaIndex 中的代理可以与 ToolRetriever
一起使用,以便在查询时检索工具。
在查询时,我们将首先使用 ObjectRetriever
检索一组相关的工具。然后将这些工具传递给代理;更具体地说,它们的函数签名将传递给 OpenAI 函数调用 API。
In [ ]
已复制!
from llama_index.core.agent.workflow import FunctionAgent, ReActAgent
from llama_index.core.workflow import Context
from llama_index.llms.openai import OpenAI
agent = FunctionAgent(
tool_retriever=obj_index.as_retriever(similarity_top_k=2),
llm=OpenAI(model="gpt-4o"),
)
# context to hold the session/state
ctx = Context(agent)
from llama_index.core.agent.workflow import FunctionAgent, ReActAgent from llama_index.core.workflow import Context from llama_index.llms.openai import OpenAI agent = FunctionAgent( tool_retriever=obj_index.as_retriever(similarity_top_k=2), llm=OpenAI(model="gpt-4o"), ) # context to hold the session/state ctx = Context(agent)
In [ ]
已复制!
resp = await agent.run(
"What's 212 multiplied by 122? Make sure to use Tools", ctx=ctx
)
print(str(resp))
print(resp.tool_calls)
resp = await agent.run( "What's 212 multiplied by 122? Make sure to use Tools", ctx=ctx ) print(str(resp)) print(resp.tool_calls)
The result of multiplying 212 by 122 is 25,864. [ToolCallResult(tool_name='multiply', tool_kwargs={'a': 212, 'b': 122}, tool_id='call_4Ygos3MpRH7Gj3R79HISRGyH', tool_output=ToolOutput(content='25864', tool_name='multiply', raw_input={'args': (), 'kwargs': {'a': 212, 'b': 122}}, raw_output=25864, is_error=False), return_direct=False)]
In [ ]
已复制!
resp = await agent.run(
"What's 212 added to 122 ? Make sure to use Tools", ctx=ctx
)
print(str(resp))
print(resp.tool_calls)
resp = await agent.run( "What's 212 added to 122 ? Make sure to use Tools", ctx=ctx ) print(str(resp)) print(resp.tool_calls)
The result of adding 212 to 122 is 334. [ToolCallResult(tool_name='add', tool_kwargs={'a': 212, 'b': 122}, tool_id='call_rXUfwQ477bcd6bxafQHgETaa', tool_output=ToolOutput(content='334', tool_name='add', raw_input={'args': (), 'kwargs': {'a': 212, 'b': 122}}, raw_output=334, is_error=False), return_direct=False)]