Deep Agents 技术剖析:LangChain 的开源 Agent Harness

TL;DR

Deep Agents 是 LangChain 在 2026 年 3 月开源的 agent harness,构建在 LangGraph 之上。核心公式:一个 LLM 循环调用工具,加上 planning、filesystem、subagent、context compaction 四个内置能力。它不是新的 agent 范式,而是把 Claude Code 的架构模式抽象成了一个模型无关的、可组合的 SDK。

  • 仓库:langchain-ai/deepagents,19.6K stars,MIT 协议
  • 当前版本:0.5.0a4(快速迭代中,alpha 间有 breaking changes)
  • 默认模型:claude-sonnet-4-6,支持任意 tool-calling LLM

一、它在技术栈里的位置

┌─────────────────────────────────────────┐
│  Deep Agents (Harness)                  │
│  planning · filesystem · subagents      │
│  context compaction · skills · memory   │
├─────────────────────────────────────────┤
│  LangChain (Framework)                  │
│  models · messages · tools · agents     │
├─────────────────────────────────────────┤
│  LangGraph (Runtime)                    │
│  state · checkpointing · streaming      │
│  durable execution · human-in-the-loop  │
└─────────────────────────────────────────┘

LangChain 自己的定义:

  • Framework:提供抽象(模型、工具、链)
  • Runtime:提供基础设施(持久化、恢复、流式、审批门控)
  • Harness:提供开箱即用的 agent 能力(planning、文件系统、subagent、上下文管理)

create_deep_agent() 内部调用 LangGraph 的 create_agent(),返回标准 CompiledStateGraph,兼容 LangGraph 全部特性(streaming、Studio、checkpointer)。


二、灵感来源:Claude Code

官方博客明确说了:

"This exploration was primarily inspired by Claude Code and reports of people using it for more than just coding."

团队分析 Claude Code 的架构后提炼出四个核心特征:

  1. 详尽的系统 prompt — Claude Code 的 prompt 很长,包含工具使用指令和 few-shot 示例
  2. Planning 工具 — 一个 todo list,本质上是个 no-op,不执行计算,纯粹是上下文工程策略
  3. Subagent — 隔离上下文,防止长任务中的上下文污染
  4. 文件系统 — 持久化状态、跨会话协作的表面

Deep Agents 把这四个模式做成了模型无关的开源实现。BASE_AGENT_PROMPT 读起来和 Claude Code 的行为指南极为相似——直接、不废话、professional objectivity。


三、API 入口:create_deep_agent()

python
def create_deep_agent(
    model: str | BaseChatModel | None = None,          # 默认 claude-sonnet-4-6
    tools: Sequence[BaseTool | Callable | dict] | None = None,
    *,
    system_prompt: str | SystemMessage | None = None,
    middleware: Sequence[AgentMiddleware] = (),          # 用户自定义中间件
    subagents: Sequence[SubAgent | CompiledSubAgent | AsyncSubAgent] | None = None,
    skills: list[str] | None = None,                    # SKILL.md 目录路径
    memory: list[str] | None = None,                    # AGENTS.md 路径
    response_format: ResponseFormat | type | dict | None = None,
    context_schema: type | None = None,
    checkpointer: Checkpointer | None = None,
    store: BaseStore | None = None,
    backend: BackendProtocol | BackendFactory | None = None,
    interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
    debug: bool = False,
    name: str | None = None,
    cache: BaseCache | None = None,
) -> CompiledStateGraph:

model 支持 "provider:model" 格式字符串("openai:gpt-5"、"openrouter:meta-llama/..."),通过 init_chat_model() 解析。返回值是标准 LangGraph CompiledStateGraph,recursion_limit=9999。


四、中间件管道(核心架构)

Deep Agents 的所有能力都以中间件形式存在,按固定顺序组装:

