|
7 | 7 | "fmt" |
8 | 8 | "io" |
9 | 9 | "net/http" |
| 10 | + "strings" |
10 | 11 |
|
11 | 12 | "github.com/Tencent/WeKnora/internal/logger" |
12 | 13 | "github.com/Tencent/WeKnora/internal/models/provider" |
@@ -241,8 +242,13 @@ func (c *RemoteAPIChat) parseCompletionResponse(resp *openai.ChatCompletionRespo |
241 | 242 | } |
242 | 243 |
|
243 | 244 | choice := resp.Choices[0] |
| 245 | + |
| 246 | + // 处理思考模型的输出:移除 <think></think> 标签包裹的思考过程 |
| 247 | + // 为设置了 Thinking=false 但模型仍返回思考内容的情况和部分不支持Thinking=false的思考模型(例如Miniax-M2.1)提供兜底策略 |
| 248 | + content := removeThinkingContent(choice.Message.Content) |
| 249 | + |
244 | 250 | response := &types.ChatResponse{ |
245 | | - Content: choice.Message.Content, |
| 251 | + Content: content, |
246 | 252 | FinishReason: string(choice.FinishReason), |
247 | 253 | Usage: struct { |
248 | 254 | PromptTokens int `json:"prompt_tokens"` |
@@ -272,6 +278,28 @@ func (c *RemoteAPIChat) parseCompletionResponse(resp *openai.ChatCompletionRespo |
272 | 278 | return response, nil |
273 | 279 | } |
274 | 280 |
|
| 281 | +// removeThinkingContent 移除思考模型输出中的 <think></think> 思考过程 |
| 282 | +// 仅当内容以 <think> 开头时才处理 |
| 283 | +func removeThinkingContent(content string) string { |
| 284 | + const thinkStartTag = "<think>" |
| 285 | + const thinkEndTag = "</think>" |
| 286 | + |
| 287 | + trimmed := strings.TrimSpace(content) |
| 288 | + if !strings.HasPrefix(trimmed, thinkStartTag) { |
| 289 | + return content |
| 290 | + } |
| 291 | + |
| 292 | + // 查找最后一个 </think> 标签(处理嵌套情况) |
| 293 | + if lastEndIdx := strings.LastIndex(trimmed, thinkEndTag); lastEndIdx != -1 { |
| 294 | + if result := strings.TrimSpace(trimmed[lastEndIdx+len(thinkEndTag):]); result != "" { |
| 295 | + return result |
| 296 | + } |
| 297 | + return "" |
| 298 | + } |
| 299 | + |
| 300 | + return "" // 未找到 </think>,可能思考内容过长被截断,返回空字符串 |
| 301 | +} |
| 302 | + |
275 | 303 | // ChatStream 进行流式聊天 |
276 | 304 | func (c *RemoteAPIChat) ChatStream(ctx context.Context, messages []Message, opts *ChatOptions) (<-chan types.StreamResponse, error) { |
277 | 305 | req := c.BuildChatCompletionRequest(messages, opts, true) |
|
0 commit comments