目录简介核心方案关键代码实现1. 初始化与配置2. SSE 解析逻辑3. 执行流式请求总结上一篇简介在 DeepSeek-R1 或 Qwen-2.5-Max 等推理模型中模型会在生成最终答案之前输出一段“思考过程”Reasoning Content。目前的 .NET OpenAI SDK (OpenAI包) 尚未完全原生支持将reasoning_content字段映射到强类型对象中。本文将演示如何通过GetRawPagesAsync和SseParser手动解析 Server-Sent Events (SSE) 数据流从而实时获取并展示模型的思考过程。核心方案JSON Patch 启用功能使用ChatCompletionOptions.Patch注入enable_thinking参数。底层 SSE 解析绕过 SDK 的强类型封装直接处理原始流数据。双流分离分别提取reasoning_content(思考) 和content(回答)。关键代码实现1. 初始化与配置首先配置客户端并使用 JSON Patch 启用思考模式以 Qwen 为例// 配置 OpenAI 客户端 var clientOptions new OpenAIClientOptions { Endpoint new Uri(Keys.QwenEndpoint) }; var openAIClient new OpenAIClient(new ApiKeyCredential(Keys.QwenApiKey), clientOptions); var chatClient openAIClient.GetChatClient(deepseek-v3.2-exp); // 启用思考模式 (关键步骤) var options new ChatCompletionOptions(); #pragma warning disable SCME0001 options.Patch.Set($.enable_thinkingu8, true); #pragma warning restore SCME00012. SSE 解析逻辑这是核心部分。我们需要处理原始的 SSE 数据包手动解析 JSON 并提取字段。using System.Net.ServerSentEvents; using System.Text.Json; // 解析 SSE 页面并分流处理 void ProcessSsePage(ClientResult page, StringBuilder reasoning, StringBuilder answer) { var contentStream page.GetRawResponse().ContentStream; if (contentStream isnull) return; // 使用 .NET 内置的 SseParser var parser SseParser.Create(contentStream); foreach (var item in parser.Enumerate()) { if (string.IsNullOrWhiteSpace(item.Data)) continue; // 解析 JSON if (!TryParseJsonMessage(item.Data, outvar message)) continue; // 提取内容 ProcessDeltaContent(message, reasoning, answer); } } void ProcessDeltaContent(JsonElement message, StringBuilder reasoning, StringBuilder answer) { // ... 省略部分校验代码 ... if (!message.TryGetProperty(choices, outvar choices)) return; var delta choices[0].GetProperty(delta); // 1. 提取思考内容 if (delta.TryGetProperty(reasoning_content, outvar rProp)) { var text rProp.GetString(); if (!string.IsNullOrEmpty(text)) { Console.ForegroundColor ConsoleColor.Gray; Console.Write(text); // 实时输出思考 reasoning.Append(text); } } // 2. 提取回答内容 if (delta.TryGetProperty(content, outvar cProp)) { var text cProp.GetString(); if (!string.IsNullOrEmpty(text)) { Console.ResetColor(); Console.Write(text); // 实时输出回答 answer.Append(text); } } }3. 执行流式请求使用GetRawPagesAsync()获取底层数据流var messages new ChatMessage[] { new UserChatMessage(如何将大象装进冰箱) }; // 发起流式请求 var chatUpdates chatClient.CompleteChatStreamingAsync(messages, options); // 遍历原始 SSE 页面 await foreach (var page in chatUpdates.GetRawPagesAsync()) { ProcessSsePage(page, reasoningContent, answerContent); }总结虽然 SDK 暂时未跟上模型 API 的更新速度但通过 .NET 强大的底层网络处理能力如SseParser我们依然可以优雅地解决问题。最佳实践关注 SDK 的GetRawPagesAsync方法它是处理非标准 API 响应的逃生舱。使用System.Net.ServerSentEvents处理流式数据避免手写复杂的流解析逻辑。上一篇引入地址