1.  TodoListMiddleware          ← planning (write_todos 工具)
2.  SkillsMiddleware            ← 渐进式技能加载 (如果提供了 skills)
3.  FilesystemMiddleware        ← 文件工具 (ls/read/write/edit/glob/grep)
4.  SubAgentMiddleware          ← task 工具 (同步 subagent)
5.  SummarizationMiddleware     ← 自动上下文压缩
6.  PatchToolCallsMiddleware    ← 修复悬挂的 tool calls
7.  AsyncSubAgentMiddleware     ← 远程/后台 subagent (如果提供了)
8.  >>> 用户自定义中间件插入点 <<<
9.  AnthropicPromptCachingMiddleware  ← prompt 缓存优化 (非 Anthropic 模型静默跳过)
10. MemoryMiddleware            ← AGENTS.md 注入到 system prompt
11. HumanInTheLoopMiddleware    ← 审批门控 (如果配置了 interrupt_on)

Memory 和 caching 故意放在最后——memory 更新不会使 Anthropic prompt cache 前缀失效。

Subagent 的中间件栈:继承父 agent 的栈,但去掉 MemoryMiddleware、SubAgentMiddleware、AsyncSubAgentMiddleware。Subagent 不能再生 sub-subagent(禁止嵌套)。


五、四大核心能力详解

5.1 Planning:write_todos

由 TodoListMiddleware 注入。数据结构:

python
{
    "content": "Query Prometheus for CPU metrics across all nodes",
    "status": "in_progress"  # pending | in_progress | completed
}

工作流:

  1. 中间件注入 write_todos 工具
  2. Agent 在任务开始时调用,写下初始计划
  3. 每次 LLM 调用前,中间件把当前 todo list 注入 system prompt
  4. Agent 边执行边更新状态

关键洞察:这个工具不执行任何计算。LangChain 自己说它是 "basically a no-op"。它的价值纯粹是上下文工程——强制模型在行动前明确计划,并在整个执行过程中保持计划可见。对需要 5-15 次工具调用的任务特别有效。

5.2 文件系统

由 FilesystemMiddleware 注入,提供 6 个工具:

工具参数说明
lspath目录列表
read_filefile_path, offset, limit带行号输出(cat -n 格式),超长行自动分割(5.1, 5.2...),图片返回多模态内容块
write_filefile_path, content写入文件
edit_filefile_path, old_string, new_string, replace_all精确替换
globpattern, path文件模式匹配
greppattern, path, glob, output_mode文本搜索(字面子串匹配,非正则)

当后端实现了 SandboxBackendProtocol 时,额外提供 execute 工具(shell 执行)。

5.3 Subagent

由 SubAgentMiddleware 注入 task 工具:

python
class TaskToolSchema(BaseModel):
    description: str    # 任务描述
    subagent_type: str  # subagent 类型名

并行执行机制:工具描述里明确指导 LLM "Launch multiple agents concurrently...use a single message with multiple tool uses"。LangGraph 的 tool node 天然并行处理同一 AI message 中的多个 tool call → N 个 task 调用 = N 个并发 subagent。

上下文隔离:Subagent 只收到任务描述作为 message history,显式过滤掉父 agent 的 messages、todos、structured_response、skills_metadata、memory_contents。只返回最终消息。

三种 Subagent 形态:

python
# 1. 声明式同步 — 最常用
SubAgent = TypedDict("SubAgent", {
    "name": str,                   # 必需
    "description": str,            # 必需
    "system_prompt": str,          # 必需
    "tools": Sequence[...],        # 可选,默认继承父 agent
    "model": str | BaseChatModel,  # 可选,默认继承父 agent
    "middleware": list[...],       # 可选,额外中间件
    "skills": list[str],           # 可选,不继承父 agent(需显式指定)
})

# 2. 预编译 — 自定义 runnable
CompiledSubAgent = TypedDict("CompiledSubAgent", {
    "name": str,
    "description": str,
    "runnable": Runnable,  # state schema 须包含 'messages' key
})

# 3. 异步远程 — 后台执行
AsyncSubAgent = TypedDict("AsyncSubAgent", {
    "name": str,
    "description": str,
    "graph_id": str,      # 远程 LangGraph 服务器上的 graph ID
    "url": str,           # Agent Protocol 服务器 URL
    "headers": dict,      # 认证头
})

异步 subagent 暴露 5 个工具:start_async_task、check_async_task、update_async_task、cancel_async_task、列表工具。

自动 general-purpose subagent:如果没有显式提供名为 "general-purpose" 的 subagent,框架自动创建一个,继承父 agent 的 model、tools、和基础中间件栈。

