npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-model-unified-sdk

v0.1.1

Published

Unified provider SDK demo with native Node.js adapters.

Downloads

20

Readme

ai-model-unified-sdk

背景

在接入多家大模型服务时,不同厂商通常在以下方面存在差异:

  • 调用入口和参数命名不一致
  • 流式输出格式不同(SSE 字段、增量内容位置不同)
  • 鉴权方式、模型名称、错误结构存在差别

这些差异会让上层业务代码重复处理适配逻辑,导致开发效率下降、维护成本升高。
本项目旨在提供一个统一的 SDK 抽象层,屏蔽底层厂商差异,让业务方通过一致接口完成模型调用。

设计思路

本项目采用“统一入口 + 厂商适配 + 协议约束”的分层设计:

  1. 统一入口层:对外暴露稳定 API(如统一创建模型实例、统一聊天调用方法)。
  2. 工厂层:根据 provider 配置动态创建具体适配器,避免业务代码直接依赖某个厂商实现。
  3. 适配器层:将统一请求转换为厂商请求,再将厂商响应规范化为统一输出。
  4. 核心能力层:沉淀通用能力,如流式处理、SSE 解析、错误处理和环境变量读取。
  5. 规范层:通过 provider spec 明确适配器契约,保证新增厂商时行为一致、扩展可控。

整体目标是:

  • 对业务透明:切换模型服务尽量不改业务代码
  • 对扩展友好:新增厂商仅需新增适配器并遵循规范
  • 对维护稳定:核心逻辑集中复用,减少重复实现

设计模式

项目中主要体现了以下设计模式:

1) 工厂模式(Factory Pattern)

  • 通过工厂模块按 provider 选择并创建对应适配器实例。
  • 优点:将“对象创建”与“对象使用”解耦,业务层无需了解具体类名和初始化细节。

2) 适配器模式(Adapter Pattern)

  • 每个厂商的适配器负责协议转换:统一输入 -> 厂商格式,厂商输出 -> 统一格式。
  • 优点:隔离外部差异,统一上层调用方式,降低供应商切换成本。

3) 策略模式(Strategy Pattern)

  • 不同 provider 的处理逻辑可视为可替换策略,在运行时根据配置切换。
  • 优点:避免大量 if/else 侵入业务流程,增强可扩展性与可测试性。

4) 模板方法思想(Template Method, 轻量体现)

  • 统一调用流程保持稳定(参数准备 -> 发起请求 -> 解析响应 -> 返回结果),差异步骤在适配器中重写。
  • 优点:保证主流程一致性,同时允许局部差异化实现。

使用方法

1) 安装与运行前提

  • 运行环境:node >= 18
  • 包名:ai-model-unified-sdk
  • 安装(示例):npm i ai-model-unified-sdk
  • 同时支持 require(CommonJS)和 import(ESM)

2) 配置环境变量(推荐)

项目内已有示例文件 .env.example,你需要复制并填写为 .env(或放到 demo/.env)。

至少要为你所选的 DEMO_PROVIDER 对应的 provider 配齐以下字段:

  • alibabaALIBABA_API_KEYALIBABA_BASE_URLALIBABA_MODEL
  • baiduBAIDU_API_KEYBAIDU_BASE_URLBAIDU_MODEL
  • zhipuZHIPU_API_KEYZHIPU_BASE_URLZHIPU_MODEL

说明:

  • DEMO_PROVIDER 默认为 alibaba
  • SDK 在运行时会读取当前工作目录下的 .env(或 demo/.env),并作为默认配置

3) 用 SDK 进行流式对话(streamChat)

SDK 目前以“单轮 prompt -> 一次对话”的方式工作(底层会把 prompt 作为 messages: [{ role: 'user', content: prompt }] 发送)。

下面示例演示如何接收流式事件并打印文本增量:

require('dotenv').config();

const { streamChat } = require('ai-model-unified-sdk');

async function main() {
  const stream = await streamChat({
    provider: 'zhipu',
    prompt: '用两句话介绍什么是统一模型网关。',
    // model: 'glm-4-flash', // 可选:优先 options.model,其次环境变量,再次默认值
  });

  for await (const event of stream) {
    if (event.type === 'text-delta') {
      process.stdout.write(event.text);
    }

    if (event.type === 'finish') {
      console.log(`\n[finish] reason=${event.reason}`);
    }

    if (event.type === 'usage') {
      console.log('\n[usage]', event.usage);
    }
  }
}

main().catch(err => {
  console.error('failed:', err?.message ?? err);
  process.exitCode = 1;
});

如果你使用 ESM(例如 .mjs 文件,或项目 package.jsontype=module),可直接使用 import

import { streamChat } from 'ai-model-unified-sdk';

const stream = await streamChat({
  provider: 'zhipu',
  prompt: '请用一句话介绍统一模型 SDK。',
});

for await (const event of stream) {
  if (event.type === 'text-delta') process.stdout.write(event.text);
}

流式事件 event.type 取值:

  • text-delta:增量文本片段,字段:event.text
  • finish:结束事件,字段:event.reason(例如 stop 或厂商的 finish_reason)
  • usage:用量信息(透传厂商返回的 json.usage),字段:event.usage

4) 辅助方法:streamChatToStdout

如果你只想“边生成边输出”,可以直接用 streamChatToStdout

require('dotenv').config();

const { streamChatToStdout } = require('ai-model-unified-sdk');

async function main() {
  const output = await streamChatToStdout({
    provider: 'alibaba',
    prompt: '用简洁中文介绍你自己,并给出三条能力要点。',
  });

  console.log('\nfinishReason:', output.finishReason);
  console.log('usage:', output.usage);
}

main().catch(err => {
  console.error('failed:', err?.message ?? err);
  process.exitCode = 1;
});

5) 命令行 demo

包内定义了命令 ai-model-unified-sdk-demo(底层会调用 streamChatToStdout)。

示例:

npx ai-model-unified-sdk-demo --provider zhipu --model glm-4-flash --prompt "你好,帮我写一段介绍。"

也可以直接用本仓库运行(假设在仓库根目录):

node index.js --provider zhipu --model glm-4-flash --prompt "你好,帮我写一段介绍。"

可扩展建议

  • 新增 provider 时,优先复用 src/coresrc/utils 的通用能力。
  • src/spec/provider-spec.js 中补充能力声明,保持契约清晰。
  • 为新适配器补充最小可运行示例,验证普通调用与流式调用均可工作。

目录参考

当前项目核心目录可理解为:

  • src/factory:统一创建入口
  • src/adapters:各厂商适配实现
  • src/core:通用核心能力(如流式会话)
  • src/spec:适配协议约束
  • src/utils:环境变量、SSE 等通用工具
  • examples:示例调用

目标总结

该 SDK 的核心价值是:以统一接口承载多模型服务接入复杂度,让上层业务聚焦在产品能力而非供应商细节。