baabakk/llm-ports
GitHub: baabakk/llm-ports
一个面向多供应商 LLM 系统的 TypeScript 抽象架构层,通过统一接口、成本管控与失败降级机制解决业务逻辑与特定模型 SDK 深度耦合的问题。
Stars: 2 | Forks: 0
# llm-ports:用于多 Provider AI 系统的 TypeScript LLM 抽象层
Provider 无关的 TypeScript LLM 架构。
无需修改代码即可切换 Provider。
避免供应商锁定。
控制成本。
将 prompt 作为可复用能力。
多 Provider 路由 • fallback 链 • USD 成本限制 • 能力工厂 • tool-use 安全 • 可观测性
[](https://opensource.org/licenses/MIT)


## 问题所在
大多数 LLM 应用程序都会以可预见的方式出错:
- SDK 升级会涉及过多文件
- 切换 Provider 需要重构
- Prompt 逻辑在各个功能中重复存在
- 成本和路由逻辑分散各处
- 业务逻辑变得与特定 Provider 的 SDK 耦合
这不仅仅是 SDK 的问题。
**这是架构问题。**
## 解决方案
`llm-ports` 将端口和适配器模式应用于 LLM 系统。
其他所有部分都与类型化接口通信。
您的应用程序不再直接调用模型,而是使用可复用的能力:
- classify
- draft
- score
- summarize
- extract
- plan
- analyze
LLM 不再是您需要管理的依赖项。
它变成了您可以配置的基础设施。
## 您将获得什么
- 跨 OpenAI、Anthropic、Ollama、Vercel AI SDK 及兼容 Provider 的**多 Provider LLM 路由**
- 当 Provider 失败或超出预算时的 **fallback 链**
- 具有每小时、每天和每月限制的**基于 USD 的成本限制**
- **可复用的 prompt 能力**,使 prompt 定义一次即可在处处复用
- 针对结构化输出失败的**验证恢复**
- 用于破坏性或需要确认的操作的 **tool-use 安全原语**
- 用于成本、延迟、质量和结果的**可观测性钩子**
- 提供完整类型支持的 **TypeScript 优先 API**
- **不依赖 LangChain、LlamaIndex 或繁重框架的运行时**
## 60 秒设置
### 1. 在 `.env` 中配置 Provider
```
LLM_PROVIDER_FAST=anthropic||cost:50/day
LLM_PROVIDER_SMART=anthropic||cost:200/day
LLM_TASK_ROUTE_TRIAGE=fast,smart
```
### 2. 创建一次 port
```
import { createRegistryFromEnv } from "@llm-ports/core";
import { createAnthropicAdapter } from "@llm-ports/adapter-anthropic";
export const llm = createRegistryFromEnv({
adapters: {
anthropic: createAnthropicAdapter({
apiKey: process.env.ANTHROPIC_API_KEY!,
}),
},
}).getPort();
```
### 3. 在任何地方使用它,无需导入 SDK
```
const result = await llm.generateText({
taskType: "triage",
prompt: "Classify this email...",
});
```
Registry 将:
- 为任务选择合适的模型
- 执行成本限制
- 在失败时通过 Provider 链进行 fallback
- 记录使用情况、成本和延迟
## 能力:可复用的 LLM 操作
无需在各个文件中复制 prompt 逻辑,只需定义一次能力并复用它。
```
import { createClassifier } from "@llm-ports/capabilities";
import { z } from "zod";
const IntentSchema = z.object({
intent: z.enum(["question", "request", "complaint", "feedback", "other"]),
urgency: z.enum(["low", "normal", "high"]),
reasoning: z.string(),
});
export const classifyIntent = createClassifier({
port: llm,
schema: IntentSchema,
schemaName: "user-intent",
rubric: `
question: asking for information
request: wants something done
complaint: reports a problem
feedback: opinion only
other: anything else
`,
});
```
现在可以在任何地方调用它:
```
const result = await classifyIntent({ content: userMessage });
```
输出示例:
```
{
intent: "request",
urgency: "high",
reasoning: "The user is asking for a concrete action."
}
```
为什么这很重要:
- 改进一次 prompt,所有调用处都会受益
- 保持整个系统行为一致
- 让调试和评估更容易
- 让业务逻辑摆脱特定于 Provider 的 SDK 细节
## 架构概述
之前:
```
Application code
├─ direct SDK call
├─ direct SDK call
├─ direct SDK call
└─ model router leaking SDK types
```
之后:
```
Application code
↓
Capabilities
↓
LLM Port
↓
Adapters and Provider Registry
↓
LLM providers
```
关键转变在于:
## 软件包
| 软件包 | 用途 |
|--------|---------|
| `@llm-ports/core` | Port 接口、registry、路由、成本限制、验证策略、内容块 |
| `@llm-ports/capabilities` | 可复用的 LLM 操作工厂 |
| `@llm-ports/adapter-openai` | OpenAI SDK 适配器,支持兼容 Provider 的 `baseURL` |
| `@llm-ports/adapter-anthropic` | Anthropic SDK 适配器 |
| `@llm-ports/adapter-google` | Google Gemini 原生适配器 (@google/genai SDK) — 完整多模态,内置定价 |
| `@llm-ports/adapter-ollama` | Ollama 原生适配器,支持模型管理 |
| `@llm-ports/adapter-vercel` | 用于迁移和兼容性的 Vercel AI SDK 适配器 |
## 示例
[`examples/`](examples/) 中有七个可运行的示例,每个都是独立的 pnpm workspace 软件包,并附带 README 解释代码:
| 示例 | 展示内容 |
|---|---|
| [`basic`](examples/basic/) | 最基础的端到端实现。一个适配器,一种任务类型,一次 `generateText` 调用。即 60 秒设置演示。 |
| [`multi-provider`](examples/multi-provider/) | Fallback 链(Anthropic 主力 → OpenAI 备用),每个 Provider 的 USD 成本限制,能力工厂。 |
| [`email-triage`](examples/email-triage/) | 最常见的生产用例,浓缩在约 150 行代码中。入站邮件 → 分类(意图 + 紧急度 + 情感)→ 策略门控 → 起草符合品牌语气的回复 → 排队等待人工审核。能力组合的故事。 |
| [`streaming-chat`](examples/streaming-chat/) | 包含三个路由的 Express 服务端:`POST /chat`(一次性)、`POST /chat/stream`(Server-Sent Events)、`POST /chat/agent`(tool-augmented)。仅用约 30 行胶水代码实现最常见的 LLM UX 模式。 |
| [`extract-from-pdf`](examples/extract-from-pdf/) | 文档提取:原始 OCR 发票文本 → 通过 Zod 转换为完全类型化的结构化对象。演示 `generateStructured`、带反馈的验证重试以及 `createExtractor` 工厂。 |
| [`agent-with-approval`](examples/agent-with-approval/) | 具有一流安全原语的 tool-use Agent。`destructive`、`requiresConfirmation`、`maxOutputBytes` 标志 + 审批门控包装器。差异化的示例。 |
| [`migrate-from-vercel-ai`](examples/migrate-from-vercel-ai/) | 针对 Vercel AI SDK 用户的两种迁移路径:(a) 使用 `@llm-ports/adapter-vercel` 包装现有的模型工厂,(b) 用原生的 llm-ports 适配器替换 `@ai-sdk/*`。并排展示前后的差异。 |
每个示例都可以从 monorepo 根目录运行:
```
pnpm --filter @llm-ports/example- start
```
运行前请设置相关的 API key(`ANTHROPIC_API_KEY`、`OPENAI_API_KEY`)。每个示例的 README 记录了其所需的 key。
## 支持的用例
在以下情况时使用 `llm-ports`:
- 需要 多 Provider LLM 路由
- 需要 LLM fallback 链
- 需要 TypeScript LLM 抽象
- 需要 OpenAI 和 Anthropic Provider 切换
- 需要为生产 LLM 应用程序控制成本
- 需要 可复用的 prompt 能力
- 需要 结构化输出验证和恢复
- 需要 agent 工作流中的 tool-use 安全
- 需要 LLM 成本、延迟和质量的 可观测性
- 需要 供应商中立的 AI 架构
## 何时使用
如果满足以下条件,请使用 `llm-ports`:
- 您使用 2 个或更多 LLM Provider
- 您以后可能会切换 Provider
- SDK 升级引起了多文件改动
- Prompt 逻辑存在重复
- 成本控制很重要
- 您希望将业务逻辑与 Provider SDK 解耦
如果有以下情况,请跳过它:
- 您只有 1 到 2 次 LLM 调用
- 您只是在进行原型设计
- 您是故意围绕某个特定 Provider 的特性进行构建
- 您想要一个完整的 agent 框架、记忆层、RAG 框架或托管网关
## 相关工具
| 工具 | `llm-ports` 与它们的关系 |
|------|--------------------------|
| Vercel AI SDK | Vercel 统一了 Provider 调用。`llm-ports` 在此基础上增加了 registry、fallback 链、USD 成本限制、验证恢复和能力工厂。 |
| LiteLLM | LiteLLM 是一个 Python 优先的 HTTP 代理。`llm-ports` 是 TypeScript 的,且在进程内运行,没有额外的网络跳转。 |
| Portkey | Portkey 是一个商业托管网关。`llm-ports` 是 MIT 许可、进程内运行的,且没有托管依赖。 |
| LangChain.js | LangChain 是一个框架。`llm-ports` 是一个轻量级的架构和控制层。 |
| LlamaIndex.TS | LlamaIndex 是检索优先的。`llm-ports` 处理 LLM 调用、路由、fallback 和成本控制。 |
| Mastra | Mastra 是 agent 优先的,内置了记忆和工作流原语。`llm-ports` 在该层之下提供了更底层的 LLM 原语。 |
## Alpha 阶段的已知限制
`llm-ports` 处于预发布状态。核心架构已经稳定,离线回归测试套件非常全面(250+ 测试,p99 延迟低于 1 ms,在 110+ 代码片段中未检测到文档陈旧)。一些适配器和 agent 路径仍在加固中。
十四个中等影响的 alpha 测试问题([#1](https://github.com/baabakk/llm-ports/issues/1), [#3](https://github.com/baabakk/llm-ports/issues/3), [#4](https://github.com/baabakk/llm-ports/issues/4), [#5](https://github.com/baabakk/llm-ports/issues/5), [#6](https://github.com/baabakk/llm-ports/issues/6), [#9](https://github.com/baabakk/llm-ports/issues/9), [#12](https://github.com/baabakk/llm-ports/issues/12), [#14](https://github.com/baabakk/llm-ports/issues/14), [#16](https://github.com/baabakk/llm-ports/issues/16), [#19](https://github.com/baabakk/llm-ports/issues/19), [#20](https://github.com/baabakk/llm-ports/issues/20), [#21](https://github.com/baabakk/llm-ports/issues/21), [#24](https://github.com/baabakk/llm-ports/issues/24), [#32](https://github.com/baabakk/llm-ports/issues/32))已在 `0.1.0-alpha.1` → `0.1.0-alpha.13` 中修复并现已关闭。Alpha 系列完成了 v0.1 表面:Gemini 多轮对话 `runAgent` + 原生 `responseSchema`,运行时模型发现(跨 4 个适配器的 `LLMPort.listModels()` + `Registry.checkPricingFreshness()`),`adapter-openai` 上的 `useStrictResponseFormat` 用于 Cerebras 的 strict-JSON,openai + anthropic 上的 `dangerouslyAllowBrowser` 选项,用于 o-series / gpt-5-nano / Groq gpt-oss-120b 推理深度控制的 `reasoningEffort` 参数,能力工厂向底层 port 调用传递 `reasoningEffort` + `signal` + `forceProviderAlias`,以及扩展后的 `attemptValidationRepair` 过程,该过程可捕获 markdown 包裹的枚举、尾随标点、字符串化 JSON 作为对象以及包含单个对象的数组等误读情况。完整的各项功能清单详见 [v0.1 状态页](https://baabakk.github.io/llm-ports/v0-1-status)。
仍然悬而未决的问题:
- 某些兼容 Provider 的模型(Groq、Together AI、Fireworks、Clarifai、SambaNova)可能需要配置 `pricingOverrides` 条目,以满足 registry 的定价验证步骤。默认情况下,内置的定价表涵盖 OpenAI、Anthropic、Google 和 Ollama。关于 Clarifai 的 Qwen3.6 35B A3B FP8 和 SambaNova 的 MiniMax-M2.7 的操作示例在 [openai 适配器文档](https://baabakk.github.io/llm-ports/adapters/openai)中。
- Vercel 适配器的 `runAgent` 仅支持单轮(多轮将在 v0.2 中实现)。
- Registry 在**预算限制**和**运行时错误**时都会遍历 Provider 链(alpha.7+,默认谓词:`ProviderUnavailableError`)。可通过 `runtimeFallback: "none" | "default" | { shouldFallback }` 进行配置。流式方法仅在流创建失败时遍历,而不是在迭代过程中。
如果您遇到了此处未列出的问题,请[提交一个 issue](https://github.com/baabakk/llm-ports/issues/new/choose) —— bug 报告模板会捕获我们所需的确切版本和复现步骤。
## 安装
`llm-ports` 处于 alpha 阶段。所有 7 个软件包以及新的 `@llm-ports/migrate` codemod 均发布在 `v0.1.0-alpha.20.1`。经过短暂的 alpha 测试后,稳定的 v0.1 将正式发布 —— 请访问 [v0.1 状态页](https://baabakk.github.io/llm-ports/v0-1-status) 查看哪些部分目前已经稳定,哪些仍在加固中。
```
npm install @llm-ports/core@0.1.0-alpha.20.1
```
根据需要安装适配器:
```
npm install @llm-ports/adapter-anthropic@0.1.0-alpha.20.1
npm install @llm-ports/adapter-openai@0.1.0-alpha.20.1
npm install @llm-ports/adapter-google@0.1.0-alpha.20.1
npm install @llm-ports/adapter-ollama@0.1.0-alpha.20.1
npm install @llm-ports/adapter-vercel@0.1.0-alpha.20.1
npm install @llm-ports/capabilities@0.1.0-alpha.20.1
```
(作用域在 `@llm-ports` 下。通过 changesets 统一进行版本控制。)
Peer dependency:`zod >=3.24.0 <5`。请自带 SDK(`@anthropic-ai/sdk`、`openai`、`ollama`、`ai`)。
### Alpha 系列期间的版本锁定
**建议:锁定到确切的 alpha 版本**,而不是 `@alpha` dist-tag,因为我们仍在锁定核心结构。`@` 标签会跟踪最新发布的预发布版本;因此,执行 `pnpm install` 或 `npm update` 可能会默默跨过多个破坏性变更进行升级。精确锁定会在您手动升级之前保持版本不变,届时您可以阅读 [MIGRATION.md](./MIGRATION.md) 并应用各版本的迁移指南。
```
// package.json — recommended during alphas
{
"dependencies": {
"@llm-ports/core": "0.1.0-alpha.20.1",
"@llm-ports/adapter-anthropic": "0.1.0-alpha.20.1"
}
}
```
`@alpha` 标签适合用于实验:
```
npm install @llm-ports/core@alpha
```
当您升级时,`@llm-ports/core` 的 postinstall 会输出一行指向迁移页面的横幅。要通过自动化方式跨多个 alpha 版本升级,请使用内置的 codemod:
```
npx @llm-ports/migrate@alpha alpha-19-to-alpha-20 --dry-run # preview
npx @llm-ports/migrate@alpha alpha-19-to-alpha-20 --write # apply
```
## 文档
文档站点(每次推送到 `main` 时从 `docs/` 自动部署):
https://baabakk.github.io/llm-ports/
页面:
- 入门指南
- 概念:ports、adapters、任务路由、成本限制、内容块、验证策略
- 指南:多 Provider 路由、本地到云端、成本控制、自定义适配器、可观测性、安全性
- 能力:每种能力一个页面
- 适配器:每个适配器一个页面及功能对比矩阵
- 迁移:从 Vercel AI SDK、LangChain.js 和直接 Provider SDK 迁移
## 安全性
没有威胁模型的 tool use 是危险的。
`llm-ports` 将安全性视为 API 的重要组成部分:
- 破坏性工具标记
- 需要确认的操作
- 最大输出字节限制
- 脱敏能力
- 针对提示词注入和工具滥用的明确指导
请参阅 [SECURITY.md](./SECURITY.md)。
## 贡献
在初始的 v0.1 脚手架落地后,欢迎各界贡献。
请参阅 [CONTRIBUTING.md](./CONTRIBUTING.md)。
## 许可证
MIT。请参阅 [LICENSE](./LICENSE)。
## 状态
预发布版。
当前目标:
- v0.1:core、adapters、成本限制、7 个能力工厂
- v0.2:扩展的能力和可观测性包
- v0.3:额外的适配器和 markdown 技能格式评估
## 关注发布
`llm-ports` 处于预发布阶段。若要在 v0.1 发布到 `latest` 标签时(以及之后每个次要版本发布时)收到通知:
1. 点击 [GitHub 仓库](https://github.com/baabakk/llm-ports) 顶部的 **Watch** 按钮
2. 选择 **Custom**
3. 勾选 **Releases**
只有在真正发布新版本时,您才会收到电子邮件或通知。不会有 PR 或 commit 的干扰噪音。
标签:AI, DLL 劫持, MITM代理, TypeScript, 多供应商路由, 大语言模型, 安全插件, 架构设计, 自动化代码审查, 自动化攻击