拆解 Deep Agents 架构:中间件、后端、Profile 三板斧,这设计比我想的还深

上一篇文章我们聊了 Deep Agents 是什么。这篇我想钻进去,看看它到底是怎么设计的。

读完源码我最大的感受:这帮人真的把 Agent 当系统来设计,而不是当 demo 来写。 整个架构的核心是三个概念——中间件栈(Middleware Stack)、后端系统(Backends)、Profile 系统。把它们搞明白了,你就知道 Deep Agents 为什么能做到"开箱即用但完全可定制"。

本文提纲

  1. 整体架构:一个 LangGraph 图的秘密
  2. 中间件栈:Deep Agent 的灵魂
  3. 后端系统:9 种后端怎么选
  4. Profile 系统:一套代码适配所有模型
  5. 上下文管理:为什么 Agent 不会"变笨"

整体架构:一个 LangGraph 图的秘密

create_deep_agent() 返回的不是什么魔法对象,而是一个编译好的 LangGraph StateGraph

def create_deep_agent(...) -> CompiledStateGraph:
    return create_agent(
        model,
        system_prompt=final_system_prompt,
        tools=_tools,
        middleware=deepagent_middleware,
        ...
    ).with_config({
        "recursion_limit": 9_999,
    })

几个关键设计决策:

1. recursion_limit: 9_999 — 几乎无限的递归深度。普通 Agent 跑几轮就停了,Deep Agent 能一直跑直到任务完成。这是"深度"的物理基础。

2. DeltaChannel 消息压缩 — 自定义的 _DeepAgentStateDeltaChannel 替代普通 list 来存储消息,把 checkpoint 的增长从 O(N²) 降到 O(N)。简单说,对话越长,省得越多。

3. Prompt 分层组装 — 系统提示词由四部分按顺序拼接:

USER (你传的 system_prompt)
  ↓
BASE (SDK 默认的 deep agent prompt)
  ↓
CUSTOM (HarnessProfile 的 base_system_prompt,替代 BASE)
  ↓
SUFFIX (HarnessProfile 的 system_prompt_suffix,追加到最后)

你的指令永远在最前面,SDK 的默认行为在后面兜底。

中间件栈:Deep Agent 的灵魂

中间件是 Deep Agent 最核心的设计。整个栈按固定顺序排列:

MERMAID_BLOCK_0

每个中间件都有明确的职责:

TodoListMiddleware

给 Agent 注入 write_todos 工具。这不是简单的 TODO list——Agent 会用它在每一步更新进度,就像一个项目经理在看板前挪卡片。

FilesystemMiddleware

最重的中间件(源码 96KB),提供所有文件操作工具。亮点是权限系统:

permissions=[
    FilesystemPermission(path="/data", allow_read=True, allow_write=False),
    FilesystemPermission(path="/tmp", allow_write=True),
]

规则按声明顺序匹配,第一个命中就生效。子代理默认继承父代理的权限,也可以完全覆盖。

SubAgentMiddleware / AsyncSubAgentMiddleware

task 工具的底层实现。支持三种子代理:

  • SubAgent:声明式同步子代理,有自己的 prompt 和 tools
  • CompiledSubAgent:预编译的可运行子代理
  • AsyncSubAgent:远程异步子代理(通过 graph_id 路由到 LangSmith 部署的 Agent)

每个子代理都有独立的中间件栈和上下文窗口,不会互相污染。

SummarizationMiddleware

63KB 的源码,做得相当精细。当对话历史超过阈值时,自动触发摘要压缩。支持多种摘要策略,能根据模型类型选择最优方案。

MemoryMiddleware

跨对话的持久记忆。加载 AGENTS.md 文件注入到系统提示词中,让 Agent 能"记住"项目约定、用户偏好等信息。

HumanInTheLoopMiddleware

工具调用前的人工审批:

interrupt_on={"edit_file": True}  # 每次编辑文件前暂停等你确认

子代理可以继承或覆盖这个配置。

后端系统:9 种后端怎么选

后端(Backend)决定了 Agent 怎么存文件、怎么执行命令。Deep Agents 提供了 9 种后端:

MERMAID_BLOCK_1

StateBackend(默认)

最简单的后端,文件存在内存中的 dict 里。通过 invoke(files={...}) 传入。适合测试和简单场景。

FilesystemBackend

直接读写本地文件系统。设置 root_dir 作为根目录。适合本地开发。

LocalShellBackend

在本地执行 shell 命令。危险但有用。 适合你完全信任 Agent 的场景。

SandboxBackend

通过沙箱执行命令,支持远程沙箱(Daytona、Modal、Runloop)。execute 工具依赖实现了 SandboxBackendProtocol 的后端。

CompositeBackend

组合多个后端。比如文件操作用 FilesystemBackend,命令执行用 SandboxBackend:

backend = CompositeBackend(
    file=FilesystemBackend(root_dir="/workspace"),
    sandbox=SandboxBackend(provider="daytona"),
)

实际选择建议:开发用 StateBackend,本地跑用 FilesystemBackend,生产用 SandboxBackend + 远程沙箱。

Profile 系统:一套代码适配所有模型

这是我觉得最精妙的设计。

不同 LLM 的能力差异很大——Claude 擅长长上下文,GPT 擅长工具调用,开源模型需要更多引导。如果每种模型都写一套代码,维护成本爆炸。

HarnessProfile 让你用声明式的方式为不同模型定制行为:

from deepagents import HarnessProfile, register_harness_profile

@register_harness_profile
class MyModelProfile(HarnessProfile):
    excluded_tools: list[str] = ["execute"]  # 不给这个模型 shell 权限
    base_system_prompt: str = "你是一个安全的助手..."
    system_prompt_suffix: str = "注意:你没有文件执行权限。"
    extra_middleware: list = [MyCustomMiddleware()]

框架会根据当前使用的模型自动匹配对应的 Profile。你不需要写 if/else,只需要注册 Profile。

内置的 Profile 包括对 Anthropic、OpenAI、Google 等主流模型的适配,处理了 prompt 缓存、工具描述格式等差异。

上下文管理:为什么 Agent 不会"变笨"

普通 Agent 跑几轮就开始"胡说八道"——因为上下文窗口塞满了,LLM 的注意力开始涣散。

Deep Agents 用了三层防御:

1. 自动摘要 — SummarizationMiddleware 监控对话长度,超过阈值自动压缩历史消息。不是简单截断,是用 LLM 生成摘要保留关键信息。

2. 文件卸载 — 大输出(比如 ls 返回几千行)自动保存到文件,只在上下文里留一个引用。_messages_reducer 负责这个逻辑。

3. DeltaChannel — 自定义的消息存储方式,checkpoint 只存增量,不存全量。100 轮对话的 checkpoint 大小和 10 轮差不多。

这三层加起来,让 Deep Agent 能跑几百轮都不会"变笨"。


说实话,读完这套架构,我对 LangChain 团队的工程能力刮目相看。这不是一个"能跑的 demo",而是一个经过深思熟虑的生产级系统。每个设计决策都有明确的理由,每个中间件都有清晰的边界。

如果你想在自己的产品里用 Agent,别从零开始写了。站在 Deep Agents 的肩膀上,你只需要关注业务逻辑。


作者: itech001
来源: 公众号:AI人工智能时代
主页: https://www.theaiera.cn,每日分享最前沿的AI新闻和技术。

本文首发于 AI人工智能时代,转载请注明出处。

posted @ 2026-05-13 22:22  iTech  阅读(12)  评论(0)    收藏  举报