来源:互联网 更新时间:2026-08-15 14:30
先说个场景:手头积压了一堆电子发片PDF,想找个法子自动把它们的关键信息扒下来。比如,从一张发片里,我们希望能提取出类似这样的结构化数据:开票日期、应税货物名称、价税合计(大写)、税率、备注。说白了,就是要让AI学会“看”发片。
现在手头有很多个电子发片PDF文件,目标很明确——用自动化工具帮我们批量提取出格式化的发片信息。举个例子,从一张发片里,我们希望得到这样一份字典数据:
DICT_DATA = {
"开票日期": "2023年01月06日",
"应税货物(或服务)名称": "*信息技术服务*技术服务费",
"价税合计(大写)": "",
"税率": "6%",
"备注": "230106163474406331"
}
这活儿如果人工做,几百张发片下来,眼睛得花。下面直接上方案。
先到官网
ollama目前支持的主流模型不少,像阿里的qwen、qwen2,Meta的llama3等等。以llama3为例,根据自己电脑的显存性能选择对应版本。如果拿不准选哪个,那就先下个试试,不合适再删,反正折腾的成本不大。
打开命令行(Windows是cmd,Mac是terminal),确保网络畅通,执行下载命令:
ollama run llama3
稍等片刻,等
要在Python中调用ollama服务,需要装一个配套的包。命令行里执行:
pip3 install ollama
在Python调用之前,得先把本地ollama服务跑起来。命令行里执行:
ollama serve
如果看到类似下面的日志输出,说明服务已经成功启动,默认监听在127.0.0.1:11434端口:
2024/06/14 14:52:24 routes.go:1011: INFO server config env="map[OLLAMA_DEBUG:false ... OLLAMA_HOST:http://127.0.0.1:11434 ...]"
time=2024-06-14T14:52:24.742+08:00 level=INFO source=images.go:725 msg="total blobs: 18"
time=2024-06-14T14:52:24.742+08:00 level=INFO source=images.go:732 msg="total unused blobs removed: 0"
time=2024-06-14T14:52:24.743+08:00 level=INFO source=routes.go:1057 msg="Listening on 127.0.0.1:11434 (version 0.1.44)"
...
time=2024-06-14T14:52:24.796+08:00 level=INFO source=types.go:71 msg="inference compute" id=0 library=metal compute="" driver=0.0 name="" total="72.0 GiB" a vailable="72.0 GiB"
先拿一张发片PDF试试手。用cntext库先读入文本:
import cntext as ct
text = ct.read_pdf('data/1.pdf')
print(ct.__version__)
text
输出结果:
2.1.2
' 机器编号:北京增值税电子普通发片发片代码:n发片号码:n开票日期:2023年01月06日n校 验 码:n购n买n方名 称: 哈尔滨所以然信息技术有限公司n密n码n区030898/5<32>*/0*440/63+79*08n纳税人识别号:91230109MABT7KBC4M /<54<1*6+49<-*+*>7<-8*04<+01n地 址、电 话:68+160026-45904*2<+3+15503>2n开户行及账号:98*2/*-*480145+-19*0917-1*61n货物或应税劳务、服务名称 规格型号 单 位 数 量 单 价 金 额 税率 税 额n*信息技术服务*技术服务费 1248.113208 248.11 6% 14.89n合 计 ¥248.11 ¥14.89n价税合计(大写)n 贰佰陆拾叁元整 (小写)¥263.00n销n售n方名 称: 北京n备 注230106163474406331n纳税人识别号:n地 址、电 话: n开户行及账号: n销售方:(章)'
可以看到,原始PDF读出来的文本比较杂乱,信息散布在各处,这正好是发挥大模型语义理解能力的地方。
我们选用llama3:8b模型,然后设计一个提示词。实验里用的提示如:
“提取TEXT中的关键信息,返回DICT_DATA,DICT_DATA为dict数据格式,所含关键词依次为"开票日期", "应税货物(或服务)名称", "价税合计(大写)", "税率", "备注"; 结果只显示DICT_DATA。”
实际调用代码:
import ollama
response = ollama.chat(model='llama3:8b', messages=[
{
'role': 'user',
'content': f'提取TEXT中的关键信息,返回DICT_DATA, DICT_DATA为dict数据格式,所含关键词依次为"开票日期", "应税货物(或服务)名称", "价税合计(大写)", "税率", "备注"; 结果只显示DICT_DATA。TEXT: {text1}',
},
])
result = response['message']['content']
result
运行结果:
'DICT_DATA = {n "开票日期": "2023年01月06日",n "应税货物(或服务)名称": "*信息技术服务*技术服务费",n "价税合计(大写)": "",n "税率": "6%",n "备注": "230106163474406331"n}'
从结果看,大模型准确提取到了我们需要的信息,耗时大约10秒。不过有一点要注意:有时大模型会返回带多余解释的文本,比如:
'Here is the extracted key information in dictionary format:\n\n```\n{\n "开票日期": "2023年01月06日",\n "应税货物(或服务)名称": "*信息技术服务*技术服务费",\n "价税合计(大写)": "贰佰陆拾叁元整",\n "税率": "6%",\n "备注": "230106163474406331"\n}\n```\n\nLet me know if you ha ve any further requests! ?'
所以需要做一步后处理,把真正的字典部分从回答中提取出来:
import re
result = response['message']['content']
result = [r for r in re.split('```|DICT_DATA = ', result) if '{' in r][0]
print(type(eval(result)))
print(eval(result))
输出:
{'开票日期': '2023年01月06日',
'应税货物(或服务)名称': '*信息技术服务*技术服务费',
'价税合计(大写)': '贰佰陆拾叁元整',
'税率': '6%',
'备注': '230106163474406331'}
实验跑通了,下一步就是把流程封装成通用函数:
import ollama
import re
def extract_info(text):
response = ollama.chat(model='llama3:8b', stream=False, messages=[
{
'role': 'user',
'content': f'提取TEXT中的关键信息,返回DICT_DATA, DICT_DATA为dict数据格式,所含关键词依次为"开票日期", "应税货物(或服务)名称", "价税合计(大写)", "税率", "备注"; 结果只显示DICT_DATA。TEXT: {text}',
},
])
result = response['message']['content']
result = [r for r in re.split('```|DICT_DATA = ', result) if '{' in r][0]
return eval(result)
result = extract_info(text)
result
运行结果:
{'开票日期': '2023 02 14',
'应税货物(或服务)名称': '*家用厨房电器具*米家 小米电热水 MJDSH03YM',
'价税合计(大写)': '壹佰贰拾叁圆玖角玖分',
'税率': '13%',
'备注': None}
假设data文件夹里躺着成百上千张发片(虽然本例只有一张),批量提取并保存为csv文件:
%%time
import os
import cntext as ct
import pandas as pd
#获取data内所有pdf的路径
pdf_files = [f'data/{file}' for file in os.listdir('data') if '.pdf' in file]
dict_datas = []
for pdf_file in pdf_files:
pdf_text = ct.read_pdf(pdf_file)
dict_data = extract_info(pdf_text)
dict_datas.append(dict_data)
df = pd.DataFrame(dict_datas)
df
运行结果:
CPU times: user 32 ms, sys: 2.17 ms, total: 15.2 ms
Wall time: 3.8 s

