domi开发者文档
DOMI · DOCS

模型运行时

本页回答四个问题:模型层怎么统一?能力矩阵怎么用?结构化输出和重试怎么兜底?出错了会怎样? packages/model —— ModelProvider 接口、AI SDK 适配、能力矩阵、结构化输出、重试。 贯穿例子:给登录接口加限流——domi 每轮调用模型,输出流式回到事件流。

先说结论

用到的词

词 意思
ModelProvider kernel 认识的唯一模型接口。
ModelEvent 模型输出的统一事件(五种)。
能力矩阵 静态声明的模型能力(toolCall / vision 等)。
适配器 把 AI SDK 的流翻译成 ModelEvent 的层。
厂商模板 纯数据的厂商配置(协议 / 地址 / 能力 / 适配器)。

1. 总体流程

模型层归约

2. ModelProvider:kernel 认识的唯一接口

interface ModelProvider {
  readonly id: string
  readonly capabilities: ModelCapabilities   // 静态声明的能力矩阵
  generate(req: ModelRequest, signal: AbortSignal): AsyncIterable<ModelEvent>
}

kernel 不 import 任何 provider SDK(INV-02),只 import 这里的类型。

ModelEvent 五种:

类型 含义
delta 输出文本增量
reason 思维链文本
tool-call 请求调用工具
usage 用量(原始字段,原样透传)
error 错误(带 recoverable 标记)

两个关键设计:

3. 工厂与厂商模板

factory.ts 是唯一知道「有哪些 provider」的地方。实现经 AI SDK(ai-sdk-provider.ts):createOpenAI / createAnthropic / createOpenAICompatible。

厂商知识在 packages/config/src/vendors.ts(guard:providers 扫全仓,SDK 包名只允许出现在 factory.ts):

厂商 协议 / 适配
openai 官方 Responses API
anthropic 官方
deepseek openai 兼容
gemini 官方
custom 自选协议

每个模板是纯数据:协议、默认地址、默认能力、惯用环境变量名、用哪种适配器。

4. 结构化输出与重试

模块 干什么
structured.ts 统一走 JSON Schema;对不支持 structured output 的模型用「Zod schema → 提示词约束 + 解析重试」兜底,接口对上层一致(generateStructured / StructuredOutputError)
retry.ts 可恢复错误的有限重试(流式中断等)
probe.ts /v1/models 探测(模型清单自动发现;探测失败用配置里的 models 清单兜底)
embedding.ts L3 语义记忆的向量嵌入(嵌入不支持 → EmbeddingUnsupportedError,语义检索降级 FTS)
stub-provider.ts CI 里的模型替身(真实 LLM 调用不进 CI 门禁)

5. 出错了怎么办:限流做到第 2 步,模型流中断了

  1. 流式中断。retry.ts 判定为可恢复错误 → 有限重试(有次数上限)。重试仍失败 → 落 model.delta 流的 error 事件。
  2. 调用了未声明的能力。发请求前抛错——不是等到响应才失败。去配置里显式打开该能力。
  3. 嵌入不支持。EmbeddingUnsupportedError → 语义检索降级 FTS 全文检索,记忆功能继续可用。
  4. 探测失败(模型清单发现不了)。用配置里的 models 清单兜底。
  5. 模型返回不可解析的结构化输出。StructuredOutputError → 按提示词约束重试解析;仍失败则上层按错误处理。

一张表看全部情况

情况 domi 做什么 你要做什么
流式中断 有限重试;仍失败落 error 事件 不用管(或看轨迹)
能力未声明 发请求前抛错 在配置里显式打开
嵌入不支持 降级 FTS 不用管
模型清单探测失败 用配置 models 兜底 在配置里写明 models
结构化输出解析失败 重试解析;仍失败按错误处理 不用管

6. 可靠性靠什么

  1. 接口单一。所有厂商归约成一个 ModelProvider,kernel 不用知道厂商差异。
  2. 能力静态声明。错配在发请求前暴露,不是运行中。
  3. usage 原样透传。缓存命中判断依赖原始字段,透传保证不丢输入。
  4. 兜底阶梯。结构化输出有提示词约束兜底;嵌入有 FTS 兜底;探测有配置兜底。
  5. CI 用替身。真实 LLM 不进 CI 门禁,测试确定性由 stub-provider 保证。

已知限制

代码在哪里

主题 位置
ModelProvider 接口与 ModelEvent packages/model/src/provider.ts
能力矩阵 packages/model/src/capability.ts
AI SDK 适配 packages/model/src/ai-sdk-provider.ts
厂商注册表(唯一) packages/model/src/factory.ts
厂商模板 packages/config/src/vendors.ts
结构化输出 / 重试 / 探测 / 嵌入 packages/model/src/{structured,retry,probe,embedding}.ts
CI 模型替身 packages/model/src/stub-provider.ts

测试:packages/model/test/(能力矩阵、结构化输出、重试、factory 注册表;全部打桩)。

相关