# llm-kit
**Repository Path**: thzxx/llm-kit
## Basic Information
- **Project Name**: llm-kit
- **Description**: 🧰 统一 LLM API 客户端 — 一套 API 同时支持 DeepSeek、Ollama、Kimi、MiniMax、MiMo、智谱 GLM、OpenAI 兼容。TypeScript,零依赖,ESM+CJS 双格式,Node/Deno/Bun/浏览器同构。
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-05-19
- **Last Updated**: 2026-05-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 🧰 llm-kit
**统一的大语言模型 API 客户端**
一个库同时支持 **Anthropic** · **DeepSeek** · **Ollama** · **Kimi** · **MiniMax** · **MiMo** · **智谱** · **OpenAI 兼容** API
[](LICENSE)
[](https://www.typescriptlang.org/)
[](https://nodejs.org/)
[](#安装)
[快速开始](#快速开始) · [架构](#架构) · [API 文档](#api-参考) · [中间件](#中间件) · [扩展 Provider](#扩展新-provider) · [Gitee](https://gitee.com/thzxx/llm-kit)
---
## ✨ 特性
| 特性 | 说明 |
|------|------|
| 🔮 **统一接口** | `createClient('deepseek')` 同一套 API,切换 Provider 零成本 |
| 🧩 **组合式架构** | 策略对象 + 中间件链 |
| 🌊 **原生流式** | TransformStream 管道,零中间层 AsyncGenerator 包装 |
| 🔧 **函数调用** | 8 个 Provider 全部支持 Tool Calling |
| 🧠 **思考模式** | Anthropic / DeepSeek / Ollama / Kimi / MiniMax / MiMo / 智谱 7 个 Provider |
| 📄 **结构化输出** | JSON 模式 + Schema,全部 Provider 支持 |
| 🖼️ **多模态** | 图片 · 视频 · 音频 · 文件 |
| 🔌 **中间件** | 日志、指标、缓存、限流 — 可组合的横切关注点 |
| ⚡ **韧性** | 可配重试(指数退避)、超时、自定义 fetch |
| 🛡️ **错误体系** | `AuthError` · `RateLimitError` · `TimeoutError` · `ValidationError` · `ConnectionError` |
| 📦 **双格式** | ESM + CJS + TypeScript 声明文件 |
| 🌐 **同构** | Node 18+ · Deno · Bun · 现代浏览器 |
---
## 📦 安装
```bash
npm install llm-kit
# or
yarn add llm-kit
# or
pnpm add llm-kit
```
从 Git 安装:
```bash
npm install git+https://gitee.com/thzxx/llm-kit.git
```
---
## ⚡ 快速开始
### 30 秒上手
```ts
import { createClient } from 'llm-kit';
const client = createClient('deepseek', {
apiKey: process.env.DEEPSEEK_API_KEY,
});
const response = await client.chat({
model: 'deepseek-v4-pro',
messages: [{ role: 'user', content: '解释 JavaScript 事件循环' }],
stream: false,
});
console.log(response.choices[0].message.content);
```
### 切换 Provider
改一个字符串,其余代码不变:
```ts
// OpenAI(官方)
const client = createClient('openai', { apiKey: 'sk-...' });
// OpenAI 兼容(vLLM / LiteLLM 等)
const client = createClient('openai-compatible', { baseURL: 'http://localhost:8000' });
// Anthropic(官方)
const client = createClient('anthropic', { apiKey: 'sk-ant-...' });
// Anthropic 兼容(国内厂商 Anthropic 格式 API)
const client = createClient('anthropic-compatible', {
apiKey: 'sk-...',
baseURL: 'https://api.xiaomimimo.com/v1',
});
// DeepSeek
const client = createClient('deepseek', { apiKey: 'sk-...' });
// Ollama(本地)
const client = createClient('ollama');
// Kimi
const client = createClient('kimi', { apiKey: 'sk-...' });
```
### 支持的 Provider
| Provider | 创建方式 | 默认 baseURL |
|----------|----------|-------------|
| OpenAI | `createClient('openai', { apiKey })` | `https://api.openai.com/v1` |
| OpenAI 兼容 | `createClient('openai-compatible', { baseURL })` | 需指定 |
| Anthropic | `createClient('anthropic', { apiKey })` | `https://api.anthropic.com` |
| Anthropic 兼容 | `createClient('anthropic-compatible', { apiKey, baseURL })` | 需指定 |
| DeepSeek | `createClient('deepseek', { apiKey })` | `https://api.deepseek.com` |
| Ollama | `createClient('ollama')` | `http://localhost:11434` |
| Kimi | `createClient('kimi', { apiKey })` | `https://api.moonshot.cn` |
| MiniMax | `createClient('minimax', { apiKey })` | `https://api.minimaxi.com` |
| MiMo | `createClient('mimo', { apiKey })` | `https://api.xiaomimimo.com/v1` |
| 智谱 | `createClient('zhipu', { apiKey })` | `https://open.bigmodel.cn/api/paas/v4` |
---
## 🏗️ 架构
llm-kit 采用**组合式架构**,通过策略对象和中间件链构建行为。
### 设计原则
1. **组合优于继承** — 行为来自策略对象
2. **依赖注入** — HTTP 层可替换,便于测试
3. **中间件** — 横切关注点独立于核心逻辑
4. **开闭原则** — 新增 Provider 只需注册,不改已有代码
### 架构图
```
┌─────────────────────────────────────────────────────────┐
│ ComposableClient │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Auth │ │ Request │ │ Response │ │ Stream │ │
│ │ Strategy │ │ Builder │ │Normalizer│ │ Parser │ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Middleware Chain │ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────────────┐ │ │
│ │ │Logger│→ │Metric│→ │Cache │→ │ HTTP Layer │ │ │
│ │ └──────┘ └──────┘ └──────┘ └──────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### 策略层
每个职责独立为可替换的策略对象:
| 策略 | 职责 | 内置实现 |
|------|------|---------|
| `AuthStrategy` | 认证头生成 | `BearerAuth` / `ApiKeyHeaderAuth` / `NoAuth` |
| `ErrorMappingStrategy` | HTTP 错误映射 | `DefaultErrorMapping` / `ChainedErrorMapping` |
| `StreamParserStrategy` | 流格式解析 | `SSEStreamParser` / `NDJSONStreamParser` |
| `RequestBuilderStrategy` | 请求体构建 | 各 Provider 独立实现 |
| `ResponseNormalizerStrategy` | 响应归一化 | 各 Provider 独立实现 |
### 流式管道
使用 TransformStream 实现零中间层的流式处理:
```
字节流 → parseTransform → mapTransform → ReadableStream
```
---
## 🌊 流式输出
### 方式一:逐 chunk 读取
```ts
const stream = await client.chat({
model: 'deepseek-v4-pro',
messages: [{ role: 'user', content: '写一首诗' }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}
```
### 方式二:统一事件流(推荐)
```ts
const eventStream = await client.chatStream({
model: 'deepseek-v4-pro',
messages: [{ role: 'user', content: '写一首诗' }],
});
const reader = eventStream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
switch (value.type) {
case 'content': process.stdout.write(value.text); break;
case 'reasoning': console.log('[思考]', value.text); break;
case 'tool_call': console.log('[工具]', value.tool_call); break;
case 'usage': console.log('[统计]', value.usage); break;
case 'done': console.log('[完成]', value.finish_reason); break;
}
}
```
---
## 🔌 中间件
中间件采用洋葱模型,请求从外到内,响应从内到外:
```ts
import { createClient, loggerMiddleware, metricsMiddleware, createMetrics } from 'llm-kit';
const metrics = createMetrics();
const client = createClient('deepseek', {
apiKey: 'sk-...',
middlewares: [
loggerMiddleware(),
metricsMiddleware(metrics),
],
});
// 使用后查看指标
console.log(`请求: ${metrics.requests}, 错误: ${metrics.errors}`);
```
### 自定义中间件
```ts
import type { Middleware } from 'llm-kit';
const rateLimiter: Middleware = async (ctx, next) => {
await waitForQuota(); // 你的限流逻辑
return next();
};
const cache: Middleware = async (ctx, next) => {
const key = `${ctx.method}:${ctx.path}:${JSON.stringify(ctx.body)}`;
const cached = cacheStore.get(key);
if (cached) return cached;
const res = await next();
cacheStore.set(key, res);
return res;
};
client.use(rateLimiter);
client.use(cache);
```
### 内置中间件
| 中间件 | 功能 |
|--------|------|
| `loggerMiddleware()` | 请求/响应日志 |
| `metricsMiddleware(metrics)` | 请求计数、延迟、错误率 |
---
## 🧠 思考模式
6 个 Provider 支持思考模式,统一通过 `reasoning_content` 字段输出:
```ts
const response = await client.chat({
model: 'deepseek-v4-pro',
messages: [{ role: 'user', content: '9.11 和 9.8 哪个更大?' }],
thinking: { type: 'enabled' },
stream: false,
});
console.log('[思考]', response.choices[0].reasoning_content);
console.log('[回答]', response.choices[0].message.content);
```
---
## 🔧 函数调用
```ts
const tools = [{
type: 'function',
function: {
name: 'get_weather',
description: '获取指定城市的天气',
parameters: {
type: 'object',
properties: { city: { type: 'string' } },
required: ['city'],
},
},
}];
const response = await client.chat({
model: 'deepseek-v4-pro',
messages: [{ role: 'user', content: '北京天气怎么样?' }],
tools,
stream: false,
});
if (response.choices[0].message.tool_calls) {
for (const call of response.choices[0].message.tool_calls) {
console.log(`${call.function.name}(${call.function.arguments})`);
}
}
```
---
## 📄 结构化输出
```ts
const response = await client.chat({
model: 'deepseek-v4-pro',
messages: [
{ role: 'system', content: '以 JSON 格式输出 name 和 age 字段' },
{ role: 'user', content: '小明今年 25 岁' },
],
response_format: { type: 'json_object' },
stream: false,
});
const data = JSON.parse(response.choices[0].message.content);
// { name: "小明", age: 25 }
```
---
## 🖼️ 多模态
```ts
// 图片
const response = await client.chat({
model: 'mimo-v2.5',
messages: [{
role: 'user',
content: [
{ type: 'text', text: '描述这张图片' },
{ type: 'image_url', image_url: { url: 'https://example.com/photo.jpg' } },
],
}],
stream: false,
});
```
### 多模态支持矩阵
| Provider | 图片 | 视频 | 音频 | 文件 |
|----------|:----:|:----:|:----:|:----:|
| Anthropic | ✅ | ❌ | ❌ | ✅ |
| DeepSeek | ❌ | ❌ | ❌ | ❌ |
| Ollama | ✅ | ❌ | ❌ | ❌ |
| Kimi | ✅ | ✅ | ❌ | ❌ |
| MiniMax | ✅ | ❌ | ❌ | ❌ |
| MiMo | ✅ | ✅ | ✅ | ❌ |
| 智谱 | ✅ | ✅ | ✅ | ✅ |
---
## 🛡️ 错误处理
```ts
import { createClient, LLMError, RateLimitError, AuthError, TimeoutError } from 'llm-kit';
try {
await client.chat({ ... });
} catch (err) {
if (err instanceof RateLimitError) {
await sleep(err.retryAfter * 1000);
} else if (err instanceof AuthError) {
console.error('API Key 无效');
} else if (err instanceof TimeoutError) {
console.error('请求超时');
} else if (err instanceof LLMError) {
console.error(`[${err.provider}] ${err.code}: ${err.message}`);
}
}
```
### 错误层级
```
LLMError (基类)
├── RateLimitError — 429 限流
├── AuthError — 401/403 认证失败
├── TimeoutError — 请求超时
├── ValidationError — 参数校验失败
└── ConnectionError — 网络连接失败
```
---
## 🔄 重试与超时
```ts
const client = createClient('deepseek', {
apiKey: 'sk-...',
retries: 3, // 最多重试 3 次
retryDelay: 1000, // 基础延迟 1s(指数退避)
timeout: 60000, // 单次请求超时 60s
});
```
---
## 🧩 扩展新 Provider
通过 `registerProvider()` 注册新 Provider,无需修改任何已有代码:
```ts
import { registerProvider, ComposableClient } from 'llm-kit';
import { BearerAuth, DefaultErrorMapping, SSEStreamParser } from 'llm-kit';
import { OpenAICompatibleRequestBuilder, OpenAICompatibleResponseNormalizer } from 'llm-kit';
registerProvider('my-provider', {
createConfig: () => ({
name: 'my-provider',
defaultBaseURL: 'https://api.my-provider.com',
defaultTimeout: 120_000,
capabilities: {
chat: true, streaming: true, thinking: false,
toolCalling: true, structuredOutput: true,
generate: false, embed: false, models: true,
balance: false, imageInput: false, fim: false,
},
auth: new BearerAuth(),
errorMapping: new DefaultErrorMapping(),
chatStreamParser: new SSEStreamParser(),
requestBuilder: new OpenAICompatibleRequestBuilder({
providerName: 'my-provider',
chatEndpoint: '/v1/chat/completions',
}),
responseNormalizer: new OpenAICompatibleResponseNormalizer({
providerName: 'my-provider',
}),
}),
requiresApiKey: true,
});
// 使用
const client = createClient('my-provider', { apiKey: 'sk-...' });
```
---
## 📂 项目结构
```
llm-kit/
├── src/
│ ├── index.ts # 主入口
│ ├── core/
│ │ ├── types.ts # 统一类型定义
│ │ ├── composable-client.ts # 组合式客户端
│ │ ├── errors.ts # 错误体系
│ │ ├── middleware.ts # 中间件系统
│ │ └── registry.ts # 注册式工厂
│ ├── strategies/
│ │ ├── auth.ts # 认证策略
│ │ ├── error-mapping.ts # 错误映射策略
│ │ ├── stream-parser.ts # 流解析策略
│ │ ├── request-builder.ts # 请求构建策略
│ │ ├── response-normalizer.ts # 响应归一化策略
│ │ └── openai-compatible-base.ts # OpenAI 兼容共享基类
│ ├── adapters/
│ │ ├── anthropic.ts # Anthropic (Claude) 适配器
│ │ ├── deepseek.ts # DeepSeek 适配器
│ │ ├── ollama.ts # Ollama 适配器
│ │ └── providers.ts # Kimi/MiniMax/MiMo/智谱/OpenAI兼容
│ └── utils/
│ ├── fetch.ts # 跨环境 HTTP
│ ├── stream.ts # SSE/NDJSON 解析器 + TransformStream 管道
│ └── validator.ts # 参数校验
├── tests/
│ ├── core.test.ts # 核心测试
│ ├── composable.test.ts # 架构测试
│ └── strategies.test.ts # 策略层测试
├── package.json
└── tsconfig.json
```
---
## 📋 API 参考
### 工厂函数
```ts
createClient('anthropic', options?) // → AnthropicClient
createClient('deepseek', options?) // → DeepSeekClient
createClient('ollama', options?) // → OllamaClient
createClient('kimi', options?) // → KimiClient
createClient('minimax', options?) // → MiniMaxClient
createClient('mimo', options?) // → MiMoClient
createClient('zhipu', options?) // → ZhipuClient
createClient('openai-compatible', options?) // → OpenAICompatibleClient
```
### ClientOptions
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `apiKey` | `string` | - | API 密钥 |
| `baseURL` | `string` | Provider 默认 | API 地址 |
| `timeout` | `number` | 120000/300000 | 请求超时(ms) |
| `headers` | `Record` | `{}` | 自定义请求头 |
| `fetch` | `typeof fetch` | 全局 fetch | 自定义 fetch |
| `retries` | `number` | `0` | 重试次数 |
| `retryDelay` | `number` | `1000` | 重试基础延迟(ms) |
| `middlewares` | `Middleware[]` | `[]` | 请求中间件 |
### Client 方法
| 方法 | 返回值 | 说明 |
|------|--------|------|
| `chat(request)` | `ChatResponse \| ReadableStream` | 对话补全 |
| `chatStream(request)` | `ReadableStream` | 统一事件流 |
| `generate(request)` | `GenerateResponse \| ReadableStream` | FIM 补全 |
| `embed(request)` | `EmbedResponse` | 文本嵌入 |
| `models()` | `ModelListResponse` | 列出模型 |
| `use(middleware)` | `this` | 添加中间件 |
---
## 🧪 开发
```bash
# 安装依赖
npm install
# 构建(ESM + CJS + Types)
npm run build
# 运行测试(120 个)
npm test
# 类型检查
npx tsc --noEmit
```
---
## 📄 许可证
[MIT](LICENSE) © [thzxx](https://gitee.com/thzxx)