Namespace Extension(命名空间扩展)

用 Provider 名字作为 key,将各 Provider 专有数据挂载在统一结构的命名空间下,实现零冲突的开放式扩展,无需修改核心接口。

定义

Namespace Extension(命名空间扩展)是一种接口扩展策略:核心接口预留一个 providerMetadata 或类似字段,每个 Provider 把自己专有的数据挂在以自己命名的 key 下,调用方通过命名空间前缀区分来源。

vercel/ai 中的实现

typescript
// LanguageModelV4GenerateResult
providerMetadata?: {
  [provider: string]: Record<string, JSONValue>;
  openai?: {
    acceptedPredictionTokens?: number;
    rejectedPredictionTokens?: number;
    logprobs?: ...;
  };
  anthropic?: { ... };
}

OpenAI 的 acceptedPredictionTokens(预测缓存命中数)只在 OpenAI 实现里有意义,通过 providerMetadata.openai.* 透传到框架层,不污染标准 LanguageModelV4GenerateResult 接口。

设计价值

  • 零冲突:每个 Provider 的数据在独立命名空间,不同 Provider 的同名字段不会互相覆盖
  • 开放扩展:新 Provider 无需修改核心类型定义,直接在自己的命名空间下添加字段
  • 向后兼容providerMetadata 整体是 optional,不用 Provider 不受影响

与 Plugin System 的区别

Plugin System 通常需要注册中心生命周期管理。Namespace Extension 是更轻量的模式——不需要注册,约定 key 即可,TypeScript 的 index signature 提供类型安全的开放式扩展点。

典型用途

  • 框架核心接口需要支持 Provider 专有能力扩展
  • 各 Provider 的专有字段数量不确定,且互不相关
  • 调用方需要可选地访问 Provider 特定数据