【知识中枢】多模态知识处理:让AI读懂PDF、表格、图片和视频

企业80%的知识以PDF、Excel、图片、视频等非结构化形式存在。如果知识中枢只能处理纯文本,就等于放弃了80%的知识资产。本文系统讲解多模态知识处理的完整技术栈:从文档解析到表格结构化,从OCR到视频理解,最终实现跨模态统一检索。

📖 导读

一个真实的场景:某制造企业的设备维修手册是300页的PDF,里面包含大量接线图、零件爆炸图和故障排查流程图。当维修工程师问AI"X型号压缩机E3故障怎么排查"时,如果AI只能读文字,那些关键的流程图和接线图就完全丢失了。

本文将覆盖:

  • 企业知识的模态分布分析
  • PDF/Word文档的深度解析技术
  • 复杂表格的结构化提取
  • 图片OCR与语义理解
  • 视频知识的自动提取
  • 多模态统一检索架构

关键词多模态 文档解析 OCR 表格提取 视频理解


一、企业知识的模态分布

1.1 被忽视的80%

1.2 各模态的处理挑战

模态 典型内容 核心挑战 信息密度
PDF 产品手册、合同、白皮书 版式复杂、图文混排、扫描件
表格 价格表、参数表、对照表 合并单元格、嵌套结构、跨页 极高
图片 架构图、流程图、截图 OCR精度、语义理解、布局
视频 培训录屏、操作演示 时长大、信息稀疏、多模态融合 低(但关键帧密度高)
PPT 方案汇报、产品介绍 碎片化、视觉依赖、逻辑隐含

1.3 多模态处理的价值公式

复制代码
知识完整度 = Σ(各模态知识 × 提取率)

当前状态(仅处理纯文本):
  知识完整度 = 20% × 90% = 18%

目标状态(全模态处理):
  知识完整度 = 20%×90% + 35%×85% + 20%×80% + 12%×75% + 8%×70% + 5%×80%
             = 18% + 29.75% + 16% + 9% + 5.6% + 4%
             = 82.35%

提升幅度:18% → 82.35%(+357%)

二、PDF/Word文档深度解析

2.1 PDF解析的技术难点

2.2 文档解析引擎实现

python 复制代码
from enum import Enum
from dataclasses import dataclass
from typing import List, Optional
from pathlib import Path

class ElementType(Enum):
    TEXT = "text"
    TABLE = "table"
    IMAGE = "image"
    HEADER = "header"
    FOOTER = "footer"
    FORMULA = "formula"
    LIST = "list"
    CODE = "code"

@dataclass
class DocumentElement:
    type: ElementType
    content: str
    position: dict          # 页面位置 {page, x, y, w, h}
    confidence: float
    metadata: dict = None

@dataclass
class ParsedDocument:
    title: str
    elements: List[DocumentElement]
    page_count: int
    metadata: dict
    reading_order: List[int]  # 元素阅读顺序

