ollama deepseek 流式web 集成think 标签处理简单示例

ollama openai 兼容api 的流式输出可以提升用户体验,当前deepseek 比较火,以下是对于deepseek think 部分部分的简单说明

处理机制

因为输出是markdown格式的,我们主要将think 部分解析到,同时进行标签的处理(比如替换为div 的同时添加class 属性)这样think 部分就可以很好的区分以及处理了(比如完成之后隐藏,或者设置不用的颜色效果)

参考代码

  • 示例代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .think {
            background-color: #f0f0f0;
        }
    </style>
    <script src="./marked.min.js"></script>
    <script >
        const renderer = new marked.Renderer();
    </script>  
    <title>Document</title>
</head>
<body>
    <div id="chat"></div>
    <script >
        const prompt = `请帮忙提供一份减肥计划,按照一周的,详细一下`;
    </script>
    <script >
        const chatDiv = document.getElementById('chat');
        // stream 模式的数据调用
        async function stream_fetch() {
            const response = await fetch('http://localhost:11434/api/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    "model": "deepseek-r1:1.5b",
                    "messages": [
                        {
                        "role": "user",
                        "content": prompt
                        }
                    ],
                    "stream": true
                }),
            });
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let done = false;
            let output = '';
            while (!done) {
                const { value, done: streamDone } = await reader.read();
                done = streamDone;
                tep_mesg = JSON.parse(decoder.decode(value, { stream: true })).message.content;
                if (tep_mesg == '\u003cthink\u003e') {
                    output += "<div class='think'>"
                } else if (tep_mesg == '\u003c/think\u003e') {
                    output += "</div>"
                }
                else {
                    output += tep_mesg;
                }
                chatDiv.innerHTML = marked.parse(output, { renderer: renderer,breaks: true, gfm: true });
                console.log(chatDiv.innerHTML);
                chatDiv.scrollTop = chatDiv.scrollHeight;
            }
        }
        stream_fetch();

    </script>
</body>
</html>
  • 效果

对于think 部分使用了不同的背景颜色,方便区分

说明

我们基于了marked js库,实际上open-web-ui 已经支持支持,以上只是一个简单的示例,使用了替换的方式(简单省事),实际上还可以通过自定义标签解析处理,这样酒复杂一些了

参考资料

https://github.com/open-webui/open-webui

https://github.com/markedjs/marked

posted on   荣锋亮  阅读(2193)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2024-02-01 dremio vectorized Parquet Reader v2 支持
2024-02-01 nginx-go-crossplane nginx 配置解析包试用
2023-02-01 mtools mongo 日志分析的利器
2023-02-01 nginx agent 来自官方的nginx 配置管理&监控方案
2022-02-01 Building a Sync Engin
2022-02-01 grouparoo 基于nodejs 的开源反向ETL 工具
2022-02-01 Castled 源码解析 - container 模块说明

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示