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

如何在R语言Shiny应用中实现LLM响应流式输出而非等待全量结果

在Shiny应用中实现LLM流式响应输出

核心实现思路

  • 放弃ellmer同步的chat()方法,改用支持流式输出的stream_async()接口
  • 借助Shiny的ExtendedTask处理异步流式任务,确保UI不被阻塞
  • 通过Shiny的自定义消息机制,将LLM返回的文本片段实时传递到前端,用JavaScript逐步更新页面内容

完整实现代码

library(shiny)
library(ellmer)
library(promises)

# 初始化LLM客户端(二选一)
# Ollama本地模型
chat <- ellmer::chat_ollama(model = "gemma3:4b")

# DeepSeek模型(测试用密钥)
# chat <- chat_deepseek(
#   api_key = "API-Key-removed",
#   model   = "deepseek-chat"
# )

ui <- fluidPage(
  tags$div(
    tags$pre("Show me a prime number: "),
    id = "user_prompt"
  ),
  actionButton("ask_llm", "Ask", icon("robot")),
  tags$div(
    id = "llm_response",
    style = "padding: 10px; border: 1px solid #eee; border-radius: 4px; margin-top: 10px;"
  ),
  # 自定义JS处理流式内容更新
  tags$script(HTML("
    Shiny.addCustomMessageHandler('stream_chunk', function(message) {
      const responseDiv = document.getElementById('llm_response');
      responseDiv.innerHTML += message.chunk;
    });
  "))
)

server <- function(input, output, session) {
  # 创建异步流式任务
  stream_task <- ExtendedTask$new(
    function(client, prompt) {
      # 获取流式响应
      stream <- client$stream_async(prompt)
      # 迭代处理每个响应片段
      stream$then(function(res) {
        for (chunk in res) {
          # 将片段发送到前端
          session$sendCustomMessage("stream_chunk", list(chunk = chunk))
          # 可选:控制输出速度,模拟真实打字效果
          Sys.sleep(0.05)
        }
      })
    }
  )

  # 监听按钮点击事件
  observeEvent(input$ask_llm, {
    # 清空之前的响应内容
    session$sendCustomMessage("stream_chunk", list(chunk = ""))
    # 触发流式任务
    stream_task$invoke(chat, "Show me a prime number: ")
  })
}

shinyApp(ui, server)

关键细节说明

  1. 前端处理:通过Shiny.addCustomMessageHandler监听后端发送的stream_chunk消息,每次收到片段就追加到响应容器中
  2. 异步任务:ExtendedTask确保流式处理在后台运行,不会卡住Shiny的UI线程
  3. 流式迭代:遍历stream_async()返回的响应流,逐个片段传递到前端,可选添加Sys.sleep()模拟自然打字速度
  4. 内容重置:点击按钮时先发送空字符串清空响应区域,避免多次点击内容叠加

内容的提问来源于stack exchange,提问作者LIANG Chen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 08:53:10