@ contentgrown/llm- service (中文(简体) )
内容增长应用统一LLM服务. 这个软件包为与各种LLM提供者(OpenAI,双子座)的互动提供了标准化的接口,并通过可插件配置支持"Bring your Own Key"(BYOK)功能.
安装
npm install @contentgrowth/llm-service
使用量
基本用途
该服务需要环境对象(通常来自Cloudflare Workers)才能访问约束.
import { LLMService } from '@contentgrowth/llm-service';
// In your Worker
export default {
async fetch(request, env, ctx) {
const llmService = new LLMService(env);
// Chat
const response = await llmService.chat('Hello, how are you?', 'tenant-id');
console.log(response.text);
// Chat Completion (with system prompt)
const result = await llmService.chatCompletion(
[{ role: 'user', content: 'Write a poem' }],
'tenant-id',
'You are a poetic assistant'
);
console.log(result.content);
}
}
配置 BYOK( B)
服务使用 ConfigManager 用于确定租户使用的 LLM 提供者和 API 密钥.
默认行为( Cloudflare KV + 持久对象)
默认情况下,服务预计 env 对象传递给构造器以包含:
TENANT_LLM_CONFIG: KV 命名空间绑定 .TENANT_DO: 持久对象命名空间绑定.
它利用这些来获取租户特有的配置.
自定义配置( 可拖放提供者)
如果您的工程以不同方式存储租户密钥( 例如在 SQL 数据库、 环境变量或不同的服务中), 您可以执行自定义 ConfigProvider。 。 。 .
import { LLMService, ConfigManager, BaseConfigProvider } from '@contentgrowth/llm-service';
// 1. Define your custom provider
class MyDatabaseConfigProvider extends BaseConfigProvider {
async getConfig(tenantId, env) {
// Fetch config from your database or other source
// You can use 'env' here if you need access to bindings
const apiKey = await getApiKeyFromDB(tenantId);
return {
provider: 'openai', // or 'gemini'
apiKey: apiKey,
models: {
default: 'gpt-4o',
// ... optional overrides
},
// Optional capabilities
capabilities: { chat: true, image: true }
};
}
}
// 2. Register the provider at application startup
ConfigManager.setConfigProvider(new MyDatabaseConfigProvider());
// 3. Use LLMService as normal - it will now use your provider
const service = new LLMService(env);
谷歌双子座 & Vertex AI 配置
该服务通过Google的AI平台提供统一支持 @google/genai SDK: (英语)
1. 双子体AI工作室(消费者API)
直接使用您的 AI Studio API 密钥 .
LLM_PROVIDER=gemini
GEMINI_API_KEY=your-api-key-from-ai-studio
GEMINI_MODEL=gemini-3.5-flash
2. Vertex AI(企业)——两种认证模式
| 模式 | 使用大小写 | 需要配置 |
|---|---|---|
| ADC / IAM (默认) | 生产、服务账户、工作量 | VERTEX_PROJECT, (中文(简体) ), VERTEX_LOCATION |
| 快捷模式( API 密钥) | 快速设置、 dev/ test, 无服务账户 | VERTEX_API_KEY (项目自动解决) |
Vertex 快捷模式( API 密钥) 建议迅速设立:
LLM_PROVIDER=vertex
VERTEX_API_KEY=AIza... # API key from Vertex AI Studio
# VERTEX_PROJECT and VERTEX_LOCATION are OPTIONAL — SDK resolves project from key
Vertex ADC/IAM 模式 - 使用服务账户生产:
LLM_PROVIDER=vertex
VERTEX_PROJECT=your-gcp-project-id
VERTEX_LOCATION=us-central1
# VERTEX_API_KEY is NOT needed (uses Application Default Credentials)
遗产别名 (也得到支持):
GOOGLE_CLOUD_PROJECT→VERTEX_PROJECTGOOGLE_CLOUD_LOCATION→VERTEX_LOCATION
模型覆盖( 所有提供者)
VERTEX_MODEL=gemini-3.5-flash
VERTEX_MODEL_EDGE=gemini-3.5-pro
VERTEX_MODEL_FAST=gemini-3.5-flash
VERTEX_IMAGE_MODEL=gemini-nano-banana-2.1
VERTEX_VIDEO_MODEL=veo
程序配置( 无环境变量)
您可以通过执行自定义直接通过代码配置提供者 ConfigProvider。当您不想依赖环境变量或需要动态配置时,此功能是有用的.
Vertex快取模式(API key)——程序化
import { LLMService, ConfigManager, BaseConfigProvider } from '@contentgrowth/llm-service';
class VertexExpressConfigProvider extends BaseConfigProvider {
constructor(apiKey) {
super();
this.apiKey = apiKey;
}
async getConfig(tenantId, env) {
return {
provider: 'vertex',
apiKey: this.apiKey,
// project & location are OPTIONAL — SDK resolves from API key
models: {
default: 'gemini-3.5-flash',
edge: 'gemini-3.5-pro',
fast: 'gemini-3.5-flash',
image: 'gemini-3.5-pro-image-preview',
video: 'veo',
},
temperature: 0.7,
maxTokens: 65536,
capabilities: { chat: true, image: true, video: true },
};
}
}
// Register once at startup
ConfigManager.setConfigProvider(new VertexExpressConfigProvider('AIza...'));
// Use normally
const service = new LLMService(env);
const response = await service.chat('Hello Vertex!', 'tenant-id');
Vertex ADC/IAM 模式——程序化
class VertexADCConfigProvider extends BaseConfigProvider {
constructor(project, location = 'us-central1') {
super();
this.project = project;
this.location = location;
}
async getConfig(tenantId, env) {
return {
provider: 'vertex',
project: this.project,
location: this.location,
// apiKey NOT needed — uses Application Default Credentials
models: {
default: 'gemini-3.5-flash',
edge: 'gemini-3.5-pro',
fast: 'gemini-3.5-flash',
image: 'gemini-3.5-pro-image-preview',
video: 'veo',
},
temperature: 0.7,
maxTokens: 65536,
capabilities: { chat: true, image: true, video: true },
};
}
}
ConfigManager.setConfigProvider(new VertexADCConfigProvider('my-gcp-project', 'us-central1'));
双子座AI工作室-程序
class GeminiStudioConfigProvider extends BaseConfigProvider {
constructor(apiKey) {
super();
this.apiKey = apiKey;
}
async getConfig(tenantId, env) {
return {
provider: 'gemini',
apiKey: this.apiKey,
models: {
default: 'gemini-3.5-flash',
edge: 'gemini-3.5-pro',
fast: 'gemini-3.5-flash',
image: 'gemini-3.5-pro-image-preview',
video: 'veo',
},
temperature: 0.7,
maxTokens: 65536,
capabilities: { chat: true, image: true, video: true },
};
}
}
ConfigManager.setConfigProvider(new GeminiStudioConfigProvider('your-gemini-api-key'));
自定义和 OpenAI 兼容供应商
许多第三方LLM代理和网关(LiteLLM,OpenRouter,自定义公司代理)暴露出一个与OpenAI兼容的API. 因为这个库的 OpenAI 提供者接受 baseURL 超接,你可以指向其中的任何服务,并使用任何它们暴露的模型——包括双子座,克洛德,或者你自己的微调模型——而不写自定义提供者.
如何运作
设定 LLM_PROVIDER=openai点 OPENAI_BASE_URL 在您的代理,并设定 OPENAI_MODEL 任何你的代理广告的模型名称。 库发送标准的 OpenAI 格式请求; 您的代理处理翻译 .
示例:双子座通过OpenAI兼容的代理
LLM_PROVIDER=openai
OPENAI_API_KEY=your-proxy-api-key
OPENAI_BASE_URL=https://your-proxy.example.com/v1
OPENAI_MODEL=gemini-3.5-flash
不需要更改代码 。 所有特性——聊天,工具调用,JSON模式——使用OpenAI线条格式通过代理工作.
示例: 程序配置
import { LLMService, ConfigManager, BaseConfigProvider } from '@contentgrowth/llm-service';
class ProxyConfigProvider extends BaseConfigProvider {
async getConfig(tenantId, env) {
return {
provider: 'openai',
apiKey: 'your-proxy-api-key',
baseURL: 'https://your-proxy.example.com/v1',
models: {
default: 'gemini-3.5-flash',
fast: 'gemini-3.5-flash',
edge: 'gemini-3.5-pro',
},
temperature: 0.7,
maxTokens: 65536,
};
}
}
ConfigManager.setConfigProvider(new ProxyConfigProvider());
const service = new LLMService(env);
BYOK 通过代理租户
对于多租户设置,租户可以提供他们自己的代理端点与他们的API密钥:
{
"provider": "openai",
"api_key": "tenant-proxy-key",
"baseURL": "https://tenant-proxy.example.com/v1"
}
在所有提供者中提供基础URL支持
每个供应商都尊重a baseURL 从环境变量和租户配置对象中取消:
| 提供者 | 新闻 var | 共享后退 |
|---|---|---|
openai | OPENAI_BASE_URL | LLM_BASE_URL |
gemini | GEMINI_BASE_URL | LLM_BASE_URL |
anthropic | ANTHROPIC_BASE_URL | LLM_BASE_URL |
vertex | VERTEX_BASE_URL | LLM_BASE_URL |
LLM_BASE_URL 适用于任何活跃的供应商,在通过一个单一的代理来引导所有流量时有用,无论提供者是谁.
洞穴: JSON 模式
如果您的代理服务器不支持 OpenAI 的本地版本 response_format: { type: 'json_schema' } 对于它的代用模式,严格的计划模式可能回落到 json_object 或返回错误。 像LiteLLM这样的代理通过翻译到目标模型的原生格式来处理这个,但并非所有都这样. 测试与 a chatCompletionJson 调用以确认 schema 模式的工作端到端.
JSON 模式和结构化产出
该服务支持OpenAI和双子座的本地JSON模式,保证JSON有效的响应而不回避问题.
基本 JSON 模式
const response = await llmService.chatCompletion(
messages,
tenantId,
'You are a helpful assistant. Always respond in JSON.',
{ responseFormat: 'json' } // ← Enable JSON mode
);
// Response includes auto-parsed JSON
console.log(response.parsedContent); // Already parsed object
console.log(response.content); // Raw JSON string
JSON 模式与 Schema 验证( 结构化产出)
定义保证反应结构的策略:
const schema = {
type: 'object',
properties: {
answer: { type: 'string' },
confidence: { type: 'number' },
sources: {
type: 'array',
items: { type: 'string' },
nullable: true
}
},
required: ['answer', 'confidence']
};
const response = await llmService.chatCompletion(
messages,
tenantId,
systemPrompt,
{
responseFormat: 'json_schema',
responseSchema: schema,
schemaName: 'question_answer'
}
);
// Guaranteed to match schema
const { answer, confidence, sources } = response.parsedContent;
方便方法
仅用于 JSON 回复,使用 chatCompletionJson() 直接获取解析对象:
// Returns parsed object directly (not response wrapper)
const data = await llmService.chatCompletionJson(
messages,
tenantId,
systemPrompt,
schema // optional
);
console.log(data.answer); // Direct access to fields
console.log(data.confidence); // No .parsedContent needed
灵活调用签名
这个 chatCompletion() 方法智能地检测是否您正在传递工具,选项,或者两者兼有:
// All these work!
await chatCompletion(messages, tenant, prompt);
await chatCompletion(messages, tenant, prompt, tools);
await chatCompletion(messages, tenant, prompt, { responseFormat: 'json' });
await chatCompletion(messages, tenant, prompt, tools, { responseFormat: 'json' });
支持的选项
responseFormat数字 :'text'(违约),'json',或'json_schema'responseSchema: JSON 计划对象(需要json_schema模式)schemaName: 计划的名称(可选,用于json_schema模式)strictSchema: 执行严格的验证(默认:true(中文(简体) )autoParse: 自动配置 JSON 响应( 默认 ):true(中文(简体) )temperature: 超过温度maxTokens: 覆盖最大符号tier: 型号级('default', (中文(简体) ),'fast', (中文(简体) ),'smart'(中文(简体) )
测试
谷歌云认证工具
该套件在边缘运行时环境(Cloudflare Workers,Vercel Edge等)中输出与Google Cloud服务账户合作的公用设备,因为那里没有传统的ADC(应用程序默认证书).
import {
parseGoogleCredentials,
GoogleTokenManager,
getGoogleOAuth2Token
} from '@contentgrowth/llm-service/utils/google';
// Parse service account from various formats
const sa = parseGoogleCredentials(jsonString); // or base64 or object
// Create token manager for automatic refresh
const tokenManager = new GoogleTokenManager(sa);
// Get token (cached or fresh)
const token = await tokenManager.getToken();
// Check if token is still valid
if (tokenManager.isValid()) {
console.log(`Token valid for ${tokenManager.getTimeToExpiry()} seconds`);
}
// Force refresh
tokenManager.invalidate();
// Or get token directly (no caching)
const freshToken = await getGoogleOAuth2Token(sa);
使用 llm 服务
import { LLMService } from '@contentgrowth/llm-service';
import { parseGoogleCredentials, GoogleTokenManager } from '@contentgrowth/llm-service/utils/google';
// Backend manages token lifecycle
const sa = parseGoogleCredentials(serviceAccountJson);
const tokenManager = new GoogleTokenManager(sa);
const token = await tokenManager.getToken();
// Pass pre-generated token to llm-service
const llmService = new LLMService(env, {
provider: 'vertex',
accessToken: token, // Pre-generated token
project: sa.project_id,
location: 'us-central1',
models: {
default: 'gemini-3.8-flash',
image: 'gemini-nano-banana-2.1'
}
});
// Use normally - llm-service will use the token
const response = await llmService.chat('Hello!', 'tenant-id');
这种办法的好处:
- 后端控制符号生命周期和缓存
- 服务账户证书留在后端
- llm- service 只接收到符号
- 边缘运行环境中的工作
运行 JSON 模式测试
-
创建
.env文件 (从.env.example:cp .env.example .env -
添加您的 API 密钥 改为
.env数字 :LLM_PROVIDER=openai # or gemini OPENAI_API_KEY=sk-your-key-here GEMINI_API_KEY=your-gemini-key-here -
运行测试数字 :
npm run test:json # Run comprehensive test suite npm run examples:json # Run interactive examples
见 试验. md 详细测试文件.
出版
向国家预防机制公布这套资料:
-
更新版本数字 : 更新
version内package.json。 。 。 . -
进入国家预防机制数字 :
npm login -
发布数字 :
# For public access npm publish --access public
发展
目录结构
src/llm-service.js: 主服务类.src/llm/config-manager.js: 配置解析逻辑.src/llm/config-provider.js: 抽象提供者接口.src/llm/providers/: 单个 LLM 提供者实施.
测试
运行本地测试脚本以验证导入和配置 :
node test-custom-config.js