LLMStream

LLMStream 是一个轻量级的大模型请求和 Markdown 实时渲染库,支持流式/非流式响应、打字机效果、自动 Markdown 渲染等功能。

ეს სკრიპტი არ უნდა იყოს პირდაპირ დაინსტალირებული. ეს ბიბლიოთეკაა, სხვა სკრიპტებისთვის უნდა ჩართეთ მეტა-დირექტივაში // @require https://update.greasyfork.org/scripts/555072/1690858/LLMStream.js.

ავტორი
wish king
ვერსია
0.0.1.20251107044450
შექმნილია
07.11.2025
განახლებულია
07.11.2025
Size
9,89 KB
ლიცენზია
პ/გ

LLMStream 使用文档(by Claude Sonnet4.5)

LLMStream 是一个轻量级的大模型请求和 Markdown 实时渲染库,支持流式/非流式响应、打字机效果、自动 Markdown 渲染等功能。


📦 快速开始

引入库

<!-- 在 HTML 中引入 -->
<script src="path/to/llmstream.js"></script>

<!-- 如果需要 Markdown 渲染,会自动加载 marked.js -->
<!-- 可选:引入代码高亮库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css">

基础用法

const stream = new LLMStream({
  url: 'https://your-api-endpoint.com/v1/chat/completions',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: {
    model: "your-model-name",
    messages: [
      { role: "user", content: "你好" }
    ],
    stream: true
  },
  target: '#output',
  markdown: true
});

stream.start();

🎯 配置选项

构造函数参数

参数 类型 必填 默认值 说明
url String - API 请求地址
method String 'POST' HTTP 请求方法
headers Object {} 请求头(如 Authorization)
body Object {} 请求体(包含 model、messages 等)
target String/Element - 渲染目标元素(CSS 选择器或 DOM 元素)
markdown Boolean true 是否启用 Markdown 渲染
stream Boolean true 是否使用流式请求(已废弃,请在 body 中配置)
typewriterEffect Boolean false 是否启用打字机效果(仅非流式)
typewriterSpeed Number 30 打字机效果速度(毫秒/字符)
onStart Function - 请求开始时的回调
onChunk Function - 接收到数据块时的回调 (chunk, fullContent)
onComplete Function - 请求完成时的回调 (fullContent)
onError Function - 请求出错时的回调 (error)

📖 使用示例

1️⃣ 流式请求(实时渲染)

流式请求会实时显示 AI 生成的内容,适合需要即时反馈的场景。

const stream = new LLMStream({
  url: 'https://api-inference.modelscope.cn/v1/chat/completions',
  method: 'POST',
  headers: {
    'Authorization': 'Bearer yourtoken',
    'Content-Type': 'application/json'
  },
  body: {
    model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
    messages: [
      { role: "user", content: "请用 Markdown 写一个快速排序的 Python 实现,并解释步骤。" }
    ],
    stream: true,  // ⚡ 启用流式响应
    temperature: 0.2
  },
  target: '#output',
  markdown: true,
  onChunk: (chunk, fullContent) => {
    console.log('收到数据块:', chunk);
  },
  onComplete: (content) => {
    console.log('✅ 流式传输完成');
  }
});

stream.start();

HTML 结构:

<div id="output" style="white-space: pre-wrap; padding: 20px;"></div>

2️⃣ 非流式请求(一次性显示)

非流式请求会等待完整响应后一次性显示,适合需要完整内容后再处理的场景。

const stream = new LLMStream({
  url: 'https://api-inference.modelscope.cn/v1/chat/completions',
  method: 'POST',
  headers: {
    'Authorization': 'Bearer yourtoken',
    'Content-Type': 'application/json'
  },
  body: {
    model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
    messages: [
      { role: "user", content: "介绍一下 Python" }
    ],
    stream: false,  // 🔒 关闭流式响应
    temperature: 0.7
  },
  target: '#output',
  markdown: true,
  onComplete: (content) => {
    console.log('✅ 内容已完整显示:', content);
  }
});

stream.start();

3️⃣ 非流式 + 打字机效果

结合非流式请求和打字机效果,可以实现更流畅的视觉体验。

const stream = new LLMStream({
  url: 'https://api-inference.modelscope.cn/v1/chat/completions',
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: {
    model: "your-model",
    messages: [
      { role: "user", content: "写一首关于春天的诗" }
    ],
    stream: false  // 非流式
  },
  target: '#output',
  markdown: true,
  typewriterEffect: true,  // ⌨️ 启用打字机效果
  typewriterSpeed: 50,     // 每个字符延迟 50ms
  onChunk: (char, fullContent) => {
    // 每输出一个字符都会触发
    console.log('打字机输出:', char);
  },
  onComplete: (content) => {
    console.log('✅ 打字机效果完成');
  }
});

stream.start();

4️⃣ 多轮对话示例

const conversationHistory = [];

