ARTICLE DETAIL

资讯详情

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

Haystack Agent API 详解:工具调用循环、退出条件与共享 State 的完整参考

Haystack Agent API 详解:工具调用循环、退出条件与共享 State 的完整参考 Haystack Agent API 详解工具调用循环、退出条件与共享 State 的完整参考【免费下载链接】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 官方 API 参考文档version-2.20 的agents_api.md系统讲解Agent组件与State类的核心 API如何构造一个 provider 无关的工具调用 Agent、如何配置退出条件exit_conditions、如何在运行期控制步骤上限与流式输出以及如何利用State让 Agent 与工具读写同一份共享上下文。读完后你可以直接按文档示例搭建可运行的工具调用 Agent并理解其底层执行循环与状态合并机制在源码中的实现方式。1. Agentprovider 无关的工具调用循环Agent是 Haystack 中的一个组件Component实现“带工具的 Agent”它处理消息并执行工具直到满足退出条件。退出条件可以由两种方式触发模型直接给出文本回复不带工具调用模型调用了某个被指定为退出条件的工具该工具执行完毕后 Agent 返回。可以指定多个退出条件。当你调用一个不带工具的Agent时它退化为一个普通的ChatGenerator生成一条回复后立即退出。对应源码位于 agent.py类定义使用component装饰器注册为管道组件因此可以直接嵌入Pipeline使用。2. 官方使用示例搜索 计算器下面是 API 文档给出的完整示例。它定义了两个工具网页搜索和计算器让 Agent 回答“在法国吃 85 欧元的饭应该给多少小费”from haystack.components.agents import Agent from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage from haystack.tools import Tool # Tool functions - in practice, these would have real implementations def search(query: str) - str: Search for information on the web. # Placeholder: would call actual search API return In France, a 15% service charge is typically included, but leaving 5-10% extra is appreciated. def calculator(operation: str, a: float, b: float) - float: Perform mathematical calculations. if operation multiply: return a * b elif operation percentage: return (a / 100) * b return 0 # Define tools with JSON Schema tools [ Tool( namesearch, descriptionSearches for information on the web, parameters{ type: object, properties: { query: {type: string, description: The search query} }, required: [query] }, functionsearch ), Tool( namecalculator, descriptionPerforms mathematical calculations, parameters{ type: object, properties: { operation: {type: string, description: Operation: multiply, percentage}, a: {type: number, description: First number}, b: {type: number, description: Second number} }, required: [operation, a, b] }, functioncalculator ) ] # Create and run the agent agent Agent( chat_generatorOpenAIChatGenerator(), toolstools ) result agent.run( messages[ChatMessage.from_user(Calculate the appropriate tip for an €85 meal in France)] ) # The agent will: # 1. Search for tipping customs in France # 2. Use calculator to compute tip based on findings # 3. Return the final answer with context print(result[messages][-1].text)执行流程可以概括为三步Agent 把消息和工具 schema 交给OpenAIChatGenerator模型决定调用search工具结果以消息形式追加到对话中模型再调用calculator计算小费金额模型生成不含工具调用的最终文本回复命中默认退出条件textrun()返回完整消息历史。版本说明当前仓库版本为 3.x见 VERSION.txt源码 docstring 中推荐使用更简洁的tool装饰器写法定义工具与 2.20 文档中手工构造Tool对象的方式等价。3. Agent.init参数详解API 文档给出的构造函数签名为def __init__(*, chat_generator: ChatGenerator, tools: Optional[ToolsType] None, system_prompt: Optional[str] None, exit_conditions: Optional[list[str]] None, state_schema: Optional[dict[str, Any]] None, max_agent_steps: int 100, streaming_callback: Optional[StreamingCallbackT] None, raise_on_tool_invocation_failure: bool False, tool_invoker_kwargs: Optional[dict[str, Any]] None) - None各参数说明如下继承自 API 文档并结合源码补充参数类型 / 默认值说明chat_generatorChatGenerator必填Agent 使用的聊天生成器。必须支持 tools 参数否则在传入工具时会抛出TypeError。源码在 agent.py 中通过inspect.signature(chat_generator.run)检查run方法是否接受tools参数。toolsTool/Toolset列表或单个Toolset默认NoneAgent 可使用的工具。不传工具时 Agent 等价于单次生成的 ChatGenerator。system_promptstr默认NoneAgent 的系统提示词。exit_conditionslist[str]默认[text]触发 Agent 返回的条件列表。可包含text模型生成不含工具调用的消息时返回也可以是工具名该工具执行完毕后返回。state_schemadict[str, Any]默认None运行时共享状态的 schema供工具读写见第 6 节。max_agent_stepsint默认100Agent 最多执行的步数。达到上限后 Agent 停止并返回当前状态。streaming_callbackStreamingCallbackT默认NoneLLM 流式响应时的回调同一回调也可配置为在工具被调用时输出工具结果。raise_on_tool_invocation_failurebool默认False工具调用失败时是否抛出异常。为False时异常会被转成一条聊天消息传给 LLM让模型自行处理失败。tool_invoker_kwargsdict[str, Any]默认None传给底层 ToolInvoker 的额外关键字参数。抛出异常来自 API 文档TypeErrorchat_generator的run方法不支持tools参数ValueErrorexit_conditions配置不合法。从源码结构看agent.pyexit_conditions为None时会被规范为[text]state_schema中的键若与 Agent 保留的内部状态键冲突会抛ValueError。此外新版构造函数还增加了如tool_concurrency_limit默认 4控制并行工具调用数设为 1 即禁用并行执行、hooks挂接点机制等参数属于 2.20 文档之后的演进核心参数语义保持一致。4. 执行循环与退出判定源码视角文档中的退出语义在 agent.py 的执行循环中可以完整印证。每个“步step” 一次 chat-generator 调用 该次调用中模型请求的所有工具执行调用 LLM将State中累积的messages以及当前步展开后的工具列表传给chat_generator.run()回复消息追加进State模型侧退出判定_get_model_exit_reason()agent.py检查最后一条消息——若没有工具调用且来自 assistant则退出。这里还能区分finish_reason为length/content_filter不完整的生成与正常文本回复text便于下游区分“完整答案”和“被截断的半截答案”工具侧退出判定若模型请求了工具调用_check_exit_conditions()agent.py遍历该步所有工具调用——只要调用了exit_conditions中列出的某个工具名且该工具没有报错就以该工具名作为退出原因返回如果该工具报错了则取消退出循环继续。这一步解释了文档中“工具名作为退出条件”的精确语义必须调用成功才退出步数上限外层while循环以max_agent_steps为界超限后 Agent 记录exit_reasonmax_agent_steps并返回当前状态同时打印警告日志。exit_reason作为输出暴露后可以方便地接ConditionalRouter等路由组件做下游分发这是把 Agent 嵌入更大管道时的关键设计。5. Agent.run 与 Agent.run_async运行期参数5.1 同步 run()API 文档给出的签名def run(messages: list[ChatMessage], streaming_callback: Optional[StreamingCallbackT] None, *, generation_kwargs: Optional[dict[str, Any]] None, break_point: Optional[AgentBreakpoint] None, snapshot: Optional[AgentSnapshot] None, system_prompt: Optional[str] None, tools: Optional[Union[ToolsType, list[str]]] None, **kwargs: Any) - dict[str, Any]参数说明messages要处理的ChatMessage对象列表streaming_callback流式响应回调同 init 参数generation_kwargs传给 LLM 的额外参数按 key 覆盖组件初始化时的同名参数break_pointAgentBreakpoint可以是chat_generator的Breakpoint或tool_invoker的ToolBreakpoint用于在调试中暂停执行snapshot先前保存的 Agent 执行快照字典包含恢复执行所需的信息可从中断处继续system_prompt若提供则覆盖默认系统提示词tools本次运行使用的工具——可以是Tool对象列表、Toolset或工具名列表从 Agent 初始化时配置的 tools 中按名字挑选。工具选择的实现见 _select_tools传名字时从初始工具集中筛选传对象时会先对其执行warm_up再使用**kwargs额外数据键必须与state_schema中定义的 schema 匹配用于初始化 State。异常RuntimeErrorAgent 未warm_up就调用run()BreakpointException触发断点时抛出。返回值是一个字典messagesAgent 运行期间交换的全部消息last_message最后一条消息state_schema中定义的任意额外键各工具/状态写入的共享数据。从源码结构看3.x 版本的返回值还固定包含运行元数据step_count执行的步数、token_usage汇总自每次 LLM 消息的meta[usage]、tool_call_counts每个工具被调用次数、exit_reason退出原因这些都作为组件输出暴露agent.py方便下游做统计与路由。5.2 异步 run_async()run_async()与run()逻辑完全一致签名相同区别在于尽可能使用异步操作——例如底层ChatGenerator提供run_async时直接走异步路径streaming_callback也需要对应使用异步回调。返回字典的键与run()相同。6. StateAgent 与工具之间的共享上下文State是一个容器用于在 Agent 及其工具执行期间存储共享信息——例如文档、上下文、中间结果。它内部包裹一个由schema定义的_data字典。每个 schema 条目的形式为{ parameter_name: { type: SomeType, // 期望的 Python 类型 handler: Callable[[Any, Any], Any] | None // 合并/更新函数 } }handler 决定调用set()时值如何合并列表类型默认merge_lists拼接列表其他类型默认replace_values覆盖旧值。schema 中会自动加入一个类型为list[ChatMessage]的messages字段。正是这一点让 Agent 和所有工具能读写同一份对话上下文。对应实现位于 state.py。官方示例from haystack.components.agents.state import State my_state State( schema{gh_repo_name: {type: str}, user_name: {type: str}}, data{gh_repo_name: my_repo, user_name: my_user_name} )6.1 方法与行为细节方法签名说明__init__(schema, dataNone)schema是参数名到类型/handler 配置的字典type必须是合法 Python 类型类、泛型、Union 均可校验见 state_utils.pyhandler必须是可调用对象或Nonedata是可选初始数据。handler 缺省时按类型自动填充列表 →merge_lists其他 →replace_valuesstate.py。get(key, defaultNone)按键取值源码中返回的是deepcopy避免调用方意外修改 State 内部数据。set(key, value, handler_overrideNone)按 schema 规则设置或合并值。合并规则优先使用handler_override否则使用 schema 中为该键定义的 handlerstate.py。键不在 schema 中会抛ValueError。dataproperty返回 State 当前全部数据字典。has(key)键是否存在于 State 中。to_dict()将 State 转为可序列化字典schema 中的类型与 handler 分别经类型序列化和可调用对象序列化_schema_to_dictstate.py。from_dictclassmethod从字典恢复 State 对象。两个默认 handler 的行为非常直观实现在 state_utils.pymerge_lists(current, new)把新旧值都归一化为列表后拼接None视为空列表。这意味着 Agent 每步产生的新消息、工具结果天然累积进messagesreplace_values(current, new)直接返回new即覆盖语义。6.2 State 在 Agent 中的集成方式从源码结构看Agent 在初始化时会把用户state_schema、内置messages字段、以及内部控制键如stop_run、context_tokens合并成resolved_state_schema并为 schema 中非保留键注册组件输入/输出agent.py。每次run()都会基于kwargs与 schema 键构造一个全新的Stateagent.py工具在执行时通过 State 读写共享数据运行结束后的公开输出就是“剔除内部键后的 State 数据”。这解释了 API 文档中run()返回字典为何会包含state_schema中定义的所有额外键。7. 序列化to_dict 与 from_dictAgent 遵循 Haystack 组件的标准序列化协议Agent.to_dict()把组件序列化为字典default_to_dict其中 chat_generator、tools/Toolset、streaming_callback 等各自调用对应的序列化器agent.pyAgent.from_dict(data)classmethod反序列化时先递归恢复chat_generator组件、state_schema的类型/handler、可调用对象与 toolsagent.py再调用default_from_dict完成构造。这意味着整个 Agent连同它绑定的生成器与工具可以作为管道的一部分被整体保存和加载也是 2.20 文档中snapshot/break_point参数能够工作的前提——快照本质上就是对运行中状态的序列化记录。断点相关的数据结构定义可参考 breakpoints.py。8. 小结与实践建议最小可用 Agent只需chat_generatortools默认exit_conditions[text]即可实现“搜索→计算→回答”的完整工具循环文档示例可直接运行控制终止用工具名作为退出条件时注意源码语义是“该工具成功执行后退出”工具报错不会触发退出配合max_agent_steps默认 100防止无限循环容错策略raise_on_tool_invocation_failureFalse默认会把工具异常转成消息喂回给 LLM适合让模型自行纠错需要严格失败语义时改为True共享上下文凡是需要跨工具/跨步骤传递的数据检索到的文档、中间结果、用户信息都应放入state_schema而非依赖消息文本——列表类型自动追加、标量类型自动覆盖set()还支持单次调用级的手动 handler 覆盖管道集成run()输出中的messages、last_message及自定义 state 键都是组件输出可直接连线到下游组件run_async()提供等价异步能力适合高并发服务场景。对照当前仓库 3.x 源码时需注意2.20 文档中的tool_invoker_kwargs已被tool_concurrency_limit等更具体的参数取代并新增了user_prompt模板变量、hooks挂接点等能力但AgentState的核心 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表