跳到主要内容

DocumentImageDescriber 图片描述工具

DocumentImageDescriberagents-flex-core 提供的文档增强工具。它会查找 Markdown 图片和内嵌 HTML <img> 标签,调用支持视觉输入的 ChatModel 生成描述,并在图片下方新建一个普通正文段落。工具不会把生成结果写入 Markdown 的 [] 或 HTML 的 alt 属性。

处理前:

markdown
内容内容内容
![](https://example.com/chart.png)

处理后:

markdown
内容内容内容
![](https://example.com/chart.png)

<!-- image-description:start -->
一张展示季度增长趋势的折线图。
<!-- image-description:end -->

生成的描述属于 Document.content 的一部分,可以继续参与文档切分、Embedding 和检索。成对的 HTML 注释用于界定描述范围,不会在 Markdown 或 HTML 页面中显示。

1. 引入依赖

Maven:

xml
<dependency>
    <groupId>com.agentsflex</groupId>
    <artifactId>agents-flex-core</artifactId>
    <version>${agents-flex.version}</version>
</dependency>

还需要引入一个具体的 ChatModel 模块,并选择支持图片输入的模型。以实际使用的供应商和模型能力为准。

2. 快速开始

java
import com.agentsflex.core.document.Document;
import com.agentsflex.core.document.DocumentImageDescriber;

Document document = Document.of(
    "季度经营数据如下:\n" +
    "![](https://example.com/chart.png)"
);

DocumentImageDescriber describer = new DocumentImageDescriber(chatModel);
describer.describe(document);

System.out.println(document.getContent());

describe(Document) 会直接更新传入文档的 content,并返回同一个 Document 实例。文档的 ID、标题、向量和 Metadata 不会被修改。

也可以只处理 Markdown 字符串:

java
String enhancedMarkdown = describer.describe(sourceMarkdown);

3. 配置模型参数

默认使用温度 0.2。可以通过 ChatOptions 指定视觉模型和其他生成参数:

java
describer.setChatOptions(ChatOptions.builder()
    .model("vision-model")
    .temperature(0.1f)
    .maxTokens(200)
    .build());

传入 null 会抛出 IllegalArgumentException

4. 自定义描述提示词

默认提示词要求模型输出适合文档检索的简洁描述,不输出 Markdown 或额外前缀。可以替换整个提示词模板:

java
describer.setPromptTemplate(
    "请描述图表中的指标、趋势和异常点,只输出描述正文。" +
    "图片替代文本:{alt}"
);

模板中的 {alt} 会替换为 Markdown 图片的替代文本。例如:

markdown
![2026 年销售趋势](https://example.com/sales.png)

此时 {alt} 的值为 2026 年销售趋势。模板可以不包含该占位符,但不能为空。

HTML 图片使用 <img> 标签的 alt 属性:

html
<img src="https://example.com/sales.png" alt="2026 年销售趋势">

5. 处理规则

输入情况行为
普通 Markdown 图片调用一次模型,在图片下方新建普通正文段落
HTML <img> 图片读取 srcalt,保留原标签并在图片下方新建普通正文段落
一行混合 Markdown 和 HTML 图片按原文中的出现顺序逐张调用模型
一行包含多张图片按出现顺序逐张调用模型并追加描述
图片下方存在 image-description:start 标记视为已有描述,不再调用模型
Markdown 代码围栏中的图片语法或 HTML 标签作为示例代码保留,不调用模型
模型返回多行描述移除空行后写入同一个普通段落
模型返回空消息保留原图片,不追加描述
模型返回错误响应抛出模型异常,由调用方决定重试或跳过

工具会保留源文本使用的 LFCRLFCR 换行风格。

6. 图片地址要求

图片地址会作为 UserMessage.imageUrls 发送给 ChatModel,工具本身不负责上传或下载图片。地址必须是目标模型适配器能够读取的形式,例如:

  • 模型服务能够访问的 HTTP 或 HTTPS URL;
  • Data URI,例如 data:image/png;base64,...
  • 具体 ChatModel 实现明确支持的其他地址格式。

相对地址(如 images/chart.png)通常无法被远程模型直接读取,应先转换为公开 URL 或 Data URI。部分 ChatModel 在配置了“仅支持 Base64 图片”能力时,会自动把 HTTP 图片转换为 Data URI。

7. 与文档提取组合

DocumentExtractors 可以先从 PDF、Word、PowerPoint 等文件中提取 Markdown 和图片,再由 DocumentImageDescriber 补充图片语义:

java
String markdown = DocumentExtractors.extract(file);
Document document = Document.of(markdown);

DocumentImageDescriber describer = new DocumentImageDescriber(chatModel);
describer.describe(document);

List<Document> chunks = splitter.split(document);

推荐顺序是:

  1. 提取文档和图片;
  2. 生成图片描述;
  3. 执行文档切分;
  4. 生成 Embedding 并写入 Store。

默认的文档图片处理器会生成 Data URI。如果改为上传对象存储,应确保返回的 URL 对视觉模型可访问。

8. 成本与并发

每张待处理图片都会发起一次同步模型调用。包含大量图片的文档会相应增加耗时、Token 消耗和供应商请求次数。批量导入时应在业务层设置并发上限、超时和重试策略,并结合模型供应商的 QPS 限制控制任务速率。

重复执行时,工具会通过 <!-- image-description:start --><!-- image-description:end --> 界定并识别已有描述。成对标记也方便后续程序精确替换或删除描述区域。