SDK 架构总览

📑 目录

这是「GSD 全景代码解析」专题的第 38 篇。

在前 37 篇文章中,我们系统梳理了 GSD 的命令系统、工作流编排层、Agent 执行层和上下文工程体系。但有一个关键问题始终悬而未决:工作流文件中频繁出现的 gsd-sdk 调用,究竟是如何工作的?

<!-- 工作流中的典型 SDK 调用 -->
{{ GSD.SDK.query('init.execute') }}
{{ GSD.SDK.runPhase('plan') }}
{{ GSD.SDK.parsePlan(planText) }}

这些调用不是魔法,而是 GSD TypeScript SDK 提供的标准化接口。本篇将揭开这个连接工作流与底层运行时的关键桥梁。


一、SDK 的定位:编排层与运行时的翻译官

在 GSD 的分层架构中,SDK 承担着承上启下的核心角色:

flowchart TB
    subgraph User["用户层"]
        U1[自然语言指令]
    end

    subgraph Orchestration["编排层"]
        W1[工作流 .md]
        A1[Agent .md]
    end

    subgraph SDK_Layer["SDK 层"]
        S1[CLI Transport]
        S2[Phase Runner]
        S3[Context Engine]
        S4[Plan Parser]
        S5[Prompt Builder]
    end

    subgraph Runtime["运行时层"]
        R1[Claude Code]
        R2[Gemini CLI]
        R3[Codex]
        R4[Copilot]
    end

    U1 --> W1
    W1 --> S1
    A1 --> S1
    S1 --> S2
    S2 --> S3
    S2 --> S4
    S2 --> S5
    S1 --> R1
    S1 --> R2
    S1 --> R3
    S1 --> R4

1.1 为什么需要 SDK

工作流和 Agent 文件本质上是带 frontmatter 的 Markdown。它们不能直接操作文件系统、不能发起 HTTP 请求、也不能感知当前运行在哪个 AI IDE 中。这些底层能力必须由一个专门的软件层来提供。

GSD SDK 的设计目标非常清晰:

目标说明
运行时无关同一套工作流可以在 Claude Code、Gemini CLI、Codex 等 15+ 运行时上无缝运行
类型安全全链路 TypeScript 类型覆盖,编译期捕获接口不匹配问题
声明式接口工作流作者只需关心"做什么",不关心"怎么做"
可测试每个模块独立可测,支持 Mock Transport 进行单元测试

1.2 SDK 与 GSD 其他组件的关系

flowchart LR
    subgraph WF["工作流"]
        wf1[execute-phase.md]
        wf2[plan-phase.md]
    end

    subgraph SDK["GSD SDK"]
        sdk1[query/]
        sdk2[plan-parser.ts]
        sdk3[phase-runner.ts]
        sdk4[context-engine.ts]
    end

    subgraph Agent["Agent"]
        ag1[gsd-executor.md]
        ag2[gsd-planner.md]
    end

    subgraph State["状态文件"]
        st1[STATE.md]
        st2[ROADMAP.md]
    end

    wf1 -->|调用| SDK
    ag1 -->|调用| SDK
    SDK -->|读写| State
    SDK -->|加载| Agent
    SDK -->|解析输出| wf2

SDK 不直接执行代码生成或架构设计——那是 Agent 的职责。SDK 提供的是通用基础设施:上下文查询、阶段执行、计划解析、提示词构建、工具调用等。


二、sdk/src/ 目录结构全景

GSD SDK 是一个标准的 TypeScript 项目,核心源码位于 sdk/src/ 目录下。让我们按文件大小和重要性逐一解析:

sdk/src/
├── cli.ts              # 22KB - CLI Transport 入口
├── phase-runner.ts     # 39KB - 阶段执行引擎(最大文件)
├── types.ts            # 23KB - 全系统类型定义
├── gsd-tools.ts        # 20KB - 工具函数集
├── plan-parser.ts      # 14KB - 计划文本解析器
├── prompt-builder.ts   # 12KB - 提示词构建器
├── context-engine.ts   # 11KB - 上下文引擎
├── index.ts            # 5KB  - 包入口
└── query/
    ├── index.ts        # 查询总入口
    ├── init.ts         # init.* 查询实现
    ├── context.ts      # 上下文查询
    ├── state.ts        # 状态文件查询
    └── agent.ts        # Agent 元数据查询

