用 Amazon Nova 多模态嵌入打造航空制造文档智能检索系统

2026-05-12 28 预计阅读时间:1 分钟
来源:aws.amazon.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:12 分钟

航空制造领域的技术文档从来不只是文字——工程图纸、工艺流程图、材料规范表、检验照片交织在一起,构成一套复杂的多模态知识体系。传统文本检索只能"看懂"文字部分,图表里的关键信息往往被遗漏。Amazon Nova Multimodal Embeddings 的出现,让图像和文本在同一向量空间里对齐,检索终于能真正"读懂"一整份文档。

这篇文章拆解一个实际方案:在 Amazon Bedrock 上调用 Nova 多模态嵌入模型,把航空制造文档(含图片)编码为向量,存入 Amazon S3 Vectors,再对 26 条真实制造查询做检索增强生成(RAG),对比纯文本管线与多模态管线的回答质量。

为什么制造场景必须多模态

航空制造的典型文档长这样:

  • 一份工艺规程,前半段是文字描述,后半段附有焊接顺序示意图;
  • 一张检验记录表,既有数值列,又有缺陷位置标注照片;
  • 材料规范 PDF 里,力学性能数据以表格呈现,微观金相图紧随其后。

纯文本嵌入只处理可提取的文字,图表被丢弃或仅靠 OCR 捕获零散字符。OCR 丢失空间关系和视觉语义——"裂纹位于焊缝热影响区"这句话,在图上是一条红色标注线指向特定区域,OCR 只能得到"裂纹"和"热影响区"两个词,丢失了位置对应关系。

Nova Multimodal Embeddings 的核心能力:同一模型同时编码文本和图像,输出到同一向量空间。这意味着一张焊接顺序图和一段描述焊接顺序的文字,在向量空间里天然靠近,无需额外对齐步骤。

系统架构拆解

整体管线分三层:

  1. 文档摄入层:从 S3 读取 PDF/图片,按页拆分,每页保留文字+图像对;
  2. 嵌入与存储层:调用 Bedrock 上的 Nova Multimodal Embeddings,生成向量,写入 S3 Vectors;
  3. 检索与生成层:用户查询同样走 Nova 嵌入,在 S3 Vectors 中做相似度搜索,取回 top-k 片段,送入 LLM 生成回答。

关键设计决策:

  • 按页而非按段落切分:制造文档的图文强耦合,拆散会破坏语义完整性;
  • 图像不单独索引:每页的图像与同页文字一起送入模型,模型内部做跨模态融合;
  • S3 Vectors 作为向量库:直接在对象存储上做向量搜索,省去独立向量数据库的运维开销。

多模态嵌入调用实战

下面给出可改造运行的 Python 示例,展示如何调用 Nova Multimodal Embeddings 并写入 S3 Vectors。

前置准备

# 安装依赖
pip install boto3 Pillow pdf2image

# 确保 AWS 凭证已配置( ~/.aws/credentials 或环境变量)
# 需要的 IAM 权限:
#   - bedrock:InvokeModel  (Nova Multimodal Embeddings)
#   - s3:PutObject / s3:GetObject
#   - s3-vector:PutVectorIndex / s3-vector:QueryVectorIndex

生成多模态嵌入

import boto3
import json
import base64
from pathlib import Path

bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")

MODEL_ID = "amazon.nova-multimodal-embedding-v1"
EMBED_DIM = 1024  # 支持维度:256 / 512 / 1024,制造场景建议用 1024

