malt666 commited on
Commit
502cd20
·
verified ·
1 Parent(s): eeda384

Delete mian.go

Browse files
Files changed (1) hide show
  1. main.go +0 -512
main.go DELETED
@@ -1,512 +0,0 @@
1
- package main
2
-
3
- import (
4
- "bytes"
5
- "context"
6
- "encoding/json"
7
- "fmt"
8
- "log"
9
- "net/http"
10
- "os"
11
- "strings"
12
- "sync"
13
- "time"
14
-
15
- "github.com/gin-gonic/gin"
16
- "github.com/google/generative-ai-go/genai"
17
- "google.golang.org/api/option"
18
- )
19
-
20
- // 配置结构
21
- type Config struct {
22
- AnthropicKey string
23
- GoogleKey string
24
- ServiceURL string
25
- DeepseekURL string
26
- OpenAIURL string
27
- }
28
-
29
- var (
30
- config Config
31
- configOnce sync.Once
32
- )
33
-
34
- // 请求结构
35
- type TokenCountRequest struct {
36
- Model string `json:"model" binding:"required"`
37
- Messages []Message `json:"messages" binding:"required"`
38
- System *string `json:"system,omitempty"`
39
- }
40
-
41
- type Message struct {
42
- Role string `json:"role" binding:"required"`
43
- Content string `json:"content" binding:"required"`
44
- }
45
-
46
- // 响应结构
47
- type TokenCountResponse struct {
48
- InputTokens int `json:"input_tokens"`
49
- }
50
-
51
- // 错误响应结构
52
- type ErrorResponse struct {
53
- Error string `json:"error"`
54
- }
55
-
56
- // 模型映射规则
57
- type ModelRule struct {
58
- Keywords []string
59
- Target string
60
- }
61
-
62
- var modelRules = []ModelRule{
63
- {
64
- Keywords: []string{"gpt"},
65
- Target: "gpt-3.5-turbo",
66
- },
67
- {
68
- Keywords: []string{"openai"},
69
- Target: "gpt-3.5-turbo",
70
- },
71
- {
72
- Keywords: []string{"deepseek"},
73
- Target: "deepseek-v3",
74
- },
75
- {
76
- Keywords: []string{"claude", "3", "sonnet"},
77
- Target: "claude-3-sonnet-20240229",
78
- },
79
- {
80
- Keywords: []string{"claude", "3", "7"},
81
- Target: "claude-3-7-sonnet-latest",
82
- },
83
- {
84
- Keywords: []string{"claude", "3", "5", "sonnet"},
85
- Target: "claude-3-5-sonnet-latest",
86
- },
87
- {
88
- Keywords: []string{"claude", "3", "5", "haiku"},
89
- Target: "claude-3-5-haiku-latest",
90
- },
91
- {
92
- Keywords: []string{"claude", "3", "opus"},
93
- Target: "claude-3-opus-latest",
94
- },
95
- {
96
- Keywords: []string{"claude", "3", "haiku"},
97
- Target: "claude-3-haiku-20240307",
98
- },
99
- {
100
- Keywords: []string{"gemini", "2.0"},
101
- Target: "gemini-2.0-flash",
102
- },
103
- {
104
- Keywords: []string{"gemini", "2.5"},
105
- Target: "gemini-2.0-flash", // 目前使用2.0-flash作为2.5的替代
106
- },
107
- {
108
- Keywords: []string{"gemini", "1.5"},
109
- Target: "gemini-1.5-flash",
110
- },
111
- }
112
-
113
- // 智能匹配模型名称
114
- func matchModelName(input string) string {
115
- // 转换为小写进行匹配
116
- input = strings.ToLower(input)
117
-
118
- // 特殊规则:OpenAI GPT-4o
119
- if (strings.Contains(input, "gpt") && strings.Contains(input, "4o")) ||
120
- strings.Contains(input, "o1") ||
121
- strings.Contains(input, "o3") {
122
- return "gpt-4o"
123
- }
124
-
125
- // 特殊规则:OpenAI GPT-4
126
- if (strings.Contains(input, "gpt") && strings.Contains(input, "3") && strings.Contains(input, "5")) ||
127
- (strings.Contains(input, "gpt") && strings.Contains(input, "4") && !strings.Contains(input, "4o")) {
128
- return "gpt-4"
129
- }
130
-
131
- // 遍历所有规则
132
- for _, rule := range modelRules {
133
- matches := true
134
- for _, keyword := range rule.Keywords {
135
- if !strings.Contains(input, strings.ToLower(keyword)) {
136
- matches = false
137
- break
138
- }
139
- }
140
- if matches {
141
- return rule.Target
142
- }
143
- }
144
-
145
- // 如果没有匹配到,返回原始输入
146
- return input
147
- }
148
-
149
- // 加载配置
150
- func loadConfig() Config {
151
- configOnce.Do(func() {
152
- config.AnthropicKey = os.Getenv("ANTHROPIC_API_KEY")
153
- if config.AnthropicKey == "" {
154
- log.Println("警告: ANTHROPIC_API_KEY 环境变量未设置,Claude模型将无法使用")
155
- }
156
-
157
- config.GoogleKey = os.Getenv("GOOGLE_API_KEY")
158
- if config.GoogleKey == "" {
159
- log.Println("警告: GOOGLE_API_KEY 环境变量未设置,Gemini模型将无法使用")
160
- }
161
-
162
- // 获取Deepseek服务URL
163
- config.DeepseekURL = os.Getenv("DEEPSEEK_URL")
164
- if config.DeepseekURL == "" {
165
- config.DeepseekURL = "http://127.0.0.1:7861" // 默认本地地址
166
- log.Println("使用默认Deepseek服务地址:", config.DeepseekURL)
167
- }
168
-
169
- // 获取OpenAI服务URL
170
- config.OpenAIURL = os.Getenv("OPENAI_URL")
171
- if config.OpenAIURL == "" {
172
- config.OpenAIURL = "http://127.0.0.1:7862" // 默认本地地址
173
- log.Println("使用默认OpenAI服务地址:", config.OpenAIURL)
174
- }
175
-
176
- // 获取服务URL,用于防休眠
177
- config.ServiceURL = os.Getenv("SERVICE_URL")
178
- if config.ServiceURL == "" {
179
- log.Println("SERVICE_URL 未设置,防休眠功能将被禁用")
180
- }
181
- })
182
- return config
183
- }
184
-
185
- // 使用Claude API计算token
186
- func countTokensWithClaude(req TokenCountRequest) (TokenCountResponse, error) {
187
- // 准备请求Anthropic API
188
- client := &http.Client{}
189
- data, err := json.Marshal(req)
190
- if err != nil {
191
- return TokenCountResponse{}, fmt.Errorf("序列化请求失败: %v", err)
192
- }
193
-
194
- // 创建请求
195
- request, err := http.NewRequest("POST", "https://api.anthropic.com/v1/messages/count_tokens", bytes.NewBuffer(data))
196
- if err != nil {
197
- return TokenCountResponse{}, fmt.Errorf("创建请求失败: %v", err)
198
- }
199
-
200
- // 设置请求头
201
- request.Header.Set("x-api-key", config.AnthropicKey)
202
- request.Header.Set("anthropic-version", "2023-06-01")
203
- request.Header.Set("content-type", "application/json")
204
-
205
- // 发送请求
206
- response, err := client.Do(request)
207
- if err != nil {
208
- return TokenCountResponse{}, fmt.Errorf("发送请求到Anthropic API失败: %v", err)
209
- }
210
- defer response.Body.Close()
211
-
212
- // 读取响应
213
- var result TokenCountResponse
214
- if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
215
- return TokenCountResponse{}, fmt.Errorf("解码响应失败: %v", err)
216
- }
217
-
218
- return result, nil
219
- }
220
-
221
- // 使用Gemini API计算token
222
- func countTokensWithGemini(req TokenCountRequest) (TokenCountResponse, error) {
223
- // 检查API密钥
224
- if config.GoogleKey == "" {
225
- return TokenCountResponse{}, fmt.Errorf("GOOGLE_API_KEY 未设置")
226
- }
227
-
228
- // 创建Gemini客户端
229
- ctx := context.Background()
230
- client, err := genai.NewClient(ctx, option.WithAPIKey(config.GoogleKey))
231
- if err != nil {
232
- return TokenCountResponse{}, fmt.Errorf("创建Gemini客户端失败: %v", err)
233
- }
234
- defer client.Close()
235
-
236
- // 使用已经匹配好的模型名称
237
- modelName := req.Model
238
-
239
- // 创建Gemini模型
240
- model := client.GenerativeModel(modelName)
241
-
242
- // 构建提示内容
243
- var content string
244
- if req.System != nil && *req.System != "" {
245
- content += *req.System + "\n\n"
246
- }
247
-
248
- for _, msg := range req.Messages {
249
- if msg.Role == "user" {
250
- content += "用户: " + msg.Content + "\n"
251
- } else if msg.Role == "assistant" {
252
- content += "助手: " + msg.Content + "\n"
253
- } else {
254
- content += msg.Role + ": " + msg.Content + "\n"
255
- }
256
- }
257
-
258
- // 计算token
259
- tokResp, err := model.CountTokens(ctx, genai.Text(content))
260
- if err != nil {
261
- return TokenCountResponse{}, fmt.Errorf("计算Gemini token失败: %v", err)
262
- }
263
-
264
- return TokenCountResponse{InputTokens: int(tokResp.TotalTokens)}, nil
265
- }
266
-
267
- // 使用Deepseek API计算token
268
- func countTokensWithDeepseek(req TokenCountRequest) (TokenCountResponse, error) {
269
- // 准备请求
270
- client := &http.Client{}
271
- data, err := json.Marshal(req)
272
- if err != nil {
273
- return TokenCountResponse{}, fmt.Errorf("序列化请求失败: %v", err)
274
- }
275
-
276
- // 创建请求
277
- request, err := http.NewRequest("POST", config.DeepseekURL+"/count_tokens", bytes.NewBuffer(data))
278
- if err != nil {
279
- return TokenCountResponse{}, fmt.Errorf("创建请求失败: %v", err)
280
- }
281
-
282
- // 设置请求头
283
- request.Header.Set("Content-Type", "application/json")
284
-
285
- // 发送请求
286
- response, err := client.Do(request)
287
- if err != nil {
288
- return TokenCountResponse{}, fmt.Errorf("发送请求到Deepseek服务失败: %v", err)
289
- }
290
- defer response.Body.Close()
291
-
292
- // 读取响应
293
- var result TokenCountResponse
294
- if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
295
- return TokenCountResponse{}, fmt.Errorf("解码响应失败: %v", err)
296
- }
297
-
298
- return result, nil
299
- }
300
-
301
- // 使用OpenAI API计算token
302
- func countTokensWithOpenAI(req TokenCountRequest) (TokenCountResponse, error) {
303
- // 准备请求
304
- client := &http.Client{}
305
- data, err := json.Marshal(req)
306
- if err != nil {
307
- return TokenCountResponse{}, fmt.Errorf("序列化请求失败: %v", err)
308
- }
309
-
310
- // 创建请求
311
- request, err := http.NewRequest("POST", config.OpenAIURL+"/count_tokens", bytes.NewBuffer(data))
312
- if err != nil {
313
- return TokenCountResponse{}, fmt.Errorf("创建请求失败: %v", err)
314
- }
315
-
316
- // 设置请求头
317
- request.Header.Set("Content-Type", "application/json")
318
-
319
- // 发送请求
320
- response, err := client.Do(request)
321
- if err != nil {
322
- return TokenCountResponse{}, fmt.Errorf("发送请求到OpenAI服务失败: %v", err)
323
- }
324
- defer response.Body.Close()
325
-
326
- // 读取响应
327
- var result struct {
328
- InputTokens int `json:"input_tokens"`
329
- Model string `json:"model"`
330
- Encoding string `json:"encoding"`
331
- }
332
- if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
333
- return TokenCountResponse{}, fmt.Errorf("解码响应失败: %v", err)
334
- }
335
-
336
- return TokenCountResponse{InputTokens: result.InputTokens}, nil
337
- }
338
-
339
- // 计算token
340
- func countTokens(c *gin.Context) {
341
- var req TokenCountRequest
342
- if err := c.ShouldBindJSON(&req); err != nil {
343
- c.JSON(http.StatusBadRequest, ErrorResponse{Error: err.Error()})
344
- return
345
- }
346
-
347
- // 保存原始模型名称
348
- originalModel := req.Model
349
-
350
- // 检查是否为不支持的模型
351
- isUnsupportedModel := true
352
-
353
- // 检查是否为支持的模型类型
354
- modelLower := strings.ToLower(req.Model)
355
- if strings.Contains(modelLower, "gpt") || strings.Contains(modelLower, "openai") ||
356
- strings.Contains(modelLower, "o1") || strings.Contains(modelLower, "o3") ||
357
- strings.HasPrefix(modelLower, "claude") ||
358
- strings.Contains(modelLower, "gemini") ||
359
- strings.Contains(modelLower, "deepseek") {
360
- isUnsupportedModel = false
361
- }
362
-
363
- // 智能匹配模型名称
364
- req.Model = matchModelName(req.Model)
365
-
366
- var result TokenCountResponse
367
- var err error
368
-
369
- // 优先检查是否为Deepseek模型
370
- if strings.Contains(strings.ToLower(req.Model), "deepseek") {
371
- // 使用Deepseek API
372
- result, err = countTokensWithDeepseek(req)
373
- } else if strings.Contains(strings.ToLower(req.Model), "gpt") || strings.Contains(strings.ToLower(req.Model), "openai") {
374
- // 使用OpenAI API
375
- result, err = countTokensWithOpenAI(req)
376
- } else if strings.HasPrefix(strings.ToLower(req.Model), "claude") {
377
- // 使用Claude API
378
- if config.AnthropicKey == "" {
379
- c.JSON(http.StatusBadRequest, ErrorResponse{Error: "ANTHROPIC_API_KEY 未设置,无法使用Claude模型"})
380
- return
381
- }
382
- result, err = countTokensWithClaude(req)
383
- } else if strings.Contains(strings.ToLower(req.Model), "gemini") {
384
- // 使用Gemini API
385
- if config.GoogleKey == "" {
386
- c.JSON(http.StatusBadRequest, ErrorResponse{Error: "GOOGLE_API_KEY 未设置,无法使用Gemini模型"})
387
- return
388
- }
389
- result, err = countTokensWithGemini(req)
390
- } else if isUnsupportedModel {
391
- // 不支持的模型,使用GPT-4o估算
392
- // 创建新的请求,使用GPT-4o
393
- gptReq := req
394
- gptReq.Model = "gpt-4o"
395
-
396
- // 使用OpenAI API
397
- result, err = countTokensWithOpenAI(gptReq)
398
-
399
- if err == nil {
400
- // 返回估算值,但添加警告信息
401
- c.JSON(http.StatusOK, gin.H{
402
- "input_tokens": result.InputTokens,
403
- "warning": fmt.Sprintf("The tokenizer for model '%s' is not supported yet. This is an estimation based on gpt-4o and may not be accurate.", originalModel),
404
- "estimated_with": "gpt-4o",
405
- })
406
- return
407
- }
408
- } else {
409
- // 完全不支持的情况,返回错误但仍提供估算值
410
- // 使用GPT-4o进行估算
411
- gptReq := req
412
- gptReq.Model = "gpt-4o"
413
-
414
- estimatedResult, estimateErr := countTokensWithOpenAI(gptReq)
415
- if estimateErr == nil {
416
- c.JSON(http.StatusOK, gin.H{
417
- "input_tokens": estimatedResult.InputTokens,
418
- "warning": fmt.Sprintf("The tokenizer for model '%s' is not supported yet. This is an estimation based on gpt-4o and may not be accurate.", originalModel),
419
- "estimated_with": "gpt-4o",
420
- })
421
- } else {
422
- c.JSON(http.StatusBadRequest, ErrorResponse{Error: fmt.Sprintf("The tokenizer for model '%s' is not supported yet.", originalModel)})
423
- }
424
- return
425
- }
426
-
427
- if err != nil {
428
- c.JSON(http.StatusInternalServerError, ErrorResponse{Error: err.Error()})
429
- return
430
- }
431
-
432
- // 返回结果
433
- c.JSON(http.StatusOK, result)
434
- }
435
-
436
- // 健康检查
437
- func healthCheck(c *gin.Context) {
438
- c.JSON(http.StatusOK, gin.H{
439
- "status": "healthy",
440
- "time": time.Now().Format(time.RFC3339),
441
- })
442
- }
443
-
444
- // 防休眠任务
445
- func startKeepAlive() {
446
- if config.ServiceURL == "" {
447
- return
448
- }
449
-
450
- healthURL := fmt.Sprintf("%s/health", config.ServiceURL)
451
- ticker := time.NewTicker(10 * time.Hour)
452
-
453
- // 立即执行一次检查
454
- go func() {
455
- log.Printf("Starting keep-alive checks to %s", healthURL)
456
- for {
457
- resp, err := http.Get(healthURL)
458
- if err != nil {
459
- log.Printf("Keep-alive check failed: %v", err)
460
- } else {
461
- resp.Body.Close()
462
- log.Printf("Keep-alive check successful")
463
- }
464
-
465
- // 等待下一次触发
466
- <-ticker.C
467
- }
468
- }()
469
- }
470
-
471
- func main() {
472
- // 加载配置
473
- loadConfig()
474
-
475
- // 设置gin模式
476
- gin.SetMode(gin.ReleaseMode)
477
-
478
- // 创建路由
479
- r := gin.Default()
480
-
481
- // 添加中间件
482
- r.Use(gin.Recovery())
483
- r.Use(func(c *gin.Context) {
484
- c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
485
- c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
486
- c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type")
487
- if c.Request.Method == "OPTIONS" {
488
- c.AbortWithStatus(204)
489
- return
490
- }
491
- c.Next()
492
- })
493
-
494
- // 路由
495
- r.GET("/health", healthCheck)
496
- r.POST("/count_tokens", countTokens)
497
-
498
- // 获取端口
499
- port := os.Getenv("PORT")
500
- if port == "" {
501
- port = "7860" // Hugging Face默认端口
502
- }
503
-
504
- // 启动防休眠任务
505
- startKeepAlive()
506
-
507
- // 启动服务器
508
- log.Printf("Server starting on port %s", port)
509
- if err := r.Run(":" + port); err != nil {
510
- log.Fatal(err)
511
- }
512
- }