test: add t.Parallel() for independent tests Improves test execution speed when running with -parallel flag. Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
test: add t.Parallel() for independent tests
Improves test execution speed when running with -parallel flag.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
LLM API Router Library
30 lines to route LLM APIs.
pool := routing.NewEndpointPool(endpoints, 3) resp, usage, _ := call.Request(ctx, pool, rawReq, routing.ProtocolOpenAI) // Done.
import ( "github.com/tokflux/fluxcore/routing" "github.com/tokflux/fluxcore/call" ) // 1. Define keys (connection credentials) keys := []*routing.Key{ {BaseURL: "https://api.openai.com", APIKey: key1, Protocol: routing.ProtocolOpenAI}, {BaseURL: "https://api.anthropic.com", APIKey: key2, Protocol: routing.ProtocolAnthropic}, {BaseURL: "https://generativelanguage.googleapis.com", APIKey: key3, Protocol: routing.ProtocolGemini}, } // 2. Create endpoints (key + model + pricing) // Note: Model is required for Gemini (used in URL), empty for OpenAI/Anthropic/Cohere endpoints := []*routing.Endpoint{ routing.NewEndpoint(1, keys[0], "", 0.01, 0.03), // OpenAI (model from request) routing.NewEndpoint(2, keys[1], "", 0.008, 0.024), // Anthropic (model from request) routing.NewEndpoint(3, keys[2], "gemini-pro", 0.001, 0.002), // Gemini (model in URL) } // 3. Create pool (auto-select cheapest, auto circuit breaker) pool := routing.NewEndpointPool(endpoints, 3) // 4. Non-streaming request resp, usage, _ := call.Request(ctx, pool, rawReq, routing.ProtocolOpenAI) // 5. Streaming request (auto protocol conversion) result, _ := call.RequestStream(ctx, pool, rawReq, routing.ProtocolAnthropic) for chunk := range result.Ch { c.Write(chunk) }
// Frontend: Anthropic SDK format // Backend: Gemini provider (cheaper) // fluxcore: auto-converts anthropicReq := `{"model": "claude-3", "messages": [...]}` resp, _, _ := call.Request(ctx, pool, anthropicReq, routing.ProtocolAnthropic) // Output is Anthropic format, even if pool chose Gemini endpoint
// Create endpoints with pricing ep1 := routing.NewEndpoint(1, key1, "", 0.01, 0.03) // OpenAI: $0.01/$0.03 ep2 := routing.NewEndpoint(2, key2, "", 0.001, 0.002) // Gemini: $0.001/$0.002 pool := routing.NewEndpointPool([]*routing.Endpoint{ep1, ep2}, 3) // Auto-select cheapest available endpoint // Gemini fails? Auto-switch to OpenAI
Healthy → Fail → Fail → Fail → 🔴 Circuit Open ↓ 60s auto-recovery probe
3 failures trigger circuit, auto-switch to other endpoints. 60s auto-recovery.
// Default: 3 failures trigger circuit, 60s recovery timeout ep := routing.NewEndpoint(id, key, model, inputPrice, outputPrice) // Check circuit breaker status if ep.IsCircuitBreakerOpen() { // Endpoint unhealthy, skip }
// Custom: 5 failures trigger circuit, 30s recovery timeout ep := routing.NewEndpointWithConfig(id, key, model, inputPrice, outputPrice, routing.CircuitBreakerConfig{ Threshold: 5, // Failures before circuit opens RecoveryTimeout: 30 * time.Second, // Time before retrying unhealthy endpoint })
IsCircuitBreakerOpen()
MarkSuccess()
MarkFail()
// English: ~4 chars/token (standard) message.EstimateTokens("Hello world!") // → 4 // Chinese: ~1.5 chars/token (accurate!) message.EstimateTokens("你好世界") // → 3 (not 4) // Mixed: auto-detect message.EstimateTokens("Hello 你好") // → 4
Useful for Chinese applications where billing depends on accurate estimation.
resp, usage, err := call.Request(ctx, pool, rawReq, routing.ProtocolOpenAI) if usage != nil { fmt.Printf("Input tokens: %d\n", usage.InputTokens) fmt.Printf("Output tokens: %d\n", usage.OutputTokens) fmt.Printf("Latency: %dms\n", usage.LatencyMs) fmt.Printf("Total tokens: %d\n", usage.TotalTokens()) // Check if usage is accurate (provider reported, not estimated) if usage.IsAccurate { fmt.Println("Usage is accurate (provider reported)") } }
InputTokens
int
OutputTokens
LatencyMs
IsAccurate
bool
┌─────────────────────────────────────────────┐ │ fluxcore │ │ LLM API Router Library │ ├─────────────┬───────────────────────────────┤ │ message/ │ routing/ │ │ Types │ Selection + Circuit Breaker│ │ (IR Layer) │ (Lock-free) │ ├─────────────┴───────────────────────────────┤ │ call/ │ │ HTTP Transport + Retry + Streaming │ │ + Protocol Conversion │ └─────────────────────────────────────────────┘ 4 packages. 17 files. 0 interfaces. 0 dependencies.
Package naming with business semantics:
message
routing
call
errors
CurrentEp()
fluxcore 提供 SSRF 防护工具,策略你来定。
ep := &routing.Endpoint{ BaseURL: userProvidedURL, // 用户输入 APIKey: "your-key", Protocol: routing.ProtocolOpenAI, } // Step 1: 验证格式(scheme, APIKey, Format) if err := ep.Validate(); err != nil { return err } // Step 2: SSRF 防护(可选,你的策略) u, _ := url.Parse(ep.BaseURL) if routing.IsPrivateIP(u.Hostname()) { return errors.New("private IPs not allowed") // 你的策略 }
ProtocolOpenAI
/v1/chat/completions
ProtocolAnthropic
/v1/messages
ProtocolGemini
/v1/models/{model}:generateContent
ProtocolCohere
/v1/chat
https://api.mistral.ai
https://api.groq.com
https://api.deepseek.com
https://open.bigmodel.cn/api/paas/v4/
package main import ( "io" "github.com/tokflux/fluxcore/routing" "github.com/tokflux/fluxcore/call" "github.com/gin-gonic/gin" ) func main() { keys := []*routing.Key{ {BaseURL: "https://api.openai.com", APIKey: "sk-xxx", Protocol: routing.ProtocolOpenAI}, {BaseURL: "https://api.anthropic.com", APIKey: "sk-yyy", Protocol: routing.ProtocolAnthropic}, } endpoints := []*routing.Endpoint{ routing.NewEndpoint(1, keys[0], "", 0.01, 0.03), routing.NewEndpoint(2, keys[1], "", 0.008, 0.024), } pool := routing.NewEndpointPool(endpoints, 3) r := gin.Default() r.POST("/v1/chat/completions", func(c *gin.Context) { rawReq, _ := io.ReadAll(c.Request.Body) resp, usage, err := call.Request(c.Request.Context(), pool, rawReq, routing.ProtocolOpenAI) if err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.Data(200, "application/json", resp) }) r.Run(":8080") }
go get github.com/tokflux/fluxcore
Next steps:
LLM API 路由库
30行代码,LLM API 路由搞定。
pool := routing.NewEndpointPool(endpoints, 3) resp, usage, _ := call.Request(ctx, pool, rawReq, routing.ProtocolOpenAI) // 完成。
import ( "github.com/tokflux/fluxcore/routing" "github.com/tokflux/fluxcore/call" ) // 1. 定义密钥(连接凭证) keys := []*routing.Key{ {BaseURL: "https://api.openai.com", APIKey: key1, Protocol: routing.ProtocolOpenAI}, {BaseURL: "https://api.anthropic.com", APIKey: key2, Protocol: routing.ProtocolAnthropic}, } // 2. 创建端点(密钥 + 模型 + 定价) // 注意:Model 参数对 Gemini 必填(用于 URL),OpenAI/Anthropic/Cohere 用空字符串 "" endpoints := []*routing.Endpoint{ routing.NewEndpoint(1, keys[0], "", 0.01, 0.03), // OpenAI(模型从请求获取) routing.NewEndpoint(2, keys[1], "", 0.008, 0.024), // Anthropic(模型从请求获取) routing.NewEndpoint(3, keys[2], "gemini-pro", 0.001, 0.002), // Gemini(模型在 URL 中) } // 3. 创建池(自动选择最便宜,自动熔断) pool := routing.NewEndpointPool(endpoints, 3) // 4. 非流式请求 resp, usage, _ := call.Request(ctx, pool, rawReq, routing.ProtocolOpenAI) // 5. 流式请求(协议自动转换) result, _ := call.RequestStream(ctx, pool, rawReq, routing.ProtocolAnthropic) for chunk := range result.Ch { c.Write(chunk) }
// 前端: Anthropic SDK 格式 // 后端: Gemini provider(更便宜) // fluxcore: 自动转换 anthropicReq := `{"model": "claude-3", "messages": [...]}` resp, _, _ := call.Request(ctx, pool, anthropicReq, routing.ProtocolAnthropic) // 输出是 Anthropic 格式,即使 pool 选择了 Gemini endpoint
// 创建端点,标注价格 ep1 := routing.NewEndpoint(1, key1, "", 0.01, 0.03) // OpenAI: $0.01/$0.03 ep2 := routing.NewEndpoint(2, key2, "", 0.001, 0.002) // Gemini: $0.001/$0.002 pool := routing.NewEndpointPool([]*routing.Endpoint{ep1, ep2}, 3) // 自动选择最便宜可用端点 // Gemini 失败?自动切换到 OpenAI
健康 → 失败 → 失败 → 失败 → 🔴 熔断 ↓ 60秒自动恢复探测
3次失败触发熔断,自动切换到其他端点。60秒后自动恢复探测。
默认配置:
// 默认:3次失败触发熔断,60秒恢复超时 ep := routing.NewEndpoint(id, key, model, inputPrice, outputPrice) // 检查熔断器状态 if ep.IsCircuitBreakerOpen() { // 端点不健康,跳过 }
自定义配置:
// 自定义:5次失败触发熔断,30秒恢复超时 ep := routing.NewEndpointWithConfig(id, key, model, inputPrice, outputPrice, routing.CircuitBreakerConfig{ Threshold: 5, // 触发熔断的失败次数 RecoveryTimeout: 30 * time.Second, // 重试不健康端点前的等待时间 })
// 英文: ~4 字符/token(标准) message.EstimateTokens("Hello world!") // → 4 // 中文: ~1.5 字符/token(精确!) message.EstimateTokens("你好世界") // → 3(不是 4) // 混合: 自动检测 message.EstimateTokens("Hello 你好") // → 4
对于需要精确计费的中文应用至关重要。
resp, usage, err := call.Request(ctx, pool, rawReq, routing.ProtocolOpenAI) if usage != nil { fmt.Printf("输入 tokens: %d\n", usage.InputTokens) fmt.Printf("输出 tokens: %d\n", usage.OutputTokens) fmt.Printf("延迟: %dms\n", usage.LatencyMs) fmt.Printf("总 tokens: %d\n", usage.TotalTokens()) // 检查使用量是否精确(Provider 报告,非估算) if usage.IsAccurate { fmt.Println("使用量精确(Provider 报告)") } }
┌─────────────────────────────────────────────┐ │ fluxcore │ │ LLM API 路由库 │ ├─────────────┬───────────────────────────────┤ │ message/ │ routing/ │ │ 数据类型 │ 路由选择 + 熔断器 │ │ (IR层) │ (无锁) │ ├─────────────┴───────────────────────────────┤ │ call/ │ │ HTTP传输 + 重试 + 流式 │ │ + 协议转换 │ └─────────────────────────────────────────────┘ 4个包。17个文件。0个接口。0个依赖。
ep := &routing.Endpoint{ BaseURL: userProvidedURL, // 用户输入 APIKey: "your-key", Protocol: routing.ProtocolOpenAI, } // Step 1: 验证格式 if err := ep.Validate(); err != nil { return err } // Step 2: SSRF 防护(可选,你的策略) u, _ := url.Parse(ep.BaseURL) if routing.IsPrivateIP(u.Hostname()) { return errors.New("私有 IP 不允许") // 你的策略 }
OpenAI 兼容提供商:
下一步:
MIT. Free forever.
fluxcore - LLM API Router Library. 30行代码,路由搞定。
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802032778号
fluxcore ⚡
LLM API Router Library
30 lines to route LLM APIs.
Highlights
4 Lines
Quick Start
Protocol Conversion
Price-First Routing
Circuit Breaker
3 failures trigger circuit, auto-switch to other endpoints. 60s auto-recovery.
Default Config
Custom Config
API Reference
IsCircuitBreakerOpen()MarkSuccess()MarkFail()Error Classification
Chinese-Aware Token Estimation
Useful for Chinese applications where billing depends on accurate estimation.
Usage Statistics
Usage Fields
InputTokensintOutputTokensintLatencyMsintIsAccurateboolArchitecture
Package naming with business semantics:
messageroutingcallerrorsPerformance
CurrentEp()MarkFail()Security (SSRF Protection)
fluxcore 提供 SSRF 防护工具,策略你来定。
Who Uses Fluxcore
Protocol Support
ProtocolOpenAI/v1/chat/completionsProtocolAnthropic/v1/messagesProtocolGemini/v1/models/{model}:generateContentProtocolCohere/v1/chatOpenAI-Compatible Providers
https://api.mistral.aihttps://api.groq.comhttps://api.deepseek.comhttps://open.bigmodel.cn/api/paas/v4/Integration Example
Get Started
Next steps:
中文说明
fluxcore ⚡
LLM API 路由库
30行代码,LLM API 路由搞定。
特性
4行代码起步
快速开始
协议透明转换
成本优先路由
熔断器自愈
3次失败触发熔断,自动切换到其他端点。60秒后自动恢复探测。
默认配置:
自定义配置:
智能错误分类
中文智能 Token 估算
对于需要精确计费的中文应用至关重要。
使用统计
架构
性能
CurrentEp()MarkFail()安全(SSRF 防护)
fluxcore 提供 SSRF 防护工具,策略你来定。
谁在使用
协议支持
ProtocolOpenAI/v1/chat/completionsProtocolAnthropic/v1/messagesProtocolGemini/v1/models/{model}:generateContentProtocolCohere/v1/chatOpenAI 兼容提供商:
https://api.mistral.aihttps://api.groq.comhttps://api.deepseek.comhttps://open.bigmodel.cn/api/paas/v4/开始使用
下一步:
License
MIT. Free forever.
fluxcore - LLM API Router Library. 30行代码,路由搞定。