📘 **TELUS Agriculture & Consumer Goods** 如何通过 **Haystack Agents** 转变促销交易

Haystack 2.9.0

在 Github 上查看

⭐️ Highlights

工具调用支持

我们引入了 Tool,这是一个简单统一的抽象,用于在 Haystack 中表示工具,以及 ToolInvoker,用于执行由 LLM 准备的工具调用。这些功能可以轻松地将工具调用集成到您的 Haystack 管道中,从而在与 OpenAIChatGeneratorHuggingFaceAPIChatGenerator 等组件一起使用时,实现与工具的无缝交互。以下是如何使用它们:

def dummy_weather_function(city: str):
    return f"The weather in {city} is 20 degrees."

tool = Tool(
    name="weather_tool",
    description="A tool to get the weather",
    function=dummy_weather_function,
    parameters={
      "type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"],
    }
)

pipeline = Pipeline()
pipeline.add_component("llm", OpenAIChatGenerator(model="gpt-4o-mini", tools=[tool]))
pipeline.add_component("tool_invoker", ToolInvoker(tools=[tool]))
pipeline.connect("llm.replies", "tool_invoker.messages")

message = ChatMessage.from_user("How is the weather in Berlin today?")
result = pipeline.run({"llm": {"messages": [message]}})

将组件用作工具 作为 Tool 的抽象,ComponentTool 允许 LLM 直接与 Web 搜索、文档处理或自定义用户组件等组件进行交互。它简化了模式生成和类型转换,使得向 LLM 公开复杂的组件功能变得容易。

# Create a tool from the component
tool = ComponentTool(
    component=SerperDevWebSearch(api_key=Secret.from_env_var("SERPERDEV_API_KEY"), top_k=3),
    name="web_search",  # Optional: defaults to "serper_dev_web_search"
    description="Search the web for current information on any topic"  # Optional: defaults to component docstring
)

新的拆分方法:RecursiveDocumentSplitter

RecursiveDocumentSplitter 引入了一种更智能的文本拆分方法。它使用一组分隔符递归地分割文本,从第一个分隔符开始。如果块仍然大于指定大小,拆分器将移动到列表中的下一个分隔符。这种方法可确保高效且精细的文本拆分,以改进处理。

from haystack.components.preprocessors import RecursiveDocumentSplitter

splitter = RecursiveDocumentSplitter(split_length=260, split_overlap=0, separators=["\n\n", "\n", ".", " "])
doc_chunks = splitter.run([Document(content="...")])

⚠️ 重构了 ChatMessage 数据类

ChatMessage 数据类已被重构,以提高灵活性和兼容性。作为此更新的一部分,已删除 content 属性,并用新的 text 属性替换,用于访问 ChatMessage 的文本值。此更改可确保未来兼容性,并更好地支持工具调用及其结果等功能。有关新 API 和迁移步骤的详细信息,请参阅 ChatMessage 文档。如果您对此重构有任何疑问,请随时在 此 Github discussion 中告诉我们。

⬆️ 升级说明

  • ChatMessage 数据类的重构包含一些涉及 ChatMessage 创建和访问属性的重大更改。如果您的 Pipeline 包含一个 ChatPromptBuilder,并且使用 haystack-ai =< 2.9.0 进行序列化,则反序列化可能会失败。有关更改的详细信息以及如何迁移,请参阅 ChatMessage 文档
  • 已从 PyPDFToDocument 中移除已弃用的 converter init 参数。请改用其他 init 参数,或创建自定义组件。
  • SentenceWindowRetriever 的输出键 context_documents 现在输出一个 List[Document],其中包含按 split_idx_start 排序的检索到的文档和上下文窗口。
  • 将转换器中的 store_full_path 默认值更新为 False

