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

函数调用

了解函数调用以及如何在 Haystack 中将其用作工具。

函数调用是一项强大功能,可显著增强大型语言模型 (LLM) 的能力。它能够实现更好的功能、即时数据访问和交互,并为与外部 API 和服务的集成奠定基础。函数调用将 LLM 转变为适用于各种用例场景的适应性工具。

用例

函数调用可用于多种目的,但以下两点尤其值得注意:

  1. 增强的 LLM 功能:函数调用增强了 LLM 的功能,使其超越了简单的文本生成。它允许将人类生成的提示转换为精确的函数调用描述符。这些描述符随后可由连接的 LLM 框架用于执行计算、操作数据以及与外部 API 交互。这种功能的扩展使 LLM 成为适用于各种任务和行业的适应性工具。
  2. 实时数据访问和交互:函数调用使 LLM 能够创建函数调用来访问和交互实时数据。这对于需要最新数据的应用程序至关重要,例如新闻、天气或金融市场更新。通过提供对最新信息的访问,此功能极大地提高了 LLM 在不断变化和时间关键型情况下的可用性和可信度。

🚧

重要提示

模型实际上并不会调用函数。函数调用会返回一个 JSON,其中包含要调用的函数名称和参数。

示例

最简单形式下,Haystack 用户可以通过直接与 ChatGenerators 交互来调用函数。在此示例中,人类提示“柏林的天气怎么样?”被转换为一个方法参数调用描述符,该描述符随后可以传递给某个假设的天气服务。

import json 

from typing import Dict, Any, List
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "format": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "The temperature unit to use. Infer this from the users location.",
                    },
                },
                "required": ["location", "format"],
            },
        }
    }
]
messages = [ChatMessage.from_user("What's the weather like in Berlin?")]
generator = OpenAIChatGenerator()
response = generator.run(messages=messages, generation_kwargs= {"tools": tools})
response_msg = response["replies"][0]

messages.append(response_msg)
print(response_msg)

>> ChatMessage(_role=<ChatRole.ASSISTANT: 'assistant'>, _content=[ToolCall(tool_name='get_current_weather', 
>> arguments={'location': 'Berlin', 'format': 'celsius'}, id='call_9kJ0Vql2w2oXkTZJ5SVt1KGh')], 
>> _name=None, _meta={'model': 'gpt-4o-mini-2024-07-18', 'index': 0, 
>> 'finish_reason': 'tool_calls', 'usage': {'completion_tokens': 21, 'prompt_tokens': 88, 
>> 'total_tokens': 109, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 
>> 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 
>> 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}})

让我们假设这个假设的天气服务响应了关于柏林当前天气数据的 JSON 响应。

weather_response = [{
  "id": "response_uhGNifLfopt5JrCUxXw1L3zo",
  "status": "success",
  "function": {
    "name": "get_current_weather",
    "arguments": {
      "location": "Berlin",
      "format": "celsius"
    }
  },
  "data": {
    "location": "Berlin",
    "temperature": 18,
    "weather_condition": "Partly Cloudy",
    "humidity": "60%",
    "wind_speed": "15 km/h",
    "observation_time": "2024-03-05T14:00:00Z"
  }
}]

我们通常会将响应打包回 ChatMessage,并将其添加到消息列表中。

fcm = ChatMessage.from_function(content=json.dumps(weather_response), name="get_current_weather")
messages.append(fcm)

将这些消息发回 LLM 使模型能够通过以下方式理解正在进行的 LLM 交互的上下文:ChatMessage 列表,并以人类可读的柏林天气报告进行回复。

response = generator.run(messages=messages)
response_msg = response["replies"][0]

print(response_msg.content)

>> Currently in Berlin, the weather is partly cloudy with a temperature of 18°C. The humidity is 60% and there is a wind speed of 15 km/h.

其他参考资料

Haystack 2.0 通过管道引入了一种更好的函数调用方式。

例如,您可以使用 OpenAPI 规范轻松地将 LLM 与 ChatGenerator 连接到外部服务。这使您可以使用函数调用解析服务参数,然后使用这些参数调用外部服务。服务的响应将被添加回 LLM 的上下文窗口。此方法支持实时、检索器增强生成,可与任何符合 OpenAPI 的服务配合使用。这是 LLM 如何使用外部结构化数据和功能方面的一项重大改进。

有关更多信息和示例,请参阅有关 OpenAPIServiceToFunctionsOpenAPIServiceConnector 的文档。

📓 教程:使用函数调用构建聊天应用程序

🧑‍🍳 食谱: