DeepAgents框架初探

DeepAgents框架的核心

DeepAgentsLangChain 团队 在 LangChain 和 LangGraph 之上推出的 第三个独立开源项目,是一个 “开箱即用”的深度智能体框架。

DeepAgent框架的由来和定义

image-20260620113107207

Deep Agents 并非颠覆性技术创新,而是将业界验证过的最佳实践打包成开箱即用的框架。它的灵感来源于 Claude Code、Deep Research、Manus 等成功应用,这些应用证明了四个关键点:

  • Agent 需要规划能力 —— 不能上来就开干,得先拆解任务
  • Agent 需要文件系统 —— 长对话中,得有地方放中间结果,需要加载本地环境
  • Agent 需要子 Agent —— 单体 Agent 会被上下文撑爆
  • Agent 需要子 Skills —— Agent 功能可以弹性扩展,并且支持模块化开发。

LangChain 团队的想法很简单:既然这些经验都验证过了,为什么不打包成一个库?于是就有了 Deep Agents。

DeepAgents是一个Langchain团队在2025年11月推出的新框架,专门用于构建能够处理复杂、长周期任务的智能体(Agent)的框架。它的核心目标是让开发者能够更容易地创建出功能强大、可靠且可长期运行的AI智能体。

DeepAgents 的核心能力 + Harness Engineering

什么是 Harness Engineering(驾驭工程)

  • **Prompt Engineering**(2022-2024 主流)主要优化单次交互的质量,重点是 “一句提示词该怎么写,模型才更容易给出想要的结果”
  • **Context Engineering**(2025 年2月后兴起)则动态构建知识、记忆、RAG,解决 “模型看什么” 的问题,减少幻觉、提高检索命中率
  • **Harness Engineering**(当前阶段)重点构建整个运行环境,解决 “模型怎么把长链路任务稳定做完” 的系统级问题。

image-20260620113647634

Harness Engineering 是当前 AI Agent 开发领域的一个核心范式转变。它不再仅仅关注如何通过提示词(Prompt Engineering)或上下文管理(Context Engineering)来“优化模型输出”,而是聚焦于构建包裹在模型之外的一整套系统化基础设施,旨在将大语言模型(LLM)那种“不稳定、非确定性”的智能,转化为能够稳定、可靠、长时间执行复杂任务的工作引擎。

  • 核心定义:Harness(马具/缰绳)指的是除了模型本身之外的所有东西——工具、记忆、规划、安全护栏、执行循环、状态管理等。LangChain 团队将其精炼为公式:Agent = Model + Harness
    • 模型(Model):负责思考和决策
    • 驾驭层(Harness):负责把思考变成稳定执行,决定Agent能访问什么、能调用什么、能走到哪一步、什么时候停下、出了错怎么回退、结果如何校验
  • 解决的问题:传统 Agent 在应对长周期、多步骤的复杂任务时,常面临上下文窗口爆炸、状态丢失、工具调用混乱、缺乏规划、无法从失败中恢复等工程难题。Harness Engineering 正是为了解决这些“工程上的‘稳’的问题”而生的。

DeepAgents 中全面采用 Harness Engineering

DeepAgents 框架本身就是 Harness Engineering 思想的具体实现。DeepAgents 可以看作是 Harness Engineering 理念的一个具体技术实现,它通过内置能力,为 Agent 提供了稳定运行的“内核”,让开发者无需从零搭建复杂系统,只需通过配置即可获得一个功能完备的深度智能体。

