🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

LLMStream

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

لا ينبغي أن لا يتم تثبيت هذا السكريت مباشرة. هو مكتبة لسكبتات لتشمل مع التوجيه الفوقية // @require https://update.greasyfork.org/scripts/555072/1690858/LLMStream.js

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

المؤلف
wish king
الإصدار
0.0.1.20251107044450
تم إنشاؤه
07-11-2025
تم تحديثه
07-11-2025
الحجم
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>