10. 渐进式实战项目
实践一:成功运行并观察核心流程
- 任务背景:熟悉开发环境,看到真实启动和日志。
- 学习目标:能安装、构建、运行并判断失败阶段。
- 涉及模块:根工程、CLI、bundle。
- 推荐修改点:先不修改代码,运行命令。
- 实现步骤:
- 记录
node --version、pnpm --version、git rev-parse HEAD。 pnpm install后先运行pnpm dsh --help。- 运行三个核心包测试:
pnpm exec vitest run packages/core/session packages/core/agent-loop packages/core/tools。 - 比较 web/headless 的 default config dump;不需要 API Key。
- 只有前述步骤通过后,才选择 mock LLM 或真实 Key 启动。
- 记录每个命令的退出码、成功/失败和首个错误文本。
- 记录
- 测试方法:以实际命令输出为准,不推测。
- 验收标准:提交一份环境记录和启动分层图;能说出失败属于依赖、配置、插件激活、模型还是缺 Key。
- 恢复方式:实践一不修改 tracked 文件;关闭服务并删除临时日志即可。
- 可能踩坑:Windows 上 bash/pwsh 平台差异;未 build 缺 artifacts;网络受限。
- 进一步挑战:使用
--dump-config观察 web/headless 组合差异。
实践二:修改一个低风险已有功能
- 任务背景:理解配置与测试流程。
- 学习目标:做一个小改动并验证。
- 涉及模块:
system-prompt、bundle patch。 - 推荐修改点:官方
scratch-plugin中新增一个study:notePrompt section,使用临时--patch挂载。 - 实现步骤:
- 按
docs/user/develop/basic/创建scratch-plugin。 - 注册固定名称与 order 的 Prompt section,并写 assemble/render 单测。
- 用
extra.yml挂载插件,比较--dump-default-config与--dump-config。 - 增加 scoped 同名 section,验证 shadow 只影响目标 Agent。
- 卸载插件,确认基础快照恢复。
- 按
- 测试方法:断言 section 文本、顺序、scope 和 disposer;dump 只用于证明真实入口。
- 验收标准:单测通过,能解释 Patch 整行替换与 Prompt scoped shadow 是两种不同机制。
- 恢复方式:移除
--patch并删除 scratch-plugin;不修改默认 Bundle。 - 可能踩坑:保留字段漏写;id 不匹配。
- 进一步挑战:把 persona 改为模板变量,观察变量解析错误。
实践三:定位并修复一个模拟问题
- 任务背景:掌握调用链、日志和断点。
- 学习目标:定位故障发生在哪个模块。
- 涉及模块:Agent loop、tools、LLM、Session log。
- 推荐修改点:使用 mock LLM 确定性地产生一个不存在的工具名,再增加一个永远 deny 的 guard。
- 实现步骤:
- 让 mock LLM 发出
missing_tool,在 lookup/execute 入口观察UNKNOWN_TOOL。 - 改为真实已注册的无副作用工具,确认成功基线。
- 注册 guard deny,确认 body 没有进入且结果被规范化。
- 移除 guard,故意返回错误 output 类型,定位失败发生在 body 之后、提交结果之前。
- 对三次运行分别保存 Session event 序列。
- 让 mock LLM 发出
- 测试方法:使用断言验证 body 调用次数、错误 kind 和是否存在最终
tool/result。 - 验收标准:能独立区分 unknown、policy deny、body/output failure,且修复后原测试通过。
- 恢复方式:移除临时 guard 和 mock response,重新运行目标 package 测试。
- 可能踩坑:工具可能没被模型选中,需选确定性任务或 mock LLM。
- 进一步挑战:模拟
agent/pre-stepreject,观察空 turn 的turn/end。
实践四:实现一个小型扩展
- 任务背景:使用正式扩展机制增加能力,证明具备初步二次开发能力。
- 学习目标:新增一个工具或 prompt section,并补测试。
- 涉及模块:
ctx.tools、ctx.systemPrompt、cordis.yml。 - 推荐修改点:在官方
scratch-plugin中实现workspace_summary,避免第一次实践就修改核心包。 - 实现步骤:
- 参数定义为
path(相对工作区)和maxFiles;禁止..、绝对路径和额外字段。 - canonical output 包含
path、fileCount、按扩展名统计和截断标记;为模型 render 简短文本。 - 用
defineTool声明输入/输出 schema,在apply(ctx)中注册。 - 使用工作区/文件系统公开能力读取目录,不直接依赖某个私有 provider 类。
- 用临时
cordis.yml/Patch 挂载,dump 配置并检查工具 schema。 - 单测覆盖空目录、混合扩展名、maxFiles 截断、越界路径、取消和 dispose。
- mock LLM 调用工具,断言最终 Session
tool/result;有真实 Key 时只做额外人工验收。
- 参数定义为
- 测试方法:纯函数统计测试 → 插件注册测试 → Tool Runtime 集成测试 → mock LLM 主链测试。
- 验收标准:无 API Key 也能完成全部自动化验收;工具只读、路径受限、结果可序列化,卸载后 registry 无残留。
- 可能踩坑:符号链接逃逸、把绝对路径暴露给模型、遍历无上限、output 与 render 不一致、错误地声明并发安全。
- 恢复方式:从 Patch 移除插件并删除 scratch-plugin;工具为只读,不产生业务数据。
- 进一步挑战:增加 keyed UI card 或 Prompt section,但不得把这些表现层代码写进 Tool Runtime 核心。