文章目录
- 前言
- 1. dcode 到底是个啥?
- 2. main.py:那个 6000 多行的总指挥
- 2.1 cli_main():第一道门
- 2.2 parse_args():你的命令先被"扒光"
- 2.3 配置与凭证:启动前的一堆灵魂拷问
- 3. 三岔路口:程序启动之后去哪
- 3.1 ACP:给别的机器人留个窗口
- 3.2 Headless:闭嘴干活模式
- 3.3 Interactive:主线剧情在这
- 4. run_textual_cli_async():跨过那条界
- 4.1 app.py:TUI 不是 Agent
- 5. 为什么要拆 Client 和 Server?
- 5.1 LangGraph Server:真正干活的地方
- 5.2 make_graph():Graph 的出生地
- 5.3 create_cli_agent():组装车间
- 5.4 create_deep_agent():站在巨人肩膀上
- 6. 完整调用链:一张图搞定
- 7. 阅读顺序:别从上往下读
- 8. 四层分界线
- 9. 后续怎么读
- 10. 总结
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看, 传送门https://blog.csdn.net/H1727548
前言
看源码这件事,跟相亲是一个套路:第一眼全是优点,第二眼全是细节,第三眼你已经分不清谁是谁了。
今天要拆的是 Deep Agents Code。很多人一上来就冲着那个 6000 多行的 main.py 去了,心想从头读到尾,总能把这家伙拿下。读了两天半,一行没落,别人问它怎么跑起来的,你只能憋出一句:跑起来了,而且跑得很复杂。
这种状态,源码圈有个专业称呼:局部清醒,整体昏迷。
所以正确的打开方式不是硬啃,而是先搞到一张地图。本文就是把这张地图给你画出来。
1. dcode 到底是个啥?
先说个扎心的真相:你在终端敲的dcode,既不是 Python 自带的命令,也不是一个独立的 py 文件。
dcode它其实是deepagents-code这个包,通过pyproject.toml注册出来的一个 CLI 入口。机制上就是一行配置:
[project.scripts] dcode = "deepagents_code.main:main"翻译成人话:装完包之后,系统给你造了个快捷键。就像家里装了智能音箱,你喊"开灯"灯就亮,但你没道理去拆音箱找灯丝。
所以读源码的时候,别傻乎乎找dcode.py,这文件压根不存在。你要找的是deepagents_code里对应的入口函数。
Windows 上装完,你会看到.venv/Scripts/dcode.exe;Linux/macOS 上则是.venv/bin/dcode。一个 exe、一个裸文件,长得不一样,干的事一模一样:把你敲的命令转手递给 Python,深藏功与名。
2. main.py:那个 6000 多行的总指挥
main.py 6000 多行,不是因为作者话多,而是因为它是个 Orchestrator——总指挥。
它不写业务,不写 Agent 能力,只负责把各种组件按正确的顺序喊起床。很像你家周末的家长:自己不起床,但能把全家都喊醒,而且喊得理直气壮。
整个启动流程可以抽象成:
dcode └─ cli_main() ├─ CLI 参数解析 ├─ 配置加载 ├─ Credentials 凭证 ├─ Model 配置 ├─ MCP 配置 ├─ Sandbox 配置 └─ Runtime 检查所以记住:main.py 是应用启动层,不是 Agent 核心实现层。别在里面找 Agent,它只是负责把 Agent 叫醒的那个闹钟。
2.1 cli_main():第一道门
所有事情从cli_main()开始:
def cli_main() -> None: ...它干的事非常多:解析参数、初始化环境、加载配置、检查凭证、选运行模式、起 TUI、兜住异常、最后还负责打扫卫生。
比入职第一天还忙——入职至少还管顿饭。
你可以把它理解为整个程序的 Bootstrap(启动引导)入口:办卡、签合同、领工位,一套流程走完,才开始干活。
2.2 parse_args():你的命令先被"扒光"
用户敲的每一句话,第一站都是parse_args():
args = parse_args()你敲dcode --model xxx、dcode --sandbox xxx,全都会被解析成结构化的args。
model sandbox sandbox_id resume_thread initial_prompt mcp_config no_mcp yolo auto_approve interpreter ...这一步的本质,是把"人话"翻译成"程序话"。用户说"我要用那个模型",程序听到的是 model=xxx。翻译过来就是:你说的都对,但我只认结构化数据。
2.3 配置与凭证:启动前的一堆灵魂拷问
真正创建 Agent 之前,程序要先回答一连串问题:
用什么模型? 用什么 API Key? 开不开 MCP? 用哪个 Sandbox? 当前工作目录是啥? 要不要恢复历史 Session? 允不允许自动执行?这些问题不回答清楚,Agent 根本起不来。很多人排查"Agent 启动失败",排查了半天 Agent,最后发现挂在配置阶段。
就跟你半夜想吃火锅,检查了半天锅,结果发现是插座没电。锅很委屈,你也很委屈。
3. 三岔路口:程序启动之后去哪
初始化完成,cli_main()会根据参数把程序送上三条路之一:
cli_main() ├─ ACP 模式 ├─ Headless 模式 └─ Interactive 模式3.1 ACP:给别的机器人留个窗口
dcode --acp走的是 ACP 模式,让其他 Agent Client 能和 Deep Agents Code 做标准化交互。
听着很高端,翻译成人话就是:给别的机器人留了个客服窗口。
如果你主要研究的是普通 Coding Agent 的 TUI,这条支线可以先放一放。不是不重要,是你现在真没空。
3.2 Headless:闭嘴干活模式
dcode -n "帮我分析当前项目"走 Headless 模式,不启动终端 UI,直接执行任务。
适合自动化脚本、CI/CD、批处理。说白了就是"闭嘴干活模式":不废话,干完拉倒。
很多打工人做梦都想要这种模式,可惜领导不给配。
3.3 Interactive:主线剧情在这
直接敲dcode,通常进入 Interactive 模式,接着进 Textual TUI。这是本文最重要的一条源码阅读路线。
记住这条线:dcode → Interactive → Textual TUI。
4. run_textual_cli_async():跨过那条界
Interactive 模式最终会走到run_textual_cli_async()。
这一跳非常关键,因为它意味着:
CLI 启动层 → TUI 应用层正式切换。后面你就要进app.py了。
4.1 app.py:TUI 不是 Agent
很多人第一次读源码会犯一个错误:以为 TUI 就是 Agent。
不是。TUI 只是 Agent 的客户端,负责接收输入、展示输出、展示工具调用、展示流式输出、展示审批请求、管理 Session。
它跟 Agent 的关系,就像餐厅服务员和后厨:服务员不炒菜,厨师不见客。你要是让服务员去颠勺,菜就糊了;让厨师出来点单,客人就跑光了。
5. 为什么要拆 Client 和 Server?
这是读这个项目时最重要的架构概念。
Deep Agents Code 不是"TUI 直接连 Agent",而是:
Client(TUI)→ 通信 → Server(LangGraph Agent)Client 管交互,Server 管干活。拆开的好处很直白:界面崩了,不影响 Agent 继续跑。相当于服务员摔了一跤,后厨的锅还能继续炒。
5.1 LangGraph Server:真正干活的地方
TUI 不会在自己的进程里跑完整 Agent,它会连接一个 LangGraph Server:
Textual TUI → RemoteAgent → LangGraph Server → Agent Graph所以读源码要分清两个问题:
main.py → app.py → RemoteAgent :用户怎么和 Agent 交互 server_graph.py → agent.py → graph.py :Agent 本身怎么构造一个是前台的事,一个是后厨的事,别混。
5.2 make_graph():Graph 的出生地
进入 Server 侧,第一个要记住的函数是server_graph.py里的make_graph()。
LangGraph Server → make_graph() → 读取配置 → 创建 Agent → 返回 Graph记住这个分界点,就像记住"过了这个收费站就进高速",不然你会在省道上绕到怀疑人生。
5.3 create_cli_agent():组装车间
make_graph()继续往下,进入agent.py,最值得关注的是create_cli_agent()。
到这里,代码才开始真正把 Coding Agent 的能力拼起来:
create_cli_agent() ├─ Model ├─ Tools ├─ Middleware ├─ Filesystem / Shell / MCP └─ Skills / Context / HITL ...这已经不是"调一个 LLM"那么简单了,这是在组装一个完整的 Agent Harness(运行框架)。
相当于你不是在买一辆车,而是在造一条生产线。
5.4 create_deep_agent():站在巨人肩膀上
create_cli_agent()继续往下,进入libs/deepagents包,核心函数是create_deep_agent()。
这里有个重要的架构思想:Deep Agents 并没有从零造一套 Agent Runtime,它是站在 LangChain Agent 和 LangGraph Runtime 肩膀上的。
这就是传说中的"站在巨人的肩膀上",区别是巨人本人可能都不知道自己被人站了。
它真正干的事是"加料":Middleware、Backend、Tools、Skills、Subagents,把底层能力包成一个更完整的 Harness。
6. 完整调用链:一张图搞定
现在把整个启动过程串起来:
dcode → cli_main() → parse_args() → Config / Credentials → Runtime 初始化 → Interactive → run_textual_cli_async() → app.py (TUI) → RemoteAgent → LangGraph Server → server_graph.make_graph() → create_cli_agent() → create_deep_agent() → LangChain create_agent() → LangGraph Agent Runtime这张图,就是整个 Deep Agents Code 源码的第一张地图。建议截图保存,不然下次你还是会迷路。
7. 阅读顺序:别从上往下读
有了地图,就别再按文件目录从上往下读了。更高效的方式是按运行时调用链读:
① main.py → cli_main() ② main.py → parse_args() ③ main.py → run_textual_cli_async() ④ app.py / TUI → Client / RemoteAgent ⑤ server_graph.py → make_graph() ⑥ agent.py → create_cli_agent() ⑦ deepagents/graph.py → create_deep_agent() ⑧ LangChain → create_agent() ⑨ LangGraph → Agent Runtime这样读的好处是:每进一个新文件,你都知道"我为什么会来到这里"。
而不是在一个 6000 多行的 main.py 里,活成一座孤岛。
8. 四层分界线
整个项目可以粗暴地分成四层:
第一层:CLI / Application(main.py) —— 程序怎么启动 第二层:Client / TUI(app.py、RemoteAgent) —— 用户怎么交互 第三层:Coding Agent(server_graph.py、agent.py) —— Agent 怎么组装 第四层:Deep Agent Harness(libs/deepagents/)—— 能力怎么组织记住这四层,你在源码里就不会再"脸盲"了。
9. 后续怎么读
本文只解决一个问题:Deep Agents Code 到底是怎么启动的。
接下来可以沿着主线继续深挖:main.py 配置系统、Textual TUI、LangGraph Server、Middleware、Backend、Tools、Skills、Subagents、完整 Agent Loop。
全程围绕一个问题:用户输入的一句话,到底经过哪些组件,最终变成一次 Tool Call?
这条链捋清楚了,源码里的细节会自己归位。就像你记住了一个人住哪栋楼,以后再见到他,就不用满小区喊了。
10. 总结
Deep Agents Code 不是简单的dcode → LLM → Tool,而是一套完整的 Coding Agent Runtime。
最核心的三个入口:
main.py → cli_main() :应用启动 server_graph.py → make_graph() :Agent Graph 创建 agent.py → create_cli_agent() :Coding Agent 组装再往下,create_deep_agent()进入 Deep Agents 的核心 Harness。
所以读这个项目,最有效的姿势不是从某个 Tool 开始硬啃,而是先拿到这张调用链地图,再逐层深入。
毕竟读源码最怕的不是代码难,而是你读了半天,发现自己连门都没找对——就像排了两个小时队,最后发现排的是隔壁奶茶店。
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看,传送门https://blog.csdn.net/H1727548