mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-20 14:41:05 +08:00
Go: add LLM usage (#17049)
### Summary ``` RAGFlow(api/default)> CHAT WITH 'glm-4-flash@new_test@zhipu-ai' MESSAGE '30 words describes LLM'; Answer: Hello! I'm ChatGLM, an AI assistant. Feel free to ask me any questions or request help with any tasks. Input tokens: 5 Output tokens: 28 Time: 12.748241 ``` Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@@ -193,6 +193,7 @@ func NewDriverHTTPClient() *http.Client {
|
||||
t.IdleConnTimeout = 90 * time.Second
|
||||
t.DisableCompression = false
|
||||
t.ResponseHeaderTimeout = 60 * time.Second
|
||||
t.TLSHandshakeTimeout = 30 * time.Second
|
||||
return &http.Client{Transport: t}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,28 @@ type ChatConfig struct {
|
||||
StreamCallback func(contentDelta, reasoningDelta string) `json:"-"`
|
||||
}
|
||||
|
||||
type ChatAppConfig struct {
|
||||
UserID string `json:"user_id"`
|
||||
UserEmail string `json:"user_email"`
|
||||
TenantID string `json:"tenant_id"`
|
||||
TenantEmail string `json:"tenant_email"`
|
||||
GroupID *string `json:"group_id"`
|
||||
GroupName *string `json:"group_name"`
|
||||
AppID string `json:"app_id"`
|
||||
AppName string `json:"app_name"`
|
||||
SessionID *string `json:"session_id"`
|
||||
ProviderName string `json:"provider_name"`
|
||||
InstanceID string `json:"instance_id"`
|
||||
ModelName string `json:"model_name"`
|
||||
Type string `json:"type"`
|
||||
InputTokens uint64 `json:"input_tokens"`
|
||||
OutputTokens uint64 `json:"output_tokens"`
|
||||
TotalTokens uint64 `json:"total_tokens"`
|
||||
RequestID *string `json:"request_id"`
|
||||
ResponseTimeMS uint64 `json:"response_time_ms"`
|
||||
ErrorMessage *string `json:"error_message"`
|
||||
}
|
||||
|
||||
type APIConfig struct {
|
||||
ApiKey *string
|
||||
Region *string
|
||||
|
||||
@@ -55,6 +55,31 @@ func (z *ZhipuAIModel) Name() string {
|
||||
return "zhipu"
|
||||
}
|
||||
|
||||
type ZhipuChatResponse struct {
|
||||
Choices []struct {
|
||||
FinishReason string `json:"finish_reason"`
|
||||
Index int `json:"index"`
|
||||
Message struct {
|
||||
Content string `json:"content"`
|
||||
ReasoningContent string `json:"reasoning_content"`
|
||||
Role string `json:"role"`
|
||||
} `json:"message"`
|
||||
} `json:"choices"`
|
||||
Created int `json:"created"`
|
||||
Id string `json:"id"`
|
||||
Model string `json:"model"`
|
||||
Object string `json:"object"`
|
||||
RequestId string `json:"request_id"`
|
||||
Usage struct {
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
PromptTokensDetails struct {
|
||||
CachedTokens int `json:"cached_tokens"`
|
||||
} `json:"prompt_tokens_details"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
} `json:"usage"`
|
||||
}
|
||||
|
||||
// ChatWithMessages sends multiple messages with roles and returns response
|
||||
func (z *ZhipuAIModel) ChatWithMessages(modelName string, messages []Message, apiConfig *APIConfig, chatModelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
if err := z.baseModel.APIConfigCheck(apiConfig); err != nil {
|
||||
@@ -155,46 +180,28 @@ func (z *ZhipuAIModel) ChatWithMessages(modelName string, messages []Message, ap
|
||||
}
|
||||
|
||||
// Parse response
|
||||
var result map[string]interface{}
|
||||
var result ZhipuChatResponse
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
choices, ok := result["choices"].([]interface{})
|
||||
if !ok || len(choices) == 0 {
|
||||
return nil, fmt.Errorf("no choices in response")
|
||||
}
|
||||
content := &result.Choices[0].Message.Content
|
||||
|
||||
firstChoice, ok := choices[0].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid choice format")
|
||||
}
|
||||
|
||||
messageMap, ok := firstChoice["message"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid message format")
|
||||
}
|
||||
|
||||
content, ok := messageMap["content"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid content format")
|
||||
}
|
||||
|
||||
var reasonContent string
|
||||
var reasonContent *string
|
||||
if chatModelConfig != nil && chatModelConfig.Thinking != nil && *chatModelConfig.Thinking {
|
||||
reasonContent, ok = messageMap["reasoning_content"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid content format")
|
||||
}
|
||||
// if first char of reasonContent is \n remove the '\n'
|
||||
if reasonContent != "" && reasonContent[0] == '\n' {
|
||||
reasonContent = reasonContent[1:]
|
||||
}
|
||||
reasonContent = &result.Choices[0].Message.ReasoningContent
|
||||
}
|
||||
|
||||
usage := &ChatUsage{
|
||||
PromptTokens: result.Usage.PromptTokens,
|
||||
CompletionTokens: result.Usage.CompletionTokens,
|
||||
TotalTokens: result.Usage.TotalTokens,
|
||||
}
|
||||
|
||||
chatResponse := &ChatResponse{
|
||||
Answer: &content,
|
||||
ReasonContent: &reasonContent,
|
||||
Answer: content,
|
||||
ReasonContent: reasonContent,
|
||||
Usage: usage,
|
||||
}
|
||||
|
||||
return chatResponse, nil
|
||||
|
||||
Reference in New Issue
Block a user