2026-08-14 07:52:01 +08:00
|
|
|
|
// Package ai 定义 AI 聊天 Provider 抽象与工厂:
|
|
|
|
|
|
// 上层只依赖 Provider 接口,通过 New 按设置创建讯飞星火 Lite 或 DeepSeek 实例。
|
|
|
|
|
|
package ai
|
|
|
|
|
|
|
|
|
|
|
|
import "context"
|
|
|
|
|
|
|
|
|
|
|
|
// Message 是一条对话消息(role: system | user | assistant)。
|
|
|
|
|
|
type Message struct {
|
|
|
|
|
|
Role string `json:"role"`
|
|
|
|
|
|
Content string `json:"content"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Chunk 是流式返回的一段增量内容;Err 非空表示流异常中止。
|
2026-08-15 17:18:00 +08:00
|
|
|
|
// Usage 在流结束时可选附带 token 用量(若服务商提供)。
|
2026-08-14 07:52:01 +08:00
|
|
|
|
type Chunk struct {
|
|
|
|
|
|
Content string
|
|
|
|
|
|
Err error
|
2026-08-15 17:18:00 +08:00
|
|
|
|
Usage *Usage
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Usage 一次调用的 token 用量。
|
|
|
|
|
|
type Usage struct {
|
|
|
|
|
|
PromptTokens int64
|
|
|
|
|
|
CompletionTokens int64
|
2026-08-17 14:00:47 +08:00
|
|
|
|
CachedTokens int64 // 提示缓存命中(服务商返回时才有)
|
2026-08-15 17:18:00 +08:00
|
|
|
|
Estimated bool
|
2026-08-14 07:52:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-17 14:00:47 +08:00
|
|
|
|
// EstimateUsage 在服务商未回 usage 时按字符粗估(约 4 字符 ≈ 1 token)。
|
|
|
|
|
|
func EstimateUsage(messages []Message, completion string) *Usage {
|
|
|
|
|
|
n := 0
|
|
|
|
|
|
for _, m := range messages {
|
|
|
|
|
|
n += len(m.Content)
|
|
|
|
|
|
}
|
|
|
|
|
|
return &Usage{
|
|
|
|
|
|
PromptTokens: int64((n + 3) / 4),
|
|
|
|
|
|
CompletionTokens: int64((len(completion) + 3) / 4),
|
|
|
|
|
|
Estimated: true,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-14 07:52:01 +08:00
|
|
|
|
// Provider 是 AI 服务商的统一抽象。
|
|
|
|
|
|
type Provider interface {
|
|
|
|
|
|
Name() string
|
|
|
|
|
|
// ChatStream 发起流式对话,返回增量内容通道;通道关闭即流结束。
|
|
|
|
|
|
ChatStream(ctx context.Context, messages []Message) (<-chan Chunk, error)
|
|
|
|
|
|
}
|