class PDFParser:
    """PDF深度解析器"""

    def __init__(self, ocr_engine, layout_model, table_model):
        self.ocr = ocr_engine
        self.layout = layout_model      # 版面分析模型
        self.table_detector = table_model

    def parse(self, pdf_path: str) -> ParsedDocument:
        """解析PDF文档"""

        # Step 1: 判断PDF类型
        pdf_type = self._detect_pdf_type(pdf_path)

        if pdf_type == "digital":
            # 数字PDF:直接提取文本层
            elements = self._parse_digital_pdf(pdf_path)
        elif pdf_type == "scanned":
            # 扫描件PDF:需要OCR
            elements = self._parse_scanned_pdf(pdf_path)
        else:
            # 混合型:部分页面有文本层,部分需要OCR
            elements = self._parse_mixed_pdf(pdf_path)

        # Step 2: 版面分析(确定阅读顺序)
        elements = self._analyze_layout(elements)

        # Step 3: 表格识别与结构化
        elements = self._process_tables(elements)

        # Step 4: 图片处理
        elements = self._process_images(elements)

        # Step 5: 构建文档结构
        doc = self._build_document_structure(elements, pdf_path)

        return doc

    def _detect_pdf_type(self, pdf_path: str) -> str:
        """检测PDF类型:数字/扫描/混合"""
        import fitz  # PyMuPDF
        doc = fitz.open(pdf_path)

        text_pages = 0
        total_pages = len(doc)

        for page in doc:
            text = page.get_text().strip()
            if len(text) > 50:  # 有足够文本
                text_pages += 1

        ratio = text_pages / max(total_pages, 1)

        if ratio > 0.8:
            return "digital"
        elif ratio < 0.2:
            return "scanned"
        else:
            return "mixed"

    def _parse_digital_pdf(self, pdf_path: str) -> List[DocumentElement]:
        """解析数字PDF"""
        import fitz
        doc = fitz.open(pdf_path)
        elements = []

        for page_num, page in enumerate(doc):
            # 提取文本块
            blocks = page.get_text("dict")["blocks"]

            for block in blocks:
                if block["type"] == 0:  # 文本块
                    text = ""
                    for line in block["lines"]:
                        line_text = "".join([
                            span["text"] for span in line["spans"]
                        ])
                        text += line_text + "\n"

                    elements.append(DocumentElement(
                        type=ElementType.TEXT,
                        content=text.strip(),
                        position={
                            "page": page_num + 1,
                            "bbox": block["bbox"]
                        },
                        confidence=0.99
                    ))

                elif block["type"] == 1:  # 图片块
                    img_data = block.get("image")
                    elements.append(DocumentElement(
                        type=ElementType.IMAGE,
                        content="[IMAGE]",
                        position={
                            "page": page_num + 1,
                            "bbox": block["bbox"]
                        },
                        confidence=0.99,
                        metadata={"image_data": img_data}
                    ))

        return elements

    def _parse_scanned_pdf(self, pdf_path: str) -> List[DocumentElement]:
        """解析扫描件PDF(OCR)"""
        import fitz
        from PIL import Image
        import io

        doc = fitz.open(pdf_path)
        elements = []

        for page_num, page in enumerate(doc):
            # 渲染页面为图片
            pix = page.get_pixmap(dpi=300)
            img = Image.open(io.BytesIO(pix.tobytes("png")))

            # 版面分析
            regions = self.layout.analyze(img)

            for region in regions:
                cropped = img.crop(region.bbox)

                if region.type == "text":
                    text = self.ocr.recognize(cropped)
                    elements.append(DocumentElement(
                        type=ElementType.TEXT,
                        content=text,
                        position={"page": page_num + 1, "bbox": region.bbox},
                        confidence=region.confidence
                    ))
                elif region.type == "table":
                    table_data = self.table_detector.extract(cropped)
                    elements.append(DocumentElement(
                        type=ElementType.TABLE,
                        content=table_data.to_markdown(),
                        position={"page": page_num + 1, "bbox": region.bbox},
                        confidence=region.confidence,
                        metadata={"structured": table_data.to_dict()}
                    ))
                elif region.type == "figure":
                    elements.append(DocumentElement(
                        type=ElementType.IMAGE,
                        content="[FIGURE]",
                        position={"page": page_num + 1, "bbox": region.bbox},
                        confidence=region.confidence,
                        metadata={"image": cropped}
                    ))

        return elements

2.3 智能分块策略

解析完成后,需要将文档切分为适合RAG检索的知识块:

python 复制代码
class DocumentChunker:
    """文档智能分块器"""

    def chunk(self, doc: ParsedDocument) -> List[dict]:
        """将解析后的文档切分为知识块"""
        chunks = []

        # 策略1:按语义结构切分(标题层级)
        sections = self._split_by_structure(doc)

        for section in sections:
            if len(section["content"]) > 1000:
                # 大段落:按段落+滑动窗口切分
                sub_chunks = self._sliding_window(
                    section["content"], 
                    window_size=512,
                    overlap=64
                )
                for i, sc in enumerate(sub_chunks):
                    chunks.append({
                        "content": sc,
                        "section_title": section["title"],
                        "chunk_index": i,
                        "total_chunks": len(sub_chunks),
                        "source_page": section.get("page"),
                        "has_table": section.get("has_table", False)
                    })
            else:
                chunks.append({
                    "content": section["content"],
                    "section_title": section["title"],
                    "chunk_index": 0,
                    "total_chunks": 1,
                    "source_page": section.get("page"),
                    "has_table": section.get("has_table", False)
                })

        # 为每个chunk添加上下文前缀
        for chunk in chunks:
            chunk["content"] = (
                f"[文档:{doc.title}] "
                f"[章节:{chunk['section_title']}] "
                f"{chunk['content']}"
            )

        return chunks

    def _sliding_window(self, text: str, 
                        window_size: int = 512,
                        overlap: int = 64) -> List[str]:
        """滑动窗口切分,保持句子完整性"""
        sentences = self._split_sentences(text)
        chunks = []
        current = ""

        for sent in sentences:
            if len(current) + len(sent) > window_size and current:
                chunks.append(current.strip())
                # 保留重叠部分
                overlap_text = current[-overlap:] if len(current) > overlap else ""
                current = overlap_text + sent
            else:
                current += sent

        if current.strip():
            chunks.append(current.strip())

        return chunks

