Skip to content

用法模式#

入门指南#

代理程序是从一组工具初始化的。以下是一个从一组工具实例化 ReAct 代理程序的示例。

from llama_index.core.tools import FunctionTool
from llama_index.llms.openai import OpenAI
from llama_index.core.agent import ReActAgent


# 定义示例工具
def multiply(a: int, b: int) -> int:
    """将两个整数相乘并返回结果整数"""
    return a * b


multiply_tool = FunctionTool.from_defaults(fn=multiply)

# 初始化 llm
llm = OpenAI(model="gpt-3.5-turbo-0613")

# 初始化 ReAct 代理程序
agent = ReActAgent.from_tools([multiply_tool], llm=llm, verbose=True)

代理程序支持 chatquery 两种端点,分别继承自我们的 ChatEngineQueryEngine

示例用法:

agent.chat("What is 2123 * 215123")

要根据 LLM 自动选择最佳代理程序,可以使用 from_llm 方法生成代理程序。

from llama_index.core.agent import AgentRunner

agent = AgentRunner.from_llm([multiply_tool], llm=llm, verbose=True)

定义工具#

查询引擎工具#

将查询引擎包装为代理程序工具也很容易。只需按照以下步骤操作:

from llama_index.core.agent import ReActAgent
from llama_index.core.tools import QueryEngineTool

# 注意:lyft_index 和 uber_index 都是 SimpleVectorIndex 实例
lyft_engine = lyft_index.as_query_engine(similarity_top_k=3)
uber_engine = uber_index.as_query_engine(similarity_top_k=3)

query_engine_tools = [
    QueryEngineTool(
        query_engine=lyft_engine,
        metadata=ToolMetadata(
            name="lyft_10k",
            description="提供 2021 年 Lyft 财务信息。"
            "使用详细的纯文本问题作为工具的输入。",
        ),
        return_direct=False,
    ),
    QueryEngineTool(
        query_engine=uber_engine,
        metadata=ToolMetadata(
            name="uber_10k",
            description="提供 2021 年 Uber 财务信息。"
            "使用详细的纯文本问题作为工具的输入。",
        ),
        return_direct=False,
    ),
]

# 初始化 ReAct 代理程序
agent = ReActAgent.from_tools(query_engine_tools, llm=llm, verbose=True)

使用其他代理程序作为工具#

我们代理程序的一个巧妙特性是,由于它们继承自 BaseQueryEngine,所以可以通过我们的 QueryEngineTool 轻松地将其他代理程序定义为工具。

from llama_index.core.tools import QueryEngineTool

query_engine_tools = [
    QueryEngineTool(
        query_engine=sql_agent,
        metadata=ToolMetadata(
            name="sql_agent", description="可以执行 SQL 查询的代理程序。"
        ),
    ),
    QueryEngineTool(
        query_engine=gmail_agent,
        metadata=ToolMetadata(
            name="gmail_agent",
            description="可以在 Gmail 上发送电子邮件的工具。",
        ),
    ),
]

outer_agent = ReActAgent.from_tools(query_engine_tools, llm=llm, verbose=True)

具有规划的代理程序#

将初始任务分解为更易理解的子任务是一种强大的模式。

LlamaIndex 提供了一个代理程序规划模块,正是做到了这一点:

from llama_index.agent.openai import OpenAIAgentWorker
from llama_index.core.agent import (
    StructuredPlannerAgent,
    FunctionCallingAgentWorker,
)

worker = FunctionCallingAgentWorker.from_tools(tools, llm=llm)
agent = StructuredPlannerAgent(worker)

一般来说,与基本的 AgentRunner 类相比,这种代理程序可能需要更长时间来响应,但输出通常会更完整。另一个要考虑的权衡是,规划通常需要一个非常有能力的 LLM(例如,gpt-3.5-turbo 有时对规划不太稳定,而 gpt-4-turbo 做得更好)。

完整指南 中了解更多信息。

低级 API#

OpenAIAgent 和 ReActAgent 只是与与 AgentRunner 交互的 AgentWorker 的简单包装。

所有代理程序都可以用这种方式定义。例如,对于 OpenAIAgent:

