☰
AI辅助开发文件提取工具:从需求拆解到批量落地全流程解析
2026/10/28 8:26:52 网站建设 项目流程

我一直有个很土的需求:每周都要从几十份格式各异的文件里把关键字段抠出来。财务发PDF,商务发Word,还有人直接发网页另存的HTML。手动复制粘贴倒是不难,但干到第三十份的时候,手是真的会酸,眼睛也花了。于是我用AI辅助开发了一个文件提取工具,专门干这种脏活。整个过程我没有从零手敲所有代码,而是把AI当成一个随叫随到的结对编程搭档——我来拆需求、定边界、审代码,它来写初版、补逻辑、处理那些我记不太住的库函数。这篇文章会把这个工具的需求来源、选型过程、踩坑记录和优化思路完整拆开,给同样想做点小工具的人一条能直接上手的路径。

1. 为什么先做文件提取:一个被重复劳动逼出来的项目

1.1 一件本该自动化的“杂活”长什么样

先还原一下场景。每周一我会收到一个压缩包,里面是上一周新增的合同、报价单、回执,混杂着PDF、Word、Excel,偶尔还有几个网页另存为的HTML。我需要把这些文件里的合同编号、甲方乙方、合同金额、签署日期挨个找出来,填进一张汇总表。听起来不复杂,但文件一多就非常折磨人。

我记得有一回,一个36页的PDF合同里,金额和日期分散在四五个不同的章节,我反复用搜索键翻了十几分钟才核清楚。等我把三十多份文件全部处理完,一个上午已经没了。最让人崩溃的是,下周一同样的流程又会来一遍。

我把这些文件的格式和要提取的字段列了一张小表:

文件类型常见来源我需要提取的字段
PDF电子签章合同、扫描件合同编号、签署日期、金额
Word商务起草的合同/报价单甲方、乙方、总金额
Excel对账单、明细表客户名、金额、交易期
HTML网页导出、邮件存档标题、日期、正文关键段落

每类文件的排版都还不一样,同一家公司的PDF合同,上个月和下个月的可能就差了页脚。这就是典型的“看起来能复制粘贴,实际上全是重复劳动”的场景,是最适合写个小工具来解放双手的。

1.2 现成工具为什么没救我

既然这么痛苦,我第一反应肯定是找现成工具。市面上的PDF提取工具、OCR识别工具、网页正文提取插件,我试了一圈,要么不顺手,要么不敢用。

先说在线转换网站。把涉密的合同文件传上去做解析,我心理上就过不去。再说桌面软件,一些老牌的PDF解析工具确实能提取文本,但批量处理要付费版才开放,而且输出格式非常固定,我想让它只提取“合同编号和金额”这种自定义字段,配置起来比手动复制还麻烦。开源方案我也试过,比如某些命令行工具,功能很强,但依赖环境复杂,装完就劝退了我这种“半吊子”使用者。

最后我确认了真实需求:要本地运行,不上传任何内容;要免费;要能一次拖入一个文件夹,批量处理;还要能自定义提取规则,而不是只能导出全文。这些东西靠手工选择很难配齐,正好适合自己写代码。

1.3 为什么选“AI辅助开发”而不是纯手写

我不是专业程序员,日常会用Python处理点Excel,但让我从零封装一个能稳定处理PDF、Word、HTML的解析工具,还是有点心虚。我记不清pdfplumber的API,也不记得BeautifulSoup的常用写法,每次都要临时翻文档。

最开始我考虑过完全让AI生成一个完整脚本,但我很快意识到一个问题:AI生成的代码,如果我看不懂,出了问题只能干瞪眼。所以我的定位是“AI辅助开发”,不是“AI全包开发”。我负责把模糊的需求拆成AI能理解的步骤,告诉它输入是什么、输出是什么、边界在哪里;它负责给我生成初版代码,帮我把不熟悉的库函数拼起来。每段代码我都会看一遍,大致知道它在干什么,再放到真实文件上跑。

