开源 AI SDK 设计:先把核心接口做薄

开源 AI SDK 设计:先把核心接口做薄

一、SDK 最怕第一版就长成框架

做开源 AI SDK 时,很容易把愿景写得很大:支持所有模型、所有工具、所有 Agent、所有存储。结果第一版接口复杂、依赖很重、用户不知道从哪里开始。SDK 的价值不在于包办一切,而在于提供稳定、薄、可组合的核心能力。

一个好的 AI SDK 应先解决最小闭环:统一请求模型、流式输出、错误处理、重试、配置和类型定义。至于 Agent 编排、记忆、插件和 UI,可以放在扩展层。核心越薄,越容易被不同项目采用。

二、分层结构:核心小,扩展自由

flowchart TD A[Core SDK] --> B[Model Client] A --> C[Streaming] A --> D[Error Types] E[Agent Extension] --> A F[Memory Extension] --> A G[UI Adapter] --> A

核心层只做稳定抽象。比如generatestreamembed这类接口可以统一;不同供应商的特殊能力,可以通过 options 或 provider 扩展。不要为了兼容所有特性,把核心接口设计成巨大的配置对象。用户看一眼就想关掉文档。

扩展层可以更灵活。Agent、工具调用、向量库、前端 Hook、Node 服务端适配,都可以作为独立包。这样用户只安装自己需要的部分,依赖更轻,维护边界也清楚。

三、接口示例:少而稳定

下面是一个简化的 TypeScript 接口。它不追求覆盖所有场景,只表达核心契约。

export interface ModelClient { generate(input: GenerateInput): Promise<GenerateOutput>; stream(input: GenerateInput): AsyncIterable<StreamChunk>; } export interface GenerateInput { messages: Array<{ role: "user" | "system" | "assistant"; content: string }>; temperature?: number; maxTokens?: number; }

这个接口的好处是容易理解。用户能很快知道 SDK 做什么。后续接入不同模型时,只需要实现ModelClient。如果一开始就把记忆、工具、路由、缓存全塞进GenerateInput,核心接口会很快失控。

错误类型也要稳定。认证失败、限流、超时、无效请求、解析失败应该分开。调用方需要根据错误类型决定重试、提示用户还是降级。

四、开源维护:文档比抽象更重要

SDK 开源后,README 是第一个产品界面。用户想知道如何安装、如何调用、如何处理错误、如何接入自己的模型。不要先写长篇架构理念,先给能跑的 20 行代码。开源项目的第一体验,往往决定用户是否继续。

版本策略也要克制。核心接口一旦发布,就不要频繁破坏。实验性能力可以放在experimental命名空间或独立包。这样既能探索,又不会让用户每次升级都痛苦。

最后,依赖要少。AI SDK 不应该因为一个小函数引入半个生态。能用原生能力就用原生能力,必须引入依赖时说明原因。少即是多,在 SDK 里尤其重要。

五、总结

开源 AI SDK 的核心应薄而稳定:模型调用、流式输出、错误类型和配置管理先做好,Agent 与记忆放到扩展层。接口越小,用户越容易理解;依赖越少,项目越容易长期维护。