mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-12 06:35:44 +08:00
Fix(Go): make Baidu Encode fail loudly on malformed responses (#14721)
### What problem does this PR solve? The Baidu (Qianfan) `Encode` method silently swallowed malformed responses. If a `data[]` item from the API was missing a field (`index`, `embedding`, or unexpected shape), the loop did `continue` instead of returning an error, leaving `nil` entries in the result slice. Callers got back partial results with no indication anything went wrong, which then crashes downstream consumers when they try to use a `nil` vector. Concrete gaps fixed: - No count-mismatch check between `data` length and input texts (only checked for empty) - No duplicate-index detection (a duplicate would silently overwrite) - No missing-index final scan - No empty-embedding rejection - No per-call context timeout - `EmbeddingConfig.Dimension` (added in #14735) was not propagated This PR replaces `map[string]interface{}` parsing with a typed `baiduEmbeddingResponse` struct, applies the standard four-layer validation (count → out-of-range → duplicate → empty → final missing-index scan), adds `context.WithTimeout(nonStreamCallTimeout)`, and forwards `embeddingConfig.Dimension` as the `dimensions` parameter (Baidu Qianfan v2 uses an OpenAI-compatible API). ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@@ -429,7 +429,7 @@ type baiduEmbeddingResponse struct {
|
||||
type baiduEmbeddingData struct {
|
||||
Object string `json:"object"`
|
||||
Embedding []float64 `json:"embedding"`
|
||||
Index int `json:"index"`
|
||||
Index *int `json:"index"`
|
||||
}
|
||||
|
||||
type baiduUsage struct {
|
||||
@@ -438,6 +438,12 @@ type baiduUsage struct {
|
||||
}
|
||||
|
||||
func (b *BaiduModel) Embed(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([]EmbeddingData, error) {
|
||||
if apiConfig == nil || apiConfig.ApiKey == nil || *apiConfig.ApiKey == "" {
|
||||
return nil, fmt.Errorf("api key is required")
|
||||
}
|
||||
if modelName == nil || *modelName == "" {
|
||||
return nil, fmt.Errorf("model name is required")
|
||||
}
|
||||
if len(texts) == 0 {
|
||||
return []EmbeddingData{}, nil
|
||||
}
|
||||
@@ -453,6 +459,9 @@ func (b *BaiduModel) Embed(modelName *string, texts []string, apiConfig *APIConf
|
||||
"model": *modelName,
|
||||
"input": texts,
|
||||
}
|
||||
if embeddingConfig != nil && embeddingConfig.Dimension > 0 {
|
||||
reqBody["dimensions"] = embeddingConfig.Dimension
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
@@ -487,12 +496,37 @@ func (b *BaiduModel) Embed(modelName *string, texts []string, apiConfig *APIConf
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
var embeddings []EmbeddingData
|
||||
for _, dataElem := range parsed.Data {
|
||||
var embeddingData EmbeddingData
|
||||
embeddingData.Embedding = dataElem.Embedding
|
||||
embeddingData.Index = dataElem.Index
|
||||
embeddings = append(embeddings, embeddingData)
|
||||
if len(parsed.Data) != len(texts) {
|
||||
return nil, fmt.Errorf("expected %d embeddings, got %d", len(texts), len(parsed.Data))
|
||||
}
|
||||
|
||||
embeddings := make([]EmbeddingData, len(texts))
|
||||
seen := make([]bool, len(texts))
|
||||
for _, item := range parsed.Data {
|
||||
if item.Index == nil {
|
||||
return nil, fmt.Errorf("missing index field in embedding item")
|
||||
}
|
||||
idx := *item.Index
|
||||
if idx < 0 || idx >= len(texts) {
|
||||
return nil, fmt.Errorf("embedding index %d out of range", idx)
|
||||
}
|
||||
if seen[idx] {
|
||||
return nil, fmt.Errorf("duplicate embedding index %d", idx)
|
||||
}
|
||||
if len(item.Embedding) == 0 {
|
||||
return nil, fmt.Errorf("empty embedding at index %d", idx)
|
||||
}
|
||||
seen[idx] = true
|
||||
embeddings[idx] = EmbeddingData{
|
||||
Embedding: item.Embedding,
|
||||
Index: idx,
|
||||
}
|
||||
}
|
||||
|
||||
for i, ok := range seen {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing embedding index %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
return embeddings, nil
|
||||
|
||||
Reference in New Issue
Block a user