# ComfyUI-Smart-Metadata-Reader 语言 / Language: 中文 | [English](README_EN.md) `ComfyUI-Smart-Metadata-Reader` 是一个 Python-only 的 ComfyUI 自定义节点。它的主节点 `Smart Metadata Reader` 是图片加载器型节点,可以选择或上传图片,读取图片里已经保存的 AI 生成 metadata,并输出图片、遮罩、真实正负提示词和常用生成参数。 ## 项目简介 这个节点不是“看图反推提示词”。它不会分析图片内容来猜 prompt,而是读取图片文件里已有的 metadata,尤其是 ComfyUI 生成 PNG 中保存的 `prompt` 和 `workflow` JSON。 它的核心目标是处理复杂 ComfyUI workflow:从最终 selected sampler 的 `positive` / `negative` conditioning 链路反向追踪,提取真正进入最终生图步骤的正面提示词、负面提示词、模型、VAE、LoRA、seed、steps、CFG、sampler、scheduler 和尺寸等信息。 ## 解决什么问题 普通 prompt reader 往往只能读取简单的 A1111 参数,或者在 ComfyUI workflow 里直接查找 `CLIPTextEncode.inputs.text`。但复杂 workflow 里,`CLIPTextEncode.inputs.text` 可能是上游链接,例如字符串拼接节点、ShowText 缓存、翻译节点、ControlNet conditioning、detailer 或其他 custom node。 本项目把 ComfyUI metadata 当成 graph 解析,而不是把 workflow 里所有文本字段扫一遍。 ## 与普通 Prompt Reader 的区别 - 从最终输出图片链路选择 sampler,而不是随便取最后一个节点。 - positive / negative 只从 selected sampler 的 conditioning 链路解析。 - 不扫描整个 workflow 的所有 `text` 字段。 - 不会把 ControlNet 的 image、strength、control_net、model_name 等参数混进 prompt。 - 不会把 Gemini / OpenAI / ChatGPT / Claude / LLM 节点的 `system_instruction`、`system_prompt`、`prompt`、`instruction`、`messages` 这类模板当成最终提示词。 - `ShowText|pysssss` 有 `text_0` 缓存结果时,会优先使用缓存结果。 - 不过滤 LoRA trigger words、角色词、风格词、NSFW 词、质量词、翻译文本或用户手写标签。 ## 安装方式 进入你的 ComfyUI 安装目录: ```bash cd ComfyUI/custom_nodes git clone https://github.com/CyberShadowX/ComfyUI-Smart-Metadata-Reader.git cd ComfyUI-Smart-Metadata-Reader pip install -r requirements.txt ``` 安装后重启 ComfyUI。 ## 使用方式 1. 在 ComfyUI 中添加节点 `Smart Metadata Reader`。 2. 从 ComfyUI `input` 目录选择图片,或通过图片控件上传图片。 3. 使用节点输出连接后续节点,或直接查看输出文本。 ## 节点参数说明 - `parameter_index`:用于 A1111 / Forge 多组参数 fallback 时选择第几组参数。普通使用保持 `0`。 - `prefer_cached_text`:优先使用 `ShowText` 等节点保存的缓存结果,避免把 Gemini / OpenAI 的 `system_instruction`、`prompt template` 当成最终提示词。普通使用保持 `true`。 - `include_raw_json`:是否在内部解析结果中保留原始 `prompt` / `workflow` JSON。普通使用保持 `true`。 - `max_depth`:graph 反向追踪最大深度,用于防止循环。普通使用保持 `40`;极复杂工作流可以适当加大。 ## 输出端口 主节点输出: - `image` - `mask` - `positive` - `negative` - `seed` - `steps` - `cfg` - `width` - `height` - `model_name` - `filename` - `setting` `setting` 是给人看的整合参数文本,包含文件名、来源、模型、VAE、LoRA 列表、seed、steps、CFG、sampler、scheduler、尺寸、状态、置信度和 unresolved 信息。 ## 支持的 Metadata 格式 - ComfyUI `prompt` metadata 优先,因为它更接近实际执行 graph。 - ComfyUI `workflow` metadata 用于补充 UI 缓存和 fallback,例如 `ShowText|pysssss` 的显示缓存。 - A1111 / Forge `parameters` 会在 ComfyUI graph 无法启动解析时作为 fallback。 - 通过 Pillow 读取 PNG、JPEG、WEBP 中的 metadata。 如果图片被平台压缩、聊天软件转发或图床处理后丢失 metadata,本节点无法恢复原始提示词。这种情况只能依赖其他图像反推工具。 ## 支持的主要节点类型 Phase 1 初始支持包括: - `KSampler` - `KSamplerAdvanced` - `SamplerCustom` - `SamplerCustomAdvanced` - `CLIPTextEncode` - `CLIPTextEncodeSDXL` - `StringFunction|pysssss` - `ShowText|pysssss` - `DeepTranslatorTextNode` - `ControlNetApply` - `ControlNetApplyAdvanced` - `ConditioningCombine` - `ConditioningConcat` - `InpaintModelConditioning` - `FaceDetailer` 和常见 detailer passthrough 模式 - `CheckpointLoaderSimple` - `CheckpointLoader` - `VAELoader` - `LoraLoader` - `LoraLoaderModelOnly` ## 重要解析原则 - positive 必须来自 selected sampler 的 `positive` conditioning 链路。 - negative 必须来自 selected sampler 的 `negative` conditioning 链路。 - 不扫描整个 workflow 的所有文本节点。 - 未连接到最终 sampler 的 Gemini、ShowText、StringFunction、PrimitiveString、备注文本或旧 CLIPTextEncode 不会污染结果。 - ControlNet、Detailer、Inpaint、ConditioningCombine、ConditioningConcat 只在最终 conditioning 链路上作为 passthrough 或 branch 解析。 - LoRA loader 的文件名和强度会单独进入 setting;但 LoRA trigger words 如果通过文本节点进入 prompt,就会保留在 positive / negative 中。 - 不做内容审查,不做提示词优化,不删 token。 ## LLM / ShowText 缓存说明 对于 Gemini / OpenAI / ChatGPT / Claude / LLM 反推工作流,插件只能恢复已经写入 metadata、并且位于最终 selected sampler/generator `positive` / `negative` 链路上的运行结果。 可以恢复: - 最终链路上的 `ShowText|pysssss` cache,例如 prompt JSON 的 `inputs.text_0` 或同 node_id workflow JSON 的 `widgets_values[0]`。 - 最终链路上的 `SmartMetadataReader` positive / negative output 递归结果。 - 最终链路上的 `StringFunction`、文本拼接、`ConditioningCombine` / `ConditioningConcat` 多分支组合结果。 无法恢复: - 只存在于 LLM runtime node 内部、但没有写入 `ShowText` cache 的运行结果。 - workflow 其他未连接分支里的 `ShowText` 缓存,即使它看起来像 prompt。 - Gemini / OpenAI 节点的 `prompt`、`system_instruction`、`system_prompt`、`messages`、模板或 API 参数。 这种情况下节点会返回 `PARTIAL` / unresolved。这是为了避免误读旧分支、备用分支、UI 展示分支或 LLM 指令模板。 ## 已验证场景 Phase 1 实机和回归测试已覆盖: - 普通 ComfyUI `prompt` / `workflow` metadata。 - Comfyroll `CR Apply ControlNet` positive conditioning passthrough。 - `ShowText|pysssss` 缓存文本。 - `StringFunction|pysssss` prompt 拼接。 - `DeepTranslatorTextNode` 文本来源。 - A1111 / Forge `parameters` fallback。 - PNG / JPEG / WEBP metadata 读取。 - UltimateSDUpscale / USDU sampler-like metadata parsing。 - nested `SmartMetadataReader` output resolution。 - `CLIPTextEncode.text -> ShowText -> SmartMetadataReader positive/negative output`。 - JPEG EXIF `UserComment` / Civitai metadata fallback。 ## 当前限制 - Phase 1 是 Python-only。节点内部三个大文本框和更像 SD Prompt Reader 的图片预览 UI 留到 Phase 2 JS 前端增强。 - 部分未知 custom conditioning 节点会返回 `PARTIAL` / unresolved,而不是猜测 prompt。 - 某些 custom node 的运行结果如果没有写入 metadata 缓存,可能无法还原。 - 如果放大图引用了原图,例如 `003.png`,但原图不存在于可解析路径中,会返回 `PARTIAL` / unresolved;插件无法凭空恢复运行时输出。 - 插件不会全局扫描 workflow 中所有 `ShowText` / `widgets_values` / `text` 字段,只解析最终 selected sampler/generator 的 `positive` / `negative` 链路。 - 被压缩或重新保存后丢失 metadata 的图片无法读取原始生成参数。 ## 后续计划 - Phase 2:JS frontend enhancement,在节点内部显示 `positive` / `negative` / `setting` 三个文本框。 - Phase 3:更多 sampler adapter,例如 Efficient / Impact / custom sampler,基于真实失败样本补充。 - Phase 4:更多 metadata format compatibility。 ## 本地验证 在插件目录运行: ```bash python -m pytest -q python -m compileall . ``` `tests/` 目录是开发和回归测试用的。普通 ComfyUI 用户不需要手动运行这些测试;仓库保留它们是为了在后续兼容更多 custom nodes 时,防止破坏已有功能。 ## 手动 ComfyUI 验证 1. 重启 ComfyUI。 2. 搜索并添加 `Smart Metadata Reader`。 3. 选择或上传一张带有 metadata 的图片。 4. 确认节点输出 `image`、`mask`、`positive`、`negative` 和 `setting`。 5. 如果解析状态是 `PARTIAL`,查看 `setting` 中的 unresolved 信息,定位不支持的 custom node。