修复:过滤空助手消息,以防止在严格API上出现400错误(fix: filter empty assistant messages to prevent 400 error on strict APIs)#7202
Open
kaixinyujue wants to merge 1 commit intoAstrBotDevs:masterfrom
Conversation
Some OpenAI-compatible APIs (e.g., Moonshot) reject requests with empty content in assistant messages when no tool_calls are present. This fix cleans up the messages payload before sending to avoid 'message at position X must not be empty' errors. Closes related issue with fallback provider behavior.
Contributor
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The message cleanup currently only treats
content == ""andcontent is Noneas empty; consider also handling whitespace-only strings or other non-string/complexcontenttypes (e.g. list/array content) to avoid leaving structurally empty assistant messages that strict providers might still reject. - For
tool_callsyou only check truthiness (if not tool_calls); if the field can be present but empty (e.g.[]), it might be clearer and safer to normalize or explicitly treat that as "no tool calls" to avoid subtle differences betweenNone, missing, and empty values.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The message cleanup currently only treats `content == ""` and `content is None` as empty; consider also handling whitespace-only strings or other non-string/complex `content` types (e.g. list/array content) to avoid leaving structurally empty assistant messages that strict providers might still reject.
- For `tool_calls` you only check truthiness (`if not tool_calls`); if the field can be present but empty (e.g. `[]`), it might be clearer and safer to normalize or explicitly treat that as "no tool calls" to avoid subtle differences between `None`, missing, and empty values.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces a message cleaning mechanism in the OpenAI provider to handle assistant messages with empty or null content. It filters out invalid messages and ensures compliance with OpenAI specifications by converting empty content to null when tool calls are present. A review comment suggests simplifying the filtering logic by merging the checks for empty and null content into a single conditional block.
Comment on lines
+468
to
+478
| # 情况1: content 为空字符串且没有工具调用 -> 删除 | ||
| if content == "" and not tool_calls: | ||
| logger.warning(f"过滤第 {idx} 条空 assistant 消息 (无工具调用)") | ||
| continue | ||
|
|
||
| # 情况2: content 为 None 但没有工具调用 -> 删除或赋予空字符串 | ||
| if content is None and not tool_calls: | ||
| logger.warning( | ||
| f"过滤第 {idx} 条 null content 的 assistant 消息" | ||
| ) | ||
| continue |
Contributor
There was a problem hiding this comment.
为了提高代码的简洁性和可读性,可以将处理空字符串 content 和 None content 且没有 tool_calls 的 assistant 消息的逻辑合并为一个条件判断。这两种情况都导致消息被过滤掉,合并后可以减少重复代码。
建议:
Suggested change
| # 情况1: content 为空字符串且没有工具调用 -> 删除 | |
| if content == "" and not tool_calls: | |
| logger.warning(f"过滤第 {idx} 条空 assistant 消息 (无工具调用)") | |
| continue | |
| # 情况2: content 为 None 但没有工具调用 -> 删除或赋予空字符串 | |
| if content is None and not tool_calls: | |
| logger.warning( | |
| f"过滤第 {idx} 条 null content 的 assistant 消息" | |
| ) | |
| continue | |
| # 情况1: content 为空字符串或 None 且没有工具调用 -> 删除 | |
| if (content == "" or content is None) and not tool_calls: | |
| logger.warning(f"过滤第 {idx} 条空或 null content 的 assistant 消息 (无工具调用)") | |
| continue |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
描述
修复调用 Moonshot (Kimi K2.5) API 时,因对话历史中存在空 assistant 消息而导致的 400 错误。
错误信息:
问题根源: 部分严格遵守 OpenAI 规范的 API(如 Moonshot)会校验 assistant 消息的
content字段,当内容为空且没有tool_calls时直接拒绝请求。而 DeepSeek 等 API 对此较为宽松,导致同样的消息历史在 Moonshot 上失败,在 DeepSeek 上却能正常工作。解决方案
在
OpenAIAPIProviderBase._query()方法中,发送请求前对消息数组进行清理:content为 None 或空字符串且没有tool_calls的 assistant 消息tool_calls时,将空字符串转为None(符合 OpenAI 官方规范)将修复放在 Provider 层而非 Agent 层,确保所有继承
OpenAIAPIProviderBase的 Provider(Moonshot、GPT、DeepSeek 等)都能受益,无需逐个适配。变更文件
astrbot/core/provider/sources/openai_source.py:在调用 API 前添加消息清洗逻辑关联 Issue
Closes #7200 - [Feature] AstrBot 在调用 Moonshot (Kimi K2.5) API 时的空消息报错解决建议
检查清单
ruff format格式化代码Summary by Sourcery
Filter and normalize assistant messages before invoking OpenAI-compatible chat APIs to avoid invalid empty-message requests on strict providers.
Bug Fixes: