前置:无 | 预计时长:45–60 分钟 | 动手环节:必须完成(不需要 API Key)
你将学会
- dsh 有哪几种启动方式,各自服务于什么场景;
- profile 是什么,为什么说它是「配置出来的应用」;
- 在不读任何源码的情况下,从磁盘上找到 dsh 的组合配置、会话日志与快照测试。
问题引入
先别管架构图。假设你拿到这个仓库,第一个问题一定是:这东西怎么跑?跑起来之后,状态存在哪? 这一课不读源码,只做三件事:跑起来、看配置、找日志。后面的每一课都会反复用到这些观察窗口。
正文
1.1 一个二进制入口:dsh
dsh 是仓库唯一被支持的 Node 应用启动器(apps/cli/README.md)。SDK、ACP 都不是独立的可执行文件,而是 profile:
| 命令 | 形态 | 用途 |
|---|---|---|
dsh web(即 --profile web) | 本地 Web UI | 默认 http://127.0.0.1:3080,日常交互 |
dsh --profile headless "任务" | 一次性任务 | 新建一个持久会话、打印最终回答、退出 |
dsh --profile sdk | stdio JSON-RPC 服务 | 给 TS/Python SDK 客户端用 |
dsh --profile sdk-minimal | 最小 agent 树 | SDK 的独立最小示例 |
dsh --profile acp | stdio ACP 服务 | 给自动化客户端用 |
五个内置 profile 都遵循同一个模板:dsh-base + 一个应用层(见第 07 课)。源码运行:
pnpm install
pnpm run build # 准备仓库产物
pnpm dsh web # 用已构建产物启动,不重新构建
1.2 profile:你自己的配置目录
首次启动任一内置 profile 时,dsh 会在 $DSH_HOME/profiles/<name>/ 自动初始化目录。目录里有:
package.json——dsh.profile.bundles是有序 bundle 列表(组合的骨架);cordis.patch.yml—— 用户自己的补丁层(你未来定制行为的落点,见第 07、10 课)。
dsh plugin --profile <name> <pnpm args> 用于在 profile 目录里管理插件依赖。当前工作目录默认是 workspace 根。
1.3 观察窗口一:组合树(不启动就能看)
pnpm dsh --dump-default-config # 内置默认组合
pnpm dsh --dump-config # 实际将要生效的组合(含你 profile 的补丁)
输出是逐层叠加后的插件条目树:每一条插件(有 id、配置、来自哪个补丁层)。它是后续课程里验证「我的补丁生效了吗」的标准手段——不需要启动、不需要 key。
1.4 观察窗口二:会话日志(状态存在哪)
dsh 的会话是事件溯源日志(第 05、06 课详解):每个会话对应一个追加文件(默认 JSONL,可切换 SQLite),位于存储根目录下。你现在不需要理解格式,只需要知道:
- 对话的每一步——用户消息、请求头、模型流式块、工具调用与结果、审批决策——都是日志里的一行事件;
- 快照测试
snapshots/里有现成的录制会话,格式与真实会话一致,可以当样本读。
1.5 观察窗口三:无 key 回放(最重要的开发闭环)
pnpm run test:snapshot # 全量回放
pnpm run test:snapshot -t <名字> # 按名字过滤
快照测试用录制的会话回放完整流程:启动真实子进程路径,但不调真实 API,所以没有 DEEPSEEK_API_KEY 也能跑。这是后面所有课程的「实验台」:想看某条行为,先找有没有对应快照;改了代码,跑快照看行为差异。
动手环节
- 在仓库根执行
pnpm install && pnpm run build(首次约几分钟)。 pnpm dsh --dump-default-config,在输出里找到dsh-base补丁插入的行,数一数默认装了多少条插件。- 打开
packages/bundle/base/cordis.patch.yml,对照上一步输出:这份补丁是不是「对空根的一次大规模 insert」? pnpm run test:snapshot -t <任意一个你猜得到的名字>跑不通就先跑全量(慢),挑一个通过的用例名记住,后面课程会复用。- (可选,需要 key)
pnpm dsh --profile headless "说一句话证明你在工作",然后到$DSH_HOME/profiles/headless/同级的存储目录里找到刚生成的会话文件,用文本编辑器打开看前几行。
自检清单
- 五个内置 profile 分别面向什么使用者?它们共享什么?
-
--dump-config和--dump-default-config的差别是什么? - 为什么说快照测试是「无 key 也能看到真实行为」的窗口?它的输入是什么?
- 你未来想给 dsh 加一个自己的行为,会落在哪个文件的哪一层?(提示:profile 目录里的补丁层,详见第 07 课)
常见误解
- 「SDK 是一个独立命令」——不是。SDK/ACP 都是 profile,
dsh是唯一启动器。 - 「必须先看懂架构才能跑」——反过来。本课程刻意让你先建立观察窗口,机制课全部基于你亲眼见过的输出。
延伸阅读
- 维基:《architecture-overview》、《repo-layout》
- 仓库:
README.md(运行章节)、apps/cli/README.md(入口模式与 profile 全表) - 下一课:第 02 课 · 一切皆插件:Cordis 骨架