news 2026/9/10 4:49:16

Deep Agents 架构全解:一个构建在 LangChain 与 LangGraph 之上的 Batteries-Included Agent Harness

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Deep Agents 架构全解:一个构建在 LangChain 与 LangGraph 之上的 Batteries-Included Agent Harness

Deep Agents 架构全解:一个构建在 LangChain 与 LangGraph 之上的 Batteries-Included Agent Harness

【免费下载链接】deepagentsThe batteries-included agent harness.项目地址: https://gitcode.com/GitHub_Trending/de/deepagents

Deep Agents 是一个"开箱即用(batteries-included)"的 Agent 框架(harness),它不是新的运行时,而是位于 LangChaincreate_agent()与 LangGraph 之上的意见化(opinionated)装配层。本文以 openwiki/architecture/overview.md 为核心骨架,结合仓库源码(libs/deepagents/deepagents/graph.py、libs/ARCHITECTURE.md 等)深入讲解三层依赖结构、create_deep_agent()的构造与执行边界、中间件栈的组装顺序、状态与持久化设计、monorepo 各包职责边界,以及安全的变更与测试路径。读完本文,你将能够在一个变更发生时迅速定位到正确的代码层,并理解 harness、通用 Agent 抽象与图运行时各自拥有什么行为。

三层架构与依赖方向

Deep Agents 的定位非常明确:它是一个意见化的 harness,而不是替代 LangChain/LangGraph 的运行时。所有行为都可以映射到三层栈中的某一层,这也是任何变更的起点——先在架构上定位行为归属,再顺着create_deep_agent()的某个参数追踪到实现它的中间件、后端、profile 或消费产品。

每一层拥有什么

三层栈的划分如下:

  • LangGraph拥有持久的图执行能力:步骤间携带的状态、checkpoint、流式(streaming)输出,以及基于 interrupt 的暂停/恢复。
  • LangChaincreate_agent()拥有通用 Agent 抽象:模型、工具、中间件,以及它构建在 LangGraph 之上的"模型-工具-循环"(model/tool/repeat loop)。
  • Deep Agents拥有上述抽象之上的开箱即用策略:默认中间件、后端(backends)、profile、子代理(subagents)、技能(skills)与记忆(memory)配置。它不引入不同的运行时。

依赖方向是Deep Agents → LangChaincreate_agent()→ LangGraph。这给出了一个递进的选择模型:需要完整 harness 用 Deep Agents;需要一个更轻的 Agent 循环用裸的create_agent();当循环本身必须是自定义图时,直接用 LangGraph。而且这个边界是可组合的——一个 LangGraphCompiledStateGraph可以作为一个 Deep Agents 子代理被接入。

在 libs/ARCHITECTURE.md 中可以看到更细致的描述:本仓库中绝大多数 Deep Agents 专属代码集中在三处——middleware向 Agent 循环添加 harness 行为,backends决定文件、记忆与 shell 执行驻留在哪里,profiles针对特定 provider 或模型调优 harness。理解这三类组件的分工,是阅读后续所有章节的前提。

SDK 构造、执行与安全护栏

create_deep_agent()定义在 libs/deepagents/deepagents/graph.py,是整个 SDK 的集成边界(integration boundary)。它在构造期完成以下工作:

  1. 解析模型(model)与适用的 harness profile;
  2. 按需重写工具描述(tool description overrides);
  3. 默认选择StateBackend()作为后端;
  4. 组合调用方系统提示词与 profile 提示词;
  5. 处理子代理(declarative / compiled / async 三种形态);
  6. 把组装好的模型、工具、中间件、schema、checkpointer、store、debug、name、cache 全部委托给 LangChaincreate_agent(...)

