1. 流式请求的本质与核心价值
流式请求(Streaming Request)是现代API交互中一种重要的通信模式,特别是在处理大语言模型响应时。与传统的"请求-响应"模式不同,流式请求允许服务端在生成内容的过程中逐步返回数据,而不是等待全部内容生成完毕后再一次性返回。
1.1 技术实现原理
在C#中实现流式请求主要依赖以下几个核心技术点:
- HTTP长连接:通过保持TCP连接不立即关闭,服务端可以持续发送数据
- Server-Sent Events (SSE):一种基于HTTP的轻量级协议,规范了服务端向客户端推送数据的格式
- 异步迭代器(IAsyncEnumerable):C# 8.0引入的特性,允许异步生成序列数据
csharp复制// 典型的流式请求方法签名
public static async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
HttpClient httpClient,
string baseUrl,
string model,
object[] messages,
double temperature = 0.7,
int maxTokens = 1000,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
1.2 为什么需要流式请求
在传统API调用中,用户需要等待整个响应生成完成后才能看到结果。对于大语言模型这种可能需要数秒甚至更长时间生成内容的场景,这种等待体验非常糟糕。流式请求解决了几个关键问题:
- 降低首字延迟(Time to First Token):用户可以在100-300ms内看到第一个字
- 提供进度反馈:避免用户面对空白屏幕不确定是否在运行
- 节省内存开销:客户端可以逐步处理数据而不必缓存整个响应
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心代码实现解析
2.1 数据结构设计
流式响应需要专门的数据结构来承载增量更新:
csharp复制public sealed class ChatResponseUpdate
{
public string? Text { get; init; } // 增量文本内容
public string? RawJson { get; init; } // 原始JSON数据(用于调试)
}
这种设计实现了两个关键目标:
- 业务层只需关注Text属性即可获取最新内容
- 保留了原始数据供调试和异常处理使用
2.2 HTTP请求配置
正确的HTTP配置是流式请求的基础:
csharp复制// 关键配置1:使用ResponseHeadersRead选项
using var response = await httpClient.SendAsync(
request,
HttpCompletionO
