[Bug] reasoning_content 为空字符串时会生成空 ThinkPart 并写入上下文

Aperta Adatta ai principianti
#11,034 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
74/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
ai, backend

Direzione di ricerca

Inizia da _complete_with_assistant_response in astrbot/core/agent/runners/tool_loop_agent_runner.py, intorno alla riga 190, poi esamina il ramo della chiamata allo strumento intorno alla riga 1084 per verificare la stessa condizione. Riproduci il problema con un provider compatibile con OpenAI che restituisce reasoning_content vuoto e verifica che entrambi i percorsi evitino di creare un ThinkPart quando non è presente una firma di ragionamento. L’issue suggerisce anche di ripulire la cronologia dai blocchi think vuoti; conferma separatamente l’ambito e i test relativi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

问题描述

Provider 返回的 reasoning_content 是空字符串时,AstrBot 仍然会生成一个 think 为空的 ThinkPart,并写进对话上下文。表现是:

  1. data_v4.db 里 conversations.content 的 assistant 消息几乎每条开头都多一个空思考块:
[
  {"type": "think", "think": "", "encrypted": null},
  {"type": "text", "text": "……正常正文……"}
]
  1. 个别轮次模型会把这个结构当成正文原样输出,QQ 里直接显示成
    {"type": "think", "think": "", "encrypted": null},后面再跟一句模型自己写的「(来源:本对话)」。
如何复现?
  1. 配置一个会返回 reasoning_content="" 的 OpenAI 兼容 Provider(我用的是 deepseek 系推理模型,很多轮返回空字符串)。
  2. 正常和机器人聊 3~5 轮。
  3. 查 data_v4.db 的 conversations.content,assistant 消息开头就是上面那个空 think 块。
  4. 继续聊,偶尔就能看到模型把这段 JSON 当正文吐出来。
AstrBot 版本

4.29.4(Windows 桌面版,runtime-manifest.json 里 core 也是 4.29.4)

操作系统

Windows

部署方式

桌面版(Desktop 安装包)

使用的消息平台适配器

aiocqhttp(QQ,SnowLuma 反向 WS)

错误日志

不报错,属于静默数据问题。关键代码在 astrbot/core/agent/runners/tool_loop_agent_runner.py:190(_complete_with_assistant_response):

if llm_resp.reasoning_content is not None or llm_resp.reasoning_signature:
    parts.append(
        ThinkPart(
            think=llm_resp.reasoning_content or "",
            encrypted=llm_resp.reasoning_signature,
        )
    )

reasoning_content 为 "" 时 "" is not None 为真,于是生成了 think="" 的 ThinkPart。

同样的写法在工具调用分支 tool_loop_agent_runner.py:1084 还有一处。

期望行为:reasoning_content 为空且没有 reasoning_signature 时不生成 ThinkPart。

建议修复(两处都改):

if llm_resp.reasoning_content or llm_resp.reasoning_signature:

另外可以考虑在读取历史时丢弃 {"type": "think", "think": ""} 的块,把已经写进库的脏数据清掉。

辅助信息

无

检查清单
  • 我已经搜索了现有的 issues,没有找到重复的问题
  • 我使用的是最新版本的 AstrBot
  • 我已经阅读了文档和常见问题
相关
  • #10215(handle empty OpenAI completions and Gemini history parts)
  • #10866(Gemini 原始 provider 回放历史时空 text part 触发 400)
Lingua principale
Python
Stelle
46.4k
Fork
3.4k
Merge medio
1g 9h
PR unite (30g)
123

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di AstrBotDevs/AstrBot

Tutte le issue di AstrBotDevs/AstrBot

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.