from llama_index.core.agent import AgentRunner
from llama_index.agent.openai import OpenAIAgentWorker

# 从工具构建 OpenAIAgent
openai_step_engine = OpenAIAgentWorker.from_tools(tools, llm=llm, verbose=True)
agent = AgentRunner(openai_step_engine)

这也是自定义代理程序的首选格式。

查看 低级代理程序指南 以获取更多详细信息。

自定义您的代理程序#

如果您希望自定义您的代理程序,可以选择对 CustomSimpleAgentWorker 进行子类化,并将其插入到 AgentRunner 中(参见上文)。

from llama_index.core.agent import CustomSimpleAgentWorker


class MyAgentWorker(CustomSimpleAgentWorker):
    """自定义代理程序工作者。"""

    # 在此定义类
    pass


# 将工作者包装到 AgentRunner 中
agent = MyAgentWorker(...).as_agent()
查看我们的自定义代理笔记指南以获取更多详细信息。

高级概念(适用于 OpenAIAgent,处于测试版)#

您还可以在更高级的设置中使用代理。例如,在查询时能够从索引中检索工具,并且能够在现有工具集上执行查询规划。

这些功能主要是使用我们的 OpenAIAgent 类实现的(依赖于 OpenAI 函数 API)。我们正在积极研究对更通用的 ReActAgent 的支持。

注意:这些功能主要仍处于测试版。抽象化可能会随时间变化并变得更通用。

功能检索代理#

如果工具集非常庞大,您可以创建一个 ObjectIndex 来索引这些工具,然后在查询时向代理传递一个 ObjectRetriever,以便在代理从候选工具中选择之前,首先动态检索相关工具。

首先,我们在现有工具集上构建一个 ObjectIndex

# 在这些工具上定义一个“对象”索引
from llama_index.core import VectorStoreIndex
from llama_index.core.objects import ObjectIndex

obj_index = ObjectIndex.from_objects(
    all_tools,
    index_cls=VectorStoreIndex,
)

然后我们定义我们的 OpenAIAgent

from llama_index.agent.openai import OpenAIAgent

agent = OpenAIAgent.from_tools(
    tool_retriever=obj_index.as_retriever(similarity_top_k=2), verbose=True
)

您可以在完整指南中找到有关对象索引的更多详细信息。

上下文检索代理#

我们的上下文增强的 OpenAI 代理在调用任何工具之前总是执行检索。

这有助于提供额外的上下文,可以帮助代理更好地选择工具,而不仅仅是在没有任何上下文的情况下做出决定。

from llama_index.core import Document
from llama_index.agent.openai_legacy import ContextRetrieverOpenAIAgent


# 玩具索引 - 存储缩写列表
texts = [
    "缩写:X = 收入",
    "缩写:YZ = 风险因素",
    "缩写:Z = 成本",
]
docs = [Document(text=t) for t in texts]
context_index = VectorStoreIndex.from_documents(docs)

# 添加上下文代理
context_agent = ContextRetrieverOpenAIAgent.from_tools_and_retriever(
    query_engine_tools,
    context_index.as_retriever(similarity_top_k=1),
    verbose=True,
)
response = context_agent.chat("2022年3月的 YZ 是什么?")

查询规划#

OpenAI 函数代理可以实现高级查询规划。关键是为代理提供一个 QueryPlanTool - 如果代理调用 QueryPlanTool,则必须推断出代表一组子工具的查询计划的完整 Pydantic 模式。

# 定义查询计划工具
from llama_index.core.tools import QueryPlanTool
from llama_index.core import get_response_synthesizer

response_synthesizer = get_response_synthesizer(
    service_context=service_context
)
query_plan_tool = QueryPlanTool.from_defaults(
    query_engine_tools=[query_tool_sept, query_tool_june, query_tool_march],
    response_synthesizer=response_synthesizer,
)

# 初始化代理
agent = OpenAIAgent.from_tools(
    [query_plan_tool],
    max_function_calls=10,
    llm=OpenAI(temperature=0, model="gpt-4-0613"),
    verbose=True,
)

# 应输出一个查询计划,以调用三月、六月和九月的工具
response = agent.query(
    "分析 Uber 在三月、六月和九月的收入增长"
)