Chapter 16

实战一:从零写出可运行的 DSH-Lite

目标不是背 API,而是建立能从顶层设计一路推导到源码细节的心智模型。读完本章,你应该能解释“为什么这样设计”,而不仅是“代码在哪里”。

这一章开始写代码。 ZIP 内含 dsh-lite/,是一个教学版骨架:插件容器、event log、tool registry、prompt registry、mock LLM 与 agent loop 都可运行。

1. 第一个里程碑:不用任何 Agent 框架,先手写循环

while (true) {
  const request = buildRequest(session.events)
  const output = await llm(request)
  session.append(output)
  if (output.toolCalls.length === 0) break
  for (const call of output.toolCalls) {
    const result = await tools.execute(call)
    session.append(result)
  }
}

这段代码就是 agent loop 的最小本体。接下来所有 DSH 复杂度,都来自“怎样让它可插拔、可恢复、可隔离、可观察、可取消”。

2. 第二个里程碑:把状态变成事件

session.append({ type: 'turn/start' })
session.append({ type: 'user/message', text })
session.append({ type: 'step/start' })
// request LLM + tools...
session.append({ type: 'step/end' })
session.append({ type: 'turn/end' })

3. 第三个里程碑:把能力从 loop 拆出去

Loop 不 import BashTool、不 import DeepSeekClient,而只拿 ctx.toolsctx.llm。此时你已经从“agent demo”迈进“harness architecture”。

4. 第四个里程碑:把注册变成 effect

工具插件卸载后,工具应该自动消失;prompt 插件卸载后 section 也消失。这一步是插件系统与“普通依赖注入容器”的分水岭。

5. 运行 ZIP 中的示例

cd dsh-lite
npm install
npm run dev

教学版默认使用 Mock LLM,不需要 API key;你可以先观察事件输出,再把 MockLlm 换成真实 DeepSeek adapter。