Deep Agents 学习笔记(一):从 Agent Harness 到第一个 Deep Agent

最近开始系统学习 Datawhale 的《Deep Agents in Action》。前两章主要解决两个问题:

  1. Deep Agents 到底是什么?它和 LangChain、LangGraph 有什么区别?

  2. 一个最简单的 Deep Agent 是怎么构建和运行起来的?

如果只是看 API,很容易把 Deep Agents 理解成"又一个 Agent 框架"。但学习完前两章后,我目前更倾向于把它理解为:

Deep Agents 的重点不是重新定义 Agent,而是在已有 Agent Framework 和 Runtime 之上,为复杂 Agent 提供一套开箱即用的 Harness。


1. 为什么已经有 LangChain 和 LangGraph,还需要 Deep Agents?

假设现在要开发一个类似 AI Coding Agent 的系统。

它不只是需要调用一次大模型,而需要:

  • 阅读代码文件;

  • 搜索整个项目;

  • 分析问题;

  • 制定修改步骤;

  • 执行多个工具;

  • 保存中间结果;

  • 必要时拆分子任务;

  • 长任务过程中控制上下文;

  • 多轮运行时保存部分状态。

理论上,这些都可以自己基于 LangChain 或 LangGraph 实现。

问题在于:

几乎每开发一个复杂 Agent,都要重复实现这些基础能力。

因此 Deep Agents 的思路不是提供一个更底层的 Agent API,而是把复杂 Agent 中反复出现的工程模式提前封装起来。


2. Agent 技术栈的三个层次

理解 Deep Agents,首先需要区分三个概念:

复制代码
┌──────────────────────────────┐
│ Agent Harness                │
│ Deep Agents                  │
│ 文件系统 / 子Agent / 上下文管理 │
├──────────────────────────────┤
│ Agent Framework              │
│ LangChain                    │
│ Model / Tool / Agent Loop    │
├──────────────────────────────┤
│ Agent Runtime                │
│ LangGraph                    │
│ 状态 / 持久化 / 执行 / 恢复    │
└──────────────────────────────┘

它们不是竞争关系,而是一个自底向上的技术栈。


2.1 Runtime:Agent 怎么可靠地运行?

代表:LangGraph

Runtime 关注的是执行问题,例如:

  • Agent 执行到一半失败怎么办?

  • 状态怎么保存?

  • 如何暂停后等待用户确认?

  • 如何恢复任务?

  • 多轮执行中的状态如何管理?

所以 LangGraph 更接近 Agent 的执行引擎。

可以粗略理解为:

复制代码
LangGraph ≈ Agent 的 Runtime / Workflow Engine

它解决的是:

Agent 怎么跑。

而不是具体告诉 Agent 应该具备什么业务能力。


3. Framework:Agent 怎么构建?

代表:LangChain

LangChain 在 Runtime 之上进一步提供:

  • Model 抽象;

  • Tool 接口;

  • Agent Loop;

  • Middleware;

  • Prompt;

  • Tool Calling 等。

例如:

复制代码
agent = create_agent(
    model=model,
    tools=[search, calculator],
    system_prompt="You are a helpful assistant."
)

开发者不用再手动实现完整的:

复制代码
调用模型
    ↓
模型判断是否调用工具
    ↓
调用工具
    ↓
把工具结果返回模型
    ↓
模型继续判断
    ↓
最终回答

LangChain 已经帮我们抽象了这个 Agent Loop。

因此我目前的理解是:

复制代码
LangGraph:负责执行 Agent
LangChain:负责构建 Agent

4. Harness:Agent 如何真正完成复杂任务?

这就是 Deep Agents 所处的位置。

Deep Agents = Agent Harness

它建立在 LangChain 和 LangGraph 之上,进一步提供复杂 Agent 常见的基础设施,例如:

能力 作用
文件系统 读取、写入、搜索和编辑文件
Context Management 控制长任务中的上下文规模
SubAgent 将子任务委派给其他 Agent
Skills 按需加载专业能力
Memory 保存长期信息
Todo / Planning 维护复杂任务计划
Human-in-the-loop 高风险操作前请求人工确认

其中需要特别注意:**Deep Agents v0.7 并不是默认开启所有能力。**例如任务规划需要显式加入 TodoListMiddleware,Skills、Memory 和人工审批等能力同样需要按需求配置。

所以三层可以总结成:

层次 代表 核心问题
Runtime LangGraph Agent 怎么可靠运行?
Framework LangChain Agent 怎么构建?
Harness Deep Agents 怎样让 Agent 更容易完成复杂长期任务?

5. 为什么叫 Harness?

Harness 原意有"装备、套件、控制系统"的意思。

我觉得可以把 Agent 开发想象成开发一个机器人。

LangGraph 给机器人提供:

复制代码
状态机
执行环境
恢复机制

LangChain 给机器人提供:

复制代码
大脑接口
工具调用接口
Agent Loop

而 Deep Agents 则进一步给机器人装备:

复制代码
文件系统
任务列表
长期记忆
专业技能
子 Agent
上下文管理
权限机制

所以 Deep Agents 并不是"另一个更大的 Agent"。

更加准确的说法应该是:

它给 Agent 装上一套完成复杂任务所需要的工程装备。

这也是我认为理解 Harness 最重要的一点。


6. Deep Agents 的核心思想:Context Engineering

这一部分是第一章中我认为最值得关注的内容。

传统 LLM 应用经常采用:

复制代码
Prompt
+
用户问题
+
所有相关资料
+
所有历史记录
+
所有文件

全部塞入 Context。

这种方式面对复杂任务会产生几个问题:

复制代码
Context 越来越大
        ↓
Token 消耗增加
        ↓
关键信息被稀释
        ↓
模型越来越难定位真正需要的信息

Deep Agents 更强调:

不要把所有信息一直放在上下文里,而是让 Agent 在需要的时候主动获取信息。

例如:

复制代码
Agent
 │
 ├── read_file()
 ├── write_file()
 ├── grep()
 ├── glob()
 └── edit_file()

需要一个文件时才读取。

需要保存大量中间信息时,就:

复制代码
write_file(...)

需要搜索项目时:

复制代码
grep(...)

大文件则只读取局部内容。

因此:

复制代码
传统方式:

所有信息
   ↓
Prompt
   ↓
LLM


Deep Agents:

             ┌── File System
             │
LLM ←──── Context ──── Search
             │
             ├── Memory
             ├── Skills
             └── SubAgent

这实际上把:

Prompt Engineering

进一步扩展成了:

Context Engineering

核心问题从:

Prompt 怎么写?

变成:

模型在当前时刻到底应该看到什么信息?

Deep Agents 通过虚拟文件系统以及可插拔 Backend,使 Agent 可以按需读取和保存信息,而不是持续把所有信息堆进 Prompt。


7. Tool、Middleware 和 Backend 必须区分

这是理解 Deep Agents 架构时非常重要的一组概念。

可以先简单记:

复制代码
Tool        = Agent 能做什么
Middleware  = Agent 的行为如何被增强/控制
Backend     = 操作真正在哪里执行和存储

例如模型决定:

复制代码
read_file("main.py")

表面上这是一个 Tool Calling。

背后其实是:

复制代码
LLM
 ↓
read_file Tool
 ↓
FilesystemMiddleware
 ↓
Backend
 ↓
真正读取文件

因此 Backend 自身并不是 Agent,也不负责思考。

它负责:

复制代码
文件存在哪里
文件怎么读取
数据如何持久化
是否使用本地磁盘
是否使用数据库
是否使用远程 Sandbox

Middleware 则处于 Agent Loop 中,可以在模型调用和工具执行等阶段加入额外逻辑。


8. 第一个 Deep Agent

理解完架构后,第二章开始真正运行 Deep Agent。

安装:

复制代码
pip install deepagents langchain-openai

当前教程要求 Python 3.11+。

最核心的 API 是:

复制代码
from deepagents import create_deep_agent

一个最简单的 Agent 可以写成:

复制代码
from langchain_openai import ChatOpenAI
from deepagents import create_deep_agent

model = ChatOpenAI(
    model="your-model",
    api_key="your-api-key",
    base_url="your-base-url"
)

def get_weather(city: str) -> str:
    """Get the weather information of a city."""
    return f"The weather in {city} is sunny."

agent = create_deep_agent(
    model=model,
    tools=[get_weather],
    system_prompt="You are a helpful assistant."
)

然后:

复制代码
result = agent.invoke({
    "messages": [
        {
            "role": "user",
            "content": "北京天气怎么样?"
        }
    ]
})

最终结果可以从:

复制代码
result["messages"][-1].content

获取。


9. create_deep_agent() 到底做了什么?

表面上我们只写了:

复制代码
agent = create_deep_agent(...)

但其内部实际上完成了更复杂的装配。

大致可以理解成:

复制代码
业务配置
  │
  ├── Model
  ├── Tools
  ├── System Prompt
  ├── Middleware
  └── Backend
       │
       ↓
create_deep_agent()
       │
       ↓
装配 Deep Agent Harness
       │
       ↓
LangChain create_agent()
       │
       ↓
Agent Loop
       │
       ↓
LangGraph Runtime

也就是说:

复制代码
create_deep_agent()
并没有替代 LangChain

而是:

复制代码
在 LangChain Agent 周围装配了一系列 Harness 能力

最终仍然由 LangGraph 执行。

这一点非常关键。


10. Tool 本质上是什么?

Deep Agents 中一个普通 Python Function 就可以作为 Tool。