🚀 新功能

  • 引入了 ComponentTool,这是一个包装 Haystack 组件的新工具,允许它们被用作 LLM(各种 ChatGenerators)的工具。此 ComponentTool 支持自动工具模式生成、输入类型转换,并支持具有运行方法的组件,这些方法具有输入类型

    • 基本类型(str、int、float、bool、dict)
    • 数据类(简单结构和嵌套结构)
    • 基本类型列表(例如,List[str]
    • 数据类列表(例如,List[Document]
    • 混合类型参数(例如,List[Document]、str 等)

    示例用法

    
    from haystack import component, Pipeline
    from haystack.tools import ComponentTool
    from haystack.components.websearch import SerperDevWebSearch
    from haystack.utils import Secret
    from haystack.components.tools.tool_invoker import ToolInvoker
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    
    # Create a SerperDev search component
    search = SerperDevWebSearch(api_key=Secret.from_env_var("SERPERDEV_API_KEY"), top_k=3)
    
    # Create a tool from the component
    tool = ComponentTool(
        component=search,
        name="web_search",  # Optional: defaults to "serper_dev_web_search"
        description="Search the web for current information on any topic"  # Optional: defaults to component docstring
    )
    
    # Create pipeline with OpenAIChatGenerator and ToolInvoker
    pipeline = Pipeline()
    pipeline.add_component("llm", OpenAIChatGenerator(model="gpt-4o-mini", tools=[tool]))
    pipeline.add_component("tool_invoker", ToolInvoker(tools=[tool]))
    
    # Connect components
    pipeline.connect("llm.replies", "tool_invoker.messages")
    
    message = ChatMessage.from_user("Use the web search tool to find information about Nikola Tesla")
    
    # Run pipeline
    result = pipeline.run({"llm": {"messages": [message]}})
    
    print(result)
    
  • 添加 XLSXToDocument 转换器,它使用 Pandas + openpyxl 加载 Excel 文件,并默认将每个工作表转换为 CSV 格式的单独 Document

  • 已向 PyPDFToDocumentAzureOCRDocumentConverter__init__ 方法添加了新的 store_full_path 参数。默认值为 True,它将完整文件路径存储在输出文档的元数据中。当设置为 False 时,仅存储文件名。

  • 添加了一个新的实验性组件 ToolInvoker。此组件根据语言模型准备的工具调用来调用工具,并将结果作为 ChatMessage 对象列表返回,其中包含工具角色。

  • 添加了 RecursiveSplitter,它使用一组分隔符来递归拆分文本。它尝试使用第一个分隔符来分割文本,如果生成的块仍然大于指定大小,它将移至列表中的下一个分隔符。

  • 添加了一个 create_tool_from_function 函数,用于从函数创建 Too 实例,自动生成名称、描述和参数。添加了一个 tool 装饰器以实现相同的结果。

  • 为 Hugging Face API Chat Generator 添加了对工具的支持。

  • 更改了 ChatMessage 数据类,以支持不同类型的内容,包括工具调用和工具调用结果。

  • 为 OpenAI Chat Generator 添加了对工具的支持。

  • 添加了一个新的 Tool 数据类,用于表示语言模型可以为其准备调用的工具。

  • 添加了 StringJoiner 组件,用于将来自不同组件的字符串连接到字符串列表中。

⚡️ 增强说明

  • AzureOpenAIDocumentEmbedderAzureOpenAITextEmbedder 添加了 default_headers 参数。

  • 添加了 token 参数到 NamedEntityExtractor,以允许使用私有的 Hugging Face 模型。

  • ChatMessage 类添加了 from_openai_dict_format 类方法。它允许您从 OpenAI Chat API 期望格式的字典创建 ChatMessage

  • 添加了一个测试作业,以检查所有包是否都可以成功导入。这应该有助于检测各种问题,例如忘记为来自惰性导入的类型提示使用前向引用。

  • DocumentJoiner 方法 _concatenate()_distribution_based_rank_fusion() 已转换为静态方法。

  • 改进了可调用对象的序列化和反序列化。我们现在允许序列化类方法和静态方法,并明确禁止序列化实例方法、lambda 函数和嵌套函数。

  • PyPDFToDocument 组件添加了新的初始化参数,以自定义从 PDF 文件中提取文本的过程。

  • 重新组织了文档存储测试套件,以隔离 dataframe 过滤器测试。此更改为将来可能弃用 Document 类的 dataframe 字段做准备。

  • Tool 移至新的专用 tools 包。重构了 Tool 的序列化和反序列化,使其更灵活并包含类型信息。

  • NLTKDocumentSplitter 已合并到 DocumentSplitter 中,后者现在提供与 NLTKDocumentSplitter 相同的功能。split_by="sentence" 现在使用基于 nltk 库的自定义句子边界检测。之前的 sentence 行为仍然可以通过 split_by="period" 来实现。

  • 通过使用 importlib 而非 sys.modules 改进了可调用对象的反序列化。此更改允许在反序列化可调用对象时导入不在 sys.modules 中的本地函数和类。

  • 更改 OpenAIDocumentEmbedder 以便在批处理嵌入失败时保持运行。现在 OpenAI 会返回一个错误,我们记录该错误并继续处理后续批次。

⚠️ 弃用说明

  • NLTKDocumentSplitter 将被弃用,并将在下一个版本中移除。DocumentSplitter 将支持 NLTKDocumentSplitter 的功能。

  • 函数角色和 ChatMessage.from_function 类方法已被弃用,并将在 Haystack 2.10.0 中移除。ChatMessage.from_function 还尝试生成一个有效的工具消息。有关更多信息,请参阅文档:https://docs.haystack.com.cn/docs/chatmessage

  • SentenceWindowRetrievercontext_documents 输出已更改。它不再是 List[List[Document],而是 List[Document],其中文档按 split_idx_start 值排序。

🐛 Bug 修复

  • LinkContentFetcher 的单 URL 场景添加了缺失的流 MIME 类型分配。

  • 以前,使用 FileTypeRouter 的管道在接收单个 URL 作为输入时可能会失败。

  • OpenAIChatGenerator 在未提供工具时不再将工具传递给 OpenAI 客户端。以前传递的是 null 值。此更改提高了与不支持工具的 OpenAI 兼容 API 的兼容性。

  • ByteStream 现在会将数据截断为 100 字节以避免过多的日志输出。

  • 使 HuggingFaceLocalChatGenerator 与新的 ChatMessage 格式兼容,方法是将消息转换为 HuggingFace 所需的格式。

  • 序列化 chat_template 参数。

  • 将 NLTK 的下载移至 DocumentSplitterNLTKDocumentSplitterwarm_up()。这可以防止在实例化过程中调用外部 API。如果在管道外使用 DocumentSplitterNLTKDocumentSplitter 进行句子拆分,现在需要在运行组件之前调用 warm_up()

  • PDFMinerToDocument 现在会创建具有基于转换文本和元数据的 id 的文档。在此之前,PDFMinerToDocument 在生成文档的 id 时未考虑文档的 meta 字段。

  • 将 OpenAI 客户端固定到 >=1.56.1,以避免与 httpx 库更改相关的问题。

  • PyPDFToDocument 现在会创建具有基于转换文本和元数据的 id 的文档。在此之前,它没有考虑元数据。

  • 修复了多线程环境中组件反序列化的问题。