DeepAgents提供Harness Engineering 的实现

  1. 规划能力(Planning)

    • 功能:提供一个 write_todos工具,允许智能体维护一个结构化的任务清单。

    • 作用:帮助智能体跟踪多个任务及其状态(‘pending’‘in_progress’‘completed’),以组织复杂的多步骤工作,尤其适用于长周期任务。

    • Harness 价值:将非结构化的模型思考,转化为可追踪、可恢复的确定性工作流。这避免了 Agent 在复杂任务中迷失方向,是长周期任务的基础。

  2. 虚拟文件系统(Virtual Filesystem)

    • 功能:提供一个可配置的虚拟文件系统,支持 ls(列出文件)、read_file(读取文件,支持图片和大型文件)、write_file(创建文件)、edit_file(编辑文件)、glob(模式匹配)、grep(内容搜索)和 execute(执行命令,仅在沙盒后端可用)等工具。

    • 作用:为其他能力(如技能、记忆、代码执行)提供基础存储和操作层,也可用于构建自定义工具。

    • Harness 价值:这是对抗 Context Rot(上下文腐烂) 的核心手段。它通过外部存储扩展了有效的上下文窗口,显著降低了 Token 消耗,并让 Agent 能处理远超单次模型限制的长任务。

  3. 任务委托/子智能体(Task Delegation / Subagents)

    • 功能:主 Agent 通过内置的 task工具和 SubAgentMiddleware,可以将专项任务(如“代码审查”、“网络研究”)委托给一个独立的子Agent。开发者可以预定义具有不同系统提示和工具集的子Agent(通过 subagents参数),实现专业化分工。

      • 作用
        • 上下文隔离:子智能体的工作不会干扰主智能体的上下文。
        • 并行执行:多个子智能体可以并发运行。
        • 专业化:可以为子智能体配置不同的工具集。
        • Token高效:将大型子任务的上下文压缩为单一结果报告返回给主智能体。
    • Harness 价值:实现了上下文隔离算力分配。子Agent在独立的上下文中运行,其繁杂的中间过程不会污染主Agent的思维空间,最终仅返回一个精简的结果。这本质上是为 Agent 系统引入了“多线程”和“微服务”架构。

  4. 上下文管理(Context Management)

    这是智能体处理长对话和复杂任务的关键,通过多种技术管理其工作记忆(上下文),确保不超出模型的处理窗口限制。主要包括:

    • 输入上下文:包括系统提示词、待办列表、记忆、技能、文件系统工具说明等,在智能体启动时注入。

    • 运行时上下文压缩

      • 卸载大型工具输入和结果:当工具调用的输入或结果超过一定大小时(默认20,000 tokens),智能体会自动将其内容保存到文件系统,并在对话历史中用文件路径和摘要替换,以节省上下文空间。当会话上下文超过模型窗口的85%时,会触发此操作。
      • **摘要化 (Summarization)**:当上下文大小达到极限且无可卸载内容时,智能体会将过去的对话历史总结为一段结构化摘要,替换原有的详细历史,同时将完整历史保存到文件系统。
      • **长期记忆 (Long-term memory)**:通过混合存储后端,允许智能体将特定路径(如 /memories/)下的信息持久化存储,使其能够跨不同的会话和线程访问,用于存储用户偏好、累积知识等。
      • Harness 价值:注入领域知识与持久状态。
  5. 代码执行(Code Execution)与安全沙箱 (Sandbox)

    • 功能:当使用沙盒后端时,会向智能体暴露一个 execute工具,允许其在隔离环境中运行 shell 命令。

    • 作用:使智能体能够安装依赖、运行脚本、执行代码,从而完成更复杂的任务,同时保证了主机系统的安全。

    • Harness 价值:遵循 “Trust the LLM”但隔离执行环境 的安全哲学。它赋予 Agent 与真实操作系统交互的能力,同时通过沙箱机制防止破坏性操作,是编码、运维等场景的基石。

  6. 人工介入(Human-in-the-loop, HITL)

    • 功能:通过 interrupt_on参数配置,可以在指定的工具调用前暂停智能体执行,等待人工批准或修改输入。

    • 作用:为具有破坏性或昂贵的操作(如编辑文件、调用API)增加安全闸门,便于交互式调试和指导。

    • Harness 价值:在高风险或关键操作前插入确定性的人工控制点。这是将 Agent 集成到生产工作流中的必备安全机制。

  7. 技能包加载和管理(Skills)

    • 功能:采用“渐进式披露”,仅在需要时加载,以减少系统提示的 token 占用。适用于任务特定、内容可能很多的场景。

      • - 渐进式披露:这是技能加载的核心机制。智能体启动时,仅读取所有 SKILL.md文件的元数据部分。当接收到用户提示后,智能体根据元数据中的描述判断是否有相关技能可用。只有匹配到相关技能时,才会去读取该技能文件夹的完整内容(包括 SKILL.md的详细指令和其他资源文件)。这大大减少了初始上下文的 token 消耗。
      • - 智能体使用流程:匹配(根据描述)→ 读取(完整技能内容)→ 执行(遵循技能指令)。
    • 作用:Skills 是用于扩展 Deep Agent 能力的可重用模块。

    • Harness 价值:实现了知识的模块化、按需加载。让 Agent 的行为具备领域专长。