2.1 文件大小背后的架构信号

这 8 个文件的体积分布非常有信息量:

文件大小职责密度架构意义
phase-runner.ts39KB极高核心引擎,包含阶段生命周期管理、Hook 调用、状态转换
types.ts23KB全系统契约,160+ 类型定义,是架构的"源代码"
cli.ts22KBTransport 层主实现,处理 15+ 运行时的适配逻辑
gsd-tools.ts20KB中高工具函数库,被所有上层模块依赖
plan-parser.ts14KB中高将自然语言计划解析为结构化数据
prompt-builder.ts12KB动态提示词组装,支持模板和变量插值
context-engine.ts11KB上下文加载、缓存和预算控制
query/~18KB声明式查询 DSL 的实现

关键洞察phase-runner.ts 以 39KB 独占鳌头,说明阶段执行是 SDK 最复杂的领域。这与我们在第 13 篇《工作流架构总览》中观察到的现象一致——工作流的核心复杂度在于阶段(Phase)的生命周期管理。


三、核心模块详解

3.1 types.ts:架构的契约层

types.ts 是 SDK 中最早应该阅读的文件。它定义了 GSD 全系统的类型契约,相当于架构的"源代码"。

flowchart TB
    subgraph Types["types.ts 核心类型族"]
        T1[GSDContext]
        T2[GSDPhase]
        T3[GSDPlan]
        T4[GSDRuntime]
        T5[GSDTool]
        T6[GSDHook]
    end

    subgraph Relations["类型间关系"]
        T1 -->|contains| T2
        T2 -->|produces| T3
        T4 -->|executes| T2
        T5 -->|called by| T2
        T6 -->|injected into| T2
    end

核心的 6 个类型族覆盖了 SDK 的全部领域:

GSDContext:上下文容器

interface GSDContext {
  project: ProjectMeta;      // 项目元数据(名称、路径、配置)
  state: StateSnapshot;      // STATE.md 的内存表示
  roadmap: RoadmapItem[];    // ROADMAP.md 解析结果
  agents: AgentRegistry;     // 当前可用的 Agent 列表
  references: ReferenceDoc[]; // @reference 加载的参考文档
  budget: ContextBudget;     // 上下文预算(tokens/字符数)
}

GSDContext 是一个不可变快照。每次 SDK 操作都会产生新的 Context 实例,旧版本可供回溯和审计。

GSDPhase:阶段定义

interface GSDPhase {
  id: string;               // 唯一标识,如 "plan", "execute", "verify"
  name: string;             // 人类可读名称
  hooks: PhaseHooks;        // 生命周期钩子(before/after/around)
  allowedAgents: string[];  // 本阶段可调用的 Agent 白名单
  outputFormat: OutputSpec; // 期望的输出格式规范
  exitCriteria: string[];   // 阶段完成的判定条件
}

GSDPhase 是工作流编排的基本执行单元。一个工作流通常由 3-7 个 Phase 串联或并联组成。

GSDPlan:结构化计划

interface GSDPlan {
  version: '2.0';
  phases: PlanPhase[];
  dependencies: Dependency[];  // 阶段间依赖图
  estimatedEffort: Effort;     // 预估工作量
  risks: RiskItem[];           // 风险清单
  checkpoints: Checkpoint[];   // 检查点(可验证的里程碑)
}

Plan 是 GSD spec-driven 开发的核心产物。plan-parser.ts 的职责就是将自然语言计划文本转换为这个结构化对象。

GSDRuntime:运行时抽象

interface GSDRuntime {
  name: RuntimeName;         // 'claude-code' | 'gemini-cli' | 'codex' | ...
  version: string;
  capabilities: Capability[]; // 支持的特性(tools, vision, mcp 等)
  commandPrefix: string;     // 命令前缀(/gsd- 或 $gsd-)
  toolMapping: ToolMap;      // 工具名映射(如 Copilot 的 Read→read)
}

GSDRuntime 是 GSD 实现运行时无关性的关键抽象。CLI Transport 在初始化时会检测当前环境,构造对应的 Runtime 实例。

3.2 phase-runner.ts:阶段执行引擎

作为 SDK 中最大的文件(39KB),phase-runner.ts 是整个系统的"心脏"。