三、复杂表格结构化提取

3.1 表格处理的特殊性

表格是企业知识中信息密度最高的载体,但也是AI最难处理的格式:

3.2 表格提取与结构化

python 复制代码
import pandas as pd
from typing import List, Dict

class TableExtractor:
    """表格结构化提取器"""

    def __init__(self, table_detect_model, llm_client):
        self.detector = table_detect_model
        self.llm = llm_client

    def extract_and_structure(self, table_image) -> dict:
        """从图片中提取表格并结构化"""

        # Step 1: 表格结构检测(行列定位)
        structure = self.detector.detect_structure(table_image)

        # Step 2: 单元格内容识别
        cells = self._recognize_cells(table_image, structure)

        # Step 3: 处理合并单元格
        cells = self._handle_merged_cells(cells, structure)

        # Step 4: 识别表头层级
        header_levels = self._identify_headers(cells)

        # Step 5: 转换为结构化数据
        df = self._to_dataframe(cells, header_levels)

        # Step 6: 生成自然语言描述(用于向量化)
        nl_description = self._to_natural_language(df)

        return {
            "dataframe": df,
            "markdown": df.to_markdown(),
            "natural_language": nl_description,
            "metadata": {
                "rows": len(df),
                "cols": len(df.columns),
                "header_levels": header_levels
            }
        }

    def _to_natural_language(self, df: pd.DataFrame) -> str:
        """将表格转换为自然语言描述(用于Embedding)"""
        descriptions = []

        for _, row in df.iterrows():
            row_desc = []
            for col in df.columns:
                val = row[col]
                if pd.notna(val):
                    row_desc.append(f"{col}为{val}")
            descriptions.append(",".join(row_desc))

        return ";".join(descriptions)

    def _handle_merged_cells(self, cells, structure) -> List[dict]:
        """处理合并单元格"""
        # 检测跨行/跨列的单元格
        for cell in cells:
            if cell["row_span"] > 1 or cell["col_span"] > 1:
                # 将合并单元格的值复制到所有覆盖的位置
                for r in range(cell["row"], cell["row"] + cell["row_span"]):
                    for c in range(cell["col"], cell["col"] + cell["col_span"]):
                        cells.append({
                            "row": r,
                            "col": c,
                            "value": cell["value"],
                            "is_merged_copy": True,
                            "merge_origin": (cell["row"], cell["col"])
                        })
        return cells


class TableQA:
    """表格问答:让用户用自然语言查询表格"""

    def __init__(self, llm_client):
        self.llm = llm_client

    def answer(self, question: str, table_md: str) -> str:
        """基于表格内容回答自然语言问题"""
        prompt = f"""请根据以下表格数据回答问题。

表格数据:
{table_md}

问题:{question}

要求:
1. 答案必须完全基于表格数据,不要推测
2. 如果表格中没有相关信息,明确说明
3. 给出具体数值时注明单位和条件"""

        return self.llm.generate(prompt)

四、图片OCR与语义理解

4.1 企业图片知识的类型

图片类型 典型场景 处理方式 难度
文字截图 错误提示、配置界面 OCR提取文字 ★☆☆
流程图 业务流程、审批流程 结构识别+文字提取 ★★★
架构图 系统架构、网络拓扑 结构识别+语义理解 ★★★★
表格图片 参数表、价格表 表格检测+OCR ★★★
产品图 零件图、爆炸图 目标检测+标注识别 ★★★★
手写笔记 白板、会议记录 手写OCR ★★★★★

4.2 图片知识处理流水线

