如果你最近尝试过从零搭一个能用的 LLM Agent,大概率会同意一件事:让它"能聊天"很简单,让它"能干活"很难。工具调用、上下文管理、长对话压缩、子任务委派,每一项单独拎出来平平无奇,凑到一起就变成了一个让人头皮发麻的工程问题。
deepagents 就是 LangChain 团队为了解决这种"散装拼凑"的痛点推出的开源框架。它跑在 LangGraph 之上,自带文件系统、子代理、上下文压缩和技能系统,定位上类似于 Claude Code 的开源版本。MIT 协议,目前在 GitHub 上拿了 26k+ stars。
三层叠一台戏
deepagents 很好理解:它在 LangChain 生态里叠了三层。最底层是 LangGraph,负责流式执行、持久化、检查点和人机协作。中间层是 LangChain 的 create_agent,一个最精简的 tool-calling 循环。最上层才是 deepagents 自己——它在中间层的基础上塞了子代理、虚拟文件系统、上下文管理和技能机制,让你拿到手就能跑,不用自己焊轮子。
整件事的设计哲学是"Opinionated":框架替你选好了一套默认配置,目标是长时运行、多步任务场景。当然每一层都可以替换,你不需要 fork 框架。
四个能力模块
deepagents 把能替你干的事归成四类:执行环境、上下文管理、委派、人工介入。
执行环境是你的 agent 能动起来的基础。自定义工具通过 tools= 参数挂载,虚拟文件系统开箱即用,代码执行则交给沙箱后端。上下文管理解决的是"聊到一半就忘了开头"的问题——技能按需加载,对话历史超长时自动摘要压缩,跨会话的持久记忆写在 AGENTS.md 里。委派能让主 agent 把任务甩给上下文隔离的子代理,只拿回最终结论,避免中间过程把对话刷爆。人工介入则是在关键工具调用之前暂停,等你点个头再往下走。
三行跑起来
deepagents 的入口函数是 create_deep_agent(),名字听着唬人,实际最小调用只需要三个参数:
from deepagents import create_deep_agent
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
tools=[your_tool],
system_prompt="你是一个能研究、计算、管理文件的助手。",
)
model 字段支持任意能 tool-calling 的模型,字符串格式是 provider:model_id,比如 openai:gpt-4o、google_genai:gemini-2.0-flash、ollama:llama3.1 都行。如果你已经在别处配好了模型实例,也可以直接传对象。
调用方式和常规 LangChain agent 一样:
result = agent.invoke(
{"messages": [{"role": "user", "content": "你的问题"}]}
)
print(result["messages"][-1].content)
文件系统、子代理、摘要压缩这些能力在这一步已经默认启用,不需要额外开关。这正是它"电池全包"的意思。
文件系统:agent 的办公桌
deepagents 内置了七个文件系统工具,agent 建好就能用。ls 列目录元数据,read_file 带行号读取并支持 offset/limit 和多模态,write_file 创建或覆盖文件,edit_file 做精确字符串替换,glob 走模式匹配,grep 搜内容,execute 则专门留给沙箱后端跑 shell。
默认情况下 agent 能碰所有工具,但你可以用 FilesystemMiddleware 把它锁在只读笼子里:
from deepagents.middleware import FilesystemMiddleware
from deepagents.filesystem import InMemoryBackend
backend = InMemoryBackend() # 内存后端,不写磁盘
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
middleware=[
FilesystemMiddleware(
backend=backend,
tools=["read_file", "ls", "glob", "grep"] # 只暴露只读工具
),
],
)
这个设计很实用:测试阶段用 InMemoryBackend 跑通逻辑,生产环境再换成真实存储后端,代码本身不用改。
子代理:别让对话被中间过程淹没
做过 Agent 项目的人都知道,一个需要十几步才能完成的任务,如果每一步的推理、工具调用、中间结果都堆在主对话里,上下文很快就会炸。deepagents 的解法是引进子代理:主 agent 把子任务派出去,子代理在隔离的上下文窗口里从头到尾跑完,只回传最终报告。
定义一个子代理需要三样东西:名字、描述和工具。描述尤其重要——主 agent 靠它判断该不该把活派给你:
from deepagents import SubAgent
researcher = SubAgent(
name="researcher",
description="专门做深度研究,返回带引用的报告",
tools=[web_search],
system_prompt="你是一个严谨的研究助手,回答必须引用来源。",
)
coder = SubAgent(
name="coder",
description="专门写代码和调试",
tools=[calculator],
system_prompt="你是一个编程助手,写简洁的 Python 代码。",
)
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
tools=[web_search, calculator],
subagents=[researcher, coder],
)
子代理之间还支持并行执行,多个独立任务可以同时派出去等结果。另外,deepagents 不限制子代理必须是自家框架——任何 LangGraph 的 CompiledStateGraph 都能塞进去当子代理用。
几个进阶开关
实际项目里,光跑起来不够用,你迟早会碰到下面几个需求。
想让 agent 记住用户偏好? 用 memory= 参数传一条字符串列表,跨会话持久。或者在项目目录下建一个 AGENTS.md,agent 启动时会自动加载。
关键操作需要人点头? 设 interrupt_on,指定哪些工具调用前先暂停:
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
tools=[query_db],
interrupt_on={"query_db": True},
)
想要结构化输出? 丢一个 Pydantic 模型给 response_format:
from pydantic import BaseModel
class Weather(BaseModel):
city: str
temperature: float
summary: str
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
response_format=Weather,
)
会话中断后想恢复? 接一个 checkpointer。比如 SQLite:
from langgraph.checkpoint.sqlite import SqliteSaver
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
checkpointer=SqliteSaver.from_conn_string("agent.db"),
)
技能系统则更进一步。在项目里建一个 skills/ 目录,往里放 .md 文件就行。agent 启动时只读 frontmatter 了解有哪些技能,真正干活时才加载全文,避免一上来就把所有知识塞进上下文。
收个尾
deepagents 会把 agent 开发里那些"不得不做但没意思"的活全部接过去——文件系统、摘要压缩、子上下文、技能加载、checkpointer,开箱即用。你只需要关心业务逻辑该怎么拆、工具该怎么定义。
如果你对 LangGraph 和 LangChain 这套生态已经上手了,想找一个趁手的"壳子"把你的 Agent 串成真正能跑的产品,deepagents 值得一试。
- 源码:langchain-ai/deepagents
- 文档:docs.langchain.com
- 托管版:Managed Deep Agents(LangSmith,当前 Beta)