flowchart LR
    subgraph Input["输入"]
        I1[Phase ID]
        I2[Context]
        I3[Agent 选择]
    end

    subgraph Runner["Phase Runner"]
        R1[验证阶段权限]
        R2[执行 beforeHooks]
        R3[调用 Agent]
        R4[解析 Agent 输出]
        R5[执行 afterHooks]
        R6[更新 STATE.md]
        R7[执行 aroundHooks]
    end

    subgraph Output["输出"]
        O1[新 Context]
        O2[PhaseResult]
    end

    I1 --> R1
    I2 --> R1
    I3 --> R1
    R1 --> R2
    R2 --> R3
    R3 --> R4
    R4 --> R5
    R5 --> R6
    R6 --> R7
    R7 --> O1
    R7 --> O2

    R3 -.->|aroundHook 包裹| R3

Phase Runner 的执行流程遵循严格的生命周期契约

  1. 验证(Validation):检查当前 Runtime 是否支持该 Phase,Agent 是否在白名单中
  2. 前置钩子(beforeHooks):加载上下文、设置环境变量、记录日志
  3. 执行(Execution):通过 CLI Transport 向 Runtime 发送指令,启动 Agent
  4. 解析(Parsing):使用 plan-parser.ts 将 Agent 的自然语言输出转为结构化数据
  5. 后置钩子(afterHooks):验证输出格式、更新状态文件、触发副作用
  6. 环绕钩子(aroundHooks):在 before/after 之间包裹,用于重试、超时、熔断等横切逻辑

Hook 系统是 Phase Runner 的灵魂

interface PhaseHooks {
  before?: HookFn[];   // 同步执行,顺序调用
  after?: HookFn[];    // 同步执行,顺序调用
  around?: AroundHookFn[]; // 嵌套执行,类似 Koa 的洋葱模型
  onError?: ErrorHookFn[]; // 错误处理,支持重试和降级
}

Hook 机制让 GSD 可以在不修改核心执行逻辑的情况下,插入自定义行为。例如:

  • 审计 Hook:记录每个 Phase 的输入输出,用于事后分析
  • 预算 Hook:在 before 阶段检查上下文预算,在 after 阶段更新已用量
  • 重试 Hook:around 级别捕获异常,按指数退避策略重试
  • 通知 Hook:after 阶段发送 Webhook 通知外部系统

3.3 cli.ts:CLI Transport 层

cli.ts 是 SDK 与外部世界交互的唯一出口。它屏蔽了 15+ 运行时的差异,提供统一的命令接口。

flowchart TB
    subgraph SDK_Internal["SDK 内部"]
        S1[phase-runner.ts]
        S2[query/index.ts]
        S3[gsd-tools.ts]
    end

    subgraph Transport["CLI Transport"]
        T1[命令序列化]
        T2[运行时检测]
        T3[适配器选择]
        T4[命令发射]
        T5[输出捕获]
    end

    subgraph Runtimes["目标运行时"]
        R1[Claude Code]
        R2[Gemini CLI]
        R3[Codex]
        R4[Copilot]
        R5[Cursor]
    end

    S1 --> T1
    S2 --> T1
    S3 --> T1
    T1 --> T2
    T2 --> T3
    T3 -->|适配器 A| T4
    T3 -->|适配器 B| T4
    T4 --> R1
    T4 --> R2
    T4 --> R3
    T4 --> R4
    T4 --> R5
    R1 --> T5
    R2 --> T5
    T5 --> S1

运行时检测机制

CLI Transport 在初始化时会通过环境变量和文件系统探测当前运行时:

function detectRuntime(): GSDRuntime {
  if (process.env.CLAUDE_CODE) {
    return createClaudeCodeRuntime();
  }
  if (process.env.GEMINI_CLI_VERSION) {
    return createGeminiRuntime();
  }
  if (existsSync('~/.codex/config.toml')) {
    return createCodexRuntime();
  }
  // ... 更多检测逻辑
  return createGenericRuntime(); // 兜底
}

命令适配策略

不同运行时对命令格式、工具调用和输出解析有不同的要求。CLI Transport 通过适配器模式处理这些差异:

运行时特殊适配
Claude Code原生 Custom Slash Commands,直接透传
CodexSkills 格式,TOML 配置包裹
Copilot工具名映射(Read→read, Bash→execute)
Cursor.cursor/rules 文件集成
Cline.clinerules 规则文件注入

