mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-20 22:51:06 +08:00
Refactor model in GO (#14398)
### What problem does this PR solve? Refactor model in GO ### Type of change - [x] Refactoring
This commit is contained in:
@@ -337,6 +337,21 @@ func (z *AliyunModel) EncodeToEmbedding(modelName *string, texts []string, apiCo
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *AliyunModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Encode not implemented", z.Name())
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *AliyunModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, EncodeQuery not implemented", z.Name())
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *AliyunModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
type AliyunModelItem struct {
|
||||
ModelName string `json:"model_name"`
|
||||
BaseCapacity int `json:"base_capacity"`
|
||||
|
||||
@@ -401,6 +401,16 @@ func (z *DeepSeekModel) EncodeToEmbedding(modelName *string, texts []string, api
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *DeepSeekModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Encode not implemented", z.Name())
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *DeepSeekModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, EncodeQuery not implemented", z.Name())
|
||||
}
|
||||
|
||||
type DSModel struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
@@ -476,3 +486,8 @@ func (z *DeepSeekModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *DeepSeekModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
@@ -58,6 +58,16 @@ func (z *DummyModel) EncodeToEmbedding(modelName *string, texts []string, apiCon
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *DummyModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Encode not implemented", z.Name())
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *DummyModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, EncodeQuery not implemented", z.Name())
|
||||
}
|
||||
|
||||
func (z *DummyModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
@@ -69,3 +79,8 @@ func (z *DummyModel) Balance(apiConfig *APIConfig) (map[string]interface{}, erro
|
||||
func (z *DummyModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
return fmt.Errorf("no such method")
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *DummyModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
@@ -367,6 +367,21 @@ func (z *GiteeModel) EncodeToEmbedding(modelName *string, texts []string, apiCon
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *GiteeModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Encode not implemented", z.Name())
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *GiteeModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, EncodeQuery not implemented", z.Name())
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *GiteeModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
func (z *GiteeModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
var region = "default"
|
||||
if apiConfig.Region != nil {
|
||||
|
||||
@@ -171,3 +171,25 @@ func (z *GoogleModel) Balance(apiConfig *APIConfig) (map[string]interface{}, err
|
||||
func (z *GoogleModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
return fmt.Errorf("no such method")
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *GoogleModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return z.EncodeToEmbedding(modelName, texts, apiConfig, nil)
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *GoogleModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
embeddings, err := z.Encode(modelName, []string{query}, apiConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(embeddings) == 0 {
|
||||
return nil, fmt.Errorf("no embedding returned")
|
||||
}
|
||||
return embeddings[0], nil
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *GoogleModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
@@ -71,6 +71,16 @@ func (z *MinimaxModel) EncodeToEmbedding(modelName *string, texts []string, apiC
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *MinimaxModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Encode not implemented", z.Name())
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *MinimaxModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, EncodeQuery not implemented", z.Name())
|
||||
}
|
||||
|
||||
func (z *MinimaxModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
@@ -112,3 +122,8 @@ func (z *MinimaxModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *MinimaxModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
@@ -73,6 +73,16 @@ func (z *MoonshotModel) EncodeToEmbedding(modelName *string, texts []string, api
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *MoonshotModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Encode not implemented", z.Name())
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *MoonshotModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, EncodeQuery not implemented", z.Name())
|
||||
}
|
||||
|
||||
func (z *MoonshotModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
var region = "default"
|
||||
if apiConfig.Region != nil {
|
||||
@@ -193,3 +203,8 @@ func (z *MoonshotModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *MoonshotModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
@@ -56,6 +56,26 @@ func (z *SiliconflowModel) Name() string {
|
||||
return "siliconflow"
|
||||
}
|
||||
|
||||
|
||||
// SiliconflowRerankRequest represents SILICONFLOW rerank request
|
||||
type SiliconflowRerankRequest struct {
|
||||
Model string `json:"model"`
|
||||
Query string `json:"query"`
|
||||
Documents []string `json:"documents"`
|
||||
TopN int `json:"top_n"`
|
||||
ReturnDocuments bool `json:"return_documents"`
|
||||
MaxChunksPerDoc int `json:"max_chunks_per_doc"`
|
||||
OverlapTokens int `json:"overlap_tokens"`
|
||||
}
|
||||
|
||||
// SiliconflowRerankResponse represents SILICONFLOW rerank response
|
||||
type SiliconflowRerankResponse struct {
|
||||
Results []struct {
|
||||
Index int `json:"index"`
|
||||
RelevanceScore float64 `json:"relevance_score"`
|
||||
} `json:"results"`
|
||||
}
|
||||
|
||||
// Chat sends a message and returns response
|
||||
func (z *SiliconflowModel) Chat(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
if message == nil {
|
||||
@@ -363,8 +383,116 @@ func (z *SiliconflowModel) ChatStreamlyWithSender(modelName, message *string, ap
|
||||
}
|
||||
|
||||
// EncodeToEmbedding encodes a list of texts into embeddings
|
||||
func (z *SiliconflowModel) EncodeToEmbedding(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
func (s *SiliconflowModel) EncodeToEmbedding(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([][]float64, error) {
|
||||
if len(texts) == 0 {
|
||||
return [][]float64{}, nil
|
||||
}
|
||||
|
||||
var region = "default"
|
||||
if apiConfig != nil && apiConfig.Region != nil {
|
||||
region = *apiConfig.Region
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", strings.TrimSuffix(s.BaseURL[region], "/"), s.URLSuffix.Embedding)
|
||||
|
||||
apiKey := ""
|
||||
if apiConfig != nil && apiConfig.ApiKey != nil {
|
||||
apiKey = *apiConfig.ApiKey
|
||||
}
|
||||
|
||||
embeddings := make([][]float64, len(texts))
|
||||
|
||||
for i, text := range texts {
|
||||
reqBody := map[string]interface{}{
|
||||
"model": modelName,
|
||||
"input": text,
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal request: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if apiKey != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||
}
|
||||
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to send request: %w", err)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("SILICONFLOW API error: %s, body: %s", resp.Status, string(body))
|
||||
}
|
||||
|
||||
// Parse response
|
||||
var result map[string]interface{}
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
data, ok := result["data"].([]interface{})
|
||||
if !ok || len(data) == 0 {
|
||||
return nil, fmt.Errorf("no data in response")
|
||||
}
|
||||
|
||||
firstData, ok := data[0].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid data format")
|
||||
}
|
||||
|
||||
embeddingSlice, ok := firstData["embedding"].([]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid embedding format")
|
||||
}
|
||||
|
||||
embedding := make([]float64, len(embeddingSlice))
|
||||
for j, v := range embeddingSlice {
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
embedding[j] = val
|
||||
case float32:
|
||||
embedding[j] = float64(val)
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected embedding value type")
|
||||
}
|
||||
}
|
||||
|
||||
embeddings[i] = embedding
|
||||
}
|
||||
|
||||
return embeddings, nil
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (s *SiliconflowModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return s.EncodeToEmbedding(modelName, texts, apiConfig, nil)
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (s *SiliconflowModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
embeddings, err := s.Encode(modelName, []string{query}, apiConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(embeddings) == 0 {
|
||||
return nil, fmt.Errorf("no embedding returned")
|
||||
}
|
||||
return embeddings[0], nil
|
||||
}
|
||||
|
||||
func (z *SiliconflowModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
@@ -435,3 +563,74 @@ func (z *SiliconflowModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (s *SiliconflowModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
if len(texts) == 0 {
|
||||
return []float64{}, nil
|
||||
}
|
||||
|
||||
var region = "default"
|
||||
if apiConfig != nil && apiConfig.Region != nil {
|
||||
region = *apiConfig.Region
|
||||
}
|
||||
|
||||
apiKey := ""
|
||||
if apiConfig != nil && apiConfig.ApiKey != nil {
|
||||
apiKey = *apiConfig.ApiKey
|
||||
}
|
||||
|
||||
reqBody := SiliconflowRerankRequest{
|
||||
Model: *modelName,
|
||||
Query: query,
|
||||
Documents: texts,
|
||||
TopN: len(texts),
|
||||
ReturnDocuments: false,
|
||||
MaxChunksPerDoc: 1024,
|
||||
OverlapTokens: 80,
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal request: %w", err)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", strings.TrimSuffix(s.BaseURL[region], "/"), s.URLSuffix.Rerank)
|
||||
|
||||
req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonData)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if apiKey != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||
}
|
||||
|
||||
resp, err := s.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to send request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return nil, fmt.Errorf("SiliconFlow Rerank API error: %s, body: %s", resp.Status, string(body))
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
var rerankResp SiliconflowRerankResponse
|
||||
if err := json.Unmarshal(body, &rerankResp); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
|
||||
scores := make([]float64, len(texts))
|
||||
for _, result := range rerankResp.Results {
|
||||
if result.Index >= 0 && result.Index < len(texts) {
|
||||
scores[result.Index] = result.RelevanceScore
|
||||
}
|
||||
}
|
||||
|
||||
return scores, nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package models
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Message represents a chat message with role
|
||||
type Message struct {
|
||||
Role string
|
||||
@@ -16,8 +18,14 @@ type ModelDriver interface {
|
||||
ChatWithMessages(modelName string, apiKey *string, messages []Message, modelConfig *ChatConfig) (string, error)
|
||||
// ChatStreamlyWithSender sends a message and streams response via sender function (best performance, no channel)
|
||||
ChatStreamlyWithSender(modelName, message *string, apiConfig *APIConfig, modelConfig *ChatConfig, sender func(*string, *string) error) error
|
||||
// Encode encodes a list of texts into embeddings
|
||||
// EncodeToEmbedding encodes a list of texts into embeddings
|
||||
EncodeToEmbedding(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([][]float64, error)
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error)
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error)
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error)
|
||||
// List suppported models
|
||||
ListModels(apiConfig *APIConfig) ([]string, error)
|
||||
|
||||
@@ -64,3 +72,73 @@ type APIConfig struct {
|
||||
|
||||
type EmbeddingConfig struct {
|
||||
}
|
||||
|
||||
// EmbeddingModel wraps a ModelDriver with embedding-specific configuration
|
||||
type EmbeddingModel struct {
|
||||
ModelDriver ModelDriver
|
||||
ModelName string
|
||||
APIConfig *APIConfig
|
||||
}
|
||||
|
||||
// NewEmbeddingModel creates a new EmbeddingModel
|
||||
func NewEmbeddingModel(driver ModelDriver, modelName string, apiConfig *APIConfig) *EmbeddingModel {
|
||||
return &EmbeddingModel{
|
||||
ModelDriver: driver,
|
||||
ModelName: modelName,
|
||||
APIConfig: apiConfig,
|
||||
}
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings
|
||||
func (e *EmbeddingModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return e.ModelDriver.EncodeToEmbedding(modelName, texts, apiConfig, nil)
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding
|
||||
func (e *EmbeddingModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
embeddings, err := e.ModelDriver.Encode(modelName, []string{query}, apiConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(embeddings) == 0 {
|
||||
return nil, fmt.Errorf("no embedding returned")
|
||||
}
|
||||
return embeddings[0], nil
|
||||
}
|
||||
|
||||
// RerankModel wraps a ModelDriver with rerank-specific configuration
|
||||
type RerankModel struct {
|
||||
ModelDriver ModelDriver
|
||||
ModelName string
|
||||
APIConfig *APIConfig
|
||||
}
|
||||
|
||||
// NewRerankModel creates a new RerankModel
|
||||
func NewRerankModel(driver ModelDriver, modelName string, apiConfig *APIConfig) *RerankModel {
|
||||
return &RerankModel{
|
||||
ModelDriver: driver,
|
||||
ModelName: modelName,
|
||||
APIConfig: apiConfig,
|
||||
}
|
||||
}
|
||||
|
||||
// Rerank calculates similarity between query and texts
|
||||
func (r *RerankModel) Rerank(query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return r.ModelDriver.Rerank(&r.ModelName, query, texts, apiConfig)
|
||||
}
|
||||
|
||||
// ChatModel wraps a ModelDriver with chat-specific configuration
|
||||
type ChatModel struct {
|
||||
ModelDriver ModelDriver
|
||||
ModelName string
|
||||
APIConfig *APIConfig
|
||||
}
|
||||
|
||||
// NewChatModel creates a new ChatModel
|
||||
func NewChatModel(driver ModelDriver, modelName string, apiConfig *APIConfig) *ChatModel {
|
||||
return &ChatModel{
|
||||
ModelDriver: driver,
|
||||
ModelName: modelName,
|
||||
APIConfig: apiConfig,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ func (z *ZhipuAIModel) ChatStreamlyWithSender(modelName, message *string, apiCon
|
||||
region = *apiConfig.Region
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/chat/completions", z.BaseURL[region])
|
||||
url := fmt.Sprintf("%s/%s", strings.TrimSuffix(z.BaseURL[region], "/"), z.URLSuffix.Chat)
|
||||
|
||||
// Build request body with streaming enabled
|
||||
reqBody := map[string]interface{}{
|
||||
@@ -440,7 +440,7 @@ func (z *ZhipuAIModel) EncodeToEmbedding(modelName *string, texts []string, apiC
|
||||
region = *apiConfig.Region
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/embedding", z.BaseURL[region])
|
||||
url := fmt.Sprintf("%s/%s", strings.TrimSuffix(z.BaseURL[region], "/"), z.URLSuffix.Embedding)
|
||||
|
||||
embeddings := make([][]float64, len(texts))
|
||||
|
||||
@@ -518,6 +518,23 @@ func (z *ZhipuAIModel) EncodeToEmbedding(modelName *string, texts []string, apiC
|
||||
return embeddings, nil
|
||||
}
|
||||
|
||||
// Encode encodes a list of texts into embeddings (convenience method)
|
||||
func (z *ZhipuAIModel) Encode(modelName *string, texts []string, apiConfig *APIConfig) ([][]float64, error) {
|
||||
return z.EncodeToEmbedding(modelName, texts, apiConfig, nil)
|
||||
}
|
||||
|
||||
// EncodeQuery encodes a single query string into embedding (convenience method)
|
||||
func (z *ZhipuAIModel) EncodeQuery(modelName *string, query string, apiConfig *APIConfig) ([]float64, error) {
|
||||
embeddings, err := z.Encode(modelName, []string{query}, apiConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(embeddings) == 0 {
|
||||
return nil, fmt.Errorf("no embedding returned")
|
||||
}
|
||||
return embeddings[0], nil
|
||||
}
|
||||
|
||||
func (z *ZhipuAIModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
@@ -559,3 +576,8 @@ func (z *ZhipuAIModel) CheckConnection(apiConfig *APIConfig) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rerank calculates similarity scores between query and texts
|
||||
func (z *ZhipuAIModel) Rerank(modelName *string, query string, texts []string, apiConfig *APIConfig) ([]float64, error) {
|
||||
return nil, fmt.Errorf("%s, Rerank not implemented", z.Name())
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"ragflow/internal/entity/models"
|
||||
)
|
||||
|
||||
// ModelType represents the type of model
|
||||
type ModelType string
|
||||
|
||||
@@ -39,9 +43,9 @@ const (
|
||||
// EmbeddingModel interface for embedding models
|
||||
type EmbeddingModel interface {
|
||||
// Encode encodes a list of texts into embeddings
|
||||
Encode(texts []string) ([][]float64, error)
|
||||
Encode(modelName *string, texts []string, apiConfig *models.APIConfig) ([][]float64, error)
|
||||
// EncodeQuery encodes a single query string into embedding
|
||||
EncodeQuery(query string) ([]float64, error)
|
||||
EncodeQuery(modelName *string, query string, apiConfig *models.APIConfig) ([]float64, error)
|
||||
}
|
||||
|
||||
// ChatModel interface for chat models
|
||||
@@ -54,8 +58,8 @@ type ChatModel interface {
|
||||
|
||||
// RerankModel interface for rerank models
|
||||
type RerankModel interface {
|
||||
// Similarity calculates similarity between query and texts
|
||||
Similarity(query string, texts []string) ([]float64, error)
|
||||
// Rerank calculates similarity between query and texts
|
||||
Rerank(query string, texts []string, apiConfig *models.APIConfig) ([]float64, error)
|
||||
}
|
||||
|
||||
// ModelConfig represents configuration for a model
|
||||
|
||||
Reference in New Issue
Block a user