[Bug] 群聊历史图片转述把本地文件路径直接传给视觉模型,导致全部失败
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
Start in astrbot/builtin_stars/astrbot/group_chat_context.py: the image URL is chosen near line 209 (comp.url if comp.url else comp.file), and get_image_caption near lines 104-109 passes it to provider.text_chat(image_urls=...) unchanged. Compare with prepare_request_images in astr_main_agent.py, which already converts local files. Add a normalization step that turns local paths and file:// into base64 data URLs, and leaves http(s) and existing data URLs alone. Done when a local image in group history gets a caption instead of a 400. Note the comment thread: a patch that treated paths as base64 produced an invalid data URL.
由索引模型根据 Issue 内容生成。
描述
问题描述
环境
- AstrBot 版本:4.29.3(已确认 4.29.4 未修复,
group_chat_context.py两版本 sha256 一致) - 平台:aiocqhttp / NapCat(QQ)
- 系统:Windows 11
- 相关配置:
provider_ltm_settings.group_icl_enable = trueprovider_ltm_settings.image_caption = trueprovider_ltm_settings.image_caption_provider_id = bigmodel/glm-4v-flash
现象
开启「群聊上下文感知 → 自动理解图片」后,群里有图片消息时日志报错,且图片描述始终为空:
[ERROR] [astrbot.group_chat_context:219]: 获取图片描述失败: Error code: 400 - 图片输入格式/解析错误
换成其他视觉模型后同样失败:
| 模型 | 报错 |
|---|---|
| glm-4v-flash | HTTP 400 · code 1210 · 图片输入格式/解析错误 |
| glm-4.6v-flash | 同上 |
| deepseek-flash | HTTP 400 · Unsupported image_url format |
原因分析
astrbot/builtin_stars/astrbot/group_chat_context.py 中,图片参数取自组件的本地落地文件:
# 第 209 行
url = comp.url if comp.url else comp.file
在本机环境下 comp.url 为空,comp.file 是一个本地临时文件路径:
C:\Users\<user>\.astrbot_launcher\instances\<id>\core\data\temp\media_image_20261101135205643_89a0.jpg
然后原样塞进 provider:
# 第 104-109 行
response = await provider.text_chat(
prompt=image_caption_prompt,
session_id=uuid.uuid4().hex,
image_urls=[image_url], # ← 本地路径,未做任何转换
persist=False,
)
而 image_urls 只接受 http(s) URL 或 base64 / data URL,不接受本地路径,因此各家模型都返回 400。
对比:主对话链路(astr_main_agent.py 的 prepare_request_images)会做格式转换,所以「当前消息里的图」能正常识别;只有这条历史转述路径漏了这一步。
验证
同一张本地图片,三种传法直接请求模型 API:
| 传入形式 | glm-4v-flash 结果 |
|---|---|
本地路径 C:\...\a.jpg |
❌ 400 · code 1210 |
标准 data URL data:image/jpeg;base64,... |
✅ 正确识别 |
| 裸 base64 | ✅ 正确识别 |
把本地文件读成字节、转成 data URL 后再请求,三张真实图片全部成功:
10 KB 表情包 → "熊猫头配上文字尬笑"
131 KB 动漫图 → "长发女孩,背景有彩色泡泡和蛋糕"
1439 KB 游戏图 → "炉石传说的卡牌图片"
期望行为
get_image_caption 应该先把图片引用统一成模型可用的形式,再进行请求。建议在第 209 行取到 url 后、或 get_image_caption 内部加一步转换:
async def get_image_caption(self, image_url, image_caption_provider_id, image_caption_prompt):
image_url = await self._normalize_image_url(image_url)
...
_normalize_image_url 需要覆盖:
- 本地路径 /
file://→ 读字节 → base64 data URL base64://xxx(OneBot 约定)→ 去掉前缀转 data URL- 裸 base64 → 转 data URL
- http(s) / 已是 data URL → 原样返回
另外建议按 provider_settings.image_compress_options.max_size(默认 1280)压缩一次再编码,避免大图请求体过大。
影响范围
- 只影响「群聊上下文感知 → 自动理解图片」这条历史转述链路
- 当前消息的图片识别不受影响(走
prepare_request_images,有转换) - 开启该功能时,每张群图都会失败一次,既产生无用的 API 调用,也可能带来明显延迟
临时规避
关闭 provider_ltm_settings.image_caption 即可不再报错,代价是历史图片只显示占位符。
需要历史图片描述的话,可以在插件里 monkey-patch GroupChatContext.get_image_caption 做上述转换,不改核心文件、升级不丢。
如何复现?
- 开启
provider_ltm_settings.image_caption,并配置任一视觉模型 - 在群里发送一张图片(无需 @ 机器人)
- 观察日志:
获取图片描述失败: Error code: 400 - 图片输入格式/解析错误 - 群聊上下文中该图片显示为空(连
[Image]占位都没有)
AstrBot 版本
4.29.3
操作系统
Windows
部署方式
windows desktop
使用的消息平台适配器
onebot v11
错误日志
控制台输出(AstrBot 4.29.3,Windows,来自用户终端截图)
[2026-11-01 13:49:50.096] [astrbot_plugin_caption_fix] [INFO] [astrbot_plugin_caption_fix.main:103]: [caption_fix] 第 1 次修正图片格式(C:\Users\<user>\... → data URL)
[2026-11-01 13:49:50.096] [Core] [WARN] [v4.29.3] [sources.openai_source:201]: 图片预处理结果为空,将忽略。
[2026-11-01 13:52:05.466] [astrbot_plugin_caption_fix] [INFO] [astrbot_plugin_caption_fix.main:103]: [caption_fix] 第 2 次修正图片格式(C:\Users\<user>\... → data URL)
[2026-11-01 13:52:05.648] [Core] [WARN] [v4.29.3] [sources.openai_source:201]: 图片预处理结果为空,将忽略。
未装补丁时的原始报错(同一环境):
[2026-11-01 13:13:31.864] [Core] [ERROR] [v4.29.3] [astrbot.group_chat_context:219]: 获取图片描述失败: Error code: 400 - 图片输入格式/解析错误
说明:
- AstrBot 未开启 log_file_enable,控制台是唯一输出渠道,故以上为逐行抄录
- 上面两行 WARN 出现在装了格式转换补丁之后;补丁把本地路径误当成 base64 处理,
产出无效 data URL,因此被 openai_source 判为空
- 未装补丁时,本地路径原样发出,模型侧返回 400
辅助信息
No response
检查清单
- 主要语言
- Python
- 星标
- 46.4k
- 派生
- 3.4k
- 平均合并
- 1 天 11 小时
- 30 天内合并 PR
- 120
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
AstrBotDevs/AstrBot 的其他 Issue
-
enhancement
难度 2/5 1-3 小时 新手友好度 75/100
AstrBotDevs/AstrBot#11038 · 2 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
AstrBotDevs/AstrBot#11034 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
AstrBotDevs/AstrBot#10999 · 1 条评论 ·
维护者通常 1 天内回复
-
[Bug] OpenAI-compatible Gemini 工具 schema const 导致 400可能已有人在做 @arccat-114 于 17 天前认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 77/100
AstrBotDevs/AstrBot#10720 · 1 条评论 ·
维护者通常 1 天内回复
-
[Bug] Discord slash command sync aborts with KeyError when a plugin handler is defined in a submodule可能已有人在做 @yuexia5 于 22 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 77/100
AstrBotDevs/AstrBot#10626 · 1 条评论 ·
维护者通常 1 天内回复
查看 AstrBotDevs/AstrBot 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
Treat corrupt-shape state files as missing in `load_state`可能已有人在做 @Qrytics 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 85/100
OvertureMaps/overturemaps-py#175 ·
维护者通常 1 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 83/100
awslabs/visual-asset-management-system#1278 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 82/100
aws-samples/sample-per-model-bedrock#835 ·
维护者通常 1 天内回复