python 复制代码
class ImageKnowledgeProcessor:
    """图片知识处理器"""

    def __init__(self, ocr_engine, vlm_client, diagram_parser):
        self.ocr = ocr_engine           # OCR引擎
        self.vlm = vlm_client           # 视觉语言模型
        self.diagram = diagram_parser   # 图表解析器

    def process(self, image, context: dict = None) -> dict:
        """处理单张图片,提取知识"""

        # Step 1: 图片分类
        img_type = self._classify_image(image)

        # Step 2: 根据类型选择处理策略
        if img_type == "text_screenshot":
            result = self._process_text_image(image)
        elif img_type == "flowchart":
            result = self._process_flowchart(image)
        elif img_type == "architecture_diagram":
            result = self._process_architecture(image)
        elif img_type == "table_image":
            result = self._process_table_image(image)
        else:
            result = self._process_general_image(image)

        # Step 3: 生成知识描述
        result["knowledge_description"] = self._generate_description(
            image, result, img_type
        )

        return result

    def _process_flowchart(self, image) -> dict:
        """处理流程图"""
        # 使用图表解析器识别节点和连接
        nodes, edges = self.diagram.parse_flowchart(image)

        # OCR提取节点内文字
        for node in nodes:
            node["text"] = self.ocr.recognize(node["crop"])

        # 构建流程描述
        flow_description = self._build_flow_description(nodes, edges)

        return {
            "type": "flowchart",
            "nodes": nodes,
            "edges": edges,
            "description": flow_description,
            "structured": self._to_step_list(nodes, edges)
        }

    def _process_architecture(self, image) -> dict:
        """处理架构图:使用VLM进行语义理解"""
        # 视觉语言模型理解架构图
        prompt = """请详细描述这张架构图的内容,包括:
1. 包含哪些组件/模块
2. 组件之间的连接关系和数据流向
3. 整体架构的设计意图
4. 关键技术选型(如果能识别)"""

        understanding = self.vlm.analyze(image, prompt)

        # OCR补充识别文字
        ocr_text = self.ocr.recognize_full(image)

        return {
            "type": "architecture",
            "description": understanding,
            "ocr_text": ocr_text,
            "components": self._extract_components(understanding)
        }

    def _generate_description(self, image, result, img_type) -> str:
        """生成用于Embedding的知识描述"""
        if img_type == "flowchart":
            return f"[流程图] {result['description']}"
        elif img_type == "architecture_diagram":
            return f"[架构图] {result['description']}"
        elif img_type == "table_image":
            return f"[表格] {result.get('natural_language', '')}"
        else:
            return f"[图片] {result.get('description', result.get('ocr_text', ''))}"

4.3 OCR精度优化策略


五、视频知识提取

5.1 企业视频知识的特点

企业视频(培训录屏、操作演示、会议录像)有两个显著特点: - 信息稀疏 :1小时视频中,有效知识可能只占5-10分钟 - 多模态融合:画面、语音、文字(PPT/字幕)需要综合理解

5.2 视频知识提取流水线

