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 已经支持支持,以上只是一个简单的示例,使用了替换的方式(简单省事),实际上还可以通过自定义标签解析处理,这样酒复杂一些了
浙公网安备 33010602011771号