输出捕获与解析

Agent 的输出通常是自然语言文本。CLI Transport 负责:

  1. 流式捕获:实时读取 stdout/stderr
  2. 边界检测:通过特殊标记(如 <!-- GSD_OUTPUT_BEGIN -->)识别结构化内容
  3. 错误分类:区分运行时错误(工具调用失败)和业务错误(Agent 报告的计划不可行)
  4. 超时处理:为长时间运行的 Agent 设置合理的超时阈值

3.4 plan-parser.ts:从自然语言到结构化数据

plan-parser.ts 解决了一个核心问题:Agent 输出的是自然语言,但工作流需要结构化数据

flowchart LR
    subgraph Input["输入"]
        I1[自然语言计划文本]
    end

    subgraph Parser["Plan Parser"]
        P1[分块:按标题层级切分]
        P2[提取:正则匹配关键字段]
        P3[验证:JSON Schema 校验]
        P4[补全:填充默认值]
    end

    subgraph Output["输出"]
        O1[GSDPlan 对象]
    end

    I1 --> P1
    P1 --> P2
    P2 --> P3
    P3 --> P4
    P4 --> O1

Parser 采用多策略容错设计:

  1. 显式标记优先:如果 Agent 输出了 \``gsd-plan` 代码块,直接按 JSON 解析
  2. Markdown 结构解析:如果没有显式标记,通过标题层级和列表结构推断层级关系
  3. 正则提取:针对常见模式(如 "Risk: XXX"、"Estimated: YYY hours")使用正则提取关键字段
  4. LLM 后处理:如果前三种策略都失败,构造一个精简的 prompt 让 LLM 重新格式化输出

3.5 context-engine.ts:上下文加载与预算控制

context-engine.ts 是我们在第 31-37 篇中深入讨论的 Context Engineering 的工程实现。

flowchart TB
    subgraph Request["查询请求"]
        R1[query('init.execute')]
    end

    subgraph Engine["Context Engine"]
        E1[解析查询 DSL]
        E2[加载基础上下文]
        E3[应用 @reference]
        E4[计算 token 预算]
        E5[优先级排序]
        E6[截断或分页]
    end

    subgraph Output["输出"]
        O1[裁剪后的 Context]
        O2[预算使用报告]
    end

    R1 --> E1
    E1 --> E2
    E2 --> E3
    E3 --> E4
    E4 --> E5
    E5 --> E6
    E6 --> O1
    E6 --> O2

Context Engine 的核心算法是优先级驱动的预算分配

function allocateBudget(context: GSDContext, budget: ContextBudget): TrimmedContext {
  const items = flattenContext(context);
  
  // 按优先级排序(必需 > 重要 > 可选)
  const sorted = items.sort((a, b) => b.priority - a.priority);
  
  let usedTokens = 0;
  const selected: ContextItem[] = [];
  
  for (const item of sorted) {
    if (usedTokens + item.tokenCount <= budget.maxTokens) {
      selected.push(item);
      usedTokens += item.tokenCount;
    } else if (budget.allowTruncation) {
      const remaining = budget.maxTokens - usedTokens;
      selected.push(truncate(item, remaining));
      break;
    }
  }
  
  return { items: selected, usedTokens, dropped: sorted.length - selected.length };
}

3.6 prompt-builder.ts:动态提示词组装

prompt-builder.ts 将静态模板和动态变量结合,生成最终发送给 LLM 的提示词。

interface PromptTemplate {
  id: string;
  template: string;           // 支持 {{variable}} 插值
  partials: string[];         // 子模板引用
  version: string;            // SemVer,用于缓存失效
  requiredVars: string[];     // 必填变量列表
}

function buildPrompt(template: PromptTemplate, vars: Record<string, any>): string {
  // 1. 验证必填变量
  validateVars(template.requiredVars, vars);
  
  // 2. 加载并渲染 partials
  const partials = template.partials.map(p => loadPartial(p));
  
  // 3. 主模板插值
  let output = template.template;
  for (const [key, value] of Object.entries(vars)) {
    output = output.replace(new RegExp(`{{\\s*${key}\\s*}}`, 'g'), String(value));
  }
  
  // 4. 拼接 partials
  return partials.join('\n---\n') + '\n---\n' + output;
}

Prompt Builder 支持模板继承条件渲染,使得工作流作者可以用声明式语法构建复杂的提示词:

<!-- 模板示例 -->
{{> header}}

{{#if roadmap}}
## 当前路线图
{{roadmap}}
{{/if}}

{{#each agents}}
- {{name}}: {{description}}
{{/each}}

{{> footer}}

3.7 gsd-tools.ts:工具函数库

gsd-tools.ts 是 SDK 的"瑞士军刀",提供各模块共享的底层工具函数:

类别函数示例用途
文件操作readFileSafe, writeFileAtomic带编码检测和原子写入的文件 I/O
路径解析resolveGSDPath, findProjectRoot从任意位置定位 GSD 项目根目录
文本处理slugify, extractFrontmatterMarkdown frontmatter 解析和字符串处理
Git 集成getGitStatus, getDiffStats读取仓库状态,用于执行前的基线记录
校验validateAbbrlink, checkSchemaabbrlink 唯一性检查和 JSON Schema 验证
日志logPhaseStart, logPhaseEnd结构化日志,支持 JSONL 格式

这些工具函数遵循纯函数优先原则:无副作用、输入确定则输出确定、便于单元测试。

3.8 query/ 目录:声明式查询 DSL

query/ 目录实现了 GSD SDK 的声明式查询接口,让工作流可以用字符串表达式获取上下文:

// 工作流中的调用
SDK.query('init.execute');      // 加载 execute 阶段的初始化上下文
SDK.query('context.agents');     // 获取当前可用的 Agent 列表
SDK.query('state.roadmap');      // 获取路线图状态
SDK.query('agent.gsd-executor'); // 获取特定 Agent 的元数据
flowchart LR
    subgraph Query["查询表达式"]
        Q1["init.execute"]
        Q2["context.agents"]
        Q3["state.roadmap"]
    end

    subgraph Router["Query Router"]
        R1[按命名空间分发]
    end

    subgraph Handlers["处理模块"]
        H1[init.ts]
        H2[context.ts]
        H3[state.ts]
        H4[agent.ts]
    end

    Q1 --> R1
    Q2 --> R1
    Q3 --> R1
    R1 -->|namespace=init| H1
    R1 -->|namespace=context| H2
    R1 -->|namespace=state| H3
    R1 -->|namespace=agent| H4

Query DSL 的设计借鉴了 GraphQL 的思想:一次查询,精确获取所需数据,避免过度加载。每个 query handler 都返回一个标准的 QueryResult<T>,包含数据、元信息和缓存控制头。


四、模块依赖关系图

flowchart TB
    subgraph Entry["入口层"]
        IDX[index.ts]
        CLI[cli.ts]
    end

    subgraph Core["核心层"]
        PR[phase-runner.ts]
        QE[query/index.ts]
    end

    subgraph Engine["引擎层"]
        CE[context-engine.ts]
        PB[prompt-builder.ts]
        PP[plan-parser.ts]
    end

    subgraph Foundation["基础层"]
        GT[gsd-tools.ts]
        TP[types.ts]
    end

    IDX --> CLI
    IDX --> PR
    IDX --> QE
    CLI --> PR
    CLI --> GT
    PR --> CE
    PR --> PB
    PR --> PP
    PR --> GT
    QE --> CE
    QE --> GT
    CE --> GT
    PB --> GT
    PP --> GT
    GT --> TP
    CE --> TP
    PB --> TP
    PP --> TP
    PR --> TP
    CLI --> TP

4.1 依赖关系的设计原则

从依赖图中可以观察到三个重要原则:

  1. 单向依赖:所有箭头都向下或平级,不存在循环依赖。types.ts 位于最底层,被所有人依赖但不依赖任何人。

  2. 入口隔离index.ts 是唯一的公共 API 入口,内部模块不直接暴露。这种"宽入口、窄出口"的设计便于后续重构。

  3. 工具下沉gsd-tools.ts 被所有上层模块使用,但它只依赖 types.ts。这意味着工具函数的修改影响面可控。


五、TypeScript 类型系统的设计哲学

GSD SDK 的类型系统不是简单的"加类型注解",而是架构设计的表达工具

5.1 区分系统类型与业务类型

// ===== 系统类型(SDK 内部使用)=====
interface TransportAdapter {
  send(command: Command): Promise<Response>;
  supports(capability: Capability): boolean;
}

// ===== 业务类型(工作流和 Agent 可见)=====
interface GSDPhase {
  id: PhaseId;
  hooks: PhaseHooks;
  // ...
}

// ===== 边界类型(序列化/反序列化)=====
interface SerializedPlan {
  version: '2.0';
  phases: Array<Pick<GSDPlan, 'id' | 'name'>>;
}

系统类型关注"如何运行",业务类型关注"做什么",边界类型关注"如何传输"。三者严格分离,避免概念混淆。

5.2 branded type 防止标识符混用

GSD 使用 TypeScript 的** branded type** 技术,防止不同领域的字符串标识符被错误混用:

type PhaseId = string & { __brand: 'PhaseId' };
type AgentId = string & { __brand: 'AgentId' };
type Abbrlink = string & { __brand: 'Abbrlink' };

function createPhaseId(id: string): PhaseId {
  return id as PhaseId;
}

// 编译期错误:不能将 AgentId 赋值给 PhaseId
const agentId: AgentId = createAgentId('gsd-executor');
const phaseId: PhaseId = agentId; // ❌ Type Error

这种设计在大型代码库中特别有价值——当系统有 60+ 工作流、33+ Agent、80+ 命令时,标识符类型的混淆是导致 bug 的高频原因。

5.3 条件类型实现运行时特性检测

type RuntimeTools<T extends GSDRuntime> = 
  T extends { capabilities: infer C }
    ? C extends (infer U)[]
      ? U extends { type: 'tool' }
        ? U['name']
        : never
      : never
    : never;

// 使用:获取 Claude Code 支持的工具名
type ClaudeTools = RuntimeTools<ClaudeCodeRuntime>;
// → 'Read' | 'Bash' | 'Edit' | 'Glob' | ...

条件类型让 SDK 在编译期就能根据运行时特性进行类型收窄,实现"一个 SDK,多种类型体验"。


六、CLI Transport 的扩展机制

CLI Transport 的设计预留了三个扩展点:

6.1 自定义 Runtime 适配器

interface RuntimeAdapterFactory {
  detect(): boolean;              // 是否匹配当前环境
  create(): GSDRuntime;           // 构造 Runtime 实例
}

// 注册自定义适配器
SDK.registerRuntimeAdapter({
  detect: () => existsSync('.my-custom-runtime'),
  create: () => ({
    name: 'my-runtime',
    capabilities: ['tools', 'mcp'],
    // ...
  })
});

6.2 自定义 Hook

SDK.registerHook('execute', {
  around: async (ctx, next) => {
    console.time('phase-execute');
    const result = await next();
    console.timeEnd('phase-execute');
    return result;
  }
});

6.3 自定义 Query Handler

SDK.registerQuery('custom', async (params, context) => {
  const data = await fetchCustomData(params);
  return { data, meta: { cached: false } };
});

这三个扩展点遵循开闭原则:SDK 核心稳定不变,新需求通过扩展机制实现,无需修改源码。


七、小结

本文系统解析了 GSD TypeScript SDK 的架构设计:

  1. 定位:SDK 是连接工作流编排层与底层运行时的翻译官和基础设施层,不是业务逻辑的执行者
  2. 目录结构:8 个核心文件 + query/ 目录,总代码量约 164KB,其中 phase-runner.ts(39KB)和 types.ts(23KB)承载最多架构信息
  3. 模块关系:单向依赖、无循环依赖、types.ts 作为公共契约层
  4. 类型系统:160+ 类型定义,branded type 防混用,条件类型实现编译期特性检测
  5. CLI Transport:适配器模式屏蔽 15+ 运行时差异,流式输出捕获,多策略容错解析
  6. 扩展机制:Runtime 适配器、Phase Hook、Query Handler 三个扩展点,支撑 SDK 的可持续发展

SDK 的设计充分体现了 GSD 的工程成熟度:它不是为某个特定场景快速 hack 出来的工具,而是经过深思熟虑的平台级基础设施。工作流和 Agent 作者可以在完全不关心底层运行时差异的情况下,编写出可移植、可测试、可维护的编排逻辑。


下一篇预告: 第 39 篇《Phase Runner 核心引擎》——深入剖析 phase-runner.ts 的 39KB 源码,详解阶段生命周期管理、Hook 执行模型、状态机转换和错误恢复机制,带你领略 GSD 最核心的执行引擎。