TextIn × Agentic RAG:让大模型真正读懂学术论文

0 阅读11分钟
  • 项目代码公众号ChallengeHub后台回复:TextIn 即可获得

一个真实的痛点场景

作为一名研究者,我每天都需要阅读大量的学术论文。最近在做文献综述时,我想到:能不能让 AI 帮我快速理解这些论文的核心内容?

于是我尝试直接把 PDF 扔给大模型,结果发现:

  • 复杂表格被识别成乱码,论文中的实验对比数据完全无法理解
  • 图表信息丢失,关键的模型架构图、实验结果图都变成了"[图片]"
  • 版面混乱,多栏排版、公式、参考文献混在一起,上下文关系完全错位

更关键的是,把整篇论文都塞给大模型不仅成本高昂,还容易让模型"迷失"在海量信息中,答非所问。

这让我开始思考:要构建一个真正好用的论文问答系统,需要解决两个核心问题:

  1. 精准的文档解析 - 让 AI 能够正确理解论文的结构化内容
  2. 智能的信息检索 - 只把相关章节传给大模型,降低成本提高准确度

Agentic RAG:更聪明的论文问答方式

传统的 RAG(检索增强生成)通常是基于向量相似度做检索,但对于学术论文这种高度结构化的文档,我们需要更智能的方式。

Agentic RAG 的核心思想是:让 AI Agent 像人类研究者一样,先理解问题,再决定需要阅读论文的哪些部分。

我设计的论文问答系统流程是这样的:

这种方式相比传统 RAG 有几个明显优势:

  • 精准定位:Agent 能理解论文结构,直接定位到"方法论"、"实验结果"等关键章节
  • 成本优化:平均只需传输 20-30% 的文档内容,大幅降低 token 消耗
  • 上下文完整:保留章节的完整性,避免向量检索可能的语义割裂

为什么选择 TextIn?

TextIn解析能力

TextIn 官网:cc.co/16YSaw

在测试了几种文档解析方案后,我发现对于学术论文这种复杂文档,TextIn 的表现明显更出色

1. 复杂表格解析能力

学术论文中最常见的就是实验对比表格,往往是跨页的、多层表头的复杂表格。

我拿一篇机器学习论文做测试,里面有个三页的模型性能对比表:

TextIn 能够:

  • 准确识别跨页表格并自动拼接
  • 保留表头层级关系
  • 正确识别数值和单位

而开源工具往往会把跨页表格识别成两个独立表格,或者表头错位。

这对于 RAG 系统至关重要 - 错误的表格解析会导致大模型产生完全错误的结论。

2. 图表数据提取

TextIn 最近上线的图表解析功能对论文问答特别有用。

论文中的图表通常包含关键实验结果,比如:

  • 模型性能对比的柱状图
  • 训练过程的损失曲线
  • 模型架构示意图

TextIn 不仅能识别图表,还能提取其中的数据:

{
  "chart_type": "bar_chart",
  "data": [
    {"label": "Model A", "value": 92.3},
    {"label": "Model B", "value": 94.1},
    {"label": "Model C", "value": 95.7}
  ]
}

这样 AI 就能基于真实数据回答"哪个模型效果最好"这类问题,而不是只能说"根据图表显示..."

3. 版面理解和结构保留

学术论文的版面复杂:双栏排版、公式、引用、脚注、页眉页脚...

TextIn 的版面理解能力让它能够:

  • 正确处理双栏到单栏的转换
  • 保留章节层级结构(######
  • 准确识别公式(支持 LaTeX 格式)
  • 过滤页眉页脚等干扰信息

最终输出的 Markdown 是真正可以直接用于 RAG 的高质量结构化文本

实战:搭建 Agentic RAG 论文问答系统

下面我分享一下具体实现(完整代码已开源)。

核心代码实现

1. TextIn 文档解析

from textin import OCRClient

client = OCRClient("your-app-id", "your-secret")

# 解析论文
result = client.parse_document(pdf_path)
markdown_content = result['markdown']

2. 章节智能分割

def split_by_sections(markdown):
    """按 # 标题自动分割章节"""
    sections = []
    current_section = {"title": "", "content": ""}
    
    for line in markdown.split('\n'):
        if line.startswith('#'):
            if current_section["content"]:
                sections.append(current_section)
            current_section = {
                "title": line.strip('#').strip(),
                "content": ""
            }
        else:
            current_section["content"] += line + '\n'
    
    return sections

3. Agent 智能章节选择

这是 Agentic RAG 的核心 - 让 AI 判断哪些章节与问题相关:

def select_relevant_sections(question, sections, model="deepseek-chat"):
    """AI Agent 智能选择相关章节"""
    
    section_summaries = "\n".join([
        f"[{i}] {s['title']}: {s['content'][:100]}..." 
        for i, s in enumerate(sections)
    ])
    
    prompt = f"""
你是一个论文分析助手。用户提出了一个问题,请分析这个问题需要阅读论文的哪些章节。

问题:{question}

论文章节列表:
{section_summaries}

请输出一个0/1数组,1表示该章节相关,0表示不相关。
只输出数组,格式如:[1,0,1,0,1,1,0]
"""
    
    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}]
    )
    
    # 解析返回的数组
    selection = eval(response.choices[0].message.content.strip())
    return [i for i, sel in enumerate(selection) if sel == 1]

