| | |
| | | .doOnError(ex -> log.error("调用 LLM 流式失败", ex)); |
| | | |
| | | flux.subscribe(payload -> { |
| | | String s = payload == null ? null : payload.trim(); |
| | | String s = payload; |
| | | if (s == null || s.isEmpty()) return; |
| | | if (s.startsWith("data:")) s = s.substring(5).trim(); |
| | | if ("[DONE]".equals(s)) return; |
| | | if (s.startsWith("data:")) { |
| | | s = s.substring(5); |
| | | if (s.startsWith(" ")) s = s.substring(1); |
| | | } |
| | | // 保留模型输出中的换行,只在判断结束标记时忽略空白 |
| | | if ("[DONE]".equals(s.trim())) return; |
| | | try { |
| | | JSONObject obj = JSON.parseObject(s); |
| | | JSONArray choices = obj.getJSONArray("choices"); |
| | |
| | | JSONObject delta = c0.getJSONObject("delta"); |
| | | if (delta != null) { |
| | | String content = delta.getString("content"); |
| | | // log.info("chunk = [{}] len = {}", content, content.length()); |
| | | // for (char ch : content.toCharArray()) { |
| | | // log.info("char: {} ({})", (int) ch, ch == '\n' ? "\\n" : ch); |
| | | // } |
| | | if (content != null) onChunk.accept(content); |
| | | } |
| | | } |