|
|
@@ -60,6 +60,17 @@ func (s *OpenAIEmbeddingService) EmbedTexts(ctx context.Context, texts []string)
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
+ // 诊断日志:确认发请求前我们到底发了几条文本(用于排查 1 文档 vs 6 向量 问题)
|
|
|
+ log.Printf("[嵌入] EmbedTexts 请求: len(texts)=%d, model=%s, apiURL=%s", len(texts), s.model, strings.TrimSuffix(s.apiURL, "/"))
|
|
|
+ for i, t := range texts {
|
|
|
+ runeLen := len([]rune(t))
|
|
|
+ preview := t
|
|
|
+ if runeLen > 60 {
|
|
|
+ preview = string([]rune(t)[:60]) + "..."
|
|
|
+ }
|
|
|
+ log.Printf("[嵌入] texts[%d] 长度=%d 字符, 预览: %q", i, runeLen, preview)
|
|
|
+ }
|
|
|
+
|
|
|
// 支持填完整路径或仅填 base:若已以 /embeddings 结尾则不再追加,否则追加 /embeddings
|
|
|
url := strings.TrimSuffix(s.apiURL, "/")
|
|
|
if url != "" && !strings.HasSuffix(strings.ToLower(url), "/embeddings") {
|
|
|
@@ -125,6 +136,14 @@ func (s *OpenAIEmbeddingService) EmbedTexts(ctx context.Context, texts []string)
|
|
|
return nil, fmt.Errorf("解析响应失败: %w", err)
|
|
|
}
|
|
|
|
|
|
+ // 诊断日志:API 实际返回了几个向量(若与 len(texts) 不一致,说明接口按长文本分块或我们发了多条)
|
|
|
+ numIn := len(texts)
|
|
|
+ numOut := len(response.Data)
|
|
|
+ log.Printf("[嵌入] EmbedTexts 响应: len(texts)=%d -> len(data)=%d (API 返回向量数)", numIn, numOut)
|
|
|
+ if numOut != numIn {
|
|
|
+ log.Printf("[嵌入] 数量不一致: 我们发了 %d 条文本,API 返回了 %d 个向量(可能接口对长文本分块,或请求被中间层改写)", numIn, numOut)
|
|
|
+ }
|
|
|
+
|
|
|
// 转换为 float32
|
|
|
result := make([][]float32, len(response.Data))
|
|
|
for i, item := range response.Data {
|