AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


GPT-4o 自动化提取PDF的内容:以雅思真题4为例
发布日期:2024-06-06 06:59:08 浏览次数: 1696


SmartFlowAI


点击上方蓝字关注我们

作者:李剑锋

全文约 3000 字,预计阅读时间 10 分钟

导读:本文从上期分享的案例“从雅思真题中定向提取听力部分的内容并分批保存”出发,将同一套提示词迁移到同类任务上,帮助大家学会举一反三

同类任务迁移

    在前两期的内容中我带大家了解了如何使用 GPT-4o 辅助编程以便从“剑雅4” PDF 中检索并提取雅思听力真题,并对部分代码进行了讲解。其实就对整体的检索工作流程有了一些基础的认知了,下面我就通过提取该雅思阅读的内容来带大家看看我是如何通过修改同一个提示词,来根据我工作的要求进行个性化定制。大家可以关注「机智流」后回复“雅思”或点击文末的“阅读原文”来获取这份文档的内容。

⚠️ 温馨提醒

在使用前,建议不要在原有的聊天界面中继续完成任务,尽可能新开一个页面消除记忆,因为假如有之前的记忆很容易出问题。

任务解析

    雅思阅读和听力有点不同,就是其不是说 Section 了,说的是 READING PASSAGE 1、2&3 了。因此我们的关键词需要修改一下。而且只有三篇而不是四篇。并且命名规则假如和之前重合也不好,所以这些都是需要修改的地方。但是总体而言差别不大。

雅思听力真题部分的示例

    但是即便有之前的完整代码,我建议还是像之前一样三步走而不是一步到位,因为大模型的输出还是不太可控,我尝试了两次都失败了,但是利用任务拆分的方法都是一次就成功了。

第一步:提取一个PASSAGE

    因此我在原本的提示词基础上进行了修改,包括把之前听力时候提取的代码作为案例给到这次的提示词里,并且把对应需要修改的部分也处理了。完整的提示词如下所示:

###任务说明###
那首先,这里有一份剑桥雅思 4 的 pdf 文件。我现在希望做的事情是,当使用 python 的 fitz 库时:
1. 先查找“Test 1”,再查找“READING”(Test 1 和 READING 可能隔得有点远,但是肯定是最接近的一个 READING了)
2. 然后在查找到“READING PASSAGE 1”后,开始读取其内部的内容
3. 直到读取到了“READING PASSAGE 2”,停止内容的读取,并将中间的内容读取出来。
请你给出完整的代码并用代码编辑器进行测试
请一步步思考后给出完整的代码。
你可以参考以下提取LISTENING部分的代码

###提取LISTENING部分的代码###
import fitz  # PyMuPDF

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""LISTENING""SECTION 1""SECTION 2"]