实际体验下来,这个分工方式让我的开发速度快了至少三倍,而且踩坑的时候不至于完全抓瞎。接下来就说说具体怎么选型、怎么让AI干活。

2. 技术选型:AI凭什么推荐这套提取方案

2.1 核心库选型:让AI先给建议,我再做兼容性检查

我把需求发给AI的第一句话是:“我想写一个批量文件提取工具,需要处理PDF、Word、Excel、HTML,分别应该用什么Python库?”它很快给出了一组推荐。这个推荐结果和我之前查过的一些技术文章基本一致,算是靠谱:

文件类型处理库主要用途我后来确认过的注意事项
PDFpdfplumber、PyMuPDF提取文本、表格合并单元格和跨页表格容易错位
Wordpython-docx读取段落、表格模板变量常被拆成多个run,直接查找会漏
Excelopenpyxl、pandas读取单元格、做汇总大文件要开启只读模式,不然很吃内存
HTMLBeautifulSoup、lxml定位节点、提取正文页面编码和标签嵌套要额外处理

AI在选型上确实有用,因为它被训练过大量技术文档和社区讨论,能直接给出常见的“最佳实践”。但我不完全盲信。我会再补一句:“这些库都有稳定的PyPI版本吗?给我一个requirements.txt。”然后让它生成依赖清单。这么做的目的,是把“道理上可行”和“当前环境能跑”的差距尽量缩小。

我最终锁定的依赖是:

pdfplumber==0.10.3 python-docx==0.8.11 openpyxl==3.1.2 beautifulsoup4==4.12.2 pandas==2.0.3

版本号都做了固定,不写“>=”,否则哪天某个库大版本更新,AI生成的旧代码可能直接跑不起来。

2.2 我发给AI的第一个详细Prompt

选型确定后,我没有直接说“帮我写个工具”,而是写了一段相对完整的Prompt:

你是一个Python开发助手。我要写一个批量文件提取工具。 背景:有大量PDF和Word合同,需要提取“合同编号、甲方、乙方、金额、签署日期”这五个字段。 输入:一个文件夹路径,里面可能有PDF、docx、xlsx、html文件。 输出:每个文件生成一个同名的markdown文件,存放在指定的输出目录,内容是一个字段表格。 约束:只读原文件,不修改原文件;遇到格式异常的文件要跳过并记录日志;所有路径要兼容Windows中文目录。 示例:如果PDF里出现“合同编号:HT-2024-001”,就提取HT-2024-001;如果找不到对应字段,留空并继续。 请先给出目录结构和关键函数,不要一次性把全部代码写完。

这里我刻意加了几个关键约束:只读不修改、跳过异常、兼容中文路径。这些都是以前手动写脚本时踩过的坑,提前告诉AI,能省掉非常多返工。

AI根据这个Prompt给出了一个目录结构:

file_extractor/ ├── extract.py # 入口,命令行解析 ├── parsers/ │ ├── pdf_parser.py │ ├── docx_parser.py │ ├── excel_parser.py │ └── html_parser.py ├── output/ # 提取结果输出目录 └── logs/ # 日志目录

然后它先写了一个PDF解析函数:

import pdfplumber def extract_from_pdf(file_path): results = {} with pdfplumber.open(file_path) as pdf: full_text = "\n".join(page.extract_text() or "" for page in pdf.pages) # 用正则做简单字段定位,后续再优化 return results

这版代码能跑通,但字段提取很粗糙。不过没关系,我的策略是先有骨架,再迭代。

2.3 为什么第一版做成了命令行工具

很多朋友一上来就想做个图形界面,但我坚持第一版做成命令行工具。原因是批量处理场景下,命令行太适合了。我可以把几十个文件丢进一个文件夹,然后执行一条命令:

python extract.py --input ./contracts --output ./extracted --formats pdf docx xlsx html