4. 生成最终答案

def answer_question(question, sections, selected_indices):
    """基于选中章节回答问题"""
    
    context = "\n\n".join([
        f"## {sections[i]['title']}\n{sections[i]['content']}"
        for i in selected_indices
    ])
    
    prompt = f"""
基于以下论文内容回答问题。

论文相关内容:
{context}

问题:{question}

请提供详细、准确的答案。
"""
    
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[{"role": "user", "content": prompt}],
        stream=True  # 流式输出
    )
    
    for chunk in response:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

完整的问答流程

# 1. 解析论文
markdown = parse_pdf_with_textin("paper.pdf")

# 2. 分割章节
sections = split_by_sections(markdown)
print(f"识别到 {len(sections)} 个章节")

# 3. 用户提问
question = "这篇论文提出的模型架构是什么?"

# 4. Agent 选择相关章节
selected = select_relevant_sections(question, sections)
print(f"Agent 选择了章节: {[sections[i]['title'] for i in selected]}")

# 5. 生成答案(流式输出)
for chunk in answer_question(question, sections, selected):
    print(chunk, end='', flush=True)

实测效果

我用这个系统测试了一篇 20 页的Qwen3论文:《Qwen3-VL-Embedding and Qwen3-VL-Reranker: A Unified Framework for State-of-the-Art Multimodal Retrieval and Ranking》

问题 1:"这篇论文的核心贡献是什么?"

  • Agent 选择:Abstract, Introduction, Conclusion(2/33 章节)

  • Token 消耗:~2K tokens(相比全文 15K tokens 节省 87%)

  • 回答质量: 准确总结了三个核心创新点

问题 2:"论文是怎么构造数据集的"

  • Agent 选择:Data(1/33 章节)

  • Token 消耗:~1.5K tokens

  • 回答质量: 完整列出了 数据集构造过程

根据论文提供的章节,论文通过以下步骤和方法构造数据集,旨在赋予模型跨多种模态、任务和领域的通用表示能力:

### 1. **整体数据策略**
- **目标**:构建一个大规模、平衡的训练语料库,以覆盖所有模态、任务和领域,解决公开和内部数据存在的严重不平衡和稀缺问题。
- **方法**:采用**数据合成**技术来生成平衡的数据集,确保鲁棒性。

### 2. **数据集格式**
- 完整数据集由多个子数据集组成,表示为 $\mathcal{D} = \{D_i\}_{i=1}^M$。
- 每个子数据集 $D_i$ 由四元组定义:$D_i = (I_i, Q_i, C_i, R_i)$,其中:
  - **指令($I_i$)**:文本描述,定义子数据集的相关性标准和任务目标。
  - **查询($Q_i$)**:包含 $N_q$ 个查询对象的集合,每个查询可以是文本、图像、视频或多模态组合。
  - **语料库($C_i$)**:包含 $N_d$ 个文档对象的存储库,每个文档可以是单模态或多模态(文本、图像、视频)。
  - **相关性标签($R_i$)**:定义查询与文档之间的关系,包括正样本(相关文档)和负样本(不相关文档)。

### 3. **数据合成过程**
数据合成是构造子数据集 $D_i$ 的核心,扩展了 Qwen3 Embedding 的方法到多模态场景。具体步骤如下:

#### **a. 种子池构建**
- **收集原始数据**:聚合大量高质量、多样化的原始图像和视频数据集。
- **质量过滤**  - 粗粒度过滤:去除低分辨率或异常宽高比的资源。
  - 结构细化:对视频数据应用场景切割检测,移除静态或损坏片段,以保持时间动态完整性。
- **细粒度标注**:使用 Qwen3-VL-32B 模型为剩余资源生成细粒度类别标签。
- **跨模态对齐**:通过 GME 嵌入模型的相似性分数,过滤低置信度注释或视觉-文本对应性差的样本。
- **类别再平衡**:对精炼后的数据集进行类别层面的再平衡,形成最终种子池(分布见图4)。

