2026-05-15 22:32:57 +08:00
|
|
|
|
//go:build llm_script
|
|
|
|
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"regexp"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-05-23 18:35:08 +08:00
|
|
|
|
const defaultYoudaoPricingURL = "https://ai.youdao.com/new/thinkflow"
|
2026-05-15 22:32:57 +08:00
|
|
|
|
|
2026-05-23 18:35:08 +08:00
|
|
|
|
var youdaoCardPattern = regexp.MustCompile(`(?s)([A-Za-z0-9.+\- ]+)\n([^\n]+)\n.*?上下文长度\s*([0-9A-Za-z., ]+)\n.*?输入[::]?\s*¥?([\d.]+)\n.*?输出[::]?\s*¥?([\d.]+)\n.*?(查看详情|即将上线)`)
|
2026-05-15 22:32:57 +08:00
|
|
|
|
|
|
|
|
|
|
func parseYoudaoPricingCatalog(raw string) ([]officialPricingRecord, error) {
|
|
|
|
|
|
matches := youdaoCardPattern.FindAllStringSubmatch(raw, -1)
|
|
|
|
|
|
if len(matches) == 0 {
|
|
|
|
|
|
return nil, fmt.Errorf("unexpected youdao pricing content")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
records := make([]officialPricingRecord, 0, len(matches))
|
|
|
|
|
|
for _, match := range matches {
|
|
|
|
|
|
modelName := strings.TrimSpace(match[1])
|
|
|
|
|
|
providerName := normalizeYoudaoProvider(match[2])
|
|
|
|
|
|
if strings.TrimSpace(match[6]) != "查看详情" {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
providerNameCn, providerCountry, providerWebsite := providerMetadata(providerName)
|
|
|
|
|
|
record := officialPricingRecord{
|
|
|
|
|
|
ModelID: normalizeExternalID("youdao", modelName),
|
|
|
|
|
|
ModelName: modelName,
|
|
|
|
|
|
ProviderName: providerName,
|
|
|
|
|
|
ProviderNameCn: providerNameCn,
|
|
|
|
|
|
ProviderCountry: providerCountry,
|
|
|
|
|
|
ProviderWebsite: providerWebsite,
|
|
|
|
|
|
OperatorName: "Youdao Zhiyun MaaS",
|
|
|
|
|
|
OperatorNameCn: "有道智云 MaaS",
|
|
|
|
|
|
OperatorCountry: "CN",
|
2026-05-23 18:35:08 +08:00
|
|
|
|
OperatorWebsite: defaultYoudaoPricingURL,
|
|
|
|
|
|
OperatorType: "official",
|
2026-05-15 22:32:57 +08:00
|
|
|
|
Region: "CN",
|
|
|
|
|
|
Currency: "CNY",
|
|
|
|
|
|
InputPrice: mustParseSubscriptionPrice(match[4]),
|
|
|
|
|
|
OutputPrice: mustParseSubscriptionPrice(match[5]),
|
|
|
|
|
|
ContextLength: parseContextLengthCommon(match[3]),
|
|
|
|
|
|
SourceURL: defaultYoudaoPricingURL,
|
|
|
|
|
|
ModelSourceURL: defaultYoudaoPricingURL,
|
|
|
|
|
|
DateConfidence: "unknown",
|
2026-05-23 18:35:08 +08:00
|
|
|
|
DateSourceKind: "official_pricing",
|
2026-05-15 22:32:57 +08:00
|
|
|
|
Modality: detectModality(modelName),
|
|
|
|
|
|
}
|
|
|
|
|
|
record.IsFree = record.InputPrice == 0 && record.OutputPrice == 0
|
|
|
|
|
|
records = append(records, record)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(records) == 0 {
|
|
|
|
|
|
return nil, fmt.Errorf("no active youdao pricing cards found")
|
|
|
|
|
|
}
|
|
|
|
|
|
return records, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func normalizeYoudaoProvider(raw string) string {
|
|
|
|
|
|
switch strings.ToLower(strings.TrimSpace(raw)) {
|
|
|
|
|
|
case "deepseek":
|
|
|
|
|
|
return "DeepSeek"
|
|
|
|
|
|
case "qwen":
|
|
|
|
|
|
return "Qwen"
|
|
|
|
|
|
case "kimi":
|
|
|
|
|
|
return "Moonshot AI"
|
|
|
|
|
|
case "minimax":
|
|
|
|
|
|
return "MiniMax"
|
|
|
|
|
|
case "zhipu":
|
|
|
|
|
|
return "Zhipu AI"
|
2026-05-23 18:35:08 +08:00
|
|
|
|
case "智谱":
|
|
|
|
|
|
return "Zhipu AI"
|
|
|
|
|
|
case "xiaomi", "小米":
|
|
|
|
|
|
return "Xiaomi"
|
2026-05-15 22:32:57 +08:00
|
|
|
|
default:
|
|
|
|
|
|
return strings.TrimSpace(raw)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|