它可以被脚本调用,可以定时执行,甚至可以并进团队自己的流程里。图形界面的拖拽体验确实更好,但那等于把“如何连接各模块”的问题变成了“如何画按钮和布局”,偏离了核心目标。

AI在这个阶段帮我生成了argparse参数解析部分,把输入目录、输出目录、格式过滤这几个参数都接好了。它还给了一个很实用的建议:输出文件和原文件同名,但放到新的“extracted”目录里,这样不容易覆盖源文件。

这一版跑通后,我的感觉是:AI辅助开发的价值不在于它能一次性写出完美代码,而在于它能帮我快速把脑子里模糊的需求变成可以运行的结构,让我把精力集中在那些真正需要判断和测试的地方。

3. AI生成的代码不能直接用:完整调试与纠错过程

3.1 第一个坑:Windows中文路径和编码问题

说实话,AI生成的代码第一次跑通只是“看起来能跑”。我把一个真实的PDF文件放进去,立刻就报错了。报错信息指向读取文件路径的地方,原因是我的文件夹名称里带中文。

AI第一版代码里用了比较简单的路径拼接写法,在Windows上遇到中文路径时,如果没有正确处理编码,很容易出现文件找不到或者乱码。让我印象更深刻的是,它读取文本时用了默认编码,结果提取出的中文字符有一半变成了“锟斤拷”这种经典乱码。

我当时的排查链路是这样的:

  • 先在命令行手动执行,观察完整报错。
  • 把报错信息贴给AI,要求它解释为什么会出问题。
  • AI给出修改建议:用pathlib.Path替代字符串拼接,读取文本时统一使用encoding="utf-8",必要时回退到gb18030。

修正后的代码类似:

from pathlib import Path def read_pdf_text(file_path): file_path = Path(file_path) # 统一转成绝对路径,避免相对路径导致的奇怪问题 with pdfplumber.open(str(file_path.resolve())) as pdf: text = "\n".join(page.extract_text() or "" for page in pdf.pages) return text

这个改动很小,但非常关键。从那之后,我再也不敢在AI生成代码里直接使用裸的字符串路径参数,都会让AI改成pathlib风格。

3.2 第二个坑:表格提取的字段错位和跨页断裂

PDF里的表格是最折磨人的。尤其是那种带合并单元格的报价单,用pdfplumber直接提取,导出来的数据经常是错位的:第一列的金额跑到了第三列,表头下面的空值也不按套路出牌。

AI第一次处理方式是“把表格原样输出”,结果我的汇总表里出现了很多None和空单元格。我拿着真实截图和提取结果对比,发现问题的本质是:视觉上合并的单元格,在底层数据结构里只有其中一个格子有值,其他格子是空的。

AI给的解决办法很朴素,却也有效:提取完表格后用pandas做“前向填充”,把空值按上一行有值的逻辑补上。

import pandas as pd def table_to_dataframe(table): # table是pdfplumber提取出的二维列表 df = pd.DataFrame(table[1:], columns=table[0]) # 合并单元格导致的空值,用上一行同列的值填充 df = df.ffill() return df

这个方案救了不少场景,但也要注意:它只适用于“纵向合并”的表格。如果遇到横向合并的复杂表头,还是得写更复杂的对齐规则。我在测试报告里把这些特殊情况单独列出来,让AI辅助生成了一个“异常表登记”文件,方便后续人工复核。

跨页表格又是另一类问题。一个表格被PDF分页拆开以后,pdfplumber会把它识别成两个独立的表格,第二页的表头可能丢失。AI帮我写了一个拼接函数:如果上一页表格最后一列和下一页表格第一列结构相同,就自动合并成同一个DataFrame。这个逻辑不复杂,但如果没有真实样本驱动,AI是想象不到这个需求的。

3.3 第三个坑:AI幻觉出一个不存在的API

