⭐️ Highlights
Agent 组件支持状态管理
The Agent 组件支持提供商无关的聊天模型,并允许工具调用功能,既可以作为独立组件使用,也可以在 pipeline 中使用。如果定义了 SERPERDEV_API_KEY 和 OPENAI_API_KEY,那么 Web 搜索 Agent 的构建将非常简单。
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.websearch import SerperDevWebSearch
from haystack.dataclasses import ChatMessage
from haystack.tools.component_tool import ComponentTool
web_tool = ComponentTool(
component=SerperDevWebSearch(),
)
agent = Agent(
chat_generator=OpenAIChatGenerator(),
tools=[web_tool],
)
result = agent.run(
messages=[ChatMessage.from_user("Find information about Haystack by deepset")]
)
Agent 支持响应流式传输、可自定义的退出条件以及灵活的状态管理系统,该系统允许工具在执行过程中共享和修改数据。
agent = Agent(
chat_generator=OpenAIChatGenerator(),
tools=[web_tool, weather_tool],
exit_conditions=["text", "weather_tool"],
state_schema = {...},
streaming_callback=streaming_callback,
)
SuperComponent 用于可重用 pipeline
SuperComponent 允许您将复杂的 pipeline 包装成可重用的组件。这使得在您的应用程序中轻松重用它们。只需使用 pipeline 初始化 SuperComponent 即可。
from haystack import Pipeline, SuperComponent
with open("pipeline.yaml", "r") as file:
pipeline = Pipeline.load(file)
super_component = SuperComponent(pipeline)
这还不是全部!为了展示其优势,haystack-experimental 中有三个现成的 SuperComponent。例如,有一个 MultiFileConverter,它包装了一个支持 CSV、DOCX、HTML、JSON、MD、PPTX、PDF、TXT 和 XSLX 转换器的 pipeline。安装集成依赖项 pip install pypdf markdown-it-py mdit_plain trafilatura python-pptx python-docx jq openpyxl tabulate 后,您就可以使用任何支持的文件类型作为输入运行了。
from haystack_experimental.super_components.converters import MultiFileConverter
converter = MultiFileConverter()
converter.run(sources=["test.txt", "test.pdf"], meta={})
这是一个从任何 Haystack pipeline 创建自定义 SuperComponent 的示例。
from haystack import Pipeline, SuperComponent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.builders import ChatPromptBuilder
from haystack.components.retrievers import InMemoryBM25Retriever
from haystack.dataclasses.chat_message import ChatMessage
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.dataclasses import Document
document_store = InMemoryDocumentStore()
documents = [
Document(content="Paris is the capital of France."),
Document(content="London is the capital of England."),
]
document_store.write_documents(documents)
prompt_template = [
ChatMessage.from_user(
'''
According to the following documents:
{% for document in documents %}
{{document.content}}
{% endfor %}
Answer the given question: {{query}}
Answer:
'''
)
]
prompt_builder = ChatPromptBuilder(template=prompt_template, required_variables="*")
pipeline = Pipeline()
pipeline.add_component("retriever", InMemoryBM25Retriever(document_store=document_store))
pipeline.add_component("prompt_builder", prompt_builder)
pipeline.add_component("llm", OpenAIChatGenerator())
pipeline.connect("retriever.documents", "prompt_builder.documents")
pipeline.connect("prompt_builder.prompt", "llm.messages")
# Create a super component with simplified input/output mapping
wrapper = SuperComponent(
pipeline=pipeline,
input_mapping={
"query": ["retriever.query", "prompt_builder.query"],
},
output_mapping={"llm.replies": "replies"}
)
# Run the pipeline with simplified interface
result = wrapper.run(query="What is the capital of France?")
print(result)
# {'replies': [ChatMessage(_role=<ChatRole.ASSISTANT: 'assistant'>,
# _content=[TextContent(text='The capital of France is Paris.')],...)
⬆️ 升级说明
-
更新了
ChatMessage的序列化和反序列化。ChatMessage.to_dict()现在返回一个包含键:role、content、meta 和 name 的字典。ChatMessage.from_dict()支持此格式,并与旧格式保持兼容。如果您的应用程序使用了
ChatMessage.to_dict()的结果,请更新您的代码以处理新格式。如果您在 Pipeline 中使用ChatPromptBuilder,则无需进行更改。 -
LLMEvaluator、ContextRelevanceEvaluator和FaithfulnessEvaluator现在内部使用 ChatGenerator 实例而不是 Generator 实例。公共属性 generator 已被 _chat_generator 替换。 -
to_pandas、comparative_individual_scores_report和score_report已从EvaluationRunResult中移除,请改用detailed_report、comparative_detailed_report和aggregated_report。
🚀 新功能
- 在类型兼容性检查期间,将裸类型(例如,List、Dict)视为带有 Any 参数的通用类型。
- 添加了对 Callable 类型的兼容性。
- 向 Tool 和 ComponentTool 添加了
outputs_to_string,允许用户自定义Tool的输出如何转换为字符串,以便可以将其提供回 ChatGenerator 的ChatMessage中。如果未提供outputs_to_string,则ToolInvoker中会使用默认的转换器。默认处理程序使用当前默认行为。 - 向 CSVDocumentSplitter 组件添加了一个新参数
split_mode来控制拆分模式。新参数可以设置为 row-wise 以按行拆分 CSV 文件。默认值为 threshold,这是之前的行为。 - 我们添加了一种新的检索技术,AutoMergingRetriever,它与 HierarchicalDocumentSplitter 一起实现了自动合并检索技术。
- 向
HuggingFaceLocalChatGenerator添加了run_async方法。此方法内部使用 ThreadPoolExecutor 返回可以 await 的协程。 - 在 LinkContentFetcher 组件中引入了异步功能和 HTTP/2 支持,从而在多个方面改进了内容获取。
- 现在,DOCXToDocument 组件可以选择将提取的超链接地址包含在输出
Documents中。它接受一个可以设置为“markdown”或“plain”的 link_format 参数。默认情况下,如前所述,不会提取超链接地址。 - 向所有 Azure OpenAI 组件添加了一个新参数
azure_ad_token_provider:AzureOpenAIGenerator、AzureOpenAIChatGenerator、AzureOpenAITextEmbedder和AzureOpenAIDocumentEmbedder。此参数可以选择接受一个返回 bearer token 的可调用对象,从而实现通过 Azure AD 进行身份验证。- 在 haystack/utils/azure.py 中引入了实用函数
default_azure_token_provider。此函数提供了一个可由 Haystack 序列化的默认 token 提供程序。用户现在可以将default_azure_token_provider作为azure_ad_token_provider传递,或者实现自定义 token 提供程序。
- 在 haystack/utils/azure.py 中引入了实用函数
- 用户现在可以在
ChatPromptBuilder中使用日期和时间。与PromptBuilder类似,ChatPromptBuilder现在支持 arrow 来处理 datetime。 - 引入新的 State dataclass,其模式可自定义,用于管理 Agent 状态。增强了 Tool 的错误日志记录,并扩展了 ToolInvoker 组件以使用新引入的 State。
- 现在 RecursiveDocumentSplitter 支持按 token 数量进行拆分。将“split_unit”设置为“token”将使用硬编码的 tiktoken 分词器(o200k_base),并需要安装 tiktoken。
⚡️ 增强说明
-
LLMEvaluator、ContextRelevanceEvaluator和FaithfulnessEvaluator现在接受一个chat_generator初始化参数,它由预先配置为返回 JSON 对象的 ChatGenerator 实例组成。以前,这些组件仅支持 OpenAI 和具有 OpenAI 兼容 API 的 LLM。无论评估器组件是使用api、api_key和api_params还是新的 chat_generator 参数进行初始化的,序列化格式现在将仅包含chat_generator,为将来移除api、api_key和api_params做准备。 - 通过引发包含组件名称和类型的运行时错误,改进了组件运行失败的错误处理。
- 使用 Haystack 的
Agent时,消息存储在 State 中并累积。这意味着- State 需要在其模式中定义“messages”类型和处理程序。如果未提供,则会提供默认类型和处理程序。用户现在可以通过 State 模式提供自定义的消息处理程序来定制消息的累积方式。
- 添加了 PDFMinerToDocument 功能,用于检测和报告 PDF 文本提取中未解码的 CID 字符,帮助用户识别处理具有非标准字体的 PDF 时的潜在文本提取质量问题。
- Agent 组件允许定义多个退出条件而不是单个条件。init 参数已从
exit_condition重命名为exit_conditions,以反映这一点。 - 引入 ChatGenerator Protocol,从静态类型检查的角度限定 ChatGenerator 组件。它定义了 Chat Generators 必须实现的最小接口。这将特别有助于标准化 Chat Generators 在其他更复杂组件中的集成。
- 在
Agent中,我们在进行退出条件检查时会检查 LLM 返回的所有消息。例如,LLM 可能会返回多条消息,如多个工具调用,或者包含带有推理的消息。现在,我们在评估是否应退出循环之前会检查所有消息。 Agent组件会检查其初始化的 ChatGenerator 是否支持工具。如果不支持,Agent 会引发 TypeError。- 更新了 SentenceTransformersDiversityRanker 以在内部使用 token 参数而不是已弃用的 use_auth_token。此组件的公共 API 已在使用 token。
- 简化了序列化代码,以提高可读性和可维护性。
- 更新了反序列化,允许用户省略标准 typing 库类型(例如,List[str] 而不是 typing.List[str])的 typing. 前缀。
- 重构了 OpenAI 流式块的处理,以简化逻辑。
- 添加了测试,以确保在使用 include_usage=True 处理流式块时具有预期的行为。
- 更新了
BranchJoiner的文档字符串,使其更易于理解,并更好地突出其有用性。 - 在 OpenAI 和 Azure ChatGenerators 中合并了 select_streaming_callback 工具的使用,该工具会检查 streaming_callback 与 async 或 non-async run 方法的兼容性。
- 向
ChatPromptBuilder和PromptBuilder添加了警告,当存在 prompt 变量且required_variables未设置时,以帮助用户避免在多分支 pipeline 中出现意外执行。警告建议用户设置required_variables。
⚠️ 弃用说明
LLMEvaluator、ContextRelevanceEvaluator和FaithfulnessEvaluator的api、api_key和api_params参数现在已弃用,将在 Haystack 2.13.0 中移除。默认情况下,这些组件将继续在 JSON 模式下使用 OpenAI。要配置特定的 LLM,请使用chat_generator参数。- LLMMetadataExtractor 的 generator_api 和 generator_api_params 初始化参数以及 LLMProvider 枚举已弃用,将在 Haystack 2.13.0 中移除。请改用
chat_generator来配置底层 LLM。例如,将generator_api=LLMProvider.OPENAI更改为chat_generator=OpenAIChatGenerator()。
🐛 Bug 修复
- 向 Document dataclass 添加了 dataframe 到 legacy 字段。这修复了一个 bug,即 haystack-ai>=2.11.0 中的
Document.from_dict()无法正确反序列化 haystack-ai<=2.10.0 中通过document.to_dict(flatten=False)获得的 Document 字典。 - 在 DALLEImageGenerator 中,确保当 max_retries 初始化参数等于 0 时,它被正确设置。
- 修复了日志模块中记录任意字符串时发生的索引错误。
- 确保在
AzureOpenAIGenerator、AzureOpenAIChatGenerator、AzureOpenAITextEmbedder和AzureOpenAIDocumentEmbedder中,当max_retries初始化参数等于 0 时,它被正确设置。 - 改进了 haystack/utils/type_serialization.py 中的序列化和反序列化,以正确处理 Optional 类型。
- 将 haystack/__init__.py 中的惰性导入替换为贪婪导入,以避免潜在的静态类型检查问题并简化维护。
- 修复了一个阻止 Jinja2 基于的 ComponentTools 在运行时传递到 pipeline 的问题。
- 改进了
component.output_types装饰器的类型提示。该装饰器的类型提示最初是为了避免覆盖 run 方法的类型提示并允许正确的静态类型检查而引入的。此更新扩展了对异步 run_async 方法的支持。 - 修复了
MistralChatGenerator在使用流式传输时未返回 finish_reason 的问题。通过调整处理流式块时查找 finish_reason 的方式来解决。现在,使用最后一个非 None 的 finish_reason 来处理 OpenAI 和 Mistral 之间的差异。