必须得说,本文只用了一张发片做实验,实际跑起来准确率可没这么高。最容易出错的字段是销售方纳税识别号(案例中没有展示这个字段的识别),问题出在ct.read_pdf读出来的文本比较杂乱,对大模型的语义理解是个不小的挑战。好在现在的大模型已经支持文本、图片、音频、视频甚至网址输入,所以这个问题在不久的将来应该能迎刃而解。
另外一点需要留意:大模型对每个输入给出的是概率最大的回答,所以提取数据时存在一定的错误识别风险。要降低这个风险,尽量选那些特征特别特殊、显眼的信息。比如价税合计(大写),因为它用的是中文大写数字,在所有文本中最为醒目、最特别,大模型在处理这类信息时会下意识地给更高权重,回答的准确率自然就上来了。
腾讯ima怎么把微信内容一键导入知识库?
黄金价格不断创新高!黄金稳定币XAU、PAXG市值达11亿美元
CC币价格预测(2026-2035):Canton币今日价格走势+长期价格预测
新浪互联网热点小时报丨2026年07月26日16时_今日实时互联网热点速递
新浪机器学习热点小时报丨2026年07月25日18时_今日实时机器学习热点速递
2026鸣潮账号交易安全指南:五大交易平台对比与风险避坑分析
腾讯ima怎么创建共享知识库?
今日比特币暴涨分析:Metaplanet的比特币BTC投资推动股价上涨17%
蚂蚁庄园今日答案7月21日(今日已更新) 蚂蚁庄园今天正确答案是什么呢
新浪人工智能热点小时报丨2026年07月30日18时_今日实时人工智能热点速递
抖音怎么取消申请退货退款?抖音上取消退货怎么操作
比特币(BTC)核心周期指标复刻历史走势 价格或跌破5.8万美元关键支撑位
Windy卫星云图怎么看?云层变化识别技巧
9条破亿视频,新号涨粉百万,过去半年谁在制造AI爆款?
短剧《史上最强洪荒修为》剧情介绍
kimi提示词专家使用方法新手指南
Celestia价格预测2026-2032:TIA币能否引领山寨币上涨行情?历史价格回顾
如何修复Edge浏览器无法通过微软账号进行身份验证?
原神霜月三处月灵龛具体位置汇总
五菱星光L六座新能源SUV上市:三版可选,中配12.28
手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc