拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Haystack 实验性 Agent API 全解析:工具调用、退出条件与人在回路确认机制

Haystack 实验性 Agent API 全解析工具调用、退出条件与人在回路确认机制【免费下载链接】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 2.19 实验性参考文档experimental_agents_api为核心系统讲解haystack_experimental.components.agents.Agent组件的完整 API如何构建支持工具调用的 Agent、如何设置多种退出条件控制运行循环、如何通过HumanInTheLoopStrategy与BreakpointConfirmationStrategy在工具执行前引入人工确认。读完本文你将能够基于ChatGeneratorTool快速搭建生产可用的工具型 Agent并为关键工具配置始终询问 / 从不询问 / 仅询问一次的确认策略甚至在无法即时交互的场景下借助断点快照实现异步人工审批。一、Agent 组件是什么根据文档定义haystack_experimental.components.agents.Agent是一个实现了工具调用tool-using能力的 Haystack 组件核心特征是与模型提供商无关的 Chat 模型支持provider-agnostic chat model support——它不绑定任何特定 LLM而是接收任意支持tools参数的ChatGenerator实例作为驱动引擎。该组件的行为模型是一个消息-工具循环接收用户消息列表交给 Chat Generator 生成回复若回复中携带工具调用tool call则执行对应工具并把结果写回对话循环往复直到某个退出条件exit condition被满足。退出条件可以是两条路径之一模型直接产出了一条不带工具调用的文本回复或者模型调用了某个被指定为终止工具的工具。文档明确说明可以同时指定多个退出条件。值得注意的一个降级行为当 Agent 不配置任何工具时它退化为一个纯粹的ChatGenerator——只生成一次回复然后立即退出见文档 When you call an Agent without tools, it acts as a ChatGenerator, produces one response, then exits.。文档特别标注该类在 Haystack 基础 Agent 之上扩展了人在回路human-in-the-loop确认策略支持这是本 API 区别于普通 Agent 的核心增强。在后续 2.19 之后的版本演进中Agent 主体与 HITL 机制已被并入核心包haystack/components/agents/agent.py与haystack/hooks/human_in_the_loop/目录本文会在讲解实验性 API 的同时结合仓库源码补充底层实现细节。二、快速上手带确认策略的工具型 Agent文档给出了完整的用法示例为计算器和搜索两个工具分别配置不同的确认策略然后运行 Agent。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这个示例揭示了三个关键设计工具通过Tool对象声明每个工具只需提供name与description即可被 LLM 感知和调度确认策略按工具粒度配置——confirmation_strategies是一个以工具名为键、HumanInTheLoopStrategy为值的字典NeverAskPolicy让计算器静默执行AlwaysAskPolicy让搜索在每次执行前都征求用户同意UI 与策略解耦——SimpleConsoleUI只是交互界面实现可以替换为 Web 界面等自定义 UI。在仓库当前源码中Tool数据类位于 haystack/tools/tool.py而确认策略、策略判定与 UI 的协议定义位于 haystack/hooks/human_in_the_loop/types/protocol.pyBlockingConfirmationStrategy即文档中HumanInTheLoopStrategy的当前核心实现位于 haystack/hooks/human_in_the_loop/strategies.py。三、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 使用的聊天生成器必须支持tools参数否则抛出TypeErrortoolsToolsType \| NoneNoneAgent 可用的Tool对象列表或一个Toolsetsystem_promptstr \| NoneNoneAgent 的系统提示词exit_conditionslist[str] \| None[text]触发 Agent 返回的条件列表text表示生成无工具调用的消息即返回也可填入工具名表示该工具执行完毕后返回非法值抛ValueErrorstate_schemadict[str, Any] \| NoneNone工具共享的运行时状态 schemamax_agent_stepsint100Agent 运行的最大步数上限超限即停止并返回当前状态streaming_callbackStreamingCallbackT \| NoneNoneLLM 流式输出回调同一回调也可配置为在工具调用时输出工具结果raise_on_tool_invocation_failureboolFalse工具调用失败时是否抛异常为False时异常会被转换为一条聊天消息回传给 LLMconfirmation_strategiesdict[str, ConfirmationStrategy] \| NoneNone按工具名映射的确认策略用于人在回路确认tool_invoker_kwargsdict[str, Any] \| NoneNone透传给ToolInvoker的额外关键字参数chat_message_storeChatMessageStore \| NoneNone用于存储与检索聊天历史的消息存储memory_storeMemoryStore \| NoneNone用于存储与检索记忆的记忆存储从仓库源码haystack/components/agents/agent.py可以印证几个底层校验逻辑初始化时会用inspect.signature(chat_generator.run).parameters检查生成器run方法是否接受tools参数不接受且又传入了工具时立即抛出TypeError对应文档中TypeError: If the chat_generator does not support tools parameter in its run methodexit_conditions为None时统一补成[text]state_schema中不允许与内部保留键step_count、token_usage、tool_call_counts、exit_reason等运行元数据键重名否则抛ValueError当前的实现还额外支持user_prompt、required_variables、tool_concurrency_limit、hooks等后续版本参数说明实验性 API 已进一步演化。四、Agent.run与Agent.run_async驱动运行循环4.1 同步rundef 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要处理的 HaystackChatMessage列表是整个对话的输入streaming_callback运行时流式回调优先级高于初始化时配置的同名参数generation_kwargs额外传给 LLM 的生成参数运行时传入会覆盖初始化时设置的同名参数break_point一个AgentBreakpoint可以是针对chat_generator的Breakpoint也可以是针对tool_invoker的ToolBreakpoint用于调试时在特定环节暂停snapshot之前保存的 Agent 执行快照包含从上次中断处恢复运行所需的全部信息system_prompt运行时系统提示词提供时覆盖默认值tools本次运行使用的工具——可以是Tool对象列表、一个Toolset或工具名字符串列表传名字时从 Agent 初始化配置的工具中按名选取confirmation_strategy_context用于向确认策略传递请求级资源request-scoped resources的字典。文档特别强调其在 Web/服务端场景的价值可以放入 WebSocket 连接、异步队列、Redis pub/sub 客户端等对象使策略实现非阻塞式用户交互chat_message_store_kwargs透传给ChatMessageStore的关键字参数例如chat_history_id与last_k用于检索历史memory_store_kwargs透传给MemoryStore的关键字参数包含user_id/run_id/agent_id按用户、运行或 Agent 维度检索、写入记忆search_criteriasearch_memories方法的参数字典可含filters记忆过滤条件字典query检索用查询串——注意一旦传入Agent 的用户查询将被忽略改用此查询做记忆检索top_k返回的记忆条数include_memory_metadata是否把记忆元数据包含进ChatMessagekwargs写入state_schema定义的运行时状态的额外数据键必须与 schema 匹配。返回值为一个字典固定包含messages本次运行期间交换的全部消息last_message最后一条消息以及state_schema中定义的任何额外键。可能抛出的异常RuntimeError未warm_up就调用run()与BreakpointException断点被触发。4.2 异步run_asyncasync def run_async(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]run_async是run的异步版本逻辑完全一致但会尽可能使用异步操作——例如优先调用ChatGenerator.run_async若可用。差异点仅在于streaming_callback应是异步回调对应异常为未warm_up就调用run_async()时的RuntimeErrormemory_store_kwargs同样支持user_id/run_id/agent_id/search_criteria。在仓库当前实现中haystack/components/agents/agent.py同步run与异步run_async共享同一套状态初始化逻辑_initialize_fresh_execution差别仅在于钩子执行、Chat Generator 调用与工具执行分别走_run_hooks/_run_hooks_async、chat_generator.run/_execute_component_async等同步或异步路径。五、退出条件机制控制 Agent 何时停止退出条件是 Agent 运行循环的刹车。文档定义了以下规则默认行为exit_conditions默认为[text]即模型产出一条不含工具调用的消息时立即返回工具退出条件把某个工具的名字加入exit_conditions如[text, search]则该工具成功执行完毕后 Agent 立即返回last_message为该工具的执行结果多条件并存列表可同时包含text与多个工具名无工具退化不配工具时 Agent 等价于 ChatGenerator一次回复即退出。从源码看haystack/components/agents/agent.py工具退出条件的判定细节是遍历本轮 LLM 消息中的所有工具调用若某调用命中了exit_conditions中的工具名且该工具未报错则返回该工具名作为退出原因若命中的工具执行出错则取消退出返回None即使同一轮还有其他命中的工具成功执行。多个退出工具同时命中时取第一个。当前实现还会在返回值中给出exit_reason字段取值包括text无工具调用的完整回复、length与content_filter模型产出了不完整回复、满足退出条件的工具名、max_agent_steps步数预算耗尽、或钩子通过stop_run状态键写入的自定义原因。exit_reason可以直接喂给ConditionalRouter做下游路由。六、state_schema工具间共享的运行时状态state_schema允许你为 Agent 定义跨工具、跨步骤共享的运行时状态。其值是一个字典每个键对应一个类型配置含必填的type与可选的handler合并策略。工具的运行时状态通过两个方向接入读工具通过inputs_from_state从状态中读取数据写工具通过outputs_to_state把结果写回状态。这些state_schema中定义的键会成为run()的额外输入参数通过**kwargs传入也会出现在返回值中。源码层面haystack/components/agents/agent.py会为每个 schema 键注册组件的输入/输出类型并自动追加一个内置的messages键类型为list[ChatMessage]handler为merge_lists用于维护对话历史。七、人在回路Human-in-the-Loop确认策略这是本文档最核心的特色能力。confirmation_strategies允许为每个工具独立配置确认策略把模型要执行某个工具这一事件交给人工把关然后再决定放行、拒绝还是修改参数后放行。7.1 策略的三层结构从文档示例与仓库源码haystack/hooks/human_in_the_loop/可以还原出三层解耦架构ConfirmationPolicy判定策略——回答要不要问用户。仓库内置三种实现haystack/hooks/human_in_the_loop/policies.pyAlwaysAskPolicyshould_ask恒为True每次执行前都询问NeverAskPolicy恒为False从不询问、直接放行AskOncePolicy带内部记忆对相同工具 相同参数只询问一次之后自动放行。ConfirmationUI交互界面——负责真正与用户对话如文档示例中的SimpleConsoleUI控制台交互。可替换为 WebSocket、异步队列等非阻塞交互实现。HumanInTheLoopStrategy确认策略——把策略与 UI 组合起来产出ToolExecutionDecision。7.2 决策结果ToolExecutionDecision策略运行后返回一个决策对象数据类定义见 haystack/hooks/human_in_the_loop/dataclasses.py字段包括tool_name目标工具名execute是否执行该工具tool_call_id可选的工具调用唯一标识用于把决策关联回具体某次调用feedback反馈文本——拒绝时含拒绝原因修改时含修改说明final_tool_params确认或修改后的最终工具参数。UI 返回的ConfirmationUIResult则包含三个字段actionconfirm/reject/modify、可选的feedback用户反馈、可选的new_tool_params用户修改后的新参数。7.3 三种处理路径BlockingConfirmationStrategy.run当前核心实现见 haystack/hooks/human_in_the_loop/strategies.py按用户动作分三条路径处理confirm确认按原参数执行工具reject拒绝不执行生成Tool execution for {tool_name} was rejected by the user.之类的拒绝反馈消息可选拼接用户提供的理由With user feedback: {feedback}作为工具结果消息回传给 LLMmodify修改用new_tool_params替换工具参数后执行并额外插入一条用户消息向 LLM 解释参数为何被修改模板The parameters for tool {tool_name} were updated by the user to: {final_tool_params}——这是防止 LLM 下一轮又用原始参数重调同一工具的关键设计。策略还支持tool_call_id关联、confirmation_strategy_context透传以及to_dict/from_dict序列化。文档在HumanInTheLoopStrategy相关条目中强调这些模板reject_template、modify_template、user_feedback_template均可用自定义模板覆盖。八、BreakpointConfirmationStrategy非交互场景的中断式确认BreakpointConfirmationStrategy是另一种确认策略专门面向无法立即与用户交互的场景如无头服务、批处理任务。核心机制当某个工具需要确认时该策略不阻塞等待而是抛出一个HITLBreakpointException异常把执行暂停下来Agent 捕获该异常后将当前状态包括工具调用细节序列化为快照保存到磁盘外部系统随后可以读取快照把待确认的工具执行请求呈现给用户审批批准后再恢复执行。class BreakpointConfirmationStrategy: def __init__(snapshot_file_path: str) - Nonesnapshot_file_path快照保存目录路径。run/run_async的入参完全一致tool_name、tool_description、tool_params、tool_call_id、confirmation_strategy_context行为也一致总是抛出HITLBreakpointException文档原话This method does not return; it always raises an exception绝不直接返回决策。confirmation_strategy_context虽不在本策略中使用但为接口兼容而保留。该策略同样实现了to_dict/from_dict序列化。九、HITLBreakpointException与快照工具函数9.1 异常对象HITLBreakpointException用于表示工具执行被ConfirmationStrategy如BreakpointConfirmationStrategy暂停这一事件。其构造函数为def __init__(message: str, tool_name: str, snapshot_file_path: str, tool_call_id: str | None None) - None字段含义message为异常消息tool_name为被暂停执行的工具名snapshot_file_path为已保存的 pipeline 快照文件路径tool_call_id为可选的工具调用唯一标识用于追踪和关联某次具体调用与后续的人工决策。定义位于 haystack/hooks/human_in_the_loop/errors.py。9.2 从快照提取工具调用信息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_only为True默认时只处理导致断点的那一个工具调用并重建其参数——典型用途是把需要人工确认的那次调用及其描述呈现给用户审批为False时返回快照中的全部工具调用。返回值为一个二元组list[dict]形式的工具调用字典列表以及dict[str, str]形式的工具描述字典工具名到描述。十、序列化支持to_dict与from_dictAgent 与BreakpointConfirmationStrategy均实现了标准的 Haystack 序列化接口Agent.to_dict()将组件序列化为字典Agent.from_dict(data)类方法从字典反序列化出 Agent 实例。这使 Agent 可以像其他 Haystack 组件一样被序列化进 YAML/JSON pipeline 定义或在分布式/服务化环境中传输与重建。当前核心实现的序列化逻辑haystack/components/agents/agent.py会递归序列化chat_generator、工具列表、提示词、退出条件、状态 schema、流式回调与钩子等全部初始化参数from_dict则逐一反序列化还原。确认策略字典的序列化haystack/hooks/human_in_the_loop/strategies.py还有一个细节当多个工具共享同一策略元组键时键会被编码为 JSON 数组字符串以便存储反序列化时再还原为元组。十一、源码级视角Agent 运行循环如何工作为了加深理解结合当前仓库实现梳理 Agent 一个 step 的完整流程haystack/components/agents/agent.py展平工具每步重新展平工具集合并做重名校验使动态 Toolset如SearchableToolset在运行中发现的新工具也能及时暴露给模型before_llm钩子在调用 Chat Generator 前执行若钩子写入了stop_run键则在本步边界终止运行调用 LLM把当前对话消息与工具列表传入chat_generator.run()得到回复消息记录用量累加 token 用量、估算上下文 token 数退出判定无工具或模型产出无工具调用的终止回复时记录exit_reason并尝试退出否则进入工具阶段before_tool钩子在工具执行前运行——这正是确认钩子如ConfirmationHook介入的时机钩子可以改写、拒绝或放行工具调用Agent 随后重新读取状态中的最后一条消息来确定真正要执行的调用执行工具把待执行的工具调用消息、运行时状态、工具列表交给工具执行器raise_on_failure、max_workers并发上限等参数在此生效after_tool钩子工具结果写回对话后运行可对结果做脱敏、截断、摘要或卸载退出条件检查若本轮调用了exit_conditions中指定的工具且未出错则以该工具名为退出原因结束on_exit/after_run钩子退出时执行on_exit钩子可通过state.set(continue_run, True)让 Agent 继续运行典型用途是必须调用某工具后才能结束。整个循环受max_agent_steps硬性约束超限即停止并返回当前状态。相关测试位于 test/components/agents/ 与 test/hooks/可进一步验证确认、拒绝、修改等各分支行为。十二、最佳实践建议为高影响工具配置AlwaysAskPolicy如发送邮件、写数据库、调用外部付费 API 等副作用明显的工具先确认再执行为纯计算、低风险工具配置NeverAskPolicy如文档示例中的calculator避免打断流程需要异步审批时使用BreakpointConfirmationStrategy配合snapshot_file_path保存快照、get_tool_calls_and_descriptions_from_snapshot提取待审调用、HITLBreakpointException.tool_call_id关联决策可以搭建完整的审批队列工作流Web 服务场景善用confirmation_strategy_context把 WebSocket 连接等请求级对象注入策略实现非阻塞确认控制循环成本始终关注max_agent_steps、exit_reason与token_usage输出防止 Agent 空转或超预算。结语haystack_experimental.components.agents.Agent把工具调用循环、多退出条件、运行时状态、人在回路确认四件事收敛到一个组件接口内配合ChatGenerator的提供商无关特性可以快速搭建从简单问答到带人工审批闸门的生产级 Agent 工作流。本文覆盖的初始化参数、run/run_async语义、确认策略三件套Policy/UI/Strategy以及断点快照机制均已通过仓库源码haystack/components/agents/agent.py、haystack/hooks/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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门