x icon indicating copy to clipboard operation
x copied to clipboard

如何解析DeepSeek推理返回的 think 标签?

Open xiaoqiang1999 opened this issue 1 year ago • 19 comments

需求动机

请问如何解析DeepSeek推理返回的 think 标签? 调用 DeepSeek openAI 规范的接口时,返回的数据为:

<think> 思考步骤 </think>
回复内容

目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的“<think>”和“</think>”并将其改为"<div class="xxx">“和”</div>"。 但是这样替换会导致真正的内容在包含“<think>“或”</think>”的时候被错误替换掉,还有没有更好的解决方法? 感谢您的回复。

提议的 API 是什么样的?

No response

xiaoqiang1999 avatar Feb 06 '25 10:02 xiaoqiang1999

解析 DeepSeek 推理返回的 think 标签时,您遇到的问题是使用字符串匹配替换方案会导致内容被错误替换。以下是一些可能的解决方案:

  1. 自定义 Markdown-it 插件

    • 您可以编写一个自定义的 Markdown-it 插件来处理 think 标签。这个插件可以在解析过程中识别 think 标签并将其转换为您需要的 HTML 结构。
  2. 使用正则表达式

    • 使用更复杂的正则表达式来匹配 think 标签,并确保只替换那些确实是标签的部分,而不是内容中的文本。例如,您可以使用正则表达式来匹配完整的标签对,而不是单个标签。
  3. HTML 解析库

    • 考虑使用一个 HTML 解析库(如 htmlparser2cheerio)来解析返回的 HTML 内容。这些库可以帮助您更精确地处理 HTML 标签,而不会误替换内容中的文本。
  4. 标记和替换

    • 在替换之前,先对内容进行标记,确保只有真正的 think 标签被替换。可以在替换前后进行标记检查,以确保替换的准确性。

这些方法可以帮助您更准确地解析和替换 think 标签,避免误替换内容中的文本。

如果您有进一步的问题或需要更多帮助,请随时告诉我!

🪧 Tips For further assistance, please describe your question in the comments and @petercat-assistant to start a conversation with me.

petercat-assistant[bot] avatar Feb 06 '25 10:02 petercat-assistant[bot]

调用 DeepSeek openAI 规范的接口时,返回的数据为

我查看了 DeepSeek 的官方文档,没有看到对于 think 标签相关的说明。麻烦确认下这个数据是否是 DeepSeek 模型服务的返回。

目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的 ... 还有没有更好的解决方法?

对于这个问题,前面 petercat 的回答可以参考下~

YumoImer avatar Feb 07 '25 08:02 YumoImer

麻烦确认下这个数据是否是 DeepSeek 模型服务的返回

是,最好给个最佳实践。

afc163 avatar Feb 07 '25 09:02 afc163

调用 DeepSeek openAI 规范的接口时,返回的数据为

我查看了 DeepSeek 的官方文档,没有看到对于 think 标签相关的说明。麻烦确认下这个数据是否是 DeepSeek 模型服务的返回。

目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的 ... 还有没有更好的解决方法?

对于这个问题,前面 petercat 的回答可以参考下~

这个think标签是使用OpenAI兼容的接口规范调用DeepSeek时返回的,比如本地部署DeepSeek时,再比如调用第三方云服务商部署的DeepSeek时,例如阿里云百炼平台的DeepSeek API文档中有如下示例:

Image

另外,百度云千帆平台的DeepSeek、我们本地部署的 deepseek-r1:7b 也是这么用,和百炼一样,都是OpenAI的接口规范,所以都会返回 <think> 标签,需要前端去解析。 像 LobeChat 这样的开源客户端,也对think标签做了适配,直接填入阿里云百炼的DeepSeek API接口选择请求格式为OpenAI即可使用:

Image

所以这个think标签应该是OpenAI的接口规范,而不是DeepSeek的。 有这么一种可能:不仅仅是DeepSeek,可能所有适配了OpenAI接口规范的、带思考功能的大模型都会返回这个think标签,所以有必要对其进行适配和处理。

xiaoqiang1999 avatar Feb 08 '25 03:02 xiaoqiang1999

麻烦确认下这个数据是否是 DeepSeek 模型服务的返回

是,最好给个最佳实践。

麻烦大佬看下我的上条回复

xiaoqiang1999 avatar Feb 08 '25 03:02 xiaoqiang1999

收到,我来看下

YumoImer avatar Feb 08 '25 06:02 YumoImer