5.4 上下文压缩

由 SummarizationMiddleware 实现,分两层:

第一层:工具参数截断(早期触发)

python
class TruncateArgsSettings(TypedDict, total=False):
    trigger: ContextSize | None    # 何时激活
    keep: ContextSize              # 保留最近多少消息不动
    max_length: int                # 每个参数值的字符上限(默认 2000)
    truncation_text: str           # 截断后缀(默认 "...(argument truncated)")

旧消息中的 write_file 内容、edit_file 补丁、execute 输出被截断。文件内容已经持久化到后端,截断不丢数据。

第二层:完整对话压缩(后期触发)

python
SummarizationMiddleware(
    model=model,
    backend=backend,
    trigger=("fraction", 0.85),  # 达到模型 max_input_tokens 的 85% 时触发
    keep=("fraction", 0.10),     # 保留最后 10% 的消息
)

ContextSize 类型:tuple[Literal["messages", "tokens", "fraction"], int | float]

工作流:

  1. 每次 LLM 调用前检查 token 用量是否超过 trigger
  2. 将消息分为"需摘要"和"保留"两部分
  3. 通过 LLM 调用生成摘要
  4. 完整对话历史写入后端 /conversation_history/{thread_id}.md
  5. 旧消息替换为包含摘要的 HumanMessage(带 lc_source='summarization' 标记)

阈值根据模型自动计算:有 max_input_tokens profile 的模型用比例(85%/10%),没有的用固定值(170K tokens 触发,保留 6 条消息)。

还提供手动压缩工具 compact_conversation(由 SummarizationToolMiddleware 注入),agent 可在用户切换话题时主动调用。


六、后端系统

所有后端实现 BackendProtocol(ABC),定义 ls()、read()、write()、edit()、grep()、glob()、upload_files()、download_files() 及其异步变体。

后端存储位置持久性Shell 执行适用场景
StateBackendLangGraph agent state单线程(临时)否默认。临时文件、单次对话
StoreBackendLangGraph BaseStore跨线程(持久)否跨会话记忆
FilesystemBackend本地磁盘永久否本地开发
LocalShellBackend本地磁盘 + subprocess永久 + shell是完整本地执行(需显式 opt-in)
CompositeBackend按路径前缀路由混合取决于子后端/memories/ → store,/ → state
LangSmithSandbox远程沙箱会话级是云端隔离执行

CompositeBackend 示例:

python
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend

backend = CompositeBackend(routes={
    "/memories/": StoreBackend(config),   # 持久化记忆
    "/": StateBackend(config),            # 临时工作文件
})

沙箱后端(BaseSandbox 子类)只需实现 execute() 和 upload_files(),其余文件操作自动通过 shell 命令派生。使用 base64 编码的 Python 脚本避免转义问题。编辑操作对 50KB 以下内容用 inline payload,更大的用临时文件上传。

文件数据格式(v2):

python
class FileData(TypedDict):
    content: str          # UTF-8 文本或 base64 编码二进制
    encoding: str         # "utf-8" 或 "base64"
    created_at: str       # ISO 8601(可选)
    modified_at: str      # ISO 8601(可选)

七、Skills:渐进式披露

skills/
  alert-investigation/
    SKILL.md          # YAML frontmatter + markdown 指令
    helper.py         # 可选辅助文件
  blog-post/
    SKILL.md

SKILL.md 格式:

markdown
---
name: alert-investigation
description: >
  Investigates production alerts by correlating metrics, logs,
  and infrastructure state.
---

# Alert Investigation Workflow
## Phase 1: Triage
...

三步执行:

  1. 启动时:SkillsMiddleware 只解析 YAML frontmatter(name + description)
  2. 每次 LLM 调用:skill 列表作为 ~200 tokens 注入 system prompt
  3. 按需加载:agent 调用 read_file("./skills/alert-investigation/SKILL.md") 获取完整指令

Token 效率:10 个 skill × 2-3K tokens = 20-30K tokens(全部预加载)。渐进式披露:启动 ~200 tokens,使用时才加载单个 skill。


八、Memory:AGENTS.md

