ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Haystack 实验性 Agents API 完全指南:工具调用、退出条件与 Human-in-the-Loop 确认策略

Haystack 实验性 Agents API 完全指南:工具调用、退出条件与 Human-in-the-Loop 确认策略 Haystack 实验性 Agents API 完全指南工具调用、退出条件与 Human-in-the-Loop 确认策略【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack本篇技术指南基于 Haystack 官方参考文档docs-website/reference_versioned_docs/version-2.22/experiments-api/experimental_agents_api.md展开围绕实验性的haystack_experimental.components.agents.Agent组件系统讲解其工具调用机制、退出条件、运行时状态State、流式回调、断点Breakpoint与快照Snapshot以及以HumanInTheLoopStrategy、BreakpointConfirmationStrategy为代表的人机协同确认策略。读完本文你将掌握如何构建一个感知工具、按需停止、可人工审批工具执行的 Agent并理解其在当前 Haystack 仓库haystack/components/agents/agent.py、haystack/hooks/human_in_the_loop/中的底层实现脉络。一、Agent 组件是什么根据参考文档haystack_experimental.components.agents.agent.Agent是一个实现了工具使用型 Agent的 Haystack 组件核心特点包括与模型提供商无关的聊天模型支持只要 Chat Generator 的run方法支持tools参数即可接入工具循环执行组件持续处理消息、执行工具直到满足某个退出条件exit condition多退出条件既可以在模型直接返回文本时退出也可以在指定的工具执行完毕后退出多个条件可以同时指定无工具时退化为普通聊天模型当不传入任何工具时Agent 的表现与ChatGenerator一致——生成一次回复后立即退出扩展了 Haystack 核心 Agent文档明确指出该类在 HaystackAgent组件之上扩展了 human-in-the-loop人机协同确认策略支持。当前仓库中核心Agent的实现位于 haystack/components/agents/agent.py而人机协同确认机制已沉淀为ConfirmationHook与BlockingConfirmationStrategy等正式组件见 haystack/hooks/human_in_the_loop/。最小使用示例参考文档给出的标准用法如下from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage from haystack.tools.tool import Tool from haystack_experimental.components.agents import Agent from haystack_experimental.components.agents.human_in_the_loop import ( HumanInTheLoopStrategy, AlwaysAskPolicy, NeverAskPolicy, SimpleConsoleUI, ) calculator_tool Tool(namecalculator, descriptionA tool for performing mathematical calculations., ...) search_tool Tool(namesearch, descriptionA tool for searching the web., ...) agent Agent( chat_generatorOpenAIChatGenerator(), tools[calculator_tool, search_tool], confirmation_strategies{ calculator_tool.name: HumanInTheLoopStrategy( confirmation_policyNeverAskPolicy(), confirmation_uiSimpleConsoleUI() ), search_tool.name: HumanInTheLoopStrategy( confirmation_policyAlwaysAskPolicy(), confirmation_uiSimpleConsoleUI() ), }, ) # Run the agent result agent.run( messages[ChatMessage.from_user(Find information about Haystack)] ) assert messages in result # Contains conversation history这段示例展示了两个关键能力为不同工具注册不同的确认策略计算器工具从不询问、搜索工具每次都询问以及通过result[messages]获取完整的对话历史。从仓库源码看这种按工具差异化审批的设计在正式版中对应ConfirmationHook的confirmation_strategies字典见 haystack/hooks/human_in_the_loop/hooks.py其键既可以是单个工具名也可以是共享同一策略的工具名元组还可以是应用于兜底的通配符*——更具体的键优先匹配。二、Agent 初始化参数详解参考文档给出了Agent.__init__的完整签名以下逐一说明每个参数的含义、默认值与源码层面的影响def __init__(*, chat_generator: ChatGenerator, tools: ToolsType | None None, system_prompt: str | None None, exit_conditions: list[str] | None None, state_schema: dict[str, Any] | None None, max_agent_steps: int 100, streaming_callback: StreamingCallbackT | None None, raise_on_tool_invocation_failure: bool False, confirmation_strategies: dict[str, ConfirmationStrategy] | None None, tool_invoker_kwargs: dict[str, Any] | None None, chat_message_store: ChatMessageStore | None None, memory_store: MemoryStore | None None) - None参数类型默认值说明chat_generatorChatGenerator必填Agent 使用的聊天生成器必须支持工具其run方法需接受tools参数toolsToolsType \| NoneNoneAgent 可用的Tool对象列表或一个Toolsetsystem_promptstr \| NoneNoneAgent 的系统提示词exit_conditionslist[str] \| None[text]使 Agent 返回的条件列表。包含text表示生成无工具调用的消息时返回也可包含工具名表示该工具执行完毕后返回state_schemadict[str, Any] \| NoneNone工具使用的运行时状态State的 schemamax_agent_stepsint100Agent 运行的最大步数上限超出后停止并返回当前状态streaming_callbackStreamingCallbackT \| NoneNoneLLM 流式输出时的回调同一回调也可配置为在工具调用时发出工具结果raise_on_tool_invocation_failureboolFalse工具调用失败时是否抛异常为False时将异常转换为聊天消息交给 LLMconfirmation_strategiesdict[str, ConfirmationStrategy] \| NoneNone按工具名映射的 human-in-the-loop 确认策略tool_invoker_kwargsdict[str, Any] \| NoneNone传递给ToolInvoker的额外关键字参数chat_message_storeChatMessageStore \| NoneNoneAgent 存取聊天消息历史的存储memory_storeMemoryStore \| NoneNoneAgent 存取记忆的存储异常当chat_generator的run方法不支持tools参数时抛出TypeErrorexit_conditions不合法时抛出ValueError。源码层面的关键实现细节在 haystack/components/agents/agent.py 中Agent.__init__对上述参数做了进一步细化与校验可作为理解实验 API 的参照工具能力自检初始化时通过inspect.signature(chat_generator.run).parameters判断生成器是否接受tools参数源码第 460 行若传入工具但不支持则立即抛出TypeError退出条件默认值exit_conditions is None时回退为[text]第 469-470 行状态 schema 保留键step_count、token_usage、tool_call_counts、exit_reason等运行元数据键以及continue_run、stop_run、tools、hook_context、context_tokens等内部控制键是保留的用户不得在state_schema中重定义第 77-99、472-480 行工具并发上限正式版还提供了tool_concurrency_limit默认 4与tool_streaming_callback_passthrough前者控制并行执行工具调用的最大数量设为 1 即禁用并行第 393-394 行。三、Agent.run驱动工具循环的核心入口Agent.run是 Agent 的主循环入口签名如下def run(messages: list[ChatMessage], streaming_callback: StreamingCallbackT | None None, *, generation_kwargs: dict[str, Any] | None None, break_point: AgentBreakpoint | None None, snapshot: AgentSnapshot | None None, system_prompt: str | None None, tools: ToolsType | list[str] | None None, confirmation_strategy_context: dict[str, Any] | None None, chat_message_store_kwargs: dict[str, Any] | None None, memory_store_kwargs: dict[str, Any] | None None, **kwargs: Any) - dict[str, Any]参数语义messages待处理的ChatMessage对象列表streaming_callbackLLM 流式输出回调与初始化时传入的回调二选一运行期优先级更高generation_kwargs传给 LLM 的额外生成参数会覆盖初始化时传入的同名参数break_pointAgentBreakpoint可以是针对chat_generator的Breakpoint或针对tool_invoker的ToolBreakpointsnapshot此前保存的 Agent 执行快照字典包含从断点处恢复执行所需的全部信息system_prompt运行期系统提示词提供时覆盖默认值tools本次运行使用的工具可以是Tool列表、Toolset或工具名字符串列表按名称从 Agent 原始配置的工具中选取confirmation_strategy_context向确认策略传递请求级资源的字典在 Web/服务端场景尤为有用例如传递 WebSocket 连接、异步队列、Redis pub/sub 客户端使策略可以进行非阻塞式用户交互chat_message_store_kwargs传给ChatMessageStore的关键字参数例如chat_history_id与last_k用于按历史 ID 和最近条数检索聊天历史memory_store_kwargs传给MemoryStore的关键字参数可包含user_id检索/写入记忆的用户 IDrun_id检索/写入记忆的运行 IDagent_id检索/写入记忆的 Agent IDsearch_criteriasearch_memories方法的参数字典可包含filters记忆检索过滤器、query检索查询注意一旦传入Agent 的用户查询在记忆检索时会被忽略、top_k返回记忆条数、include_memory_metadata是否在ChatMessage中包含记忆元数据kwargs传入 State schema 的额外数据键必须与state_schema定义匹配。返回值run返回一个字典包含以下键messagesAgent 运行期间交换的全部消息列表last_message运行期间交换的最后一条消息state_schema中定义的任何其他键。异常未warm_up就调用run()会抛RuntimeErrorAgent 断点被触发时抛BreakpointException。底层运行循环源码视角从当前仓库 haystack/components/agents/agent.py 的run实现第 826-907 行可以清晰看到这个循环的骨架预热调用self.warm_up()预热工具、钩子与聊天生成器第 872 行初始化执行上下文_initialize_fresh_execution构建State、选定工具、解析流式回调并初始化step_count、token_usage、tool_call_counts、exit_reason等运行元数据第 874-882 行主循环在counter max_agent_steps的条件下反复执行_run_step每步一次聊天生成调用加上该轮所有工具调用当_run_step返回False时跳出循环第 889-891 行步数上限兜底若循环正常耗尽未break说明是max_agent_steps触顶此时记录exit_reason max_agent_steps并输出警告日志第 892-899 行组装结果剔除内部状态键后从messages中取最后一条作为last_message返回第 900-905 行。四、Agent.run_async异步版本run_async是run的异步版本遵循相同逻辑但尽可能使用异步操作——例如优先调用ChatGenerator.run_async若可用。其参数与run基本一致streaming_callback为异步回调、generation_kwargs同样覆盖初始化参数差异仅在于需先调用warm_up_async()而非warm_up()未预热即调用抛RuntimeError断点触发抛BreakpointException返回值与run完全一致messages、last_messagestate_schema键。在源码中run_async第 909-993 行与run的差异点集中在预热阶段调用warm_up_async第 958 行、钩子调用替换为_run_hooks_async第 972、986 行、步骤执行替换为_run_step_async第 976 行。这也与仓库中OpenAIChatGenerator等组件普遍提供run_async的趋势一致参见 releasenotes 中的add-run-async-to-*系列说明。五、序列化to_dict 与 from_dict实验 Agent 与 Haystack 其他组件一样支持完整的序列化/反序列化便于 YAML 描述、管道持久化与远程传输def to_dict() - dict[str, Any]将组件序列化为字典并返回。对应的类方法classmethod def from_dict(cls, data: dict[str, Any]) - Agent从字典反序列化出Agent实例参数data为待反序列化的字典。从源码看haystack/components/agents/agent.py 第 633-679 行to_dict通过default_to_dict序列化chat_generator、工具、提示词、退出条件、state_schema、流式回调经serialize_callable、钩子等全部初始化参数from_dict则依次反序列化聊天生成器、状态 schema、流式回调、工具与钩子最终交给default_from_dict完成实例重建。六、Human-in-the-Loop让工具执行接受人工审批实验 Agent 的亮点在于为工具调用引入了人工确认层。参考文档将其划分为三个模块human_in_the_loop.breakpoint、human_in_the_loop.errors与human_in_the_loop.strategies。6.1 确认策略HumanInTheLoopStrategy实验 API 中confirmation_strategies参数接受dict[str, ConfirmationStrategy]将每个工具名映射到其确认策略如示例中的HumanInTheLoopStrategy(confirmation_policy..., confirmation_ui...)。策略由两部分组合而成确认策略ConfirmationPolicy决定何时询问。当前仓库 haystack/hooks/human_in_the_loop/policies.py 提供三种现成实现AlwaysAskPolicy每次都询问should_ask恒返回TrueNeverAskPolicy从不询问should_ask恒返回FalseAskOncePolicy对同一工具的相同参数只询问一次内部记录已确认的tool_name - tool_params映射避免重复打断。确认 UIConfirmationUI决定如何询问。见 haystack/hooks/human_in_the_loop/user_interfaces.pySimpleConsoleUI基于标准输入输出的纯文本交互支持y/n/m确认/拒绝/修改无需额外依赖RichConsoleUI基于rich库的富文本面板交互同样支持确认/拒绝/修改三选一修改参数时非字符串类型按 JSON 解析需要pip install rich。三种交互结果由 haystack/hooks/human_in_the_loop/dataclasses.py 中的ConfirmationUIResult承载actionconfirm/reject/modify、可选feedback用户反馈文本、可选new_tool_params修改后的参数。6.2 决策处理流程源码纵深从 haystack/hooks/human_in_the_loop/strategies.py 的BlockingConfirmationStrategy.run第 66-139 行可以看到一次完整的审批闭环先调用confirmation_policy.should_ask(...)判断是否需要询问若不需要则直接放行executeTrue需要询问时调用confirmation_ui.get_user_confirmation(...)收集用户意见将结果回传给confirmation_policy.update_after_confirmation(...)供AskOncePolicy这类有状态策略记录学习根据action分派reject不执行生成拒绝反馈文本模板Tool execution for {tool_name} was rejected by the user.可拼接用户反馈modify用new_tool_params替换原参数后执行并生成参数修改说明模板The parameters for tool {tool_name} were updated by the user to: ...confirm按原参数直接执行。最终产出ToolExecutionDecisiontool_name、execute、tool_call_id、feedback、final_tool_params。tool_call_id用于将决策与具体工具调用一一关联避免并行工具调用时错配。6.3 ConfirmationHook接入 Agent 主循环的桥梁在当前仓库中确认逻辑以before_tool钩子的形式挂载到核心 Agent 上haystack/hooks/human_in_the_loop/hooks.pyhook ConfirmationHook( confirmation_strategies{ delete_file: BlockingConfirmationStrategy( confirmation_policyAlwaysAskPolicy(), confirmation_uiRichConsoleUI() ), *: BlockingConfirmationStrategy( confirmation_policyNeverAskPolicy(), confirmation_uiSimpleConsoleUI() ), } ) agent Agent(chat_generatorOpenAIChatGenerator(), tools[delete_file], hooks{before_tool: [hook]})要点allowed_hook_points (before_tool,)即该钩子只能在工具执行前的钩子点注册Agent 会在构造时校验并拒绝其他位置对应 haystack/components/agents/agent.py 中_validate_hooks的钩子点限制逻辑运行时从state.data读取可用工具tools与请求级上下文hook_context只处理最后一条含工具调用的消息通过confirmation_strategy_context实验 API 的run参数/ 正式版的hook_context传递 WebSocket、队列等每请求资源实现非阻塞交互——这正是实验文档中confirmation_strategy_context参数的设计意图。七、BreakpointConfirmationStrategy无法即时交互时的审批方案实验 API 中还有一种专门为无法即时交互场景设计的策略BreakpointConfirmationStrategy。它不阻塞等待用户输入而是通过抛出断点异常来暂停执行将状态序列化保存随后再异步通知用户审批。7.1 构造与运行def __init__(snapshot_file_path: str) - None参数snapshot_file_path为快照保存目录路径。def run( *, tool_name: str, tool_description: str, tool_params: dict[str, Any], tool_call_id: str | None None, confirmation_strategy_context: dict[str, Any] | None None ) - ToolExecutionDecision该方法总是抛出HITLBreakpointException不会返回。confirmation_strategy_context参数仅用于接口兼容此策略并不使用它。run_async是run的异步包装同样总是抛异常。7.2 HITLBreakpointException该异常模块human_in_the_loop.errors在工具执行被ConfirmationStrategy暂停时抛出构造参数message异常消息tool_name被暂停执行的工具名snapshot_file_path已保存的管道快照文件路径tool_call_id可选工具调用的唯一标识用于将审批决策关联回具体的工具调用。抛出后Agent 捕获异常并序列化其当前状态含工具调用细节这些信息可用于通知用户审阅并确认工具执行。7.3 从快照提取工具调用信息配套的辅助函数def get_tool_calls_and_descriptions_from_snapshot( agent_snapshot: AgentSnapshot, breakpoint_tool_only: bool True ) - tuple[list[dict], dict[str, str]]从AgentSnapshot中提取工具调用与工具描述。默认breakpoint_tool_onlyTrue只处理导致断点的那个工具调用并重建其参数适合将相关工具调用及其描述呈现给人工确认后再执行的场景设为False则返回全部工具调用。返回值是一个二元组工具调用字典列表 工具名到描述的字典。八、实践组装一个带人工审批的 Agent 工作流综合以上 API一个完整的工具调用 差异化审批工作流可以这样组织from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage from haystack.tools.tool import Tool from haystack_experimental.components.agents import Agent from haystack_experimental.components.agents.human_in_the_loop import ( HumanInTheLoopStrategy, AlwaysAskPolicy, NeverAskPolicy, AskOncePolicy, SimpleConsoleUI, ) calculator_tool Tool(namecalculator, descriptionA tool for performing mathematical calculations., ...) send_email_tool Tool(namesend_email, descriptionSend an email to a recipient., ...) search_tool Tool(namesearch, descriptionA tool for searching the web., ...) agent Agent( chat_generatorOpenAIChatGenerator(), tools[calculator_tool, send_email_tool, search_tool], exit_conditions[text, send_email], # 文本回复或发送邮件后退出 max_agent_steps50, # 限制步数上限防止失控循环 confirmation_strategies{ # 计算器从不打扰用户 calculator_tool.name: HumanInTheLoopStrategy( confirmation_policyNeverAskPolicy(), confirmation_uiSimpleConsoleUI() ), # 搜索每次都确认 search_tool.name: HumanInTheLoopStrategy( confirmation_policyAlwaysAskPolicy(), confirmation_uiSimpleConsoleUI() ), # 发送邮件同一参数只确认一次 send_email_tool.name: HumanInTheLoopStrategy( confirmation_policyAskOncePolicy(), confirmation_uiSimpleConsoleUI() ), }, ) result agent.run( messages[ChatMessage.from_user(Find the latest Haystack release and email it to me)], generation_kwargs{temperature: 0.3}, # 运行期覆盖生成参数 ) assert messages in result assert last_message in result在 Web 服务场景中还可以通过confirmation_strategy_context传入每请求的 WebSocket 连接或异步队列让审批以非阻塞方式推送给前端用户而run_async则保证整个 Agent 循环不会占用事件循环。九、小结与进一步阅读实验性 Agents API 为 Haystack 提供了完整的模型规划 → 工具执行 → 人工把关能力exit_conditions与max_agent_steps双保险控制循环生命周期state_schema让工具间共享运行时状态HumanInTheLoopStrategy策略 UI与BreakpointConfirmationStrategy异常 快照覆盖了可即时交互与不可即时交互两类审批场景run_async则保证高并发服务场景下的可用性。若想深入了解上述机制在当前仓库中的正式实现建议继续阅读Agent 主循环与状态管理haystack/components/agents/agent.py、haystack/components/agents/state/state.py人机协同确认机制haystack/hooks/human_in_the_loop/hooks.py、haystack/hooks/human_in_the_loop/strategies.py、haystack/hooks/human_in_the_loop/policies.py、haystack/hooks/human_in_the_loop/user_interfaces.py协议定义haystack/hooks/human_in_the_loop/types/protocol.py、haystack/hooks/human_in_the_loop/dataclasses.py对应测试test/hooks/human_in_the_loop/test_hooks.py、test/hooks/human_in_the_loop/test_strategies.py、test/hooks/human_in_the_loop/test_policies.py。【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表