190 防线
与多个 AI 提供者互动的有意见的统一接口,包括 开放AI, (中文(简体) ), 安东尼, (中文(简体) ), 谷歌, (中文(简体) ), 格罗克, (中文(简体) ), 打开路透社,以及 AWS 贝德洛克。该软件包提供一致的API,用于在处理重试、流式和多模式输入时向不同的LLM提供者提出请求.
特征
跨越多个AI供应商的全地统一接口包括:
- * 在所有提供者之间调用一致的功能/工具
- & 系统指令
- 图像格式和大小正常化
- 🔄 有可配置尝试的自动重试
- * 默认流出
- 支持的云服务供应商(Azure, AWS Bedrock)
- QQ 为任何模型提供前缀字符串而无需等待软件包更新
安装
npm install 190proof
使用量
基本示例
使用来自任何提供商的任何模式 provider:model-id 格式 :
import { callWithRetries, GenericPayload } from "190proof";
const payload: GenericPayload = {
model: "openai:gpt-4o-mini",
messages: [
{
role: "user",
content: "Tell me a joke.",
},
],
};
const response = await callWithRetries("my-request-id", payload);
console.log(response.content);
使用不同的供应商
import { callWithRetries, GenericPayload } from "190proof";
// OpenAI
const openaiPayload: GenericPayload = {
model: "openai:gpt-5",
messages: [{ role: "user", content: "Hello!" }],
};
// Anthropic
const claudePayload: GenericPayload = {
model: "anthropic:claude-sonnet-4-5",
messages: [{ role: "user", content: "Hello!" }],
};
// Google
const geminiPayload: GenericPayload = {
model: "google:gemini-2.0-flash",
messages: [{ role: "user", content: "Hello!" }],
};
// Groq
const groqPayload: GenericPayload = {
model: "groq:llama-3.3-70b-versatile",
messages: [{ role: "user", content: "Hello!" }],
};
// OpenRouter
const openRouterPayload: GenericPayload = {
model: "openrouter:google/gemma-4-31b-it:free",
messages: [{ role: "user", content: "Hello!" }],
};
const response = await callWithRetries("request-id", claudePayload);
有函数调用
const payload: GenericPayload = {
model: "openai:gpt-4o",
messages: [
{
role: "user",
content: "What is the capital of France?",
},
],
functions: [
{
name: "get_country_capital",
description: "Get the capital of a given country",
parameters: {
type: "object",
properties: {
country_name: {
type: "string",
description: "The name of the country",
},
},
required: ["country_name"],
},
},
],
};
const response = await callWithRetries("function-call-example", payload);
// response.function_call contains { name: string, arguments: Record<string, any> }
带有图像
const payload: GenericPayload = {
model: "anthropic:claude-sonnet-4-5",
messages: [
{
role: "user",
content: "What's in this image?",
files: [
{
mimeType: "image/jpeg",
url: "https://example.com/image.jpg",
},
],
},
],
};
const response = await callWithRetries("image-example", payload);
图像如何到达模型取决于提供者. OpenAI、Anthropic、和
Google获得本土图像块. Groq 仅为文本: 图像可降解为内线
Image (url) 文本参考。 OpenRouter 发送 OpenAI 风格 image_url 内容
部件( 远程 URL 当存在时, 否则为 a) data: (URI)——但如果模型有
openRouter 以一个
路由层404,所以重试回环 重接有效载荷的图像退化
以相同的内置文本引用 Groq 得到,并记住模型
(正在处理中, 直至重启) 所以以后的调用 降级到前面 。 没有信件
图像附件以相同的方式序列化 .
带有系统信件
const payload: GenericPayload = {
model: "google:gemini-2.0-flash",
messages: [
{
role: "system",
content: "You are a helpful assistant that speaks in a friendly tone.",
},
{
role: "user",
content: "Tell me about yourself.",
},
],
};
const response = await callWithRetries("system-message-example", payload);
检查模式运行
使用 parseModelString 以查看模式字符串的路由 :
import { parseModelString } from "190proof";
parseModelString("openai:gpt-7");
// → { provider: "openai", modelId: "gpt-7" }
parseModelString("openrouter:org/model-name:free");
// → { provider: "openrouter", modelId: "org/model-name:free" }
提供者前缀格式
模型字符串格式为 provider:model-id,其中提供者前缀为:
| 前缀 | 提供者 |
|---|---|
openai | 开放AI |
anthropic | 安东尼 |
google | 谷歌( 格米尼 ) |
groq | 格罗克 |
openrouter | 打开路透社 |
前缀在发送到API之前被剥去,所以模型ID应该是提供者所期望的(例如. "openai:gpt-4o" 发送 "gpt-4o" 改为OpenAI).
支持的模式
这些模型经过测试. 你可以使用任何模型 与 provider:model-id 格式.
开放AI
openai:gpt-5openai:gpt-5-miniopenai:gpt-4.1openai:gpt-4.1-miniopenai:gpt-4.1-nanoopenai:gpt-4oopenai:gpt-4o-miniopenai:o3-miniopenai:o1-previewopenai:o1-mini
安东尼
anthropic:claude-opus-4-5anthropic:claude-sonnet-4-5anthropic:claude-haiku-4-5anthropic:claude-opus-4-1anthropic:claude-opus-4-20250514anthropic:claude-sonnet-4-20250514anthropic:claude-3-5-sonnet-20241022anthropic:claude-3-5-haiku-20241022
谷歌
google:gemini-3.1-flash-lite-previewgoogle:gemini-3-flash-previewgoogle:gemini-2.5-flash-preview-04-17google:gemini-2.0-flashgoogle:gemini-2.0-flash-exp-image-generationgoogle:gemini-1.5-pro-latest
格罗克
groq:llama-3.3-70b-versatilegroq:llama3-70b-8192groq:qwen/qwen3-32bgroq:deepseek-r1-distill-llama-70b
打开路透社
openrouter:google/gemma-4-31b-it:freeopenrouter:google/gemma-4-31b-it
环境变量
为您想要使用的提供者设置以下环境变量:
# OpenAI
OPENAI_API_KEY=your-openai-api-key
# Anthropic
ANTHROPIC_API_KEY=your-anthropic-api-key
# Google
GEMINI_API_KEY=your-gemini-api-key
# Groq
GROQ_API_KEY=your-groq-api-key
# OpenRouter
OPENROUTER_API_KEY=your-openrouter-api-key
# AWS Bedrock (for Anthropic via Bedrock)
AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
API 参考
callWithRetries(identifier, payload, config?, retries?, chunkTimeoutMs?)
主要职能是向任何得到支持的人工智能提供者提出请求.
参数
identifier数字 :string | string[]- 请求的独特标识符(用于伐木)payload数字 :GenericPayload- 请求载有模型、信息和可选功能的有效载荷config数字 :OpenAIConfig | AnthropicAIConfig- 特定提供者的可选配置retries数字 :number- 重新尝试的次数(默认:5)chunkTimeoutMs数字 :number- 流出块以毫秒计的超时(默认:1500)
可选的按要求选择的接字 payload (单位:千美元)GenericPayload:
payload.requestTimeoutMs数字 :number- Per-Attoption HTTP 超时(默认:1200),每个适配器都遵守——除了流出OpenRouter的尝试,它故意不约束(见下文)。 对于OpenRouter的非流式运输,默认为180000.payload.streaming数字 :boolean- OpenRouter-只(默认:真实). 流过SSE完成。 串流尝试由两个独立的计时器而不是requestTimeoutMs数字 :streamTimeoutMs(墙上钟表总数,默认为60000)和每用一卡通的摊位超时(chunkTimeoutMs参数,默认 1500。 一个块只有当它推进内容,推理,工具调用片段,完成 解释,或者使用——SSE 注释保持-活性时,才"有用"(S: OPENROUTER PROCESSING),而只扮演角色的三角洲不会重置摊位计时器,因此一个挂起的提供者死在一个摊位窗口内,而健康的长世代可以跑到总预算. 设定streaming: false旧的JSON车体运输.payload.streamTimeoutMs数字 :number- OpenRouter - 仅限:每次溪流努力的总墙上小时预算(默认:600000).payload.streamDeadlineAt数字 :number- 仅开放路透:整个呼叫的绝对截止日期(划时代) 包括复试 ——呼叫员轮到预算. 每次尝试都得到min(streamTimeoutMs, deadline - now),而一旦不到10岁,电话就会迅速失效,而不是开始无法发送的一代。 每当呼叫者有自己的超时,就使用它:每一次重试都只给每个超时预算,并且可以活过超时.payload.thinkingConfig数字 :Record<string, unknown>- 仅谷歌:逐字传送为generationConfig.thinkingConfig根据双子座的要求——例如:.{ thinkingBudget: 0 }要禁用思维,{ thinkingLevel: "HIGH" }在模型 一个级别。 被所有其他适配器所忽略;形状是特有模型并被Google验证,而不是SDK.payload.reasoningEffort数字 :string-OpenAI和OpenRouter的推理努力。 有效值取决于模型(none编号 :minimal编号 :low编号 :medium编号 :high编号 :xhigh编号 :max. OpenRouter: 作为巢穴发送reasoning: { effort }对象——犬形,唯一接受的max(平顶楼)reasoning_effort字段盖xhigh) (中文(简体) ). 直接 OpenAI: 发送平分为reasoning_effort· ;max并拒绝功能工具/chat/completions除非这明确无误"none"- 他们的默认是medium. 通过OpenRouter,同样的模型在任何努力中都接受工具(OpenRouter前沿)/v1/responses),所以省略了这些在他们本土默认情况下运行的. 被其他适配器忽略.
当流出尝试被切断时 截止时间总数 传教士已经到来, 部分回答随即返回 truncated: true 而不是丢弃 这些信物是生成和开具的 所以丢弃它们要花钱 给用户什么也没有 这种答复表面为不完整。 救赎从来不适用于工具调用转折(半流参数是不可分取的JSON),也不适用于摊位(提供者中思而死),或适用于调用者中止. 当无物可救时,丢弃物被记录在一个近似符号数中——中断的尝试从未收到OpenRouter的 usage 块,所以日志行是浪费开支的唯一记录.
OpenRouter 重试也执行 适度驱逐: 提供者内容- 修改拒绝( 如"Alibaba的上游错误: 输出数据可能包含不适当的内容") 对给定的有效载荷具有决定性意义, 因此第一个拒绝提供者被从请求提供者的偏好中去除( )ignore 子弹, order -=switt),而所剩的每一个尝试都改道到下一个提供者. 非修改错误以不变的偏好重试,以及 fallbackModel 如果整个游泳池拒绝,则仍然适用.
payload.signal数字 :AbortSignal- 呼叫者提供的取消。 当它中止时,飞行中提供商的请求被取消callWithRetries立即拒绝,它不会重试或退后 (复试回环和倒置分行保释)signal.aborted) (中文(简体) ). 串到每个提供者的基本获取/ axios/ SDK 调用 .
回返
Promise<ParsedResponseMessage>数字 :
interface ParsedResponseMessage {
role: "assistant";
content: string | null;
function_call: FunctionCall | null;
function_calls: FunctionCall[];
files: File[]; // For models that return files (e.g., image generation)
// Who actually served the response: OpenRouter's upstream provider from the
// response body (e.g. "Baidu"), or the SDK provider name ("anthropic", ...)
// for direct providers. On fallback, reflects the model that answered.
provider?: string;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
// Reasoning/thinking tokens spent before the visible answer; currently
// populated from Google's usageMetadata.thoughtsTokenCount.
thoughts_tokens?: number;
} | null; // null when streaming
}
setLogger(sink | null)
每个呼叫和重试190个防守日志到控制台. 将这些线路引导到自己的日志或通过 null 让他们安静下来(当190 previdence是图书馆的附属物时) :
import { setLogger } from "190proof";
setLogger(null); // silent
setLogger({ log: myLog.info, warn: myLog.warn, error: myLog.error });
错误 callWithRetries 从不携带 HTTP 请求( 也从不携带 API 密钥) ; 提供者状态和响应机构继续运行 error.response。 。 。 .
parseModelString(model)
将一个模型字符串分析到它的提供者和模型ID组件中.
参数
model数字 :string- 一个模型串英寸"provider:model-id"格式
回返
{ provider: Provider, modelId: string }
配置选项
OpenAI 配置
interface OpenAIConfig {
service: "azure" | "openai";
apiKey: string;
/**
* Optional base URL. Defaults to `https://api.openai.com/v1`. Set to point
* at any OpenAI-compatible endpoint (e.g. a self-hosted proxy). The path
* `/chat/completions` is appended automatically. Ignored for Azure.
*/
baseUrl?: string;
orgId?: string;
modelConfigMap?: Record<
string,
{
resource: string;
deployment: string;
apiVersion: string;
apiKey: string;
endpoint?: string;
}
>;
}
要与 OpenAI 兼容的服务器对话, 而不是 OpenAI 本身 :
await callWithRetries(
"my-identifier",
{
model: "openai:gpt-4o-mini",
messages: [{ role: "user", content: "hi" }],
},
{
service: "openai",
apiKey: process.env.SOME_SERVER_API_KEY,
baseUrl: "https://your-proxy.example.com/v1",
},
);
Athropic 配置
interface AnthropicAIConfig {
service: "anthropic" | "bedrock";
}
许可证
公务员制度委员会