用 think 标签包裹思考过程应该是deepseek-r1模型的特性,而不是所有推理模型的共性。 即使是deepseek,它的API还有时会把思考过程放在 reasoning_content 字段里,有时放到 think 标签里 我觉得我们应该考虑如何展示这种 模型的额外输出 ,现在可以 自定义 ReactNode 放在Bubble中,我们是否可以提供一个最佳实践?

nianhua99 avatar Feb 08 '25 07:02 nianhua99

调用 DeepSeek openAI 规范的接口时,返回的数据为

我查看了 DeepSeek 的官方文档,没有看到对于 think 标签相关的说明。麻烦确认下这个数据是否是 DeepSeek 模型服务的返回。

目前按照官方文档使用markdown-it解析会忽略think标签,所以用了临时的“字符串匹配替换”方案,来匹配返回文本中的 ... 还有没有更好的解决方法?

对于这个问题,前面 petercat 的回答可以参考下~

这个think标签是使用OpenAI兼容的接口规范调用DeepSeek时返回的,比如本地部署DeepSeek时,再比如调用第三方云服务商部署的DeepSeek时,例如阿里云百炼平台的DeepSeek API文档中有如下示例:

Image

另外,百度云千帆平台的DeepSeek、我们本地部署的 deepseek-r1:7b 也是这么用,和百炼一样,都是OpenAI的接口规范,所以都会返回 标签,需要前端去解析。 像 LobeChat 这样的开源客户端,也对think标签做了适配,直接填入阿里云百炼的DeepSeek API接口选择请求格式为OpenAI即可使用:

Image

所以这个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

nianhua99 avatar Feb 08 '25 09:02 nianhua99

用 think 标签包裹思考过程应该是deepseek-r1模型的特性,而不是所有推理模型的共性。 即使是deepseek,它的API还有时会把思考过程放在 reasoning_content 字段里,有时放到 think 标签里 我觉得我们应该考虑如何展示这种 模型的额外输出 ,现在可以 自定义 ReactNode 放在Bubble中,我们是否可以提供一个最佳实践?

感大佬指正。另外我也赞同您的说法,提供一个展示模型额外输出的最佳实践

xiaoqiang1999 avatar Feb 08 '25 09:02 xiaoqiang1999

可以尝试用markdown的blockquotes替换think模拟下效果,主要看业务接不接受吧。 目前我们是在数据层面把think替换成了blockquotes的方式来模拟,可以省去各种兼容问题的成本

Rapliangle avatar Feb 13 '25 07:02 Rapliangle

本地调试调用百炼api 没有提示跨域吗?

OxOld avatar Feb 25 '25 03:02 OxOld

deepseek的思考过程 怎么显示在BubbleList 中 哪个大佬给个示例看看

GBcui avatar Mar 04 '25 06:03 GBcui

deepseek的思考过程 怎么显示在BubbleList 中 哪个大佬给个示例看看

我用bubble示例的自定义渲染 markdown做的 把reasoning_content前都加了 >

Image

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); },

MichaelPorter0 avatar Mar 11 '25 06:03 MichaelPorter0

我和你的差不多 BubbleList直接渲染markdown 后端直接转了 把reasoning_content前都加了 >

GBcui avatar Mar 11 '25 06:03 GBcui

上拉加载历史记录你解决了吗 BubbleList好像不行有bug

GBcui avatar Mar 11 '25 06:03 GBcui

亲测这个包npm i parse-reasoning好用。可以解析think标签内部内容,1.0.3版本适配Stream流。 https://www.npmjs.com/package/parse-reasoning

titusTong avatar Mar 17 '25 10:03 titusTong

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 }
}我是思考内容和回复内容拼接在一起

Image

Image

ghost avatar Mar 18 '25 08:03 ghost

上拉加载历史记录你解决了吗 BubbleList好像不行有bug

BubbleList 都不支持这个功能吧得自己去整,我是用 react-infinite-scroll-component 库这个处理的,但是也遇到了一个问题就是加载历史记录后滚动条依然在顶部,视图的内容全是第二页的内容,你想看你加载前的那条数据还得往下滚动,不连续不丝滑,这个问题有解决思路吗?

liaowentao1016 avatar Mar 21 '25 05:03 liaowentao1016

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 }
}我是思考内容和回复内容拼接在一起

Image

Image

你这个效果很好,和现在市面上的思考过程一样,可以贴个Demo吗?

suns0926 avatar Mar 21 '25 07:03 suns0926

蹲有没有相关的组件封装

PineSongCN avatar Jul 16 '25 03:07 PineSongCN

自己js处理一下 加markd自己js处理一下 加markdown样式就可以了

GBcui avatar Jul 16 '25 03:07 GBcui

https://github.com/ant-design/x/pull/946

afc163 avatar Aug 19 '25 01:08 afc163