由 MemoryMiddleware 实现。加载指定路径的 AGENTS.md 文件,每次 LLM 调用都注入 system prompt(区别于 skills 的按需加载)。

python
agent = create_deep_agent(
    memory=["~/.deepagents/AGENTS.md", "./.deepagents/AGENTS.md"],
    backend=FilesystemBackend(root_dir="/"),
)

Agent 可以通过 edit_file 自主更新 memory 文件——实现跨会话学习。遵循 agents.md 规范。

Memory 仅限主 agent;subagent 通过 task 工具描述接收上下文。


九、完整示例:Cloud Ops Agent

python
from deepagents import create_deep_agent, SubAgent
from deepagents.backends import FilesystemBackend
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.checkpoint.memory import MemorySaver

metric_tools = await load_mcp_tools(connection=grafana_connection)
infra_tools = await load_mcp_tools(connection=infra_connection)

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-5-20250929",
    tools=[*metric_tools, *infra_tools],
    system_prompt="""\
You are a Cloud Operations Agent. Investigate production incidents.

## Decision Flow
1. Match request to a skill -> read SKILL.md -> execute
2. Pasted alert data -> use alert-investigation skill
3. No match -> plan with write_todos -> execute

## Rules
- Complete every investigation in <=12 tool calls
- Batch parallel tool calls where possible
""",
    memory=["./AGENTS.md"],
    skills=["./skills/"],
    subagents=[{
        "name": "metrics-collector",
        "description": "Query Prometheus/Grafana metrics in isolation",
        "system_prompt": "You are a metrics specialist.",
        "model": "anthropic:claude-haiku-4-5-20251001",  # 便宜模型做子任务
    }],
    backend=FilesystemBackend(root_dir="./workspace"),
    checkpointer=MemorySaver(),
    interrupt_on={"execute": True},  # shell 执行需要人工审批
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "CPU >95% on web-us-east-1-app3"}]},
    config={"configurable": {"thread_id": "incident-42"}},
)

MCP 工具自动传播到所有 subagent。如需限制 subagent 工具访问,在 subagent spec 中显式指定 tools。


十、CLI

包名:deepagents-cli,基于 Textual TUI。

bash
# 安装
curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/scripts/install.sh | bash

# 带额外模型提供商
DEEPAGENTS_EXTRAS="nvidia,ollama" curl -LsSf ... | bash

# 或直接
uv tool install 'deepagents-cli[nvidia,ollama]'

CLI 在 SDK 基础上增加:交互式 TUI、跨会话恢复、Web 搜索、远程沙箱(LangSmith / AgentCore / Daytona / Modal / Runloop)、headless 模式(-n,用于 CI/脚本)。


十一、ACP 集成(编辑器支持)

ACP(Agent Client Protocol)是 agent 与代码编辑器通信的开放标准(JSON-RPC 2.0 over stdio),类似 LSP 之于语言服务器。

Python:

python
from deepagents_acp.server import AgentServerACP

agent = create_deep_agent(tools=[...], checkpointer=MemorySaver())
server = AgentServerACP(agent, models=[
    {"value": "anthropic:claude-opus-4-6", "name": "Claude Opus 4"},
    {"value": "openai:gpt-4-turbo", "name": "GPT-4 Turbo"},
])
await run_agent(server)

JS(Zed 编辑器配置):

json
{
  "agent": {
    "profiles": {
      "deepagents": {
        "name": "DeepAgents",
        "command": "npx",
        "args": ["deepagents-acp"]
      }
    }
  }
}

十二、NVIDIA OpenShell 集成

仓库:langchain-ai/openshell-deepagent(110 stars)

在 NVIDIA OpenShell 沙箱中运行 Deep Agent,使用 NVIDIA Nemotron 模型:

LangGraph Dev Server (127.0.0.1:2024)
    │
    ▼
Deep Agent (Nemotron Super 3)
    │
    ├── OpenShellBackend (gRPC → 沙箱执行)
    └── FilesystemBackend (持久化 memory/skills)
    │
    ▼
OpenShell Gateway (k3s in Docker)
    │
    ▼
Sandbox Container (策略强制执行)

策略热重载:

