[Bug] aiocqhttp:引用机器人自己发送的图片无法解析(get_msg 返回空 url + 裸文件名)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 22/100
Línea de trabajo
Start in astrbot/core/astr_main_agent.py around lines 1601-1621 and 1665, where has_embedded_image is set and the quoted-image fallback is skipped, then read _materialize_media_ref in astrbot/core/utils/media_utils.py. A reasonable done state is that a reply image which fails to materialize falls through to image_resolver.py instead of injecting the [Image unavailable] text, with a test covering that path. The SnowLuma protocol-side resolution is a separate, open question.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
问题描述
AstrBot 4.29.3(Docker)+ aiocqhttp(OneBot v11)+ SnowLuma。
机器人通过插件发送一张图片(Comp.Image),QQ 端显示正常。随后用户引用这条机器人自己发出的图片消息并补上文字,AstrBot 无法解析引用中的图片:
- 日志出现两条 WARN;
- 请求中注入
TextPart("[Image unavailable]"); - 模型据此回复“图片没加载出来”。
与 #10179(私聊中引用图片无法解析)的触发场景不同:这里是引用机器人自己发送的图片,并且协议端对这张图的 get_msg / get_image 都只返回空 url 和裸文件名。相关 PR #10225 / #10194 曾尝试修复 quoted image 的引用解析,但均未合并;当前 master(2026-11-03)仍存在下文的短路逻辑。
如何复现?
- 让机器人发送任意一张图片(插件使用
Comp.Image即可),确认 QQ 端正常显示; - 在 QQ 中引用该图片消息,并回复任意文字;
- 查看 AstrBot 日志。
预期行为
引用中的图片能作为视觉输入送给模型。如果协议端确实无法提供可访问的图片来源,至少不应让模型产生“我这边图片加载失败”的表述。
实际行为
图片被判定为 unresolved media ref,模型收到 [Image unavailable],并回复图片未加载。
AstrBot 版本
4.29.3
操作系统
Linux(Docker)
部署方式
Docker
使用的消息平台适配器
aiocqhttp(OneBot v11)+ SnowLuma
错误日志
[WARN] Image processing in reply chain failed for unresolved media ref
name='<md5>.png' len=36: [Errno 2] image reference is not an existing local file
or a valid payload: '<md5>.png'
[WARN] Quoted image is unavailable (FileNotFoundError): unresolved media ref
name='<md5>.png' len=36
每条引用该图片的消息都会稳定出现这两条 WARN。
根因分析
-
发送侧:
astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py:36-44将Image/Record段无条件转为base64://后发送给协议端。协议端把图片缓存为 md5 命名的文件。 -
协议端返回:用户引用该消息后,
get_msg返回的图片段为:{"type":"image","data":{"url":"","file":"<md5>.png","sub_type":0,"summary":"[图片]"}}没有
file_id、没有本地路径、没有 CDN URL。对同一张图单独调用get_image/get_file,同样只得到url: ""。 -
解析失败:适配器构造出
Image(file="<md5>.png", url="")。astrbot/core/utils/media_utils.py的_materialize_media_ref()(约 463 行)只接受http(s)://、file:、data:、base64://、裸 base64,或真实存在的本地文件;裸文件名在这里抛出FileNotFoundError(错误文案约 646 行),describe_media_ref()(约 326、382 行)将其格式化为unresolved media ref name='<md5>.png' len=36。astrbot/core/pipeline/preprocess_stage/stage.py:215先记录第一条 WARN,随后astrbot/core/astr_main_agent.py:1610再次失败并记录第二条 WARN。 -
fallback 被短路:
astrbot/core/astr_main_agent.py:1601-1621只要 reply chain 中存在Image就把has_embedded_image置为True;convert_to_file_path()失败后注入[Image unavailable]。由于has_embedded_image已为True,约 1665 行的if not has_embedded_image:分支被跳过,现成的astrbot/core/utils/quoted_message/image_resolver.py(会依次尝试get_image/get_file/get_group_file_url/get_private_file_url)根本没有机会执行。 -
即使进入该 fallback,SnowLuma 对同一张图的
get_image/get_file仍只返回url: "",因此该协议端场景还需要额外的解析途径;但第 4 点会让支持get_image的协议端也一起失效,属于独立的 AstrBot 侧缺陷。
代码位置
- 发送:
astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py:36-44 - 媒体解析:
astrbot/core/utils/media_utils.py:463(_materialize_media_ref)、:326/:382(describe_media_ref)、:646(FileNotFoundError文案) - 引用图片处理与 fallback 短路:
astrbot/core/astr_main_agent.py:1601-1621、:1665 - 预处理阶段日志:
astrbot/core/pipeline/preprocess_stage/stage.py:215 - 已存在但未触发的引用解析器:
astrbot/core/utils/quoted_message/image_resolver.py
修复建议
- 最小修复:
astr_main_agent.py中把has_embedded_image改为“图片成功物化后才置为True”,或在物化失败时仍进入 quoted fallback。这样get_image可用的协议端能恢复正常。 - SnowLuma 场景:
get_msg和get_image都只给空url+ 裸文件名。若可通过协议端共享缓存目录、get_private_file_url或额外参数解析,请在ImageResolver中补上;若确实无法解析,warning 建议带上reply message_id与协议端 action 的原始返回,便于区分协议端限制和 AstrBot 缺陷。 - 失败提示:解析失败时不要注入
[Image unavailable](或改成中性文本,例如“引用中的图片无法获取”),也可以只记录日志并通过事件暴露给插件,避免模型对用户输出“图片加载失败”。 - 发送侧:考虑到 #6717 中维护者说明 base64 是为兼容“协议端与 AstrBot 不同机部署”而保留,这里不建议直接改回
file://。如果协议端能访问callback_api_base,可以在发送后登记图片的可回取 URL / 协议端file_id映射,供引用解析使用;否则优先级应低于第 1、3 点。
相关 issue / PR
- #10179(open):私聊中引用图片无法解析,触发场景与本条不同,且未提供日志/根因;
- #3895(closed):v4.7.4 下“引用机器人自身消息 + 图片无法识别”,当时以“插件生成的图片不计入上下文”关闭,本路径未修复;
- #10225、#10194(closed,未合并):曾尝试解析 quoted image 的 opaque / unusable reference;当前 master 仍存在第 4 点的短路问题。
辅助信息
日志与文件名已脱敏:不含 QQ 号、服务器 IP、Cookie、token 或人格名。
检查清单
- Lenguaje dominante
- Python
- Estrellas
- 46.4k
- Forks
- 3.4k
- Merge medio
- 1 d 11 h
- PR fusionados (30 d)
- 120
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de AstrBotDevs/AstrBot
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
AstrBotDevs/AstrBot#11038 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
AstrBotDevs/AstrBot#11034 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
AstrBotDevs/AstrBot#10999 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Bug] OpenAI-compatible Gemini 工具 schema const 导致 400Posiblemente ocupada @arccat-114 la tomó hace 16 días. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
AstrBotDevs/AstrBot#10720 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Bug] Discord slash command sync aborts with KeyError when a plugin handler is defined in a submodulePosiblemente ocupada @yuexia5 la tomó hace 21 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
AstrBotDevs/AstrBot#10626 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de AstrBotDevs/AstrBot
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Project-N-E-K-O/N.E.K.O#3670 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
type:docs
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
jejjohnson/xtremax#123 ·
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
triage
Dificultad 1/5 Menos de una hora Aptitud para principiantes 78/100
microsoft/agent-framework#10218 ·
Los mantenedores suelen responder en 1 día
-
fidelity
Dificultad 2/5 Medio día Aptitud para principiantes 66/100
Los mantenedores suelen responder en 1 día