You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法实现Ollama响应流式输出,请求RAG应用技术支持

实现流式响应的改造方案

要实现类似ChatGPT的流式输出,Spring MVC中可以通过**SSE(Server-Sent Events)**来实现,核心是使用SseEmitter逐步向客户端发送生成的token,而非等待全部内容生成后再返回。以下是改造后的完整代码:

import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.output.Response;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api")
public class OllamaController {
    private final StreamingChatLanguageModel streamingChatModel;
    // SSE超时时间与模型超时保持一致
    private static final long SSE_TIMEOUT = TimeUnit.MINUTES.toMillis(5);

    public OllamaController() {
        this.streamingChatModel = OllamaStreamingChatModel.builder()
                .baseUrl("你的Ollama服务地址")
                .modelName("llama3")
                .timeout(Duration.ofMinutes(5))
                .temperature(0.6)
                .build();
    }

    @PostMapping("/generate")
    public SseEmitter generateResponse(@RequestBody String userMessage) {
        // 初始化SseEmitter并设置超时时间
        SseEmitter emitter = new SseEmitter(SSE_TIMEOUT);

        streamingChatModel.generate(userMessage, new StreamingResponseHandler<AiMessage>() {
            @Override
            public void onNext(String token) {
                try {
                    // 实时发送单个生成的token
                    emitter.send(token);
                } catch (Exception e) {
                    // 发送失败时终止连接并传递错误
                    emitter.completeWithError(e);
                }
            }

            @Override
            public void onComplete(Response<AiMessage> response) {
                // 所有内容发送完毕,关闭SSE连接
                emitter.complete();
            }

            @Override
            public void onError(Throwable error) {
                // 模型生成出错时,终止连接并传递错误
                emitter.completeWithError(error);
            }
        });

        // 处理超时场景
        emitter.onTimeout(() -> emitter.completeWithError(new RuntimeException("请求超时")));

        return emitter;
    }
}

关键改动说明

  • 返回类型替换:将原方法的String返回类型改为SseEmitter,这是Spring MVC实现SSE的核心类,负责维护客户端与服务器的长连接并逐步推送数据。
  • 实时推送token:在onNext方法中,不再将token缓存到StringBuilder,而是直接通过emitter.send(token)将每个生成的token实时发送给客户端。
  • 连接生命周期管理:
    • onComplete中调用emitter.complete(),告知客户端响应已全部发送,主动关闭连接。
    • onError中调用emitter.completeWithError(error),将错误传递给客户端并关闭连接。
    • 添加超时回调,处理请求超时的异常场景。
  • 超时时间对齐:SSE的超时时间与Ollama模型的超时时间保持一致,避免出现模型仍在生成但连接已断开的情况。

客户端接收示例(JavaScript)

客户端需要支持SSE协议来接收流式响应,示例代码如下:

const response = await fetch('/api/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify("你的问题内容")
});

const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  // 实时将token追加到页面元素中
  document.getElementById('response-container').textContent += decoder.decode(value);
}

内容的提问来源于stack exchange,提问作者Rounak Chakraborty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:59:54