DeepAgents框架中Harness Engineering 的核心原理

  1. 配置优于编码:DeepAgents 将上述所有复杂能力封装为可配置的中间件(Middleware) 栈。开发者通过 create_deep_agent函数,以声明式的方式组合这些中间件,而非编写底层控制流。这实现了 “Batteries Included, Customize in Minutes”(开箱即用,分钟级定制)。
  2. 中间件架构:每个核心能力(规划、文件、子Agent等)都是一个独立的 AgentMiddleware。这些中间件在 Agent 运行的生命周期各阶段插入钩子(hooks),动态注入工具、修改提示、管理上下文。这种架构使得 Harness 高度模块化和可扩展。
  3. 后端协议抽象:统一的 BackendProtocol抽象了文件存储和执行环境。无论是内存、本地磁盘、云存储还是沙箱,对 Agent 而言都是统一的 lsreadwrite接口。这种设计实现了存储与计算环境的解耦和灵活替换。
  4. 上下文工程自动化:Harness 承担了“上下文工程师”的角色。它自动执行摘要压缩、内容卸载、按需加载等策略,确保模型在任何时刻看到的都是最相关、最精炼的信息,从而将有限的模型注意力集中在核心决策上。
  5. 从智能到系统:Harness Engineering 的本质是将模型的“认知能力”系统化、工程化。它通过规划来管理目标,通过文件系统来管理状态,通过子Agent来管理复杂度,通过安全沙箱来管理风险,通过人在回路来管理不确定性。最终,它将一个“聪明的对话者”转变为一个“可靠的操作者”。

在 DeepAgents 框架中全面采用 Harness Engineering,意味着您的开发范式发生了根本转变:

  • 从前:您需要手动编写任务分解逻辑、管理上下文窗口、实现子Agent通信、构建安全机制。
  • 现在:您只需通过 create_deep_agent配置所需的“能力模块”(规划、文件、子Agent、技能、内存、沙箱、人工审批),即可立即获得一个具备生产级可靠性的深度智能体。

框架对比

维度 LangGraph LangChain Deep Agents
定位 智能体核心开发框架 智能体开发的基础框架 复杂智能体开发框架
抽象层级 低层(自己造轮子) 基础层(积木块) 高层(开箱即用)
核心抽象 StateGraph、Node、Edge Chain、Runnable、Tool DeepAgent、Middleware、Backend
规划能力 需要自己实现 非原生支持 ✅ write_todos 内置
文件系统 需要自己实现 非原生支持 ✅ 完整文件系统工具集
子代理委托 可通过子图实现 非原生支持 ✅ task 工具内置
长期记忆 需要自己配置 基础记忆抽象 ✅ 原生支持 + 外部持久化
上下文管理 通过图结构控制 依赖模型上下文窗口 ✅ 文件系统 + 持久化记忆
学习曲线 陡峭 中等 陡峭
灵活性 极高 中等(但很实用)
适用对象 复杂企业流程序列化开发者 库开发者 / 底层构建 应用开发者 / 企业级解决方案

DeepAgents的核心定位是:DeepAgents 是 LangChain 生态中面向“复杂任务”的“上层应用框架”。

专门为构建能够处理复杂、多步骤、长时间运行任务的“深度”智能体(Deep Agent)而设计。它并非要取代 LangChain 或 LangGraph,而是在它们提供的底层运行时和基础抽象之上,封装了业界已验证的最佳实践(如 Claude Code、Manus 等应用的模式),将这些复杂能力标准化、产品化,模块化,工程化。

