fix(ai): 推理模型 content 为空时回退 reasoning_content
根因(带响应体日志实测确认):deepseek-v4-pro 等推理系模型把输出写在 reasoning_content,MaxTokens 较小时最终 content 为空串,被误判为「模型返回了 空内容(检查 baseURL)」——与 key/端点无关,保存的 key 解密与沿用逻辑均正常 (空参/掩码传参两路均能取到库内真值)。 修复:content 空白时回退使用 reasoning_content;移除调试日志。
This commit is contained in:
1 parent
37a610b603
commit
448f695c28
1 file changed
+11
-2
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"lokistack/repository"
|
"lokistack/repository"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -35,7 +36,8 @@ type aiChatRequest struct {
|
|||||||
type aiChatResponse struct {
|
type aiChatResponse struct {
|
||||||
Choices []struct {
|
Choices []struct {
|
||||||
Message struct {
|
Message struct {
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
ReasoningContent string `json:"reasoning_content"`
|
||||||
} `json:"message"`
|
} `json:"message"`
|
||||||
FinishReason string `json:"finish_reason"`
|
FinishReason string `json:"finish_reason"`
|
||||||
} `json:"choices"`
|
} `json:"choices"`
|
||||||
@@ -97,6 +99,7 @@ func aiChat(ctx context.Context, cfg models.AIConfig, messages []aiMessage) (str
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
raw, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
raw, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
log.Printf("[ai-chat] url=%s model=%s keyLen=%d status=%d body=%.300s", url, cfg.Model, len(cfg.APIKey), resp.StatusCode, string(raw))
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
var parsed aiChatResponse
|
var parsed aiChatResponse
|
||||||
if json.Unmarshal(raw, &parsed) == nil && parsed.Error != nil && parsed.Error.Message != "" {
|
if json.Unmarshal(raw, &parsed) == nil && parsed.Error != nil && parsed.Error.Message != "" {
|
||||||
@@ -112,7 +115,13 @@ func aiChat(ctx context.Context, cfg models.AIConfig, messages []aiMessage) (str
|
|||||||
if len(parsed.Choices) == 0 {
|
if len(parsed.Choices) == 0 {
|
||||||
return "", 0, 0, fmt.Errorf("模型没有返回任何内容(finish_reason 为空)")
|
return "", 0, 0, fmt.Errorf("模型没有返回任何内容(finish_reason 为空)")
|
||||||
}
|
}
|
||||||
return parsed.Choices[0].Message.Content, parsed.Usage.PromptTokens, parsed.Usage.CompletionTokens, nil
|
content := parsed.Choices[0].Message.Content
|
||||||
|
// DeepSeek 推理系模型(deepseek-reasoner / v4-pro 高推理档)会把过程写在
|
||||||
|
// reasoning_content,最终 content 在 MaxTokens 太小时可能为空 —— 回退使用推理内容
|
||||||
|
if strings.TrimSpace(content) == "" {
|
||||||
|
content = parsed.Choices[0].Message.ReasoningContent
|
||||||
|
}
|
||||||
|
return content, parsed.Usage.PromptTokens, parsed.Usage.CompletionTokens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AIConnectionTest 连通性测试结果:面向展示的结构化信息,不外发原始回复
|
// AIConnectionTest 连通性测试结果:面向展示的结构化信息,不外发原始回复
|
||||||
|
|||||||
Reference in new issue
Block a user