如何解析DeepSeek推理返回的 think 标签?
需求动机
请问如何解析DeepSeek推理返回的 think 标签? 调用 DeepSeek openAI 规范的接口时,返回的数据为:
<think> 思考步骤 </think>
回复内容
目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的“<think>”和“</think>”并将其改为"<div class="xxx">“和”</div>"。 但是这样替换会导致真正的内容在包含“<think>“或”</think>”的时候被错误替换掉,还有没有更好的解决方法? 感谢您的回复。
提议的 API 是什么样的?
No response
解析 DeepSeek 推理返回的 think 标签时,您遇到的问题是使用字符串匹配替换方案会导致内容被错误替换。以下是一些可能的解决方案:
-
自定义 Markdown-it 插件:
- 您可以编写一个自定义的 Markdown-it 插件来处理
think标签。这个插件可以在解析过程中识别think标签并将其转换为您需要的 HTML 结构。
- 您可以编写一个自定义的 Markdown-it 插件来处理
-
使用正则表达式:
- 使用更复杂的正则表达式来匹配
think标签,并确保只替换那些确实是标签的部分,而不是内容中的文本。例如,您可以使用正则表达式来匹配完整的标签对,而不是单个标签。
- 使用更复杂的正则表达式来匹配
-
HTML 解析库:
- 考虑使用一个 HTML 解析库(如
htmlparser2或cheerio)来解析返回的 HTML 内容。这些库可以帮助您更精确地处理 HTML 标签,而不会误替换内容中的文本。
- 考虑使用一个 HTML 解析库(如
-
标记和替换:
- 在替换之前,先对内容进行标记,确保只有真正的
think标签被替换。可以在替换前后进行标记检查,以确保替换的准确性。
- 在替换之前,先对内容进行标记,确保只有真正的
这些方法可以帮助您更准确地解析和替换 think 标签,避免误替换内容中的文本。
如果您有进一步的问题或需要更多帮助,请随时告诉我!
🪧 Tips
For further assistance, please describe your question in the comments and @petercat-assistant to start a conversation with me.
调用 DeepSeek openAI 规范的接口时,返回的数据为
我查看了 DeepSeek 的官方文档,没有看到对于 think 标签相关的说明。麻烦确认下这个数据是否是 DeepSeek 模型服务的返回。
目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的 ... 还有没有更好的解决方法?
对于这个问题,前面 petercat 的回答可以参考下~
麻烦确认下这个数据是否是 DeepSeek 模型服务的返回
是,最好给个最佳实践。
调用 DeepSeek openAI 规范的接口时,返回的数据为
我查看了 DeepSeek 的官方文档,没有看到对于 think 标签相关的说明。麻烦确认下这个数据是否是 DeepSeek 模型服务的返回。
目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的 ... 还有没有更好的解决方法?
对于这个问题,前面 petercat 的回答可以参考下~
这个think标签是使用OpenAI兼容的接口规范调用DeepSeek时返回的,比如本地部署DeepSeek时,再比如调用第三方云服务商部署的DeepSeek时,例如阿里云百炼平台的DeepSeek API文档中有如下示例:
另外,百度云千帆平台的DeepSeek、我们本地部署的 deepseek-r1:7b 也是这么用,和百炼一样,都是OpenAI的接口规范,所以都会返回 <think> 标签,需要前端去解析。 像 LobeChat 这样的开源客户端,也对think标签做了适配,直接填入阿里云百炼的DeepSeek API接口选择请求格式为OpenAI即可使用:
所以这个think标签应该是OpenAI的接口规范,而不是DeepSeek的。 有这么一种可能:不仅仅是DeepSeek,可能所有适配了OpenAI接口规范的、带思考功能的大模型都会返回这个think标签,所以有必要对其进行适配和处理。
麻烦确认下这个数据是否是 DeepSeek 模型服务的返回
是,最好给个最佳实践。
麻烦大佬看下我的上条回复
收到,我来看下
用 think 标签包裹思考过程应该是deepseek-r1模型的特性,而不是所有推理模型的共性。 即使是deepseek,它的API还有时会把思考过程放在 reasoning_content 字段里,有时放到 think 标签里 我觉得我们应该考虑如何展示这种 模型的额外输出 ,现在可以 自定义 ReactNode 放在Bubble中,我们是否可以提供一个最佳实践?
调用 DeepSeek openAI 规范的接口时,返回的数据为
我查看了 DeepSeek 的官方文档,没有看到对于 think 标签相关的说明。麻烦确认下这个数据是否是 DeepSeek 模型服务的返回。
目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的 ... 还有没有更好的解决方法?
对于这个问题,前面 petercat 的回答可以参考下~
这个think标签是使用OpenAI兼容的接口规范调用DeepSeek时返回的,比如本地部署DeepSeek时,再比如调用第三方云服务商部署的DeepSeek时,例如阿里云百炼平台的DeepSeek API文档中有如下示例:
另外,百度云千帆平台的DeepSeek、我们本地部署的 deepseek-r1:7b 也是这么用,和百炼一样,都是OpenAI的接口规范,所以都会返回
标签,需要前端去解析。 像 LobeChat 这样的开源客户端,也对think标签做了适配,直接填入阿里云百炼的DeepSeek API接口选择请求格式为OpenAI即可使用:
所以这个think标签应该是OpenAI的接口规范,而不是DeepSeek的。 有这么一种可能:不仅仅是DeepSeek,可能所有适配了OpenAI接口规范的、带思考功能的大模型都会返回这个think标签,所以有必要对其进行适配和处理。
这个说法是有误的。deepseek官方文档中写到推理(思考)内容会放在 reasoning_content 字段中,开源版的r1模型则使用 think 标签包裹。这一点是Deepseek自己定义的,并不属于OpenAI的规范。目前OpenAI定义的API规范中还没有定义 推理内容放在何处。
ds文档: https://api-docs.deepseek.com/zh-cn/guides/reasoning_model#%E4%B8%8A%E4%B8%8B%E6%96%87%E6%8B%BC%E6%8E%A5
另外,OpenWebui也遇到了这个问题 https://github.com/open-webui/open-webui/pull/9241#issuecomment-2629707340
用 think 标签包裹思考过程应该是deepseek-r1模型的特性,而不是所有推理模型的共性。 即使是deepseek,它的API还有时会把思考过程放在 reasoning_content 字段里,有时放到 think 标签里 我觉得我们应该考虑如何展示这种 模型的额外输出 ,现在可以 自定义 ReactNode 放在Bubble中,我们是否可以提供一个最佳实践?
感大佬指正。另外我也赞同您的说法,提供一个展示模型额外输出的最佳实践
可以尝试用markdown的blockquotes替换think模拟下效果,主要看业务接不接受吧。 目前我们是在数据层面把think替换成了blockquotes的方式来模拟,可以省去各种兼容问题的成本
本地调试调用百炼api 没有提示跨域吗?
deepseek的思考过程 怎么显示在BubbleList 中 哪个大佬给个示例看看
deepseek的思考过程 怎么显示在BubbleList 中 哪个大佬给个示例看看
我用bubble示例的自定义渲染 markdown做的 把reasoning_content前都加了 >
onUpdate: (chunk) => { if (chunk.data.trim() !== '[DONE]') { const data = JSON.parse(chunk.data); let reasoning_word:string=data?.choices[0].delta.reasoning_content; let words=data?.choices[0].delta.content; if(reasoning_word){ if(reasoning_word.includes('\n')) reasoning_word+='>' reasoning_content+=reasoning_word; } if(words){ content+=words; } } onUpdate(reasoning_content+content); },
我和你的差不多 BubbleList直接渲染markdown 后端直接转了 把reasoning_content前都加了 >
上拉加载历史记录你解决了吗 BubbleList好像不行有bug
亲测这个包npm i parse-reasoning好用。可以解析think标签内部内容,1.0.3版本适配Stream流。
https://www.npmjs.com/package/parse-reasoning
deepseek的思考过程 怎么显示在BubbleList 中 哪个大佬给个示例看看 parser: (content) => { let thinkingContent = '' let msg = ''
const match = content.match(/THINKING:([\s\S]*?),MSG:([\s\S]*)/)
if (match) {
thinkingContent = match[1]
msg = match[2]
} else {
msg = content
}
return { thinkingContent, msg }
}我是思考内容和回复内容拼接在一起
上拉加载历史记录你解决了吗 BubbleList好像不行有bug
BubbleList 都不支持这个功能吧得自己去整,我是用 react-infinite-scroll-component 库这个处理的,但是也遇到了一个问题就是加载历史记录后滚动条依然在顶部,视图的内容全是第二页的内容,你想看你加载前的那条数据还得往下滚动,不连续不丝滑,这个问题有解决思路吗?
deepseek的思考过程 怎么显示在BubbleList 中 哪个大佬给个示例看看 parser: (content) => { let thinkingContent = '' let msg = ''
const match = content.match(/THINKING:([\s\S]*?),MSG:([\s\S]*)/) if (match) { thinkingContent = match[1] msg = match[2] } else { msg = content } return { thinkingContent, msg } }我是思考内容和回复内容拼接在一起
你这个效果很好,和现在市面上的思考过程一样,可以贴个Demo吗?
蹲有没有相关的组件封装
自己js处理一下 加markd自己js处理一下 加markdown样式就可以了
https://github.com/ant-design/x/pull/946