#### **b. 多任务标注**
基于种子池,使用 Qwen3-VL-32B 进行多模态和多任务注释,包括:

- **图像任务**  1. **图像分类**:查询为图像和分类指令,文档为类别标签。合成对象识别、场景解析、地标识别等任务数据,包括正类别和语义混淆的负标签。
  2. **图像问答**:查询为图像和问题,文档为答案。生成涵盖事实识别、视觉推理、OCR 提取等 QA 对,包括真实答案和误导性干扰项。
  3. **图像检索**:查询为搜索文本,文档为候选图像。合成不同语义层次的检索查询,如视觉描述、抽象场景、逻辑约束等。

- **视频任务**  1. **视频分类**:查询为视频和分类任务,文档为类别。合成活动识别、事件分类等数据,包括正类别和相关负标签。
  2. **视频问答**:查询为视频和问题,文档为答案。生成涉及事实识别、时间定位、主题推理等的 QA 对。
  3. **视频检索**:查询为文本描述,文档为视频。合成从实体搜索到主题发现的检索查询。
  4. **时刻检索**:查询为文本(可选关键帧),文档为视频片段。进行细粒度时间定位,包括相关片段和无关负片段。

- **辅助步骤**:在生成任务注释前,要求模型为每个图像或视频生成描述性标题,以提供上下文,确保注释质量。

### 4. **正样本精炼和难负样本挖掘**
为了提升对比表示学习的效果,实施自动化的两阶段挖掘流程:

- **召回阶段**:使用嵌入模型提取查询和文档的表示,基于余弦相似度为每个查询检索 top-K 相关候选文档。
- **相关性过滤阶段**  - **正样本精炼**:仅保留那些至少有一个正样本文档得分超过阈值 $t^+$ 的查询,否则丢弃。
  - **难负样本选择**:对于有效查询,计算其精炼正样本的平均得分 $\bar{s}^+$,选择得分低于 $\bar{s}^+ + \delta^-$ 的非正样本作为难负样本,避免“假负样本”混入。

### 总结
论文通过**数据合成**构建了一个结构化、多模态的数据集,包括种子池构建、多任务标注(覆盖图像和视频的分类、问答、检索等任务),以及正负样本的精炼和挖掘。这一方法旨在解决数据不平衡问题,并确保模型在多样化的模态和任务上具有鲁棒性。具体示例和提示见附录。

问题 3:"表3显示了什么结果?"

  • Agent 选择:Benchmarks(7/33 章节)

  • 回答质量:由于 TextIn 准确解析了表格,AI 能直接引用数据

相比传统"全文塞进去"的方式,Agentic RAG + TextIn 的组合:

  • 准确度提升:聚焦相关内容,减少干扰信息
  • 成本降低 80%+ :平均只需传输 20% 的内容
  • 响应速度更快:更少的 token 意味着更快的生成

对 RAG 系统架构的思考

通过这次实践,我有几点体会:

1. 文档解析是 RAG 的"地基"

很多人做 RAG 系统,花大量时间调优 Embedding 模型、检索策略,却忽视了文档解析这个环节。

实际上,如果解析就是错的(表格错位、图表丢失、版面混乱),后面做再多优化都是徒劳。

TextIn 这样专业的文档解析工具,能让你的 RAG 系统赢在起跑线上。,我们可以直接通过产品官网可以体验效果,也可以通过API SDK的形式调用接口,非常方便!

2. Agentic 是 RAG 的进化方向

传统 RAG:Embedding → 向量检索 → Top-K
Agentic RAG:AI 理解问题 → 智能决策 → 精准定位

这不仅是技术路线的改变,更是范式的升级。就像从"关键词搜索"到"语义搜索"的跨越。

3. 结构化解析 > 纯文本

对于专业文档(论文、研报、技术文档),结构化解析远比纯文本重要:

  • 章节层级 → 让 Agent 能"目录式"理解文档
  • 表格数据 → 让 AI 能进行数值推理
  • 图表信息 → 让答案有数据支撑

TextIn 的强项就在于能输出真正高质量的结构化数据

写在最后

如果你也在做:

  • 企业知识库构建
  • RAG/Agent 应用开发
  • 文档智能处理

强烈建议试试 TextIn 的文档解析能力,特别是它的:

  • 跨页表格拼接功能(太适合处理研报、合同了)
  • 图表解析能力(年报、数据分析必备)
  • 高精度 OCR 和版面理解

相关资源:

欢迎在评论区分享你的 RAG 实践经验,或者提出问题,我会尽量回复!

#TextIn #AgenticRAG #文档解析 #智能体应用 #论文问答