文档API 参考📓 教程🧑‍🍳 食谱🤝 集成💜 Discord🎨 Studio
文档

Agent

本页面介绍如何在 Haystack 中创建能够使用各种 Haystack 组件检索信息、生成响应和执行操作的 AI 智能体。

什么是 AI 智能体?

AI 智能体是一个能够

  • 理解用户输入(文本、图像、音频和其他查询),
  • 检索相关信息(文档或结构化数据),
  • 生成智能响应(使用 OpenAI 或 Hugging Face 模型等 LLM),
  • 执行操作(调用 API、获取实时数据、执行函数)。

理解 AI 智能体

AI 智能体是利用大型语言模型 (LLM) 来做出决策和解决复杂任务的自主系统。它们使用工具、记忆和推理与环境进行交互。

构成 AI 智能体的要素

AI 智能体不仅仅是一个聊天机器人。它会主动规划、选择正确的工具并执行任务以实现目标。与传统软件不同,它能适应新信息并根据需要改进其流程。

  1. LLM 作为大脑:智能体的核心是 LLM,它理解上下文、处理自然语言并作为中央智能系统。
  2. 交互工具:智能体连接到外部工具、API 和数据库以获取信息并采取行动。
  3. 用于上下文的记忆:短期记忆有助于跟踪对话,而长期记忆则存储知识以供将来交互使用。
  4. 推理和规划:智能体分解复杂问题,制定分步行动计划,并根据新数据和反馈进行调整。

AI 智能体的工作原理

AI 智能体以一个定义其角色和目标的提示开始。它决定何时使用工具,收集数据,并通过推理和行动循环来完善其方法。它评估进展并调整其策略以改进结果。

例如,一个客服智能体使用数据库回答查询。如果它没有答案,它会获取实时数据,对其进行摘要,然后提供响应。一个编码助手会理解项目需求,建议解决方案,甚至编写代码。

关键组件

Agent

Haystack 有一个通用的 Agent 组件,可以与基于聊天的 LLM 和工具进行交互以解决复杂的查询。它需要一个支持工具的 Chat Generator 才能工作,并且可以根据您的需求进行自定义。请查看 Agent 文档,或下面的 示例,了解它是如何工作的。

附加组件

您可以使用管道中的三个主要元素,自己构建一个 Haystack AI 智能体。

  • Chat Generators 用于使用 LLM 生成工具调用(包括工具名称和参数)或助手响应,
  • Tool 类,允许 LLM 执行操作,例如运行管道或调用外部 API,连接到外部世界,
  • ToolInvoker 组件,用于执行 LLM 生成的工具调用。它解析 LLM 的工具调用响应,并从管道中调用具有正确参数的相应工具。

Haystack 中创建工具的三种方法:

  • Tool 类 – 为所有 Generators 创建一个工具表示,以实现一致的工具调用体验。它允许大多数自定义,因为您可以定义自己的名称和描述。
  • ComponentTool 类 – 将 Haystack 组件包装成一个可调用的工具。
  • @tool 装饰器 – 从 Python 函数创建工具,并自动使用其函数名称和文档字符串。
  • Toolset – 一个用于分组多个工具的容器,可以直接传递给 Agents 或 Generators。

示例智能体

工具调用智能体

您可以使用Agent 组件创建一个类似的工具调用智能体。

from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.websearch import SerperDevWebSearch
from haystack.dataclasses import Document, ChatMessage
from haystack.tools.component_tool import ComponentTool

from typing import List

# Create the web search component
web_search = SerperDevWebSearch(top_k=3)

# Create the ComponentTool with simpler parameters
web_tool = ComponentTool(
    component=web_search,
    name="web_search",
    description="Search the web for current information like weather, news, or facts."
)

# Create the agent with the web tool
tool_calling_agent = Agent(
    chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
    system_prompt="""You're a helpful agent. When asked about current information like weather, news, or facts, 
                     use the web_search tool to find the information and then summarize the findings.
                     When you get web search results, extract the relevant information and present it in a clear, 
                     concise manner.""",
    tools=[web_tool]
)

# Run the agent with the user message
user_message = ChatMessage.from_user("How is the weather in Berlin?")
result = tool_calling_agent.run(messages=[user_message])

# Print the result - using .text instead of .content
print(result["messages"][-1].text)