function sendMessage(userMessage) {
  // 添加用户消息到历史
  conversationHistory.push({
    role: "user",
    content: userMessage
  });

  const stream = new LLMStream({
    url: 'https://your-api-endpoint.com/v1/chat/completions',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: {
      model: "your-model",
      messages: conversationHistory,
      stream: true
    },
    target: '#chat-output',
    markdown: true,
    onComplete: (content) => {
      // 添加助手回复到历史
      conversationHistory.push({
        role: "assistant",
        content: content
      });
    }
  });

  stream.start();
}

// 使用
sendMessage("你好");
// 等待回复后...
sendMessage("你能做什么?");

🎮 API 方法

start()

开始请求。

stream.start();

stop()

停止请求(取消 HTTP 请求或停止打字机效果)。

stream.stop();

getContent()

获取当前已接收的内容。

const content = stream.getContent();
console.log(content);

clear()

清空内容和目标元素。

stream.clear();

📋 回调函数详解

onStart()

请求开始时触发。

onStart: () => {
  console.log('🚀 请求开始');
  document.getElementById('loading').style.display = 'block';
}

onChunk(chunk, fullContent)

每次接收到数据块时触发(流式或打字机效果)。

onChunk: (chunk, fullContent) => {
  console.log('收到:', chunk);
  console.log('累计内容长度:', fullContent.length);
}

onComplete(fullContent)

请求完成时触发。

onComplete: (content) => {
  console.log('✅ 完成,总字数:', content.length);
  document.getElementById('loading').style.display = 'none';
}

onError(error)

请求出错时触发。

onError: (error) => {
  console.error('❌ 错误:', error);
  alert('请求失败: ' + error.message);
}

🎨 样式建议

/* 输出容器样式 */
#output {
  background: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 20px;
  min-height: 200px;
  max-height: 600px;
  overflow-y: auto;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  line-height: 1.6;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* Markdown 代码块样式 */
#output pre {
  background: #282c34;
  color: #abb2bf;
  padding: 15px;
  border-radius: 5px;
  overflow-x: auto;
}

#output code {
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
}

/* 行内代码 */
#output p code {
  background: #e8e8e8;
  color: #c7254e;
  padding: 2px 6px;
  border-radius: 3px;
}

🔧 支持的响应格式

LLMStream 自动识别以下响应格式:

  1. OpenAI / 通义千问标准格式

    {
      "choices": [
        {
          "message": {
            "content": "响应内容"
          }
        }
      ]
    }
    
  2. 简化格式

    {
      "content": "响应内容"
    }
    
  3. Output 字段

    {
      "output": {
        "content": "响应内容"
      }
    }
    
  4. 其他支持字段: response, text, result, message


⚠️ 注意事项

  1. 流式 vs 非流式:在 body.stream 中配置,而非构造函数的 stream 参数
  2. 打字机效果:仅在非流式模式下生效
  3. Markdown 渲染:会自动加载 marked.js,无需手动引入
  4. CORS 问题:确保 API 支持跨域请求
  5. API Key 安全:不要在前端代码中硬编码 API Key,建议通过后端代理

📦 完整示例

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>LLMStream Demo</title>
  <style>
    body { font-family: sans-serif; max-width: 800px; margin: 50px auto; }
    #output { 
      background: #f9f9f9; 
      border: 1px solid #ddd; 
      padding: 20px; 
      min-height: 300px;
      white-space: pre-wrap;
    }
    button { padding: 10px 20px; margin: 5px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>LLMStream 演示</h1>
  <button onclick="testStream()">流式请求</button>
  <button onclick="testNormal()">非流式请求</button>
  <button onclick="testTypewriter()">打字机效果</button>
  <button onclick="stream.stop()">停止</button>
  <button onclick="stream.clear()">清空</button>

  <div id="output"></div>

  <script src="llmstream.js"></script>
  <script>
    let stream;

    function testStream() {
      stream = new LLMStream({
        url: 'https://api-inference.modelscope.cn/v1/chat/completions',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: {
          model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
          messages: [{ role: "user", content: "写一个冒泡排序" }],
          stream: true
        },
        target: '#output',
        markdown: true,
        onComplete: () => alert('完成!')
      });
      stream.start();
    }

    function testNormal() {
      stream = new LLMStream({
        url: 'https://api-inference.modelscope.cn/v1/chat/completions',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: {
          model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
          messages: [{ role: "user", content: "介绍 JavaScript" }],
          stream: false
        },
        target: '#output',
        markdown: true
      });
      stream.start();
    }

    function testTypewriter() {
      stream = new LLMStream({
        url: 'https://api-inference.modelscope.cn/v1/chat/completions',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: {
          model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
          messages: [{ role: "user", content: "写一首诗" }],
          stream: false
        },
        target: '#output',
        markdown: true,
        typewriterEffect: true,
        typewriterSpeed: 30
      });
      stream.start();
    }
  </script>
</body>
</html>