python 复制代码
class VideoKnowledgeExtractor:
    """视频知识提取器"""

    def __init__(self, asr_engine, vlm_client, ocr_engine):
        self.asr = asr_engine      # 语音识别
        self.vlm = vlm_client      # 视觉语言模型
        self.ocr = ocr_engine      # OCR

    def extract(self, video_path: str) -> List[dict]:
        """从视频中提取知识片段"""

        # Step 1: 关键帧提取(去除冗余帧)
        keyframes = self._extract_keyframes(video_path)

        # Step 2: 语音转文字
        transcript = self.asr.transcribe(video_path)

        # Step 3: 视频分段(按主题切分)
        segments = self._segment_by_topic(transcript, keyframes)

        # Step 4: 逐段提取知识
        knowledge_items = []
        for segment in segments:
            ki = self._extract_segment_knowledge(segment)
            if ki:
                knowledge_items.append(ki)

        return knowledge_items

    def _extract_keyframes(self, video_path: str) -> List[dict]:
        """提取关键帧(场景切换检测)"""
        import cv2

        cap = cv2.VideoCapture(video_path)
        keyframes = []
        prev_frame = None
        threshold = 30  # 场景切换阈值

        frame_idx = 0
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break

            if prev_frame is not None:
                diff = cv2.absdiff(frame, prev_frame)
                change = diff.mean()

                if change > threshold:
                    keyframes.append({
                        "frame_idx": frame_idx,
                        "timestamp": frame_idx / cap.get(cv2.CAP_PROP_FPS),
                        "image": frame
                    })

            prev_frame = frame
            frame_idx += 1

        cap.release()
        return keyframes

    def _segment_by_topic(self, transcript, keyframes) -> List[dict]:
        """按主题切分视频"""
        # 使用LLM对转录文本进行主题分段
        prompt = f"""请将以下视频转录文本按主题切分为多个段落。
每段应该是一个独立的知识主题。

转录文本:
{transcript}

输出JSON数组,每项包含:
- topic: 主题名称
- start_time: 起始时间(秒)
- end_time: 结束时间(秒)
- summary: 内容摘要"""

        segments = self.vlm.generate_json(prompt)

        # 为每段关联关键帧
        for seg in segments:
            seg["keyframes"] = [
                kf for kf in keyframes 
                if seg["start_time"] <= kf["timestamp"] <= seg["end_time"]
            ]

        return segments

    def _extract_segment_knowledge(self, segment: dict) -> Optional[dict]:
        """从单个视频片段中提取知识"""

        # 综合语音转录 + 关键帧OCR + 视觉理解
        context_parts = []

        # 语音内容
        if segment.get("transcript"):
            context_parts.append(f"[语音内容]\n{segment['transcript']}")

        # 关键帧OCR(PPT文字等)
        for kf in segment.get("keyframes", []):
            ocr_text = self.ocr.recognize(kf["image"])
            if len(ocr_text.strip()) > 20:
                context_parts.append(f"[画面文字 @{kf['timestamp']:.0f}s]\n{ocr_text}")

        if not context_parts:
            return None

        # LLM综合提取知识
        prompt = f"""从以下视频片段中提取核心知识点。

{chr(10).join(context_parts)}

输出:
1. 知识点标题
2. 详细内容(结构化描述)
3. 关键要点(3-5个)
4. 适用场景"""

        result = self.vlm.generate(prompt)

        return {
            "title": segment.get("topic", "未命名"),
            "content": result,
            "source_timestamp": f"{segment['start_time']:.0f}s - {segment['end_time']:.0f}s",
            "type": "video_knowledge"
        }

六、多模态统一检索架构

6.1 统一Embedding空间

6.2 统一检索引擎

python 复制代码
class MultiModalRetriever:
    """多模态统一检索引擎"""

    def __init__(self, text_encoder, image_encoder, 
                 vector_store, reranker, llm_client):
        self.text_enc = text_encoder
        self.image_enc = image_encoder
        self.store = vector_store
        self.reranker = reranker
        self.llm = llm_client

    def search(self, query: str, top_k: int = 10,
               modality_filter: List[str] = None) -> List[dict]:
        """跨模态统一检索"""

        # Step 1: 查询编码
        query_vector = self.text_enc.encode(query)

        # Step 2: 向量检索(跨所有模态)
        candidates = self.store.search(
            vector=query_vector,
            top_k=top_k * 3,  # 多召回,后续重排
            filter={"modality": {"$in": modality_filter}} 
                   if modality_filter else None
        )

        # Step 3: 重排序(Cross-encoder精排)
        reranked = self.reranker.rerank(query, candidates)

        # Step 4: 模态感知后处理
        results = self._post_process(reranked[:top_k], query)

        return results

    def _post_process(self, results, query) -> List[dict]:
        """模态感知后处理"""
        processed = []

        for item in results:
            result = {
                "content": item["content"],
                "modality": item["metadata"]["modality"],
                "score": item["score"],
                "source": item["metadata"].get("source"),
            }

            # 根据模态类型补充展示信息
            if item["metadata"]["modality"] == "table":
                result["display"] = item["metadata"].get("markdown_table")
                result["content_type"] = "structured_table"
            elif item["metadata"]["modality"] == "image":
                result["display"] = item["metadata"].get("image_url")
                result["content_type"] = "visual"
            elif item["metadata"]["modality"] == "video":
                result["display"] = item["metadata"].get("video_url")
                result["timestamp"] = item["metadata"].get("timestamp")
                result["content_type"] = "video_clip"
            else:
                result["content_type"] = "text"

            processed.append(result)

        return processed

    def generate_answer(self, query: str, 
                        search_results: List[dict]) -> str:
        """基于多模态检索结果生成回答"""

        # 构建多模态上下文
        context_parts = []
        for i, r in enumerate(search_results[:5]):
            if r["modality"] == "table":
                context_parts.append(
                    f"[参考{i+1}-表格] {r.get('display', r['content'])}"
                )
            elif r["modality"] == "text":
                context_parts.append(
                    f"[参考{i+1}-文本] {r['content']}"
                )
            elif r["modality"] == "image":
                context_parts.append(
                    f"[参考{i+1}-图片描述] {r['content']}"
                )

        context = "\n\n".join(context_parts)

        prompt = f"""基于以下多来源参考资料回答用户问题。
如果参考资料中包含表格,请优先使用表格数据。
如果信息不足,请明确说明。

参考资料:
{context}

用户问题:{query}"""

        return self.llm.generate(prompt)

