跳到内容

代理#

在 LlamaIndex 中,我们将“代理”定义为一个特定的系统,它使用 LLM、内存和工具来处理来自外部用户的输入。这与“agentic”一词形成对比,“agentic”通常指代理的超类,即任何在过程中具有 LLM 决策能力的系统。

在 LlamaIndex 中创建一个代理只需要几行代码

import asyncio
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI


# Define a simple calculator tool
def multiply(a: float, b: float) -> float:
    """Useful for multiplying two numbers."""
    return a * b


# Create an agent workflow with our calculator tool
agent = FunctionAgent(
    tools=[multiply],
    llm=OpenAI(model="gpt-4o-mini"),
    system_prompt="You are a helpful assistant that can multiply two numbers.",
)


async def main():
    # Run the agent
    response = await agent.run("What is 1234 * 4567?")
    print(str(response))


# Run the agent
if __name__ == "__main__":
    asyncio.run(main())

调用此代理会启动一个特定的行动循环

  • 代理获取最新消息 + 聊天记录
  • 工具模式和聊天记录通过 API 发送
  • 代理以直接响应或工具调用列表进行响应
    • 每个工具调用都得到执行
    • 工具调用结果被添加到聊天记录中
    • 代理使用更新的记录再次被调用,并直接响应或选择更多调用

工具#

工具可以简单地定义为 Python 函数,或使用 FunctionToolQueryEngineTool 等类进行进一步定制。LlamaIndex 还使用称为 Tool Specs 的东西为常见 API 提供了一系列预定义工具。

您可以在工具指南中阅读有关配置工具的更多信息

内存#

内存是构建代理时的核心组件。默认情况下,所有 LlamaIndex 代理都使用 ChatMemoryBuffer 作为内存。

要定制它,您可以在代理外部声明它并将其传入

from llama_index.core.memory import ChatMemoryBuffer

memory = ChatMemoryBuffer.from_defaults(token_limit=40000)

response = await agent.run(..., memory=memory)

您可以在内存指南中阅读有关配置内存的更多信息

多模态代理#

一些 LLMs 将支持多种模态,例如图像和文本。通过使用带有内容块的聊天消息,我们可以将图像传递给代理进行推理。

例如,假设您有此演示文稿中幻灯片的屏幕截图。

您可以将此图像传递给代理进行推理,并查看它如何读取图像并相应地执行操作。

from llama_index.core.agent.workflow import FunctionAgent
from llama_index.core.llms import ChatMessage, ImageBlock, TextBlock
from llama_index.llms.openai import OpenAI

llm = OpenAI(model="gpt-4o-mini", api_key="sk-...")


def add(a: int, b: int) -> int:
    """Useful for adding two numbers together."""
    return a + b


workflow = FunctionAgent(
    tools=[add],
    llm=llm,
)

msg = ChatMessage(
    role="user",
    blocks=[
        TextBlock(text="Follow what the image says."),
        ImageBlock(path="./screenshot.png"),
    ],
)

response = await workflow.run(msg)
print(str(response))

多代理系统#

您可以将代理组合成一个多代理系统,其中每个代理都可以将控制权交给另一个代理,以便在完成任务时进行协调。

from llama_index.core.agent.workflow import AgentWorkflow

multi_agent = AgentWorkflow(agents=[FunctionAgent(...), FunctionAgent(...)])

resp = await agent.run("query")

继续阅读以了解有关多代理系统的更多信息。

手动代理#

虽然 FunctionAgentReActAgentCodeActAgentAgentWorkflow 等代理类抽象掉了许多细节,但有时最好构建自己的低级代理。

直接使用 LLM 对象,您可以快速实现一个基本的代理循环,同时完全控制工具调用和错误处理的工作方式。

from llama_index.core.llms import ChatMessage
from llama_index.core.tools import FunctionTool
from llama_index.llms.openai import OpenAI


def select_song(song_name: str) -> str:
    """Useful for selecting a song."""
    return f"Song selected: {song_name}"


tools = [FunctionTool.from_defaults(select_song)]
tools_by_name = {t.metadata.name: t for t in [tool]}

# call llm with initial tools + chat history
chat_history = [ChatMessage(role="user", content="Pick a random song for me")]
resp = llm.chat_with_tools([tool], chat_history=chat_history)

# parse tool calls from response
tool_calls = llm.get_tool_calls_from_response(
    resp, error_on_no_tool_call=False
)

# loop while there are still more tools to call
while tool_calls:
    # add the LLM's response to the chat history
    chat_history.append(resp.message)

    # call every tool and add its result to chat_history
    for tool_call in tool_calls:
        tool_name = tool_call.tool_name
        tool_kwargs = tool_call.tool_kwargs

        print(f"Calling {tool_name} with {tool_kwargs}")
        tool_output = tool(**tool_kwargs)
        chat_history.append(
            ChatMessage(
                role="tool",
                content=str(tool_output),
                # most LLMs like OpenAI need to know the tool call id
                additional_kwargs={"tool_call_id": tool_call.tool_id},
            )
        )

        # check if the LLM can write a final response or calls more tools
        resp = llm.chat_with_tools([tool], chat_history=chat_history)
        tool_calls = llm.get_tool_calls_from_response(
            resp, error_on_no_tool_call=False
        )

# print the final response
print(resp.message.content)

示例 / 模块指南#

您可以在模块指南页面找到更完整的示例和模块指南列表。