返回的图携带 Deep Agents 元数据,并设置了9,999 的递归上限(recursion limit)。函数末尾的实现(libs/deepagents/deepagents/graph.py#L956-L978)展示了最终委托调用:create_agent(...).with_config({"recursion_limit": 9_999, "metadata": {...}}),元数据中包含ls_integration: "deepagents"、Deep Agents 版本号与lc_agent_name。对应的单元测试 libs/deepagents/tests/unit_tests/test_graph.py(如test_ls_integration_metadata_preservedtest_versions_metadata_reports_release_for_wheel_install)验证了这些元数据与版本信息的写入。

这就是构造与执行的边界:SDK 负责构建配置,LangGraph 负责驱动被 invoke 的图。

中间件栈的顺序与定制点

主中间件栈是有顺序的(ordered)。结合源码(libs/deepagents/deepagents/graph.py#L861-L938)与 openwiki/architecture/middleware-stack.md 的详细拆解,装配逻辑为:

核心带(core band),按序:

  1. SkillsMiddleware——仅在传入了skills时加入;
  2. FilesystemMiddleware——内置文件工具与权限执行的载体;
  3. SubAgentMiddleware——存在同步内联子代理(通常因默认 general-purpose 子代理被自动添加)时加入;
  4. Deep Agents 的 summarization 中间件(可截断旧的大工具参数、压缩历史、在ContextOverflowError后通过 compaction 重试);
  5. PatchToolCallsMiddleware——工具调用修补;
  6. AsyncSubAgentMiddleware——存在远程 async 子代理 spec 时加入。

尾部带(tail band),按序:

  • 实例化后的HarnessProfile.extra_middleware
  • provider 的 prompt-caching 中间件(Anthropic 无条件安装、对非 Anthropic 模型 no-op;Bedrock 与 Fireworks 变体仅当对应集成包可导入时添加);
  • MemoryMiddleware——传入了memory时加入;
  • HumanInTheLoopMiddleware——解析出的 interrupt 映射非空时加入。

缓存中间件故意放在 memory 之前:profile extras 在缓存前运行,而 memory 对系统提示词的修改发生在 Anthropic 缓存前缀之后,避免 memory 更新使缓存前缀失效。

调用方(caller)自定义中间件的插入规则_apply_custom_middleware(libs/deepagents/deepagents/graph.py#L204-L238)实现:按.name合并而非盲目追加——若调用方条目与栈中现存名称相同,则原位替换保持栈序;新名称则插入最后一个核心成员之后、profile extras/prompt-caching/memory/审批之前。profile 的排除(excluded_middleware)在调用方中间件合并前后各执行一次过滤,工具排除(_ToolExclusionMiddleware)则最后追加——这样后续任何自定义中间件都无法"复活"被排除的工具。

子代理的三种形态与各自边界

子代理在构造期按形态分派(源码见 libs/deepagents/deepagents/graph.py#L663-L788):

  • graph_id的 spec 是AsyncSubAgent,由AsyncSubAgentMiddleware以非阻塞后台任务方式运行(当前支持通过 LangSmith deployments 部署的代理);
  • runnable的是CompiledSubAgent,按调用方预编译的 runnable 原样使用;
  • 其余为declarative SubAgent,各自独立解析自己的模型与 harness profile,构建独立的中间件栈(Filesystem + summarization + PatchToolCalls,加上自身 skills 或 fork 继承的父 skills、profile extras、prompt caching、两轮排除过滤与覆盖率校验)。

declarative 子代理只在省略某字段时继承顶层toolspermissionsinterrupt_on;自己提供的permissions整体替换父规则而不是扩展。默认模式是isolated(子代理只收到承载委托任务的HumanMessage而非父对话),handoff是其遗留别名;实验性的fork模式则继承父对话的有效压缩历史并重建父提示词,且 fork 子代理不允许定义独立 skills,也不允许递归调用task。若未提供名为general-purpose的子代理且 profile 未禁用,harness 会自动添加默认通用子代理。

工具可见性 ≠ 授权

一个重要的排障原则:工具不可见,通常指向中间件装配问题或 profile 工具排除;工具可见但调用失败,则指向所选后端的能力或文件系统权限执行问题。

文件系统权限(permissions)由内置的FilesystemMiddleware在其内置文件工具层强制执行,而不是在后端层——直接使用后端不会经过这些中间件权限规则。permissions规则按声明顺序求值、首个匹配生效,支持allow/deny/interrupt三种 mode;interrupt模式会安装 human-in-the-loop 中间件,并在配置的调用前暂停等待人工审批。权限派生出的 interrupt 配置与用户interrupt_on合并时,同名工具以用户条目优先(_merge_fs_interrupt_on,libs/deepagents/deepagents/graph.py#L185-L201)。

DeepAgentState 与状态/持久化边界

DeepAgentState扩展了 LangChain 的AgentState,将messages字段挂到DeltaChannelreducer 上(snapshot frequency 为 50),使长线程的 checkpoint 增长从二次方降到线性(见 libs/deepagents/deepagents/graph.py#L73-L76)。自定义状态 schema 必须继承DeepAgentState才能保留该 reducer(由于TypedDict继承无法在运行时检查,这是一个仅靠类型系统约束的契约)。该 schema 与中间件贡献的 schema 合并后转发给 declarative 子代理;compiled 与 remote 子代理则需要自行编译/配置所需的状态。

持久化同样分两层:图状态与 checkpoint 属于 LangGraph(对话状态、消息历史、interrupt、可恢复性);文件与记忆的持久化属于 Deep Agents 后端(默认StateBackend是线程级作用域,store-backed 或 filesystem-backed 路由可以让文件跨线程持久或映射到磁盘/沙箱存储)。

Fail-Closed 的构造校验

构造期会拒绝不安全或无效的 profile 排除配置:受保护脚手架(FilesystemMiddlewareSubAgentMiddleware,即_REQUIRED_MIDDLEWARE定义的集合,见 libs/deepagents/deepagents/graph.py#L241-L268)、私有(下划线前缀)名称、歧义的类匹配、以及未匹配到任何已装配中间件的条目,都会抛出ValueError。字符串排除项按AgentMiddleware.name精确匹配(公共别名如SummarizationMiddleware可以命中实现类),类条目按精确类型而非isinstance匹配。这样做是为了让 profile 配置失败关闭(fail closed),而不是静默地产生一个残缺的 harness。

产品层与集成层:monorepo 的职责边界

libs/是一个各包独立版本化的 monorepo。下表中的边界把"可复用的 harness 行为"与"消费它的应用和适配器"区分开来——通用图策略放在 SDK,终端表现、协议适配、宿主生命周期、行为测量、供应商行为与工作流编排放在各自的消费者中。

架构角色
deepagents核心 SDK:create_deep_agent、中间件与可插拔后端。可复用的 harness 变更都应落在这里。
codedeepagents-codeDeep Agents Code,以dcode命令暴露的终端编码应用,包含 Textual TUI、远程沙箱、记忆、技能与无头模式。其create_cli_agent()产品入口以 CLI 上下文 schema、复合后端、CLI 中间件、中断策略、子代理、checkpoint/store 与净化后的助手名称构造 SDK 代理。
acpdeepagents-acpAgent Client Protocol 适配器,用于在 Zed 等 ACP 编辑器中运行 Python Deep Agent。AgentServerACP运行传入的代理;配合持久化 LangGraph checkpointer 与load_sessions=True,可在进程重启后重载线程、校验原始工作目录并重放会话更新。dcode --acp通过 stdio 暴露预构建的编码代理。
evalsdeepagents-evals端到端行为评测套件。运行真实 LLM 代理、记录工具调用/文件变更/最终响应,再评估正确性与效率;Harbor 集成可运行 Terminal Bench 2.0 等沙箱化基准。
talondeepagents-talon实验性的本地单事件循环宿主,用于长期运行代理、频道适配器与 cron 调度。属 alpha 软件,明确缺乏生产级审批、管理员、沙箱隔离与多租户控制。
partners/供应商与沙箱集成区:Daytona、Modal、Runloop、Vercel、QuickJS。

依赖方向为:deepagents-code消费deepagentsdeepagents-evalsdeepagents-talon同时消费 SDK 和 Code。依赖朝向 SDK 流动,而不是从 SDK 流向产品包。整体关系也可参考 libs/README.md 的包列表与 openwiki/architecture/source-map.md 的公共面映射。

dcode 的双运行时路径

值得强调的是,deepagents-code内部有两条刻意分离的运行时路径(详见 openwiki/architecture/code-agent.md):

  • 普通交互式与无头模式:终端客户端与自有的本地langgraph dev服务运行在不同进程。客户端拥有表现、输入与审批;服务端拥有模型、图、工具、记忆、技能、后端与 checkpoint。
  • dcode --acp:进程内 ACP 服务(stdio),构建本地会话图,既不启动langgraph dev也不用RemoteAgent

这是所有权边界而非可互换的传输层——对普通服务端的改动必须独立评估其对 ACP 的影响。create_cli_agent()(libs/code/deepagents_code/agent.py)是 dcode 特有的 SDK 组装接缝,make_graph()(libs/code/deepagents_code/server_graph.py)是 LangGraph 服务端工厂。

Talon 生命周期与运维边界

Talon包装而非替换SDK 图(详见 libs/talon/deepagents_talon/runtime.py):

  • DeepAgentRuntime.start()解析子代理并构建create_deep_agent()图;默认后端是本地 shell 执行,默认 checkpointer 在内存中,因此需要持久历史的调用方必须自行提供宿主的持久 checkpoint/archive 配置;
  • 每个请求的invoke()要求图已启动,先刷新运行时工具,建立请求级作用域的 authorization、history、cron、graph 与 background-result 上下文,然后持续调用直到获得文本;结束后总是重置这些上下文并确认已完成的 background 结果;
  • stop()先取消后台子代理,再释放图并关闭可关闭的 checkpointer。

Talon 可以在 MCP 工具或子代理配置重载时重建图;失败的 MCP 刷新会让旧图保持可用并把已保存的变更标记为未激活。其安全警告是实质性的:在 Talon 仍属实验性期间,频道访问应被视为直接访问操作者的代理、凭据、MCP 工具与本地宿主资源

实际的变更路径与测试路径

大多数 SDK 变更从 libs/deepagents/deepagents/graph.py 开始,再按行为归属进入middleware/backends/profiles/。扩展 harness 时必须保留中间件顺序与DeepAgentState的 reducer。产品专属的终端工作流属于code;ACP 协议/会话语义属于acp;频道生命周期、调度与宿主持久化属于talon;基准定义与评分属于evals

测试策略上,先用聚焦测试,再跑宽泛套件

  • libs/deepagents/tests/unit_tests/test_graph.py 覆盖图构造与编译图元数据(profile、提示词顺序、不可变的工具重写、中间件顺序/排除、默认与自定义子代理、权限 interrupt 接线、自定义状态传播、元数据),以及该模块内其他的 profile 与状态行为;
  • SDK 的 pytest 默认会排除带 benchmark 标记的测试,并把非预期的 warning 视为错误;
  • 集成边界则使用各包本地的测试:ACP 会话处理(libs/acp/tests/test_agent.py)、Talon 运行时生命周期/重载行为(libs/talon/tests/test_runtime.py)、以及受变更影响的端到端评测轨迹(evals包内)。

更多可深入的主题包括:中间件栈与定制边界、SDK 构造与执行细节、按职责划分的源码地图、ACP 与 Talon 集成、openwiki/integrations/talon.md,以及 dcode 产品架构 code-agent.md。

小结

Deep Agents 的价值不在于发明新的运行时,而在于把长期运行 Agent 通常需要的部件默认打包:有顺序的中间件栈、可插拔后端、provider 特定的 profile、三种形态的子代理、技能、记忆、权限与人工审批。只要掌握"harness 装配配置、LangChain 构建循环、LangGraph 驱动执行"这条依赖链,面对任何行为问题都能从create_deep_agent()的某个参数出发,一步步追踪到真正拥有该行为的中间件、后端、profile 或消费产品。

【免费下载链接】deepagentsThe batteries-included agent harness.项目地址: https://gitcode.com/GitHub_Trending/de/deepagents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 4:48:33

一站式开发板调试平台BoardLab:串口、引脚、协议一网打尽

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 4:47:13

AI工具时代,品味才是拉开差距的核心竞争力

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 4:45:54

AI编码省钱实战:WorkBuddy+CNB流水线将API成本降低80%

DeepSeek 这次调价,说白了就是给所有把大模型 API 当“自来水”用的开发者上了一课。尤其是像我这种日常靠 AI 辅助写代码、补注释、跑测试的人,每个月的 API 账单已经从“一杯咖啡”悄悄涨到了“一顿火锅”。涨价本身不是坏事,说明服务真的被…

作者头像 李华
网站建设 2026/9/10 4:45:52

AI视频制作全流程实战:工具选型、提示词与后期包装指南

我从今年上半年开始正经接触AI视频,起因是身边好几个做自媒体和电商的朋友都在问同一件事:那些朋友圈里刷屏的野生动物短片、产品宣传片、个人Vlog配片,到底是不是人拍出来的?是不是要学剪辑、买相机、请模特?实话说&a…

作者头像 李华
网站建设 2026/9/10 4:42:56

CANN/GE ES私有属性构图Python示例

Sample Usage Guide 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Tensor…

作者头像 李华