七、工程实践:性能与质量

7.1 处理性能基准

模态 处理速度 准确率 瓶颈
纯文本 100页/秒 99%+
数字PDF 20页/秒 95%+ 版面分析
扫描件PDF 3页/秒 88-92% OCR
表格图片 2张/秒 85-90% 结构检测
流程图 1张/秒 80-85% 结构理解
视频(1h) 5-10分钟 75-85% ASR+分段

7.2 质量保障机制

yaml 复制代码
# multimodal_quality_config.yaml
quality:
  ocr:
    min_confidence: 0.80          # OCR最低置信度
    fallback_to_vlm: true         # 低置信度时用VLM补充
    domain_dictionary: "custom"   # 领域词典纠错

  table:
    structure_validation: true    # 表格结构校验
    cell_count_threshold: 4       # 最少4个单元格才算有效表格
    numeric_validation: true      # 数值合理性校验

  image:
    min_resolution: 200           # 最低分辨率(DPI)
    blur_threshold: 100           # 模糊度阈值(Laplacian方差)
    skip_decorative: true         # 跳过装饰性图片

  video:
    min_segment_length: 30        # 最短有效片段(秒)
    speech_ratio_threshold: 0.3   # 最低语音占比
    keyframe_quality: 0.7         # 关键帧质量阈值

📌 本文要点回顾

  1. 企业80%的知识是非纯文本形态:PDF(35%)、表格(20%)、图片(12%)、视频(8%)构成了知识的主体,仅处理纯文本意味着放弃大部分知识资产。

  2. PDF解析需要区分三种类型:数字PDF直接提取文本层,扫描件需要OCR流水线,混合型需要逐页判断。版面分析是保证阅读顺序正确性的关键。

  3. 表格是信息密度最高的知识载体:处理难点在于合并单元格、多级表头和跨页表格。结构化后应同时生成Markdown(供展示)和自然语言描述(供Embedding)。

  4. 图片处理按类型分策略:文字截图用OCR,流程图/架构图用结构检测+VLM语义理解,表格图片用表格检测+OCR。

  5. 多模态统一检索的核心是统一Embedding空间:所有模态的知识都转换为向量存入统一索引,查询时一次检索跨所有模态,重排阶段考虑模态相关性。


❓ FAQ

Q1:扫描件PDF的OCR准确率能达到多少?手写内容呢?

印刷体扫描件在300DPI以上、图像质量良好的情况下,OCR准确率可达95%-98%。经过领域词典纠错和语言模型后处理,实际可用率可达97%+。手写内容的识别率显著下降,印刷体手写约80-85%,草书约60-70%。对于手写内容,建议结合VLM(视觉语言模型)进行语义级理解,而非逐字识别。

Q2:视频知识提取的ROI如何?1小时视频值得花算力处理吗?

企业培训视频的知识密度通常在5%-15%(即1小时视频有3-9分钟的有效知识内容)。如果这些视频是核心培训材料(如产品操作、维修流程),提取后的知识可以被反复检索引用,ROI非常高。建议优先处理:① 高频被问到的操作类视频;② 专家经验类培训;③ 新产品/新功能介绍视频。鲲溟智能的知识中枢支持视频批量处理,1小时视频约5-10分钟完成提取。

Q3:多模态处理和纯文本RAG相比,系统复杂度增加了多少?

复杂度主要增加在三个方面:① 预处理管道(需要OCR、表格检测、视频ASR等额外组件);② 存储层(需要同时存储原始文件、提取结果、向量索引);③ 检索层(需要跨模态对齐和模态感知重排)。但检索和生成层面的架构与纯文本RAG基本一致。建议分阶段建设:第一阶段做好PDF和表格(覆盖55%知识),第二阶段加入图片(覆盖67%),第三阶段处理视频(覆盖75%)。


💬 互动话题:你的企业中,哪种格式的知识最难被AI利用?是复杂表格、技术图纸,还是培训视频?欢迎在评论区聊聊你遇到的多模态知识处理难题。