必须承认,AI生成的代码里出现过“看起来合理但实际不存在”的API。比如它在某个函数里写:

page.extract_tables_with_lines()

我跑测试的时候直接报AttributeError。这个方法是它根据extract_tables()和lines推测出来的,文档里根本没有。

我的处理方式不是自己去查API,而是把这个报错重新投喂给AI,并要求它“先解释这段代码想做什么,再给出当前pdfplumber版本中真正可用的替代方法”。它很快承认自己“记混了API”,然后改成:

page.extract_tables()

这条经验很重要:AI生成的代码必须经过“运行验证”,不能因为它看起来讲得头头是道就直接投入生产。我给自己定了个规矩:凡是AI生成的代码,至少要在一个最小样例上跑通,再放到真实文件集上做回归测试。

我还整理了一张排错表,记录常见问题:

现象可能原因处理方式
中文乱码编码指定错误统一用utf-8,并做编码回退
提取结果为None页面没有文字层,可能是扫描件先提示需要OCR,不强行处理
字段错位合并单元格未被展开用pandas ffill,并人工抽查
报错AttributeErrorAI生成了不存在的API贴回让AI修正,并跑测试集

这些看起来很小的问题,才是工具能否真正稳定使用的决定性因素。

4. 实测效果与性能优化:从“能跑”到“好用”

4.1 用一批真实文件做的回归测试

代码修完以后,我马上做了一个“小规模回归测试”。我从历史文件里挑了50份脱敏后的真实样本,按类型分组,跑了一遍工具,并记录了字段级提取准确率。

文件类型样本数量字段级准确率主要失败原因
PDF2085%扫描件、复杂表格
Word1095%模板变量被拆成多个run
Excel1090%单元格跨行合并
HTML1088%编码和动态加载

这个结果比我预想的好,但距离“免人工复核”还差不少。我特别注意到PDF扫描件几乎全军覆没,因为扫描件根本没有文本层,任何基于文本提取的方案都无能为力。我后来在工具的说明文档里明确标注:扫描件需要先用OCR预处理,不在当前版本的支持范围内。承认边界,反而让工具更可靠。

与此同时,我让AI辅助生成了一个“人工复核脚本”,把提取结果导成Excel,自动标记出空值和格式可疑的值,然后我只需要检查这些标记行就行。这比从头到尾看一遍表格效率高很多。

4.2 性能瓶颈:串行读PDF确实慢

第一批测试跑完,功能上已经能用了,但性能让人着急。处理100份混合文件,耗时将近三分钟。大部分时间花在PDF上,因为一份几十页的PDF打开后要逐页解析,有的库还会重复加载同一个文件。

我用Python内置的profile工具简单看了一下,发现瓶颈在“多次调用pdfplumber.open”和“字符串逐页拼接”。AI给我的优化建议是:

  • 在整个处理流程里,每个文件只打开一次。
  • 批量任务改成线程池并发,PDF解析是IO密集型和部分CPU密集型混合,开4个线程是个比较稳的选择。

我按它的建议改成了这样:

from concurrent.futures import ThreadPoolExecutor def process_one_file(file_path): # 每个文件只处理一次,返回结果和日志 return extract_single(file_path) with ThreadPoolExecutor(max_workers=4) as pool: results = list(pool.map(process_one_file, file_paths))

这个改动立竿见影,同样100份文件,从2分55秒降到了38秒左右。要注意的是,线程数不是越大越好。我曾经试着开8个线程,反而因为CPU资源争抢导致速度没提升多少。4个线程在我的机器上是最稳的平衡点。

4.3 从命令行到拖拽执行:提高日常使用率

工具做好后,我打算让同事也用起来。但让同事打开终端敲命令,基本不可能。我需要的是一种“双击即用”的交互方式。

于是AI辅助我给工具加了一个拖拽入口。Windows下,可以把文件或文件夹直接拖到某个脚本图标上,拖入的文件路径会通过sys.argv传给程序。核心脚本很简单:

