1. 从财务的“发票地狱”到智能归档:为什么你需要这个工作流
如果你是一名财务人员,或者经常需要处理报销、对账,那你一定对下面这个场景不陌生:邮箱里塞满了各种格式的电子发票PDF和图片,微信群里时不时弹出同事发来的报销凭证。你的任务就是把这些文件一张张打开,像玩“大家来找茬”一样,从密密麻麻的信息里,手动摘出开票日期、发票号码、销售方、金额、税额这些关键信息,再复制粘贴到Excel或者飞书表格里。一天处理几十张发票下来,眼睛花了,脖子僵了,还特别容易看串行、输错数字,月底对账时发现差了几毛钱,又得从头翻一遍,简直是精神和体力的双重折磨。
我管这叫“发票地狱”。几年前我自己创业,兼任公司财务,就深陷其中。直到我开始接触AI自动化工具,尤其是扣子(Coze)之后,才发现原来这些重复、枯燥且易错的工作,完全可以交给机器。今天我要分享的,就是一个我打磨了很长时间的“财务神器”——一个基于扣子工作流搭建的电子发票智能归档系统。它的核心目标就一个:把你丢给它的任何格式的电子发票(PDF或图片),自动识别、提取关键信息,并整整齐齐地归档到你指定的飞书表格里,全程零手动输入,准确率极高。
你可能会问,市面上不是有OCR(光学字符识别)软件吗?没错,但普通的OCR只是把图片上的文字识别出来,变成一堆杂乱无章的文本。你需要的是结构化数据:识别出来的“2024年5月20日”要自动填到“开票日期”栏,“¥128.50”要准确地拆分成“金额”和“税额”。这正是扣子工作流的强大之处:它把强大的多模态大模型(能看懂图片和PDF里的文字和版式)和灵活的流程编排结合在了一起。大模型负责像人一样“理解”发票内容,工作流则负责把理解后的结果,按照你设定的格式,自动写入飞书表格。
这个方案特别适合中小团队、自由职业者或者部门内的报销专员。它不需要你懂复杂的编程,在扣子的可视化界面里拖拖拽拽就能搭建起来。一旦搭好,你就拥有了一个7x24小时不知疲倦的财务助理。接下来,我就带你一步步拆解这个工作流,从原理到实操,从踩坑到优化,让你也能亲手打造出这个效率翻倍的利器。
2. 核心武器库:认识工作流中的每个“齿轮”
在动手搭建之前,我们得先搞清楚这个自动化流水线里都有哪些关键部件,以及它们各自扮演什么角色。你可以把整个工作流想象成一个智能工厂的流水线,发票文件是原材料,飞书表格里的规整记录是成品。
### 2.1 起点与终点:“开始”节点与飞书表格
一切从“开始”节点出发。这里我们需要定义两个最重要的输入参数,相当于给流水线设定好原料入口和成品仓库地址。
feishu_table_url:这是你的飞书多维表格的完整URL。重要提示:你必须提前在飞书里创建好一个表格,并且设计好表头。通常,我会建议包含这些列:发票号码、开票日期、销售方名称、购买方名称、金额(不含税)、税率、税额、价税合计、发票类型、归档时间。把浏览器地址栏的链接复制过来就行。files:这里接受一个文件列表,类型是Array<File>。这意味着你可以一次性上传多张发票图片或PDF文件,系统会批量处理,效率倍增。
终点就是飞书表格本身。当工作流跑完,你打开那个表格链接,就会看到新增了几行数据,所有发票信息都各就各位。
### 2.2 识别引擎:“链接读取”与“大模型”节点
原材料(发票文件)进入流水线,第一步是“拆包”并“理解内容”。
“链接读取”插件:这个节点就像一个文件内容提取器。它接收
files列表,无论是图片还是PDF,都能将其转换成后续节点可以处理的文本内容。这里的关键是选择“批处理”模式,并把url字段关联到files列表中的每一项(item1)。这样,无论你上传多少文件,它都能逐个处理。“大模型”节点:这是整个系统的“大脑”,也是精度高低的关键。我实测下来,扣子平台上的DeepSeek-V3或GPT-4V模型在发票识别上表现非常稳定。这个节点的任务很明确:你给它一段从发票里提取出来的原始文本(可能顺序是乱的,夹杂着无关信息),它需要根据你的指令,精准地找出所需字段,并以严格的格式输出。这里的“系统提示词”和“用户提示词”是核心机密,直接决定了识别效果。我优化后的提示词会明确告诉模型:“你是一个专业的发票信息提取助手。请从用户提供的发票文本中,提取以下字段:发票号码、开票日期、销售方、购买方、金额、税额、价税合计。如果任何字段找不到,请输出‘无’。请以严格的JSON格式输出,例如:{“invoice_number”: “12345678”, “date”: “2024-05-20”…}” 通过这样精确的指令,大模型输出的就不再是散文,而是规整的数据结构了。
### 2.3 装配流水线:“循环”与“代码”节点
“大脑”输出了一堆结构化的数据(比如一个包含多条发票信息的JSON数组),我们需要把这些数据一个个加工成飞书表格能接受的格式。
- “循环”节点:顾名思义,它用来遍历大模型输出的结果列表。假设一次处理了5张发票,大模型节点会输出一个包含5个元素的数组。循环节点会把这个数组拆开,一次只处理一个元素(一张发票的信息),然后传递给下一个环节。这里“并行运行数量”设为1更稳定,避免对飞书API造成并发压力。
- “代码”节点:这是工作流中唯一需要写一点点代码的地方,但别怕,代码我已经帮你写好了。循环节点每次吐出一条发票信息的JSON,代码节点的任务就是把这个JSON对象,转换成飞书多维表格新增记录所需的特定数据结构。飞书API要求的数据格式是
{“fields”: {“列名1”: “值1”, “列名2”: “值2”}}。所以,代码节点里的Python脚本,就是做一个简单的映射:把JSON里的invoice_number映射到飞书表格的“发票号码”列。这个节点是连接AI识别结果和外部系统(飞书)的桥梁。
### 2.4 入库机械臂:“飞书多维表格”插件
经过代码节点的格式化,数据已经准备好了。最后一步就是由“飞书多维表格”插件这个机械臂,把数据记录“抓取”并“放置”到飞书表格的末尾。你需要在这里配置app_token(从飞书表格的URL中可以解析出来,或者通过飞书开放平台获取),并将records字段指向代码节点的输出。配置成功后,每次执行工作流,这里就会发起一次API调用,向你的表格新增一行数据。
3. 手把手搭建:从零到一的详细配置指南
理论讲完了,我们进入实战环节。我会假设你已经有了一个扣子账号和一个飞书账号,我们从一张空白的画布开始,还原整个搭建过程。
### 3.1 第一步:创建你的飞书表格模板
在扣子里操作之前,先要把“仓库”建好。打开飞书,进入云文档,创建一个新的多维表格。我建议你按照下面这个结构来设计列,这能覆盖绝大多数增值税普通发票和专用发票的信息:
| 列名 | 列类型 | 说明 |
|---|---|---|
| 发票号码 | 文本 | 发票的唯一号码,必填项 |
| 开票日期 | 日期 | 选择日期类型,方便后续筛选 |
| 销售方名称 | 文本 | 开票方公司全称 |
| 购买方名称 | 文本 | 受票方公司全称(你们公司) |
| 金额(不含税) | 数字 | 货币类型,设置两位小数 |
| 税率 | 数字 | 百分比,如13%就填0.13 |
| 税额 | 数字 | 货币类型,设置两位小数 |
| 价税合计 | 数字 | 货币类型,即总支付金额 |
| 发票类型 | 单选 | 可选项:增值税专用发票、增值税普通发票等 |
| 归档时间 | 创建时间 | 使用“创建时间”自动记录 |
创建好后,复制浏览器地址栏的URL备用。这个URL看起来像https://your-domain.feishu.cn/base/xxxxxxxxxx。
### 3.2 第二步:在扣子中创建工作流并配置输入
- 进入扣子平台,点击“创建” -> “工作流”。
- 从左侧节点库中,拖出一个“开始”节点到画布。
- 选中“开始”节点,在右侧参数面板,点击“添加输入参数”。
- 第一个参数:名称填
feishu_table_url,类型选择“文本”,描述可以写“飞书表格的完整URL”。 - 第二个参数:名称填
files,类型务必选择Array<File>,描述写“待处理的电子发票文件列表(支持图片和PDF)”。
- 第一个参数:名称填
- 这样,工作流的入口就定义好了。运行工作流时,你就需要提供这两个参数。
### 3.3 第三步:配置发票内容提取链条
添加“链接读取”插件:从插件区找到“链接读取”,拖到“开始”节点后面并连接。在节点配置中:
- “单次/批处理”选择“批处理”。
- 在“item1”处,点击引用,选择“开始”节点的
files变量。 - 在“url”处,同样点击引用,但这次选择本节点上方的
item1。这个设置的意思是:循环处理files数组里的每一个文件,并将其内容读取出来。
添加“大模型”节点:从基础节点拖出“大模型”节点,连接到“链接读取”之后。
- “单次/批处理”同样选择“批处理”。
- “模型”选择:我强烈推荐DeepSeek-V3,它在中文发票识别和JSON格式遵从性上性价比很高。如果追求极致精度,可以选GPT-4系列。
- “item1”处,引用“链接读取”节点输出的
outputList。 - “input”处,引用本节点自身的
item1。 - 最关键的系统提示词:在“系统提示词”框中,粘贴以下内容(这是我经过大量测试优化后的版本):
你是一个专业的财务发票信息提取专家。你的任务是从用户提供的发票文本中,准确提取出以下字段信息。请严格遵循以下规则:
- 只提取以下字段:
invoice_number(发票号码),date(开票日期,格式化为YYYY-MM-DD),seller(销售方名称),buyer(购买方名称),amount(不含税金额,数字),tax_rate(税率,小数形式如0.13),tax_amount(税额,数字),total(价税合计,数字),type(发票类型,如:增值税专用发票、增值税普通发票)。 - 输出必须且只能是合法的JSON对象,不要有任何额外的解释、标记或换行。
- 如果某个字段在文本中明确找不到,其值设为“无”。
- 金额类数字请去除“¥”等货币符号,只保留纯数字。
- 日期请统一转换为“2024-05-20”这样的格式。
- 用户提示词:在“用户提示词”框中,简单地写:
请提取以下发票信息:{{input}}
这个配置让大模型扮演一个高度专业且守规矩的数据提取员,确保输出格式的纯净。
### 3.4 第四步:配置数据转换与写入链条
添加“循环”节点:从“业务逻辑”中拖出“循环”节点,连接在“大模型”节点之后。
- “并行运行数量”填
1。 - “批处理次数上限”填一个足够大的数,比如
100。 - “item”处,引用“大模型”节点输出的
outputList。这样,大模型批量识别出的多条发票JSON数据,会在这里被一条条拆开处理。
- “并行运行数量”填
添加“代码”节点:从“业务逻辑”中拖出“代码”节点,连接到“循环”节点内部(通常循环节点会有一个“循环体”区域,将代码节点拖入其中)。
- “语言”选择Python。
- “input”处,引用“循环”节点每次循环输出的
output(即单条发票JSON)。 - 在代码编辑器中,粘贴以下Python脚本:
# 输入是单条发票信息的JSON字符串 import json # 解析输入 invoice_data = json.loads(input) # 构建飞书多维表格所需的records格式 # 注意:这里的字段名(如“发票号码”)必须和你飞书表格的列名完全一致! record = { "fields": { "发票号码": invoice_data.get("invoice_number", "无"), "开票日期": invoice_data.get("date", "无"), "销售方名称": invoice_data.get("seller", "无"), "购买方名称": invoice_data.get("buyer", "无"), "金额(不含税)": float(invoice_data.get("amount", 0)) if invoice_data.get("amount", "无") != "无" else None, "税率": float(invoice_data.get("tax_rate", 0)) if invoice_data.get("tax_rate", "无") != "无" else None, "税额": float(invoice_data.get("tax_amount", 0)) if invoice_data.get("tax_amount", "无") != "无" else None, "价税合计": float(invoice_data.get("total", 0)) if invoice_data.get("total", "无") != "无" else None, "发票类型": invoice_data.get("type", "无") } } # 输出一个包含单条记录的列表,符合飞书插件预期 records = [record] # 输出 output = { "records": records }这段代码的作用就是“翻译”,把我们的通用JSON格式,“翻译”成飞书表格API能听懂的“方言”。
添加“飞书多维表格”插件:在插件区找到“飞书多维表格”,拖到循环体外(与循环节点并列),用于接收循环处理完的所有结果。
- “操作”选择“新增记录”。
app_token的获取需要一点步骤:你需要进入飞书开放平台,创建一个应用,并获取该应用的app_token。更简单的方法是,在扣子插件配置时,它通常会引导你通过OAuth授权,授权成功后会自动填充。你也可以手动从飞书表格的URL中解析出base_token来使用。records处,引用“代码”节点输出的records变量。
### 3.5 第五步:连接与测试
最后,从“开始”节点拉出一条线,连接到“链接读取”节点,启动整个流程。再从“飞书多维表格”节点拉出一条线,连接到一个“结束”节点。在“结束”节点,你可以设置一个输出,比如引用feishu_table_url,这样每次运行完,你都能直接点击链接查看结果。
点击工作流右上角的“运行”,在弹出的窗口里粘贴你的飞书表格URL,并上传几张测试用的发票图片或PDF。如果一切配置正确,几十秒后,你就能在飞书表格里看到自动新增的、信息完整的记录了!
4. 避坑指南与高阶优化技巧
第一次搭建成功并成功运行,成就感满满。但要想让这个系统在生产环境中稳定、高效地运行,还需要注意下面这些我踩过坑才总结出来的细节。
### 4.1 常见问题与排查
- 问题一:大模型节点报错或输出格式混乱。
- 原因:提示词不够精确,或者发票图片质量太差(如拍摄模糊、有遮挡)。
- 解决:首先,反复优化你的系统提示词,用更严厉的措辞要求JSON格式,比如加上“输出必须是纯JSON,不能包含
json等标记”。其次,确保上传的发票文件清晰可辨。对于PDF,如果是扫描件而非文本型PDF,识别率也会下降。
- 问题二:飞书插件报错“无权限”或“app_token无效”。
- 原因:飞书多维表格的权限没有正确配置。
- 解决:确保你的飞书应用有该表格的“读写”权限。在飞书开放平台,进入你的应用,在“权限管理”中为“多维表格”申请权限,并将你的表格添加进该应用的“权限配置”范围。然后重新授权给扣子。
- 问题三:处理大量发票时速度慢或失败。
- 原因:扣子工作流对单次运行有超时限制,且免费版可能有调用频率限制。
- 解决:对于超过20张发票的批量处理,建议分批上传。可以在“循环”节点前,先对文件列表进行分片处理,或者直接分多次运行工作流。另外,检查网络环境是否稳定。
### 4.2 提示词优化:让AI更懂你的发票
系统提示词是灵魂,这里分享几个进阶优化点:
- 针对特定发票类型:如果你的发票主要是某一类(如滴滴出行的行程单、某电商平台的电子发票),可以在提示词中加入例子。“例如,一张滴滴出行发票,其销售方通常是‘北京小桔科技有限公司’。” 这样能大幅提升特定场景的准确率。
- 处理模糊信息:有些发票的购买方名称可能只写简称。你可以在提示词中补充:“如果购买方名称不完整,但文本中出现‘我司’、‘本公司’等字样,请统一替换为‘[你的公司全称]’。”
- 强化格式要求:在提示词末尾加上:“请再次检查,你的输出必须能被Python的
json.loads()函数直接解析,不能有任何语法错误。” 这能进一步约束模型。
### 4.3 工作流扩展:不止于归档
基础版实现了自动归档,但这个工作流的潜力远不止于此。你可以轻松地扩展它:
- 自动校验:在“代码”节点之后,“飞书写入”之前,可以插入一个“条件判断”节点。判断逻辑可以是:如果“价税合计”不等于“金额+税额”(考虑浮点数误差),或者关键字段如“发票号码”为“无”,则将该条记录导入一个“待人工审核”的表格,而不是主表。这实现了初步的自动稽核。
- 触发自动化:扣子工作流可以设置为由“定时触发器”启动。你可以设置每周五下午5点自动运行一次,处理当周积累在某个云盘文件夹里的所有发票。或者,结合“飞书群消息”触发器,当有人在指定的报销群里发送发票图片时,自动触发工作流进行识别归档,实现真正的“随到随处理”。
- 数据汇总分析:归档完成后,可以再连接一个“代码”节点,对本次归档的数据进行快速统计,比如“本周报销总额”、“交通类发票占比”,并将统计结果通过“飞书群消息”插件发送到财务群,实现归档即报告。
把这些技巧用上,你的这个“财务神器”就从自动化工具,升级为了一个智能化的财务处理中心。它节省的远不止是手动输入的时间,更是避免了因疲劳导致的错误,让财务工作从繁琐的重复劳动中解放出来,去从事更有价值的分析和决策工作。