ARTICLE DETAIL

资讯详情

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

DeepAgents框架架构05:状态治理与结果回写

DeepAgents框架架构05:状态治理与结果回写 状态治理与结果回写ToolMessage/Command/PrivateState的三层分离给模型看的 ≠ 写进状态的 ≠ 暴露给调用方的。三件事必须走三条通道混淆任何一个都会导致不可排查的状态污染。一、状态是Agent系统的血液Agent系统本质上是一个状态机。每一轮循环都在更新状态用户输入写进消息历史、工具结果写进消息历史、模型输出写进消息历史。状态流经模型的上下文窗口驱动下一步推理。但这里有一个容易被忽视的致命问题并不是所有状态都应该被模型看到。举个典型场景子Agent内部跑了30轮推理生成了5次工具调用中间出过一次错误后来修复这些中间过程对子Agent自身是必要的——它在逐步解决问题但对主Agent来说这30轮消息是纯粹的噪音——它只需要知道任务完成了结果是X如果把子Agent的全部中间消息写进主Agent的状态结果就是上下文窗口瞬间被撑爆Token成本暴增主Agent迷失在子Agent的内部细节中。DeepAgents通过三层状态视图分离解决了这个问题。二、三层视图分离每个受众看到不同的状态DeepAgents将Agent状态分为三个层次每层有不同的受众治理细节 - Private State记忆内容 / 技能索引 / ...系统状态 - Statemessages / async_tasks / ...模型视图 - 对话消息ToolMessage / AIMessage模型视图这是模型通过上下文窗口读到的内容——经过裁剪和过滤的消息流。子Agent的内部消息被_EXCLUDED_STATE_KEYS阻断只留下最终结果的ToolMessage。模型不需要知道子Agent内部跑了几轮只需要知道结果。系统状态这是Agent运行时的完整状态快照——messages、async_tasks、todos等所有状态字段。框架通过LangGraph的StateGraph管理这些状态中间件通过Command机制更新它们。治理细节这是中间件的私有数据——记忆内容、技能索引、缓存元数据等。通过PrivateStateAttr隔离模型不可见调用方也不可见。三层分离的核心价值每层只暴露给它真正需要的信息。多暴露一层就多一层的污染风险。三、同步结果回写ToolMessage的干净交付子Agent跑完怎么把结果交给主Agent同步子Agent执行完毕后结果回传经历了三层过滤子Agent内部messages30轮对话_EXCLUDED_STATE_KEYS 过滤阻断对话历史、待办列表、长期记忆只保留最后一条AI消息的内容包装为 ToolMessageCommand(update...) 写回主Agent主Agent看到干净的 ToolMessage具体来说_EXCLUDED_STATE_KEYS是一个白名单机制——它定义了哪些主Agent状态不能传给子Agent也定义了哪些子Agent状态不能回传给主Agent。两边隔离双向过滤。为什么ToolMessage而不是其他格式ToolMessage是LangChain/LangGraph中工具调用的标准返回格式。用ToolMessage包装子Agent结果意味着主Agent像处理普通工具结果一样处理子Agent的输出——不需要特殊通道不需要特殊解析逻辑。这体现了统一接口的架构原则对主Agent来说调task子Agent委派和调read_file文件读取是同一种交互模式——工具调用→ToolMessage返回→继续推理。四、异步结果回写async_tasks状态账本异步任务不能靠聊天历史记住同步任务的结果立刻返回给模型模型可以记住它。但异步任务可能跑几分钟甚至几小时——等它跑完时模型上下文可能已经更新了很多轮甚至会话都断了又恢复了。因此DeepAgents专门设计了async_tasks状态字段# AsyncSubAgentStateasync_tasks:dict[str,AsyncTaskStatus]# key task_id, value 任务状态这个字段不依赖模型记忆——它是结构化状态通过LangGraph的StateGraph持久化。即使模型忘了有异步任务在跑框架通过Reducer机制保证任务状态不会丢失。Reducer合并不是直接覆盖async_tasks的更新用的是Reducer模式# 不是 state[async_tasks] new_tasks 覆盖# 而是 state[async_tasks] {**state[async_tasks], **new_tasks} 合并为什么必须用Reducer因为同一时刻可能有多个异步任务在并发执行。一个任务完成时只更新自己的状态条目不能覆盖其他任务的状态。Reducer保证多任务并发更新时的数据一致性。异步任务的生命周期状态含义触发条件pending已登记等待执行AsyncSubAgentMiddleware发起任务running执行中后台开始处理success执行成功任务正常完成结果写入账本error执行失败任务异常错误信息写入账本cancelled已取消主Agent主动取消主Agent通过list_async_tasks工具随时查看所有异步任务的状态——不需要记住task_id不需要遍历聊天历史。AsyncSubAgentMiddleware发起任务后台开始处理主Agent主动取消任务正常完成结果写入账本任务异常错误信息写入账本主Agent主动取消自动重试可配置次数与间隔重试耗尽pendingrunningcancelledsuccesserror五、PatchToolCallsMiddleware状态合法性的自动修复悬空工具调用问题这是Agent系统中一个常见但容易被忽视的Bug用户工具执行器模型用户工具执行器模型工具B尚未执行消息序列不合法[...assistant(tool_calls[A,B]), tool_result(A), user(换方案)]生成工具调用 [call_A, call_B]工具A执行完毕返回结果插入新消息: 别搞了换一个方案工具B的调用悬空了——模型说要调但没结果。下次调模型时API会因为消息序列不合法而报错。怎么修补PatchToolCallsMiddleware在before_agent()阶段检查消息序列发现悬空工具调用时自动补充一条ToolMessage(contentTool call cancelled.)让消息序列恢复合法格式。关键点这个修补发生在模型推理之前。模型还没看到用户的新消息中间件先帮它把上一轮说要做但没做完的事收个尾。模型下一轮推理时面对的是一个干净合法的消息序列。六、Command机制同时更新消息和其他状态为什么需要Command普通的工具返回只能更新messages。但如果一个工具执行后还需要更新其他状态字段——比如子Agent完成后不仅要返回结果还要更新async_tasks账本——就需要一种能力在一次操作中同时更新多个状态字段。DeepAgents用Command(update...)实现这一点# 子Agent完成后的状态更新Command(update{messages:[ToolMessage(contentresult,tool_call_idcall_id)],async_tasks:{task_id:{status:success,result:result}}})一个Command两种更新原子操作。和三层的对应关系Command(update...)一次原子操作update.messagesToolMessageupdate.async_tasks任务状态字典PrivateStateAttr治理元数据模型视图模型可见系统状态框架可见治理细节中间件可见模型不可见Command.update[messages]→ 更新模型视图模型可见Command.update[async_tasks]→ 更新系统状态框架可见PrivateStateAttr→ 更新治理细节中间件可见模型不可见三层各走各的通道互不污染。七、状态设计的工程准则这些设计加在一起形成了DeepAgents状态治理的工程准则准则一区分模型该看的和系统该记的模型上下文窗口是昂贵的资源。只放模型推理必需的信息——当前任务、最近几轮对话、工具调用结果。系统元数据任务状态、配置、缓存走独立状态字段。准则二状态更新走Reducer不走直接赋值多Agent多工具并发执行时直接赋值必然导致覆盖丢失。Reducer模式保证并发安全。准则三状态异常主动修复不等报错悬空工具调用、消息序列不合法等问题通过PatchToolCalls在每一轮开始前主动修复。修复在前推理在后——不让脏数据进入模型上下文。准则四治理状态私有化记忆内容、技能元数据、中间件内部状态走PrivateStateAttr。这些信息是给中间件用的模型不应该看到调用方也不应该看到。暴露治理状态就是暴露实现细节。八、小结状态是Agent系统最容易被忽视的核心资产。代码写错了可以改状态脏了就很难清——因为脏状态会持续影响后续所有推理。DeepAgents的状态治理遵循一个简单原则给模型看的、写进状态的、暴露给调用方的 —— 三件事走三条通道。ToolMessage→ 模型看到干净的对话流Command(update...)→ 框架管理完整的状态数据PrivateStateAttr→ 中间件持有治理元数据async_tasks Reducer → 并发安全的异步任务追踪PatchToolCallsMiddleware→ 主动修复状态异常不让脏数据进模型这五层保障加起来让Agent的状态始终干净、可追踪、可恢复。对一个生产系统来说状态干净比模型聪明更重要。
返回列表