结果

>>> The current weather in Berlin is approximately 60°F. The forecast for today includes clouds in the morning with some sunshine later. The high temperature is expected to be around 65°F, and the low tonight will drop to 40°F. 

- **Morning**: 49°F
- **Afternoon**: 57°F
- **Evening**: 47°F
- **Overnight**: 39°F

For more details, you can check the full forecasts on [AccuWeather](https://www.accuweather.com/en/de/berlin/10178/current-weather/178087) or [Weather.com](https://weather.com/weather/today/l/5ca23443513a0fdc1d37ae2ffaf5586162c6fe592a66acc9320a0d0536be1bb9).

带工具的管道

以下是如何在的帮助下构建工具调用智能体的示例。ToolInvoker.

以下是此代码示例中发生的情况:

  1. OpenAIChatGenerator 使用 LLM 分析用户的消息,并确定是提供助手响应还是启动工具调用。
  2. ConditionalRouter 将来自OpenAIChatGenerator 的输出定向到there_are_tool_calls 分支(如果它是工具调用)或定向到final_replies 以直接返回给用户。
  3. ToolInvoker 执行 LLM 生成的工具调用。ComponentTool 包装了SerperDevWebSearch 组件,该组件会获取实时搜索结果,使其可供ToolInvoker 作为工具执行。
  4. 在工具提供其输出后,ToolInvoker 将此信息连同由MessageCollector 存储的原始用户问题一起发送回MessageCollector.
from haystack import component, Pipeline
from haystack.components.tools import ToolInvoker
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.routers import ConditionalRouter
from haystack.components.websearch import SerperDevWebSearch
from haystack.core.component.types import Variadic
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool

from typing import Any, Dict, List

# helper component to temporarily store last user query before the tool call 
@component()
class MessageCollector:
    def __init__(self):
        self._messages = []

    @component.output_types(messages=List[ChatMessage])
    def run(self, messages: Variadic[List[ChatMessage]]) -> Dict[str, Any]:

        self._messages.extend([msg for inner in messages for msg in inner])
        return {"messages": self._messages}

    def clear(self):
        self._messages = []

# Create a tool from a component
web_tool = ComponentTool(
    component=SerperDevWebSearch(top_k=3)
)

# Define routing conditions
routes = [
    {
        "condition": "{{replies[0].tool_calls | length > 0}}",
        "output": "{{replies}}",
        "output_name": "there_are_tool_calls",
        "output_type": List[ChatMessage],
    },
    {
        "condition": "{{replies[0].tool_calls | length == 0}}",
        "output": "{{replies}}",
        "output_name": "final_replies",
        "output_type": List[ChatMessage], 
    },
]

# Create the pipeline
tool_agent = Pipeline()
tool_agent.add_component("message_collector", MessageCollector())
tool_agent.add_component("generator", OpenAIChatGenerator(model="gpt-4o-mini", tools=[web_tool]))
tool_agent.add_component("router", ConditionalRouter(routes, unsafe=True))
tool_agent.add_component("tool_invoker", ToolInvoker(tools=[web_tool]))

tool_agent.connect("generator.replies", "router")
tool_agent.connect("router.there_are_tool_calls", "tool_invoker")
tool_agent.connect("router.there_are_tool_calls", "message_collector")
tool_agent.connect("tool_invoker.tool_messages", "message_collector")
tool_agent.connect("message_collector", "generator.messages")

messages = [
    ChatMessage.from_system("You're a helpful agent choosing the right tool when necessary"), 
    ChatMessage.from_user("How is the weather in Berlin?")]
result = tool_agent.run({"messages": messages})

print(result["router"]["final_replies"][0].text)

结果

>>> The current weather in Berlin is around 46°F (8°C) with cloudy conditions. The high for today is forecasted to reach 48°F (9°C) and the low is expected to be around 37°F (3°C). The humidity is quite high at 92%, and there is a light wind blowing at 4 mph.

For more detailed weather updates, you can check the following links:
- [AccuWeather](https://www.accuweather.com/en/de/berlin/10178/weather-forecast/178087)
- [Weather.com](https://weather.com/weather/today/l/5ca23443513a0fdc1d37ae2ffaf5586162c6fe592a66acc9320a0d0536be1bb9)