# 初始化状态变量
found_test = False
found_listening = False
found_section1 = False
found_section2 = False
content = []

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()

    # 查找 "Test 1"
    if not found_test:
        if keywords[0in text:
            found_test = True
    # 查找 "LISTENING"
    if found_test and not found_listening:
        if keywords[1in text:
            found_listening = True
    # 查找 "SECTION 1"
    if found_test and found_listening and not found_section1:
        if keywords[2in text:
            found_section1 = True
    # 开始读取内容
    if found_test and found_listening and found_section1:
        lines = text.split('\n')
        for line in lines:
            # 检查是否到达 "SECTION 2"
            if keywords[3in line:
                found_section2 = True
                break
            content.append(line)
        # 如果找到 "SECTION 2",停止读取
        if found_section2:
            break

# 打印读取的内容
content_text = "\n".join(content)
content_text

    最终也是得到了一个非常近似于之前听力部分的代码,只不过是在关键词部分修改了一点。并且是一次就成功实现,并没有像听力的时候还出现了错误。从这里我们就可以看出大语言模型真的可以模仿之前的代码风格进行撰写。假如我们能够使用一些few-shot的提示词技巧是真的可以提升大语言模型的准确率。

提取结果

    提取雅思阅读部分的完整代码如下所示:

import fitz  # PyMuPDF

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""READING""READING PASSAGE 1""READING PASSAGE 2"]

# 初始化状态变量
found_test = False
found_reading = False
found_passage1 = False
content = []

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()

    # 查找 "Test 1"
    if not found_test:
        if keywords[0in text:
            found_test = True
    
    # 查找 "READING"
    if found_test and not found_reading:
        if keywords[1in text:
            found_reading = True
    
    # 查找 "READING PASSAGE 1"
    if found_test and found_reading and not found_passage1:
        if keywords[2in text:
            found_passage1 = True
    
    # 开始读取内容
    if found_test and found_reading and found_passage1:
        lines = text.split('\n')
        for line in lines:
            # 检查是否到达 "READING PASSAGE 2"
            if keywords[3in line:
                break
            content.append(line)
        
        # 如果找到 "READING PASSAGE 2",停止读取
        if keywords[3in text:
            break

# 打印读取的内容
content_text = "\n".join(content)
content_text

第二步:扩展到所有的 PASSAGE

    那第二步我们也是类似的修改了这部分代码,以下是鉴别这些 READING PASSAGE 的提示词:

###任务说明###
现在我想要提取整个 Test 1 里 READING 部分的内容(总共有3个PASSAGE)。
第一个 PASSAGE 的提取方式就是刚刚那样读取到“Test 1”、“READING”和“READING PASSAGE 1”,直到“READING PASSAGE 1”结束。
那第二个 PASSAGE 的开始就是“READING PASSAGE 2”直到“READING PASSAGE 3”结束。
那第三个SECTION就是从“READING PASSAGE 3”开始到“WRITING”结束。(就是READING PASSAGE 3紧接着的下一个WRITING,这个PDF里可能有很多的WRITING,但是我只考虑最接近的下一个WRITING)。

最后你要给出的是不同PASSAGE的md文件。分别保存在不同的位置处。

请一步步思考后给出完整的代码并使用代码编辑器测试。

    这一部分同样也是一次就生成了正确的代码,并且也通过了代码解释器的检验。

提取结果

    生成的完整代码如下所示:

import fitz  # PyMuPDF

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""READING""READING PASSAGE 1""READING PASSAGE 2""READING PASSAGE 3""WRITING"]

# 初始化状态变量
found_test = False
found_reading = False
found_passage1 = False
found_passage2 = False
found_passage3 = False
content = {"READING PASSAGE 1": [], "READING PASSAGE 2": [], "READING PASSAGE 3": []}

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()

    # 查找 "Test 1"
    if not found_test:
        if keywords[0in text:
            found_test = True
    
    # 查找 "READING"
    if found_test and not found_reading:
        if keywords[1in text:
            found_reading = True
    
    # 查找 "READING PASSAGE 1"
    if found_test and found_reading and not found_passage1:
        if keywords[2in text:
            found_passage1 = True
    
    # 查找 "READING PASSAGE 2"
    if found_test and found_reading and found_passage1 and not found_passage2:
        lines = text.split('\n')
        for line in lines:
            if keywords[3in line:
                found_passage2 = True
                break
            content["READING PASSAGE 1"].append(line)
    
    # 查找 "READING PASSAGE 3"
    if found_test and found_reading and found_passage2 and not found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[4in line:
                found_passage3 = True
                break
            content["READING PASSAGE 2"].append(line)
    
    # 查找 "WRITING"
    if found_test and found_reading and found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[5in line:
                break
            content["READING PASSAGE 3"].append(line)
        
        # 如果找到 "WRITING",停止读取
        if keywords[5in text:
            break

# 保存内容到不同的md文件
for passage, lines in content.items():
    with open(f"/mnt/data/{passage}.md""w", encoding="utf-8"as file:
        file.write("\n".join(lines))

# 返回保存的文件路径
saved_files = [f"/mnt/data/{passage}.md" for passage in content]
saved_files

第三步:扩展到所有的 TEST

    最后我们也是修改了一些命名的规则,然后给出类似的提示词指令:

###任务说明###
非常好,你这个都成功提取出来了,那下一步我要把每一个Test里的 READING 的部分都提取出来。
一个雅思真题里都有 4 个 Test,每个 Test 都有 3 个 PASSAGE,我希望你能将每个 PASSAGE 都提取为单独的一个 md 文件。
不同 TEST 的不同 PASSAGE 的标题是 T1P1、T1P2、T1P3、T2P1,以此类推直到 T4P3。

GPT-4o同样是非常精准的完成了其任务,并且也给出了所有的文件。这里我就没有让继续检查是否空白文件了,因为阅读统一都是三篇,没有出现两篇或者四篇的情况发生。

提取结果

    完整的代码如下所示:

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""Test 2""Test 3""Test 4""READING""READING PASSAGE 1""READING PASSAGE 2""READING PASSAGE 3""WRITING"]

# 初始化状态变量
found_test = [False] * 4
found_reading = False
found_passage1 = False
found_passage2 = False
found_passage3 = False
content = {"T1P1": [], "T1P2": [], "T1P3": [], "T2P1": [], "T2P2": [], "T2P3": [], "T3P1": [], "T3P2": [], "T3P3": [], "T4P1": [], "T4P2": [], "T4P3": []}
current_test = -1
current_passage = ""

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()
    
    # 查找 Test 1-4
    for i in range(4):
        if not found_test[i] and keywords[i] in text:
            found_test[i] = True
            current_test = i + 1
            break
    
    # 查找 "READING"
    if found_test[current_test - 1and not found_reading:
        if keywords[4in text:
            found_reading = True
    
    # 查找 "READING PASSAGE 1"
    if found_reading and not found_passage1:
        if keywords[5in text:
            found_passage1 = True
            current_passage = f"T{current_test}P1"
    
    # 查找 "READING PASSAGE 2"
    if found_passage1 and not found_passage2:
        lines = text.split('\n')
        for line in lines:
            if keywords[6in line:
                found_passage2 = True
                current_passage = f"T{current_test}P2"
                break
            content[f"T{current_test}P1"].append(line)
    
    # 查找 "READING PASSAGE 3"
    if found_passage2 and not found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[7in line:
                found_passage3 = True
                current_passage = f"T{current_test}P3"
                break
            content[f"T{current_test}P2"].append(line)
    
    # 查找 "WRITING"
    if found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[8in line:
                break
            content[f"T{current_test}P3"].append(line)
        
        # 如果找到 "WRITING",重置状态以查找下一个 Test
        if keywords[8in text:
            found_reading = False
            found_passage1 = False
            found_passage2 = False
            found_passage3 = False

# 保存内容到不同的md文件
for passage, lines in content.items():
    with open(f"/mnt/data/{passage}.md""w", encoding="utf-8"as file:
        file.write("\n".join(lines))

# 返回保存的文件路径
saved_files = [f"/mnt/data/{passage}.md" for passage in content]
saved_files

小结

    在这部分任务中,我们成功实现了从PDF中提取雅思阅读部分的内容,并通过分步法提高了代码的准确性。首先,我们修改了原有代码的关键词,以适应雅思阅读的结构,然后在每一步测试中逐步扩展代码,从提取单个PASSAGE到提取整个Test中的所有PASSAGE,最后完成了所有Test的提取工作。通过这种方法,我们确保了每一步的准确性,并最终生成了所有Test的阅读部分的Markdown文件。这一过程展示了大语言模型在处理文档解析任务中的灵活性和高效性,同时也证明了通过任务拆分和逐步测试可以显著提高代码的可靠性和成功率。

总结

    总的来说,在本文中,首先介绍了利用编程简化PDF内容提取的重要性,以及如何借助GPT-4o生成代码并进行测试。通过任务拆分和逐步测试的方法,从提取单个SECTION的内容开始,逐步扩展到提取整个Test中的所有SECTION,再到处理阅读部分的内容,最终生成了各自的Markdown文件。

    另外,文章还详细解析了代码的每一部分,包括关键词定义、状态变量初始化、遍历每一页的内容提取、内容保存到Markdown文件中的步骤,以及删除空白内容的处理。这一过程不仅展示了大语言模型在处理复杂文档解析任务中的灵活性和高效性,还证明了通过逐步引导和任务分解可以显著提高代码生成的成功率,为批量处理和自动化文档分析提供了有效的解决方案。



?点击阅读原文,获取「剑雅4」PDF原件


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询