开发建议和Agent生态分层

  • 底层框架(如LangChain)解决通用性问题。提供 create_agent,tool, LLM调用等高层抽象和标准组件。
    • 简单、直接的任务 → 使用 LangChaincreate_agent
  • 专项框架(如LangGraph for 多Agent, DeepAgents for 长任务)在通用框架上针对特定场景做深度优化。
    • LangGraph:提供最底层的状态管理、工作流编排。需要完全自定义、复杂控制流的工作流 → 使用 LangGraph从底层构建。
    • DeepAgents:专为 “重任务” 设计,不适合简单聊天机器人,需要处理复杂、多步骤、长时间运行的“深度”任务 → 选择 DeepAgents
      • 其典型场景包括:
      • 深度研究与报告撰写:自动进行多轮搜索、阅读、分析并生成长篇报告。
      • 全栈代码生成与重构:在沙箱中编写、测试、调试和重构整个代码库。
      • 复杂数据分析流水线:连接数据库、执行查询、处理中间文件并生成可视化图表。
      • 自动化运维与业务流程:操作文件、执行命令、编排需要多角色协作的复杂工作流。

DeepAgents的Agent开发

参考:https://docs.langchain.com/oss/python/langgraph/local-server#2-create-a-langgraph-ap

  1. 创建虚拟环境,并安装依赖库

     pip install deepagents dotenv langchain-openai zai-sdk
    
     pip install -U "langgraph-cli[inmem]"
    
  2. 复制 langgraph 本地服务所支持的项目模板

    下载地址:https://github.com/langchain-ai/new-langgraph-project,(备用下载地址:https://github.com/starzy1990/new-langgraph-project)

    image-20260621190015031

    将上述内容复制到项目中,src 目录设置为 Sources Root,并修改文件 .env.example.env ,并将模型对应的 API_KEY 和 BASE_URL 放在此文件中。

  3. 调用LLM和定义工具

    from langchain_openai import ChatOpenAI
    from src.utils.env_util import ZHIPU_API_KEY, ZHIPU_API_URL, QWEN3_API_KEY, QWEN3_API_URL
    
    llm_qwen3 = ChatOpenAI(
        api_key=QWEN3_API_KEY,
        base_url=QWEN3_API_URL,
        model="qwen-plus",
        temperature=0.9,
    )
    
    llm_zhipu = ChatOpenAI(
        model="glm-5.2",
        temperature=0.9,
        api_key=ZHIPU_API_KEY,
        base_url=ZHIPU_API_URL
    )
    
  4. 创建一个DeepAgent对象

    import os
    from deepagents import create_deep_agent
    
    from utils.llm_util import llm_zhipu
    from utils.tools_util import web_search
    
    agent = create_deep_agent(
        model=llm_zhipu,
        tools=[web_search],
        system_prompt="你是一位财经分析师。请用简洁的语言总结网络搜索结果中的关键信息,按重要性排序并引用来源日期。今天的日期是2026年6月29日。",
    )
    
  5. 修改配置文件: langgraph.json

    修改 graphs 中 的 agent 属性修改为自定义的 deepagent,以及后面对应自定义的 deepagent 名称

    image-20260623230832246

    1."$schema"
    •作用:指定用于验证此 JSON 配置文件结构的 JSON Schema 文件的地址。
    •解释:它指向一个在线模式定义文件 (https://langgra.ph/schema.json)。支持 JSON Schema 的代码编辑器(如 VS Code)可以利用它来为这个配置文件提供自动完成、语法高亮和错误检查,帮助你更准确、高效地编写配置。
    
    
    2."dependencies"
    •作用:声明此项目运行所依赖的代码路径或包。
    •解释:当前配置为 ["."],表示依赖当前目录(即项目根目录)下的所有代码。这意味着当你运行 LangGraph 应用时,框架会将当前目录添加到 Python 的模块搜索路径中,从而能够找到并导入你编写的本地模块(例如 src目录下的文件)。
    
    
    3."graphs"
    •作用:定义本项目中的一个或多个“图”(即智能体工作流),并为每个图指定一个可调用的入口点。
    •解释:这是一个键值对对象。在本配置中:
        •键 "agent":这是你为这个图定义的名称。你之后可以通过这个名字(例如在命令行中)来引用并运行这个特定的工作流。
        •值 "./src/agent/test1.py:agent":这是指向图中入口点的路径,采用 文件路径:可调用对象名的格式。
    
            •./src/agent/test1.py:是包含图定义代码的 Python 文件路径。
            •agent:是 test1.py文件中导出的、代表整个图的主要可调用对象(通常是一个已经编译好的 Graph或 StateGraph对象)。
           
            
    4."env"
    •作用:指定项目使用的环境变量文件。
    •解释:其值为 ".env",表示在项目根目录下存在一个名为 .env的文件。LangGraph 在运行时会加载这个文件,将其中的键值对设置为环境变量。这通常用于安全地管理 API 密钥、数据库连接字符串等敏感或可配置的信息(例如 OPENAI_API_KEY)。
    
  6. 启动langgraph的本地服务

    • 初始化服务安装依赖(首次启动)

      # 第一次启动需要先安装依赖
      pip install -e .
      
    • 本地启动服务

          langgraph dev
      

      image-20260623231305252

  7. 打开LangSmith Studio-Langmith UI并测试

    image-20260629144029255

  8. Agent本地测试并流式输出

    定义一个函数:负责流式输出

    import asyncio
    from typing import AsyncIterator
    
    from agent.test1 import agent
    
    
    async def stream_agent_interaction_corrected(agent, thread_id: str) -> AsyncIterator[str]:
        """
        使用官方推荐的 `agent.stream()` 方法进行流式交互。
        根据调试信息,chunk的结构是 (AIMessageChunk, metadata_dict)
        """
        config = {"configurable": {"thread_id": thread_id}}
    
        while True:
            try:
                user_input = input("\n\n[用户] >>> ").strip()
            except (EOFError, KeyboardInterrupt):
                print("\n\n对话结束。")
                break
    
            if user_input.lower() in ('quit', 'exit', '退出', 'q'):
                print("再见!")
                break
            if not user_input:
                continue
    
            print("\n[Agent] ", end="", flush=True)
    
            # 准备输入
            inputs = {"messages": [{"role": "user", "content": user_input}]}
    
            # 关键修正:使用 agent.stream() 并设置 stream_mode
            stream = agent.stream(inputs, config=config, stream_mode="messages", subgraphs=False)
    
            full_response = ""
            try:
                # 使用同步 for 循环,因为 agent.stream() 返回的是同步生成器
                for chunk in stream:  # 移除 async
                    # 根据调试信息,chunk 的结构是 (AIMessageChunk, metadata_dict)
                    if isinstance(chunk, tuple) and len(chunk) == 2:
                        token, metadata = chunk
    
                        # 1. 流式输出 AI 生成的文本内容
                        if hasattr(token, 'content') and token.content is not None:
                            content_str = str(token.content)
                            if content_str:
                                yield content_str  # 生成器
                                full_response += content_str
    
                        # 2. 捕获并显示工具调用开始
                        if hasattr(token, 'tool_call_chunks') and token.tool_call_chunks:
                            for tool_chunk in token.tool_call_chunks:
                                if tool_chunk and hasattr(tool_chunk, 'get'):
                                    if tool_chunk.get('name'):
                                        tool_name = tool_chunk['name']
                                        yield f"\n[调用工具: {tool_name}]\n"
    
                        # 3. 捕获并显示工具调用结果
                        # 注意:工具调用结果通常不会出现在同一个 token 中
                        # 它们通常以独立的 token 形式出现
    
                    else:
                        # 如果 chunk 不是预期的元组结构,打印调试信息
                        print(f"\n[调试] 意外的 chunk 结构: {type(chunk)}")
                        continue
    
            except Exception as e:
                yield f"\n❌ Agent 执行出错: {e}\n"
                import traceback
                traceback.print_exc()
                continue
    
    
    async def main_test():
        # 测试运行Agent,并且进行交互
        thread_id = "demo_thread_01"
        async for response in stream_agent_interaction_corrected(agent, thread_id):
            print(response, end="", flush=True)
    
    if __name__ == '__main__':
        asyncio.run(main_test())
    
--- 本文结束 The End ---