def encode_image_to_base64(image_path: str) -> str:
    """将本地图片转为 base64 字符串,供 Bedrock 调用"""
    with open(image_path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

def get_multimodal_embedding(text: str, image_path: str = None) -> list[float]:
    """
    调用 Nova Multimodal Embeddings,同时编码文字和图片。
    如果没有图片,只传文字即可。
    """
    content = [{"text": text}]

    if image_path:
        content.append({
            "image": {
                "format": Path(image_path).suffix.lstrip("."),  # jpg / png
                "source": {"bytes": encode_image_to_base64(image_path)}
            }
        })

    body = {
        "input": {"content": content},
        "configuration": {"outputDimensionality": EMBED_DIM}
    }

    response = bedrock.invoke_model(
        modelId=MODEL_ID,
        body=json.dumps(body),
        accept="application/json",
        contentType="application/json"
    )

    result = json.loads(response["body"].read())
    return result["embedding"]


# ---- 示例:编码一页制造文档 ----
page_text = "焊接顺序:先焊内环缝(G1),再焊外环缝(G2),层间温度控制在150°C以下。"
page_image = "weld_sequence_diagram.png"  # 本地图片路径

embedding = get_multimodal_embedding(page_text, page_image)
print(f"向量维度: {len(embedding)}")  # 1024

注意image_path 为本地文件路径,实际生产中可从 S3 下载到临时文件再编码。如果文档页只有文字没有图片,image_pathNone,模型退化为纯文本嵌入,但输出仍在同一向量空间。

写入 S3 Vectors 并检索

import boto3

s3v = boto3.client("s3-vector", region_name="us-east-1")

VECTOR_BUCKET = "aero-manufacturing-vectors"
INDEX_NAME = "doc-pages-index"

# 1. 创建向量索引(首次运行)
s3v.create_vector_index(
    vectorBucketName=VECTOR_BUCKET,
    indexName=INDEX_NAME,
    dimension=EMBED_DIM,
    distanceMetric="cosine"
)

# 2. 写入向量
def upsert_page_vector(page_id: str, embedding: list[float], metadata: dict):
    s3v.put_vectors(
        vectorBucketName=VECTOR_BUCKET,
        indexName=INDEX_NAME,
        vectors=[
            {
                "key": {"id": page_id},
                "values": embedding,
                "metadata": metadata  # 如 {"doc": "WS-2024-037", "page": 5}
            }
        ]
    )

upsert_page_vector(
    page_id="WS-2024-037_p5",
    embedding=embedding,
    metadata={"doc": "WS-2024-037", "page": 5, "type": "weld_procedure"}
)

# 3. 查询检索
def search_pages(query_text: str, top_k: int = 5) -> list[dict]:
    query_emb = get_multimodal_embedding(query_text)  # 纯文本查询
    result = s3v.query_vector_index(
        vectorBucketName=VECTOR_BUCKET,
        indexName=INDEX_NAME,
        queryVector={"values": query_emb},
        topK=top_k,
        returnMetadata=True
    )
    return result["results"]

# 实际查询
hits = search_pages("内环缝焊接的层间温度要求是多少?")
for hit in hits:
    print(f"文档: {hit['metadata']['doc']}, 页码: {hit['metadata']['page']}, 距离: {hit['distance']}")

检索增强生成闭环

from anthropic import AnthropicBedrock

anthropic = AnthropicBedrock()

def generate_answer(query: str, top_k: int = 5) -> str:
    hits = search_pages(query, top_k)
    # 组装上下文:取回页面的文字部分(metadata 中可扩展存储原文)
    context_blocks = []
    for hit in hits:
        context_blocks.append({
            "type": "text",
            "text": f"[文档 {hit['metadata']['doc']}{hit['metadata']['page']}页]\n"
                    + hit["metadata"].get("page_text", "")
        })
        # 如果检索到的页面有图片,也可以把图片直接传给 LLM
        img_path = hit["metadata"].get("page_image_path")
        if img_path:
            context_blocks.append({
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": encode_image_to_base64(img_path)
                }
            })

    response = anthropic.messages.create(
        model="anthropic.claude-3-5-sonnet-20241022-v2:0",
        max_tokens=1024,
        system="你是航空制造工艺专家,根据提供的文档内容准确回答问题。如果文档中没有相关信息,明确说明。",
        messages=[{
            "role": "user",
            "content": context_blocks + [{"type": "text", "text": query}]
        }]
    )
    return response.content[0].text

answer = generate_answer("内环缝焊接的层间温度要求是多少?")
print(answer)

26 条查询的对比结论

原文对 26 条航空制造真实查询做了系统评测,核心发现:

维度 纯文本管线 多模态管线
图表信息召回 低——图表内容几乎无法检索 高——图像语义被编码进向量
空间关系问答 无法回答"图中哪个位置"类问题 能定位到对应图像区域
纯文字问题 两者持平 持平,无退化
整体准确率 约 60% 约 85%

多模态管线在纯文字问题上没有退化,这是关键——同一向量空间意味着文字查询仍然能精准匹配文字片段,同时额外获得了图表理解能力。

值得注意的边界:

  • 图像质量敏感:低分辨率扫描件或手写批注,嵌入质量会下降,建议预处理时做分辨率增强;
  • 成本:多模态嵌入的调用费用高于纯文本嵌入,需评估文档中图片的实际密度——如果 90% 的页面只有文字,可以只对含图页面走多模态,其余走纯文本,混合索引仍有效;
  • 维度选择:256 维适合大规模粗筛,1024 维适合最终精准检索,制造场景建议 1024。

上手清单

  1. 确认文档结构:统计制造文档中含图页面的比例,决定是否需要全量多模态还是混合策略;
  2. 开通 Bedrock Nova 模型:在 AWS Console 的 Bedrock 区域申请 Nova Multimodal Embeddings 访问权限;
  3. 创建 S3 Vectors 索引:选定维度和距离度量(制造场景推荐 cosine + 1024 维);
  4. 编写摄入脚本:按页拆分 PDF,提取文字 + 渲染页面为图片,批量调用嵌入并写入向量库;
  5. 评测检索质量:用 20-30 条真实业务查询对比纯文本 vs 多模态的召回率和生成准确率;
  6. 决定生产策略:根据评测结果选择全量多模态或混合索引,设置合理的 top-k 和 rerank 逻辑。

制造文档的智能检索,瓶颈从来不在文字理解,而在图表理解。Nova Multimodal Embeddings 把图文统一到同一向量空间,S3 Vectors 把向量存储拉回对象存储的简单运维模型——两个组件组合起来,制造场景的多模态 RAG 从"概念验证"进入了"可投产"阶段。


相关推荐