例如:

复制代码
def search_paper(
    query: str,
    max_results: int = 10
) -> list:
    """Search papers according to a research query."""
    ...

对于 Agent 来说,最重要的是三个东西:

复制代码
1. 参数名称和类型
2. Docstring
3. 默认参数

因为 LLM 会根据这些信息判断:

复制代码
这个工具是干什么的?
什么时候使用?
应该传什么参数?
哪些参数可以省略?

因此:

Tool 的 docstring 实际上就是写给 Agent 阅读的 API 文档。

工具描述写得含糊,Agent 的 Tool Calling 质量自然也会下降。


11. agent.invoke() 并不是"调用一次模型"

这一点很容易产生误解。

代码:

复制代码
agent.invoke(...)

看起来只有一次调用。

实际上内部可能发生:

复制代码
User
 ↓
LLM
 ↓
决定调用 Search
 ↓
Search Tool
 ↓
结果返回 LLM
 ↓
LLM
 ↓
决定读取文件
 ↓
read_file
 ↓
LLM
 ↓
决定调用 SubAgent
 ↓
task()
 ↓
SubAgent
 ↓
返回结果
 ↓
LLM
 ↓
Final Answer

所以更准确的结构是:

复制代码
while True:

    response = model(context)

    if response.need_tool:
        result = tool(response.tool_call)
        context.add(result)

    else:
        return response

当然,实际实现比这复杂很多,因为 Middleware 还会介入模型调用、工具执行、上下文处理和审批等环节。


12. 一个 Research Agent 可能怎么工作?

如果给 Agent 一个任务:

复制代码
调研 LangGraph,并生成一份研究报告

假如我们显式开启了 Todo Planning,它可能自己完成:

复制代码
用户任务
   ↓
1. write_todos()
   ↓
2. internet_search()
   ↓
3. internet_search()
   ↓
4. write_file()
   ↓
5. task(SubAgent)
   ↓
6. read_file()
   ↓
7. 综合信息
   ↓
8. 输出报告

这里最有意思的是:

开发者可能只写了一句:

复制代码
agent.invoke(...)

但是 Agent 内部可能进行了十几次模型和工具交互。

Harness 的价值,就是隐藏大量重复的 Agent Engineering 基础设施,同时保留配置能力。


13. Planning 并不是固定工作流

这里还有一个很重要的认识。

例如:

复制代码
Planning
→ Search
→ File
→ SubAgent
→ Final Answer

只是 Agent 可能选择的一条路径。

它不是传统 Workflow:

复制代码
step1()
step2()
step3()
step4()

真正执行的时候,模型可能认为任务很简单,于是直接:

复制代码
User
 ↓
Search
 ↓
Answer

也可能:

复制代码
User
 ↓
Planning
 ↓
Search
 ↓
Search
 ↓
File
 ↓
SubAgent
 ↓
Search
 ↓
Answer

所以 Agent 系统的一个重要特点就是:

开发者定义能力空间,模型在运行时决定具体路径。

这和传统 Workflow Programming 有明显区别。


14. 为什么 Agent 开发必须做 Observability?

普通程序报错通常可以看:

复制代码
Exception
Stack Trace
Log

但 Agent 出现的问题可能是:

复制代码
模型为什么没有调用 Search?

为什么调用了错误的 Tool?

为什么参数传错?

为什么 SubAgent 没有被调用?

为什么消耗了大量 Token?

为什么 Agent 循环十几次还没结束?

这些问题只看最终输出很难分析。

因此复杂 Agent 开发需要 Trace。

教程中使用 LangSmith,可以查看:

  • 每次模型调用;

  • Tool Calling;

  • Tool 参数;

  • Tool 返回值;

  • SubAgent 执行;

  • Token 消耗;

  • 执行耗时;

  • 文件变化等。

所以我目前认为:

复制代码
LLM Application
      +
Tool Calling
      +
Agent Loop
      +
Trace

才构成比较完整的 Agent 开发闭环。


15. 我目前对 Deep Agents 的整体理解

学习前我容易把:

复制代码
Deep Agents

理解成:

一个用于构建 Agent 的新框架。

现在感觉这种理解并不准确。

更合理的是:

复制代码
                     Application
                         │
                         ↓
                 ┌───────────────┐
                 │ Deep Agents   │
                 │ Agent Harness │
                 └───────┬───────┘
                         │
                 ┌───────▼───────┐
                 │   LangChain   │
                 │ Agent Framework│
                 └───────┬───────┘
                         │
                 ┌───────▼───────┐
                 │   LangGraph   │
                 │ Agent Runtime │
                 └───────────────┘

Deep Agents 真正有价值的地方,是把复杂 Agent 中已经反复被验证有效的工程模式进行了封装。

例如:

