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

Haystack 2.18.0

在 Github 上查看

⭐️ Highlights

🔁 管道错误恢复与快照

管道现在会在运行失败时捕获最后一个成功步骤的快照,包括中间输出。这使您可以诊断问题(例如,失败的工具调用),修复它们,然后从检查点恢复,而不是重新启动整个运行。目前支持同步的PipelineAgentAsyncPipeline尚不支持)。

快照包含在管道运行失败时抛出的PipelineRuntimeError异常中。您需要将pipeline.run()包装在try-except块中。

try:
  pipeline.run(data=input_data)
except PipelineRuntimeError as exc_info
	snapshot = exc_info.value.pipeline_snapshot
	intermediate_outputs = pipeline_snapshot.pipeline_state.pipeline_outputs

# Snapshot can be used to resume the execution of a Pipeline by passing it to the run() method using the snapshot argument	
pipeline.run(data={}, snapshot=saved_snapshot)

🧠 OpenAI/Azure OpenAI 的结构化输出

OpenAIChatGeneratorAzureOpenAIChatGenerator支持通过response_format(Pydantic模型或JSON Schema)进行结构化输出。

from pydantic import BaseModel
from haystack.components.generators.chat.openai import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage

class CalendarEvent(BaseModel):
    event_name: str
    event_date: str
    event_location: str

generator = OpenAIChatGenerator(generation_kwargs={"response_format": CalendarEvent})

message = "The Open NLP Meetup is going to be in Berlin at deepset HQ on September 19, 2025"
result = generator.run([ChatMessage.from_user(message)])
print(result["replies"][0].text)

# {"event_name":"Open NLP Meetup","event_date":"September 19","event_location":"deepset HQ, Berlin"}

🛠️ 使用PipelineTool将管道转换为工具

新的PipelineTool允许您将整个Haystack管道公开为与LLM兼容的工具。它将之前的SuperComponent + ComponentTool模式简化为一个抽象,并直接公开input_mappingoutput_mapping以进行精细控制。

from haystack import Pipeline
from haystack.tools import PipelineTool

retrieval_pipeline = Pipeline()
retrieval_pipeline.add_component...
..

retrieval_tool = PipelineTool(
    pipeline=retrieval_pipeline,
    input_mapping={"query": ["bm25_retriever.query"]},
    output_mapping={"ranker.documents": "documents"},
    name="retrieval_tool",
    description="Use to retrieve documents",
)

🗺️ Agent 的运行时系统提示

Agent的system_prompt现在可以在运行时动态更新,以实现更灵活的行为。

