Files
llm-intelligence/scripts/youdao_pricing_lib.go

81 lines
2.4 KiB
Go
Raw Normal View History

//go:build llm_script
package main
import (
"fmt"
"regexp"
"strings"
)
const defaultYoudaoPricingURL = "https://ai.youdao.com/new/thinkflow"
var youdaoCardPattern = regexp.MustCompile(`(?s)([A-Za-z0-9.+\- ]+)\n([^\n]+)\n.*?上下文长度\s*([0-9A-Za-z., ]+)\n.*?输入[:]?\s*¥?([\d.]+)\n.*?输出[:]?\s*¥?([\d.]+)\n.*?(查看详情|即将上线)`)
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",
OperatorWebsite: defaultYoudaoPricingURL,
OperatorType: "official",
Region: "CN",
Currency: "CNY",
InputPrice: mustParseSubscriptionPrice(match[4]),
OutputPrice: mustParseSubscriptionPrice(match[5]),
ContextLength: parseContextLengthCommon(match[3]),
SourceURL: defaultYoudaoPricingURL,
ModelSourceURL: defaultYoudaoPricingURL,
DateConfidence: "unknown",
DateSourceKind: "official_pricing",
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"
case "智谱":
return "Zhipu AI"
case "xiaomi", "小米":
return "Xiaomi"
default:
return strings.TrimSpace(raw)
}
}