检索增强型 OpenAI 代理¶
这是一个用于演示 OpenAI GPT-3 模型的示例,该模型已经通过检索增强技术进行了增强。在这个示例中,我们将展示如何使用检索增强技术来改进对话系统的性能。
在本教程中,我们将向您展示如何使用我们的OpenAIAgent
实现与工具检索器,以构建一个基于OpenAI的函数API的代理,并存储/索引任意数量的工具。我们的索引/检索模块有助于消除由于函数过多而无法适应提示的复杂性。
初始设置¶
让我们从导入一些简单的基本模块开始。
我们主要需要的是:
- OpenAI API
- 一个用于保存对话历史记录的地方
- 代理程序可以使用的工具定义。
如果您在Colab上打开此笔记本,您可能需要安装LlamaIndex 🦙。
In [ ]:
Copied!
%pip install llama-index-agent-openai-legacy
%pip install llama-index-agent-openai-legacy
In [ ]:
Copied!
!pip install llama-index
!pip install llama-index
In [ ]:
Copied!
import json
from typing import Sequence
from llama_index.core.tools import BaseTool, FunctionTool
import json
from typing import Sequence
from llama_index.core.tools import BaseTool, FunctionTool
/Users/suo/miniconda3/envs/llama/lib/python3.9/site-packages/deeplake/util/check_latest_version.py:32: UserWarning: A newer version of deeplake (3.6.7) is available. It's recommended that you update to the latest version using `pip install -U deeplake`. warnings.warn(
让我们为我们的代理人定义一些非常简单的计算器工具。
In [ ]:
Copied!
def multiply(a: int, b: int) -> int: """将两个整数相乘,并返回结果整数""" return a * bdef add(a: int, b: int) -> int: """将两个整数相加,并返回结果整数""" return a + bdef useless(a: int, b: int) -> int: """无用的玩具函数。""" passmultiply_tool = FunctionTool.from_defaults(fn=multiply, name="multiply")useless_tools = [ FunctionTool.from_defaults(fn=useless, name=f"useless_{str(idx)}") for idx in range(28)]add_tool = FunctionTool.from_defaults(fn=add, name="add")all_tools = [multiply_tool] + [add_tool] + useless_toolsall_tools_map = {t.metadata.name: t for t in all_tools}
def multiply(a: int, b: int) -> int: """将两个整数相乘,并返回结果整数""" return a * bdef add(a: int, b: int) -> int: """将两个整数相加,并返回结果整数""" return a + bdef useless(a: int, b: int) -> int: """无用的玩具函数。""" passmultiply_tool = FunctionTool.from_defaults(fn=multiply, name="multiply")useless_tools = [ FunctionTool.from_defaults(fn=useless, name=f"useless_{str(idx)}") for idx in range(28)]add_tool = FunctionTool.from_defaults(fn=add, name="add")all_tools = [multiply_tool] + [add_tool] + useless_toolsall_tools_map = {t.metadata.name: t for t in all_tools}
构建对象索引¶
在LlamaIndex中,我们有一个名为ObjectIndex
的构造,允许用户在任意对象上使用我们的索引数据结构。
ObjectIndex将处理对象的序列化和反序列化,并使用底层索引(例如VectorStoreIndex、SummaryIndex、KeywordTableIndex)作为存储机制。
在这种情况下,我们有一个大型的Tool对象集合,并且希望在这些Tool上定义一个ObjectIndex。
该索引捆绑了一个检索机制,即ObjectRetriever
。
这可以传递给我们的代理,以便在查询时执行Tool检索。
In [ ]:
Copied!
# 在这些工具上定义一个“对象”索引from llama_index.core import VectorStoreIndexfrom llama_index.core.objects import ObjectIndexobj_index = ObjectIndex.from_objects( all_tools, index_cls=VectorStoreIndex,)
# 在这些工具上定义一个“对象”索引from llama_index.core import VectorStoreIndexfrom llama_index.core.objects import ObjectIndexobj_index = ObjectIndex.from_objects( all_tools, index_cls=VectorStoreIndex,)
使用工具检索的OpenAIAgent¶
我们在LlamaIndex中提供了一个OpenAIAgent
实现,它可以接受一组BaseTool
对象上的ObjectRetriever
。
在查询时,我们首先会使用ObjectRetriever
来检索一组相关的工具。然后这些工具将被传递给agent;更具体地说,它们的函数签名将被传递给OpenAI函数调用API。
In [ ]:
Copied!
from llama_index.agent.openai import OpenAIAgent
from llama_index.agent.openai import OpenAIAgent
In [ ]:
Copied!
agent = OpenAIAgent.from_tools(
tool_retriever=obj_index.as_retriever(similarity_top_k=2), verbose=True
)
agent = OpenAIAgent.from_tools(
tool_retriever=obj_index.as_retriever(similarity_top_k=2), verbose=True
)
In [ ]:
Copied!
agent.chat("What's 212 multiplied by 122? Make sure to use Tools")
agent.chat("What's 212 multiplied by 122? Make sure to use Tools")
=== Calling Function === Calling function: multiply with args: { "a": 212, "b": 122 } Got output: 25864 ========================
Out[ ]:
Response(response='212 multiplied by 122 is 25,864.', source_nodes=[], metadata=None)
In [ ]:
Copied!
agent.chat("What's 212 added to 122 ? Make sure to use Tools")
agent.chat("What's 212 added to 122 ? Make sure to use Tools")
=== Calling Function === Calling function: add with args: { "a": 212, "b": 122 } Got output: 334 ========================
Out[ ]:
Response(response='212 added to 122 is 334.', source_nodes=[], metadata=None)