CHAPTER 01 · STAGE 01 · 建立项目地图
如何使用这套教材
学习 DeepSeek Harness 的目标不是把两百多个 workspace 包背下来。真正有用的能力只有四项:看到一个包时能判断它负责什么;看到一个事件时知道它属于持久日志还是运行时控制;看到一个功能需求时知道应该挂在哪个扩展点;修改后知道需要哪一层测试证明它真的工作。你最终要获得什么能力
学习 DeepSeek Harness 的目标不是把两百多个 workspace 包背下来。真正有用的能力只有四项:看到一个包时能判断它负责什么;看到一个事件时知道它属于持久日志还是运行时控制;看到一个功能需求时知道应该挂在哪个扩展点;修改后知道需要哪一层测试证明它真的工作。
学完后,你应该能完成下面的任务:
- 从用户输入追踪到模型请求、工具调用和最终回复。
- 解释
ctx.tools、ctx.llm、ctx.sessions和ctx.agents分别由谁提供、由谁消费。 - 在不修改
agent-loop的前提下添加一个工具、策略或上下文插件。 - 为改动选择单元测试、真实组合测试或快照测试。
不要采用“从第一个目录读到最后一个目录”的方法
大型仓库的目录结构表达所有权,不表达教学顺序。packages/core/session 可能依赖 packages/llm/llm 的消息类型,packages/core/agent-loop 又同时使用 Session、LLM、Tools、System Prompt 和 Agent。按照字母顺序或目录顺序阅读,会不断遇到还没有建立的概念。
更好的方法是围绕一个真实动作建立纵向切片。例如研究 Bash 时,只追踪三层:shell 定义能力、bash-local 实现能力、tool-bash 把能力交给模型。其他包先不展开。
每次学习只做四件事
1. 看一个场景
先问“用户做了什么”。例如:用户说“列出当前目录”,模型决定调用 Bash,系统执行命令,再把结果发回模型。
2. 画一条数据流
不要一开始画完整架构图。只画本次场景经过的对象:
UserMessage → Agent → LLM → ToolCall → Shell → ToolResult → LLM
3. 打开不超过三个源码文件
第一次追踪只看入口类型、主要实现和一个测试。测试经常比实现更容易说明“这个包承诺什么行为”。
4. 用自己的例子复述
把 bash 换成“天气查询”或“读取文件”。如果替换例子后仍能解释 Definition、Provider、Consumer 的关系,才说明概念已经掌握。
阅读源码时固定问六个问题
遇到任何插件,先回答:
- 它在
ctx上提供哪个 Service? - 它通过
inject依赖哪些 Service? - 它注册哪些事件监听器、工具或提示词片段?
- 注册是否有 disposer,插件卸载后会清理什么?
- 它产生的内容是否会被模型看到?如果会,内容如何进入 Session 日志?
- 它的失败应该在哪一层被观察或恢复?
这六个问题比“每一行代码是什么意思”更重要。前者帮你找到结构,后者只会让你陷入局部细节。
学习节奏
建议每篇分两次完成。第一次用 30 到 45 分钟阅读并画图;第二次用 30 到 60 分钟打开源码、运行测试并完成练习。
如果某篇出现三个以上陌生术语,先去常用概念词典查词,再回到原文。不要为了一个术语跳进十层源码。
打卡格式
每次学习后用下面四项汇报:
完成内容:读了哪一篇,打开了哪些源码
运行结果:运行了什么命令,成功或失败
我的解释:用自己的话讲清一个概念
仍不明白:只写一个最阻碍继续学习的问题
这种格式能区分“已经看过”和“已经理解”。运行成功不等于理解,解释正确也不等于能操作;两者都需要。
第一阶段的合格标准
在进入 AgentLoop 之前,你至少要能解释:
- 插件为什么通过
ctx获取服务,而不是直接导入具体实现。 inject为什么不是普通的导入语句。ctx.effect()为什么与热重载和资源释放有关。cordis.yml为什么描述的是插件树,而不只是配置值。
如果这些问题答不出来,继续读 AgentLoop 只会看到大量陌生方法调用,却无法理解它们为什么这样组织。