bash
uv run openshell policy get deepagent-sandbox --full > policy.yaml
# 编辑 policy.yaml(文件系统路径、网络访问、进程权限)
uv run openshell policy set deepagent-sandbox --policy policy.yaml --wait

十三、安全模型

项目附带正式的 THREAT_MODEL.md:

  • "Trust the LLM" 模型:安全边界在工具/沙箱层强制执行,不依赖模型自我约束
  • LocalShellBackend 不是默认后端,需显式 opt-in,带安全警告
  • FilesystemBackend 的 virtual_mode 在 v0.5.0 默认改为 True,阻止路径遍历
  • Shell 输出截断在 100KB,不被框架持久化
  • 使用 openai: 模型时有 Responses API 数据保留警告

十四、Benchmark

Terminal Bench 2.0:

  • Deep Agents + Claude Sonnet 4.5:42.65%(两轮分别 44.9% / 40.4%)
  • Deep Agents + GPT-5.2-Codex:66.5%(排名 #20)
  • 榜首(GPT-5.4 / Claude Opus 4.6):81.8%

定位是通用 harness,不是专用 coding agent。与 Claude Code 在同等模型层级上"on par"。


十五、版本迭代

版本日期关键变更
首次发布2026-03-11—
0.4.11~03-13Token 统计、/reload、ACP 服务器模式
0.5.0a103-23LangSmith 集成元数据、eval 框架(28 模型 / 7 提供商)
0.5.0a203-23LangSmithSandbox 从 CLI 移入 SDK、async subagent 重命名
0.5.0a304-01泛型支持、async subagent bug 修复、沙箱文件传输
0.5.0a404-03移除 legacy subagents API、继承父 interrupt_on、CRLF 标准化

78 个 release。Alpha 版本间有 breaking changes,务必 pin 版本号。


十六、什么时候该用 Deep Agents

场景推荐
简单 chatbot + 几个工具直接用 create_react_agent(LangGraph)
需要 planning 的多步任务Deep Agents
域特定工作流(SKILL.md)Deep Agents
长任务(10+ tool calls)Deep Agents(auto-summarization)
并行跨数据源工作Deep Agents(subagent + context 隔离)
需要文件产物Deep Agents(filesystem 内置)
需要完全控制图拓扑直接用 LangGraph

社区经验:"Start at the highest abstraction that feels honest, not the most powerful. Move downward only when runtime control becomes the bottleneck."


十七、vs 其他 Harness

维度Deep AgentsClaude CodeCodex SDK
模型任意 tool-calling LLMClaude onlyOpenAI only
沙箱工具级(无 OS 级隔离)进程级OS 级沙箱
可观测性LangSmith 原生内置 trace有限
长期记忆AGENTS.md + StoreBackendCLAUDE.md + memory 系统有限
编辑器集成ACP(Zed 等)VS Code / JetBrains 扩展VS Code
扩展性中间件 + 自定义后端Hooks + SkillsMCP
开源MIT部分开源部分开源
Terminal Bench42.65% (Sonnet 4.5)~同级模型表现相当—

Deep Agents 的核心优势:模型无关 + LangSmith 可观测性 + 中间件可组合性。 核心劣势:没有 OS 级沙箱,对不可信输入是生产风险。


十八、踩坑提醒

  1. grep 是字面匹配,不是正则 — 如果你习惯了 Claude Code 的 ripgrep,注意这里的行为不同
  2. Subagent 不能嵌套 — 没有 sub-sub-agent,需要在架构层面考虑好任务分解的层级
  3. Alpha 版本 breaking changes 频繁 — 0.5.0a1 到 a4 之间就有 legacy API 移除、返回类型变更、后端方法重命名
  4. 过度使用的陷阱 — 不是所有问题都需要 Deep Agents,简单任务用 LangGraph 的 create_react_agent 就够了
  5. Skills 继承规则 — general-purpose subagent 继承父 agent 的 skills,自定义 subagent 不继承,需显式指定
  6. 工具名冲突 — JS 版本如果自定义工具用了内置名称会抛 ConfigurationError(code: TOOL_NAME_COLLISION)
  7. OpenAI 模型自动启用 Responses API — 注意数据保留策略

参考来源

Comments (0)

No comments yet

imfht
April 6, 2026