复制代码
Filesystem
Planning
SubAgent
Memory
Skills
Context Management
Human-in-the-loop
Sandbox

开发者不再需要每做一个 Agent 都从零重新实现。


16. Deep Agents 和 Codex / Claude Code 应该怎么理解?

从 Harness 这个角度,再去理解 Codex、Claude Code 这类产品会清楚很多。

它们并不是:

复制代码
LLM + 一个 Shell 工具

而更接近:

复制代码
LLM
+
Agent Loop
+
Filesystem
+
Search
+
Shell
+
Planning
+
Context Management
+
Permission
+
Sandbox
+
Observability

也就是说:

真正复杂的 Agent 产品,核心竞争力很大一部分其实存在于模型之外的 Harness。

模型决定:

复制代码
Agent 能有多聪明

Harness 决定:

复制代码
这个聪明的模型能不能稳定地完成复杂任务

这是我学习这两章之后最大的认知变化。


17. 两章学习后的知识地图

最后把目前内容压缩成一张知识图:

复制代码
Deep Agents
│
├── 1. Runtime
│      └── LangGraph
│          ├── State
│          ├── Persistence
│          ├── Durable Execution
│          └── Human-in-the-loop
│
├── 2. Framework
│      └── LangChain
│          ├── Model
│          ├── Tool
│          ├── Agent Loop
│          └── Middleware
│
└── 3. Harness
       └── Deep Agents
           ├── Filesystem
           ├── Context Engineering
           ├── SubAgent
           ├── Planning
           ├── Skills
           ├── Memory
           ├── Backend
           └── Human-in-the-loop

而一次实际运行可以概括成:

复制代码
User
 ↓
Deep Agent
 ↓
Model
 ↓
判断下一步
 ├───────────────┐
 ↓               ↓
Tool           Final Answer
 ↓
Middleware
 ↓
Backend / External API
 ↓
Result
 ↓
重新进入 Model

18. 小结

前两章真正需要掌握的,我认为不是 create_deep_agent() 这个 API,而是下面几个概念:

第一,区分 Runtime、Framework 和 Harness。

复制代码
LangGraph → Runtime
LangChain → Framework
Deep Agents → Harness

第二,理解 Deep Agents 为什么强调 Context Engineering。

复杂 Agent 的核心问题已经不仅是 Prompt 怎么写,而是:

复制代码
什么信息
在什么时间
以什么形式
进入模型 Context

第三,理解 Agent 是一个循环,而不是一次 LLM 调用。

复制代码
Model
 ↕
Tools

会持续交互,直到模型认为任务完成。

第四,理解 Tool、Middleware、Backend 三者职责。

复制代码
Tool       → 能做什么
Middleware → 怎么控制和增强
Backend    → 在哪里真正执行和保存

第五,Harness 才是复杂 Agent 产品非常关键的工程层。

模型能力当然重要,但一个真正能够长期、稳定执行任务的 Agent,还需要文件系统、上下文管理、权限、规划、子任务委派、Sandbox 和可观测性等大量模型之外的工程能力。

这也是继续学习 Deep Agents 时,我认为最值得保持的一条主线:

不要只学习"怎么调用 Agent API",而要理解一个复杂 Agent Harness 是如何被设计出来的。


参考资料

  • Datawhale《Deep Agents in Action》第 1 章:从 Agent Framework 到 Agent Harness

  • Datawhale《Deep Agents in Action》第 2 章:快速上手------构建第一个 Deep Agent

相关推荐
昇腾CANN1 小时前
10月16日16点直播丨基于950超节点的万亿MoE模型预训练参考实践
人工智能·昇腾·cann·cann开源
过河卒_zh15667661 小时前
再更新!人工智能安全治理指引性文件第三版发布!
人工智能·算法·aigc·生成式人工智能·算法备案
霸道流氓气质1 小时前
在线 AI 绘图平台:Flux 模型集成、Serverless 弹性部署与 ComfyUI 工作流的 React + Spring AI 全栈实战
人工智能·react.js·serverless
武科大许志伟1 小时前
GPX:TSP中的两条好路线,怎样拼成一条更好的路线?
人工智能·演化计算·组合优化
CallFay云起未来1 小时前
2026年AI客服能不能减少人工回复?从知识检索到人机协同的技术实现
java·大数据·前端·人工智能·架构·文心一言
xieyan08111 小时前
HyperFrames:给一段文字让 AI 自动做视频,实测效果怎么样?
人工智能·音视频
IT_陈寒1 小时前
一文搞懂SpringBoot的核心概念
前端·人工智能·后端
LX567771 小时前
用AI减少网点重复劳动:从识别问题到设计辅助工作流
人工智能
旖旎夜光1 小时前
【LangGraph实战】LangGraph 学习笔记(五):信息裁剪、人机交互与时间旅行
笔记·python·学习·ai·人机交互·langgraph