🚀 新功能

  • OpenAIChatGeneratorAzureOpenAIChatGenerator现在使用response_format参数支持结构化输出,该参数可以传递给generation_kwargs。对于非流式响应,response_format参数可以是Pydantic模型或JSON Schema。对于流式响应,response_format必须是JSON Schema。response_format参数的示例用法

    from pydantic import BaseModel
    from haystack.components.generators.chat import OpenAIChatGenerator
    from haystack.dataclasses import ChatMessage
    
    class NobelPrizeInfo(BaseModel):
        recipient_name: str
        award_year: int
        category: str
        achievement_description: str
        nationality: str
    
    client = OpenAIChatGenerator(
        model="gpt-4o-2024-08-06",
        generation_kwargs={"response_format": NobelPrizeInfo}
    )
    
    response = client.run(messages=[
        ChatMessage.from_user("In 2021, American scientist David Julius received the Nobel Prize in"
        " Physiology or Medicine for his groundbreaking discoveries on how the human body"
        " senses temperature and touch.")
    ])
    print(response["replies"][0].text)
    >>> {"recipient_name":"David Julius","award_year":2021,"category":"Physiology or Medicine","achievement_description":"David Julius was awarded for his transformative findings regarding the molecular mechanisms underlying the human body's sense of temperature and touch. Through innovative experiments, he identified specific receptors responsible for detecting heat and mechanical stimuli, ranging from gentle touch to pain-inducing pressure.","nationality":"American"}
    
  • 添加了PipelineTool,这是一个新的工具包装器,允许将Haystack管道公开为与LLM兼容的工具。

    • 以前,可以通过先将管道包装在SuperComponent中,然后将其传递给ComponentTool来实现此目的。
    • PipelineTool将此模式简化为专用抽象。它在底层使用相同的方法,但直接公开input_mappingoutput_mapping,以便用户可以轻松控制哪些管道输入和输出可用。
    • 自动为管道输入的LLM工具调用生成输入模式。
    • 从底层组件文档字符串中提取描述,以获得更好的工具文档。
    • 可以直接传递给Agent,从而在多步推理工作流中无缝集成完整的管道作为工具。
  • StreamingChunk添加reasoning字段,该字段可以选择性地接受ReasoningContent数据类。这是为了允许以结构化的方式将推理内容传递到流式块。

  • 如果在管道执行过程中发生错误,管道将引发PipelineRuntimeError异常,其中包含错误消息和直到失败点的组件输出。这允许您检查和调试直到失败点的管道。

  • LinkContentFetcher:添加request_headers以允许自定义每个请求的HTTP标头。标头优先级:httpx客户端默认值 → 组件默认值 → request_headers → 旋转的User-Agent。此外,使HTTP/2处理具有导入安全性:如果未安装h2,则回退到HTTP/1.1并发出警告。感谢@xoaryaa。(修复#9064)

  • 当管道运行出错时,还会引发最后一个成功步骤的快照。允许调用者捕获它以检查崩溃的可能原因,并从中恢复管道执行。

  • SerperDevWebSearch组件添加exclude_subdomains参数。当设置为True时,此参数将搜索结果限制为allowed_domains中指定的精确域,不包括任何子域。例如,当allowed_domains=\["example.com"\]exclude_subdomains=True时,“blog.example.com”或“shop.example.com”的搜索结果将被过滤掉,只返回“example.com”的结果。此参数默认为False,以保持与现有行为的向后兼容性。

⚡️ 增强说明

  • 添加了system_prompt到agent运行参数中,以增强agent行为的可定制性和控制。
  • 内部Agent逻辑进行了重构,以提高可读性和可维护性。这应该有助于开发人员理解和扩展内部Agent逻辑。

🐛 Bug 修复

  • 在反序列化无效内容部分的ChatMessage时,重新引入详细的错误消息。虽然LLM仍可能生成格式不正确的消息,但此错误提供了对预期结构的指导,使agent运行期间的重试更容易和更可靠。此错误消息在之前的重构中被意外删除。
  • SentenceSplitter使用的英文和德文缩写文件现在已包含在发行版中。由于.gitignore文件中的配置,它们之前缺失。
  • SentenceTransformersDiversityRanker中保留显式lambda_threshold=0.0,而不是由于短路求值将其覆盖为0.5
  • 修复MetaFieldGroupingRanker,使其在subgroup_by值为列表等不可哈希类型时仍能工作。我们通过对doc.meta\[subgroup_by\]的内容进行字符串化来处理此问题,就像我们对doc.meta\[group_by\]的值进行字符串化一样。
  • 修复了通过同步ToolInvoker路径执行的工具的缺失的跟踪父级。更新了ToolInvoker.run(),将contextvars传播到ThreadPoolExecutor工作线程中,确保所有工具跨度(ComponentTool、包装在ComponentTool中的Agent或自定义工具)都能正确链接到外部Agent的跟踪,而不是启动新的根跟踪。这改善了整个工具执行链的端到端可观察性。
  • 修复了MetadataRouterfrom_dict方法,使得在从YAML加载时,在Haystack 2.17中引入的output_type参数现在是可选的。这确保了与旧版Haystack管道的兼容性。
  • OpenAIChatGenerator中,改进了排除不支持的自定义工具调用的逻辑。之前的实现导致了与Mistral Haystack核心集成的兼容性问题,该集成扩展了OpenAIChatGenerator
  • 修复了在使用inputs_from_stateComponentTool中的参数模式生成。以前,参数仅在状态键和参数名称完全匹配时才从模式中删除。例如,inputs_from_state={"text": "text"}如预期那样删除了text,但inputs_from_state={"state_text": "text"}则没有。现在此问题已解决,此类情况按预期工作。

💙 非常感谢所有为本次发布做出贡献的人!

@Amnah199, @Ujjwal-Bajpayee, @abdokaseb, @anakin87, @davidsbatista, @dfokina, @rigved-telang, @sjrl, @tstadel, @vblagoje, @xoaryaa