import sys from pathlib import Path if __name__ == "__main__": for arg in sys.argv[1:]: p = Path(arg) if p.is_dir(): run_batch(p) elif p.is_file(): run_single(p)

我把这个脚本打包成了一个run_extract.bat,里面加了一行切换到工作目录再调用Python。同事只要把文件拖到run_extract.bat上,松手,就会自动弹出一个结果文件夹。这个体验虽然不如精美GUI,但对内部工具来说已经足够实用。

这一步让我真正感受到:好用的工具不是“功能堆砌”,而是“在最省事的前提下把活儿干完”。

5. 把“文件提取”扩展成“一系列小工具”的思路

5.1 模块化设计:解析层、规则层、输出层

文件提取工具做顺手以后,我很快意识到它可以继续扩展成一系列小工具,而核心是把代码拆成可复用的模块。

我最终把工具分成了三层:

  • 解析层:负责把PDF、Word、Excel、HTML变成结构化的文本或表格;
  • 规则层:负责定义要提取哪些字段、用什么正则、如何做后处理;
  • 输出层:负责生成Markdown、Excel、日志等结果。

这样拆的好处是,新工具无需重写解析层。比如我想做一个“文件去重工具”,只需要复用“读文件 + 计算哈希”的逻辑;我想做一个“格式转换工具”,也只需要把解析层的结果重新序列化成其他格式。

AI在这件事上帮了我大忙,因为它能轻松把一个复杂的“解析层”函数改造成独立模块。但我仍然需要自己定义模块之间的接口,这是AI很难替代的判断。

5.2 沉淀下来的AI辅助开发提示词模板

经过这个项目,我沉淀出了一个相对通用的AI辅助开发提示词模板,以后做任何小工具都用它:

你是一个[语言]开发助手。我要做一个[工具名]。 目标:用一句话说清楚这个工具解决什么问题。 输入:描述输入是什么,包含哪些格式。 输出:描述输出是什么,存放位置、命名规则、格式要求。 约束:列出边界,例如只读不修改、兼容中文路径、遇到异常要跳过、不做删除操作等。 示例:给出1到2个具体例子,说明理想结果和允许的容错。 请先给目录结构和关键函数,不要一次性写完所有代码。写完后解释每个函数的作用,特别说明哪些地方需要我人工确认。

这个模板最关键的部分是“约束”和“示例”。没有约束,AI会自由发挥;没有示例,它很难理解“提取合同编号”这种模糊指令到底长什么样。

我还会在AI给出初步方案后追问一句:“这段代码在Windows上能直接跑吗?依赖哪个版本?”这两句能过滤掉不少坑。

5.3 我判断“哪些能让AI放手写、哪些必须自己盯”的标准

用AI辅助开发多了,我慢慢总结出一条个人经验:不是所有代码都值得让AI直接生成,也不是所有代码都需要自己逐行手写。

我现在的判断标准很简单:如果代码只处理“纯文本、纯内存、不碰外部敏感资源”,那可以让AI放手写,我负责提供清晰输入输出和测试集。比如格式转换、文本清洗、图表统计,这些都很安全。但如果代码涉及删除文件、覆盖源文件、网络请求、权限切换,那我一定会自己看完整逻辑,再加一道“确认开关”,绝不会让AI直接“一把梭”。

这次的文件提取工具,正好处在安全区:它只读文件,不删不传,顶多提取结果不准,不会造成破坏性后果。所以我敢让AI生成大量代码,也敢放心地在本地批量跑。

最后分享一个我自己很受用的小习惯:每个AI辅助开发的工具,我都会准备一个test_samples目录,里面放着不同格式的真实脱敏文件,每次改完代码就跑一遍。不一定能覆盖所有边界,但至少能拦住大部分回归问题。文件提取这种工具,做得再炫,也不如一次性能稳定更重要。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询