From 1526acc85fcb90f628c91337874d3ee2d839ec34 Mon Sep 17 00:00:00 2001 From: Echo <1711788888@qq.com> Date: Wed, 4 Mar 2026 02:15:16 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20ai=E8=B0=83=E7=94=A8=E6=97=B6=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E8=AF=A6=E7=BB=86=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/service/app/ai_proxy.go | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/server/service/app/ai_proxy.go b/server/service/app/ai_proxy.go index 226580d..592f805 100644 --- a/server/service/app/ai_proxy.go +++ b/server/service/app/ai_proxy.go @@ -56,6 +56,49 @@ func (s *AiProxyService) ProcessChatCompletion(ctx context.Context, req *request if regexLogs.TotalMatches > 0 || len(regexLogs.InputScripts) > 0 || len(regexLogs.OutputScripts) > 0 { resp.RegexLogs = regexLogs } + + // 记录匹配到正则时的脚本名称 + if regexLogs.TotalMatches > 0 { + matchedScripts := make([]string, 0) + for _, scriptLog := range regexLogs.InputScripts { + if scriptLog.MatchCount > 0 { + matchedScripts = append(matchedScripts, scriptLog.ScriptName) + } + } + for _, scriptLog := range regexLogs.OutputScripts { + if scriptLog.MatchCount > 0 { + matchedScripts = append(matchedScripts, scriptLog.ScriptName) + } + } + + // 记录接口调用参数和 AI 输出内容 + aiOutput := resp.Choices[0].Message.Content + global.GVA_LOG.Info("AI 请求完成", + zap.Any("request", req), + zap.String("ai_output", aiOutput), + zap.Strings("matched_regex_scripts", matchedScripts), + ) + } else { + // 未匹配到正则时仅记录请求和输出 + aiOutput := resp.Choices[0].Message.Content + global.GVA_LOG.Info("AI 请求完成(无正则匹配)", + zap.Any("request", req), + zap.String("ai_output", aiOutput), + ) + } + } else { + // 无预设或无注入器时也记录基础请求与输出 + if len(resp.Choices) > 0 { + aiOutput := resp.Choices[0].Message.Content + global.GVA_LOG.Info("AI 请求完成(无预设/注入器)", + zap.Any("request", req), + zap.String("ai_output", aiOutput), + ) + } else { + global.GVA_LOG.Info("AI 请求完成(无输出)", + zap.Any("request", req), + ) + } } return resp, nil @@ -200,6 +243,9 @@ func (s *AiProxyService) forwardStreamRequest(c *gin.Context, provider *app.AiPr return fmt.Errorf("不支持流式响应") } + // 聚合 AI 输出内容用于日志 + var fullContent bytes.Buffer + for { line, err := reader.ReadBytes('\n') if err != nil { @@ -234,6 +280,8 @@ func (s *AiProxyService) forwardStreamRequest(c *gin.Context, provider *app.AiPr // 应用输出正则处理 if injector != nil && len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" { + // 先记录原始内容到日志汇总 + fullContent.WriteString(chunk.Choices[0].Delta.Content) chunk.Choices[0].Delta.Content = injector.ProcessResponse(chunk.Choices[0].Delta.Content) } @@ -246,6 +294,40 @@ func (s *AiProxyService) forwardStreamRequest(c *gin.Context, provider *app.AiPr } } + // 流式请求结束后记录日志 + if injector != nil { + regexLogs := injector.GetRegexLogs() + + if regexLogs != nil && (regexLogs.TotalMatches > 0 || len(regexLogs.InputScripts) > 0 || len(regexLogs.OutputScripts) > 0) { + matchedScripts := make([]string, 0) + for _, scriptLog := range regexLogs.InputScripts { + if scriptLog.MatchCount > 0 { + matchedScripts = append(matchedScripts, scriptLog.ScriptName) + } + } + for _, scriptLog := range regexLogs.OutputScripts { + if scriptLog.MatchCount > 0 { + matchedScripts = append(matchedScripts, scriptLog.ScriptName) + } + } + + global.GVA_LOG.Info("AI 流式请求完成", + zap.Any("request", req), + zap.String("ai_output", fullContent.String()), + zap.Strings("matched_regex_scripts", matchedScripts), + ) + } else { + global.GVA_LOG.Info("AI 流式请求完成(无正则匹配)", + zap.Any("request", req), + zap.String("ai_output", fullContent.String()), + ) + } + } else { + global.GVA_LOG.Info("AI 流式请求完成(无预设/注入器)", + zap.Any("request", req), + ) + } + return nil }