1. 项目概述:一个开源的发票处理智能体
最近在折腾AI智能体(Agent)和工具调用(Tool Calling)时,发现了一个挺有意思的开源项目:klodr/mercury-invoicing-mcp。简单来说,这是一个基于模型上下文协议(Model Context Protocol, MCP)构建的、专门用于处理发票的AI智能体工具服务器。
如果你正在研究如何让大语言模型(LLM)更“接地气”地处理现实世界中的结构化文档,比如从五花八门的发票PDF里自动提取关键信息、进行汇总分析,那这个项目绝对值得你花时间研究一下。它不是一个独立的桌面应用,而是一个“能力提供者”——通过标准化的MCP协议,将复杂的发票解析能力封装成一套工具,供像Claude Desktop、Cursor等支持MCP的AI客户端调用。这意味着,你可以在你熟悉的AI聊天界面里,直接让AI帮你处理发票,而无需自己写一堆解析PDF、识别表格的代码。
这个项目解决的核心痛点很明确:将非结构化的发票文档,转化为结构化、可查询、可分析的数据。无论是个人报销整理,还是中小企业对流水单据的快速录入与审核,手动处理效率低下且易错。mercury-invoicing-mcp试图用AI自动化这条流水线,其技术栈选择了当前比较前沿的“LLM + 专用工具”的智能体范式,通过MCP实现与AI前端的解耦,设计思路清晰且具有很好的扩展性。
2. 核心架构与MCP协议解析
2.1 什么是MCP?为什么是它?
在深入项目之前,必须得先搞懂MCP。Model Context Protocol 是由Anthropic提出的一种开放协议,旨在标准化AI应用程序(客户端)与工具、数据源(服务器)之间的通信方式。你可以把它想象成AI世界的“USB协议”或者“gRPC”。
在MCP出现之前,每个AI应用(如Claude Desktop)如果要集成新能力,往往需要客户端和工具提供方进行深度定制化开发,耦合度高,生态难以形成。MCP的目标就是解决这个问题:
- 标准化:定义了统一的服务器-客户端通信规范(基于JSON-RPC over stdio/SSE),包括工具发现、调用、资源读取等。
- 解耦:工具服务器(如本项目的发票处理服务)独立开发、部署,任何支持MCP的客户端都可以无缝接入。
- 安全与可控:工具能力由服务器定义,客户端按需请求,用户能清晰知道AI使用了哪些工具,处理了哪些数据。
对于mercury-invoicing-mcp而言,采用MCP意味着:
- 无需绑定特定AI前端:只要客户端支持MCP(如Claude Desktop、Cursor、自行开发的客户端),就能使用其发票处理能力。
- 专注于核心能力:项目团队可以全力优化发票解析的准确率和功能,而不用分心去做各种客户端的UI适配。
- 易于集成和扩展:其他开发者可以基于相同的协议,开发针对收据、合同、报表的类似工具服务器,共同丰富AI的工具生态。
2.2 项目整体设计思路拆解
这个项目的架构是典型的“智能体工具层”。我们可以将其分解为三个核心层次:
协议接口层(MCP Server): 这是项目的“外壳”。它实现了一个标准的MCP服务器,负责:
- 向连接的AI客户端宣告自己提供的工具列表(例如:
extract_invoice,list_invoices)。 - 接收客户端发来的工具调用请求(包含发票文件路径或URL等参数)。
- 将处理结果(结构化JSON数据)按照MCP格式返回给客户端。
- 向连接的AI客户端宣告自己提供的工具列表(例如:
业务逻辑层(Invoice Processing Core): 这是项目的“大脑”和“心脏”。当协议层收到一个
extract_invoice调用时,它会将实际处理任务交给这一层。这一层通常包含以下关键步骤:- 文档加载:读取PDF文件,可能使用
PyPDF2、pdfplumber或pymupdf等库。 - 文本与布局提取:不仅提取纯文本,更重要的是获取文本的坐标、字体大小、表格结构等布局信息。一张发票上,“总价”旁边的数字和角落里的页码数字,重要性是天差地别的。
- AI信息抽取:这是最核心的一步。项目很可能利用提示词工程(Prompt Engineering),将提取的文本和布局信息组织成一段高质量的提示,发送给大语言模型(如OpenAI GPT系列、Anthropic Claude系列或本地部署的Ollama模型),要求模型按照预定义的JSON Schema输出结构化信息。例如:
“你是一名专业的会计。请从以下发票文本中,提取出‘供应商名称’、‘发票日期’、‘发票号码’、‘税号’、‘商品行项目’(包括描述、数量、单价、金额)、‘小计’、‘税费’和‘总计’金额。请以JSON格式输出。”
- 后处理与验证:对AI返回的JSON进行清洗,比如统一日期格式、校验数字计算是否正确(例如,各行金额之和是否等于小计),并处理可能的AI输出错误或模糊情况。
- 文档加载:读取PDF文件,可能使用
配置与模型管理层: 这一层决定了项目的灵活性和可用性。它需要处理:
- AI模型配置:允许用户指定使用哪个AI模型API(如OpenAI, Anthropic, Azure OpenAI)以及对应的API密钥。
- 提示词管理:可能提供不同语言、不同发票模板的提示词,以优化抽取效果。
- 缓存与状态管理:为了节省成本和提高速度,可能会对处理过的发票结果进行缓存。
注意:项目的具体实现可能不会严格区分这些层,但理解这个逻辑架构有助于我们阅读源码、进行调试或二次开发。
3. 环境部署与核心配置实战
要让mercury-invoicing-mcp跑起来,你需要完成两部分工作:部署MCP服务器本身,以及配置一个支持MCP的客户端。这里我们以最流行的组合——项目服务器 + Claude Desktop为例,进行详细说明。
3.1 服务器端:安装与配置
首先,你需要获取项目代码并安装依赖。通常开源项目会提供多种安装方式。
方案一:通过pip从源码安装(适用于开发与深度定制)
# 1. 克隆仓库 git clone https://github.com/klodr/mercury-invoicing-mcp.git cd mercury-invoicing-mcp # 2. 创建并激活虚拟环境(强烈推荐) python -m venv .venv source .venv/bin/activate # Linux/macOS # 或 .venv\Scripts\activate # Windows # 3. 安装依赖包 pip install -e . # 或者根据项目要求安装 # pip install -r requirements.txt这种方式将项目以“可编辑”模式安装,你直接修改本地代码,效果会立即反映出来,非常适合后续的代码研究和功能修改。
方案二:全局安装(追求简洁)如果项目已经发布到PyPI,你可以直接:
pip install mercury-invoicing-mcp关键配置:连接AI模型项目核心能力依赖大语言模型,因此你必须配置模型访问权限。通常,项目会通过环境变量或配置文件来读取API密钥。
获取API密钥:根据你选择的模型提供商(如OpenAI, Anthropic),去其官网注册并获取API Key。
设置环境变量(最常见的方式):
# 如果你使用OpenAI的模型(如gpt-4o-mini) export OPENAI_API_KEY="sk-your-openai-api-key-here" # 如果你使用Anthropic的模型(如claude-3-5-sonnet) export ANTHROPIC_API_KEY="your-anthropic-api-key-here" # 有些项目也支持本地Ollama模型 export MCP_MODEL_PROVIDER="ollama" export MCP_MODEL_NAME="llama3.2"Windows用户可以在命令提示符中使用
set命令,或在系统属性中设置环境变量。配置文件:检查项目根目录下是否有
config.yaml或.env文件示例(如config.example.yaml)。复制一份并填入你的配置。# config.yaml 示例 model: provider: "openai" # 或 "anthropic", "ollama" name: "gpt-4o-mini" api_key: "${OPENAI_API_KEY}" # 引用环境变量,更安全 invoice: default_currency: "CNY" enable_cache: true
实操心得:模型选择与成本权衡
- 精度优先:处理格式复杂、印刷质量差的发票,建议使用能力更强的模型,如
gpt-4o或claude-3-5-sonnet。它们的结构化输出能力和对上下文的理解更优,但API调用成本也更高。 - 成本/速度优先:如果发票格式相对规范,或者进行批量处理,
gpt-4o-mini、claude-3-haiku或本地llama3.2是性价比很高的选择。在正式处理大批量发票前,务必用小样本测试不同模型的准确率。 - 本地部署:如果涉及敏感的商业发票数据,无法上云,那么使用Ollama部署本地模型是唯一选择。你需要一台性能足够的机器(通常需要16GB以上内存),并牺牲一些处理速度。
3.2 客户端:Claude Desktop配置详解
服务器跑起来后,需要让Claude Desktop知道它的存在。Claude Desktop通过一个名为claude_desktop_config.json的配置文件来管理所有MCP服务器。
找到配置文件位置:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
- macOS:
编辑配置文件:如果文件不存在,就创建它。我们需要在
mcpServers字段下添加新的服务器配置。{ "mcpServers": { "mercury-invoicing": { "command": "/path/to/your/venv/bin/python", "args": [ "-m", "mercury_invoicing_mcp.server" ], "env": { "OPENAI_API_KEY": "sk-your-actual-key-here" } } } }参数拆解:
"mercury-invoicing":这是你给这个服务器起的名字,在Claude里会显示为工具来源。"command":Python解释器的路径。如果你使用了虚拟环境,就像示例一样指向虚拟环境内的python可执行文件。如果是全局安装,可能直接写"python3"。"args":启动参数。-m mercury_invoicing_mcp.server表示以模块方式运行项目中的服务器主程序。"env":这里设置的环境变量会覆盖系统环境变量。强烈建议将API密钥写在这里,而不是系统环境变量中,这样更安全、配置更清晰。
重启Claude Desktop:保存配置文件后,完全退出并重新启动Claude Desktop。
验证连接:重启后,在Claude Desktop的聊天界面,你应该能在输入框附近看到一个新的工具图标(可能是一个螺丝刀或魔杖)。点击它,如果能看到名为
mercury-invoicing的服务器,并且其下有extract_invoice等工具,说明配置成功。
踩坑记录:最常见的错误是
command路径不对或虚拟环境未激活状态下的python路径问题。一个检查方法是,在终端中手动运行command+args里的完整命令,看服务器是否能正常启动并打印日志。另一个常见问题是环境变量未正确传递,导致服务器无法调用AI API,会在Claude Desktop的后台日志中报错。
4. 核心工具使用与发票解析全流程
配置成功后,你就可以在Claude中直接使用发票提取功能了。整个过程是自然语言交互,但背后是标准的MCP工具调用。
4.1 基础使用:单张发票提取
最直接的用法是让Claude分析你本地上传的一张发票图片或PDF。
操作对话示例:
你:我上传了一张发票图片“invoice_202410.pdf”,请帮我提取里面的关键信息。 Claude: (识别到上传的文件,并自动建议或调用 `extract_invoice` 工具)或者你可以更直接地指示:
你:请使用mercury-invoicing工具,解析我刚上传的PDF文件,提取供应商、日期、总额等信息。工具调用背后的逻辑:
- Claude会将你的指令和文件路径(或内容)打包成一个MCP请求,发送给
mercury-invoicing-mcp服务器。 - 服务器执行我们在第2章描述的“业务逻辑层”流程:加载PDF -> 提取文本/布局 -> 构造提示词 -> 调用AI模型 -> 后处理。
- 服务器将得到的结构化JSON返回给Claude。
- Claude将这个JSON以清晰、易读的格式(通常是表格或列表)呈现给你。
解析结果示例: Claude可能会这样回复:
已从发票中提取以下信息:
字段 内容 供应商 某某云计算有限公司 发票号码 INV-2024-00158 开票日期 2024年10月27日 购买方 我的公司 税号 91110108MAABCD1234 商品/服务 云服务器ECS - 通用型g6 (月度) 数量 1 单价 ¥ 480.00 金额 ¥ 480.00 小计 ¥ 480.00 增值税 (6%) ¥ 28.80 总计 (大写) 伍佰零捌元捌角整 总计 (小写) ¥ 508.80
4.2 高级功能:批量处理与数据查询
一个强大的工具服务器不会只提供一个单一功能。根据项目README和源码,它可能还提供了其他工具,例如:
list_invoices/query_invoices:如果你之前处理并缓存了一些发票,这个工具可以让你查询历史记录。例如,你可以问:“帮我找出上个月所有总额超过5000元的发票”。Claude会调用查询工具,并可能结合自然语言理解你的时间范围和金额条件,在缓存的数据中进行筛选和汇总。- 批量提取:虽然MCP工具调用通常是单次交互,但你可以通过编写一段提示词,让Claude帮你规划批量任务。例如:“我这里有一个包含10张发票PDF的文件夹 ‘invoices_october/’,请逐一分析它们,并为我生成一个本月支出的汇总表格,按供应商分类。” Claude可能会规划多次
extract_invoice调用,然后自己汇总结果。
实操心得:如何获得最佳解析效果
- 文件质量是关键:AI模型,尤其是视觉能力不强的纯文本模型,对PDF质量有要求。扫描件最好清晰、方正。如果是图片,确保文字不倾斜、亮度均匀。
- 提供上下文:在让Claude解析前,可以简单说明一下发票类型。例如:“这是一张中国的增值税普通发票,请重点提取发票代码、号码、税额和合计金额。” 这可以帮助Claude更好地选择或调整内部的提示词策略。
- 结果校验不可少:AI并非100%准确,特别是面对罕见格式或模糊印刷时。对于重要的财务数据,务必人工核对关键字段,如金额、账号、税号。可以将此作为自动化流程的一个审核环节,而不是完全替代人工。
- 利用结构化输出:要求Claude将结果以JSON或Markdown表格形式输出,便于你直接复制到Excel、数据库或其他系统中,实现真正的流程自动化。
5. 源码导读与二次开发潜力
对于开发者来说,mercury-invoicing-mcp更大的价值在于其作为一个清晰、可扩展的MCP服务器范例。我们来剖析一下其源码结构,看看如何定制自己的文档处理智能体。
5.1 项目结构概览
典型的项目结构可能如下:
mercury-invoicing-mcp/ ├── src/ │ └── mercury_invoicing_mcp/ │ ├── __init__.py │ ├── server.py # MCP服务器主程序,工具注册和路由 │ ├── core/ │ │ ├── __init__.py │ │ ├── extractor.py # 信息抽取核心逻辑 │ │ ├── models.py # Pydantic数据模型(Invoice, LineItem等) │ │ └── parser.py # PDF解析器封装 │ ├── prompts/ # 存放不同场景的提示词模板 │ │ └── invoice_extraction.jinja2 │ └── config.py # 配置管理 ├── tests/ # 单元测试 ├── pyproject.toml # 项目依赖和构建配置 ├── README.md └── ...server.py:这是入口。你会看到它使用mcpSDK 创建服务器实例,并通过@server.tool()装饰器注册工具函数(如extract_invoice)。这是学习如何将任意Python函数暴露为MCP工具的最佳范例。extractor.py:这里是业务核心。它很可能包含一个InvoiceExtractor类,其extract()方法协调了文档加载、文本预处理、调用LLM、结果解析和验证的全过程。研究这里面的提示词构造和模型调用方式,是提升抽取精度的关键。models.py:使用Pydantic定义了Invoice等数据结构。这确保了输入输出的类型安全,也是AI模型需要输出的JSON Schema的基础。如果你想增加提取字段(如“付款条款”),首先需要在这里修改数据模型。
5.2 如何定制与扩展
假设你的业务需要处理“货物运输单”,你可以基于此项目快速开发一个logistics-waybill-mcp。
- 复制并重命名项目:Fork或复制一份源码,作为新项目的基础。
- 修改数据模型:在
models.py中,将Invoice改为Waybill,字段变更为“运单号”、“发货人”、“收货人”、“货物名称”、“重量”、“体积”、“运费”等。 - 重写提示词:在
prompts/目录下,创建waybill_extraction.jinja2模板,根据运单的特点设计提示词。例如:“请从以下运单中提取结构化信息,重点关注运单编号、收发方信息和货物详情...” - 调整核心逻辑:在
extractor.py中,修改extract()方法,使其加载你的新提示词模板,并期望模型返回Waybill模型对应的JSON。 - 更新工具注册:在
server.py中,将工具名从extract_invoice改为extract_waybill,并关联到新的处理函数。 - 测试与部署:用一些运单样本进行测试,调整提示词直至效果满意。然后就可以像部署原项目一样部署你的新MCP服务器了。
扩展思路:
- 多格式支持:除了PDF,可以增加对图片(通过OCR)、Word、Excel文件的支持。在
parser.py中实现对应的文件加载器。 - 后处理增强:在
extractor.py的后续处理中,加入更复杂的校验规则,比如通过正则表达式二次核验电话号码、身份证号等格式固定的字段。 - 缓存与数据库:将
list_invoices工具连接到真实的数据库(如SQLite、PostgreSQL),实现持久的发票数据管理,并支持更复杂的查询。
6. 常见问题排查与性能优化
在实际使用和开发过程中,你肯定会遇到各种问题。这里汇总了一些典型场景和解决思路。
6.1 连接与配置问题
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
Claude Desktop中看不到mercury-invoicing工具。 | 1. 配置文件路径或格式错误。 2. Claude Desktop未重启。 3. 服务器启动命令执行失败。 | 1. 检查claude_desktop_config.json的JSON语法(可用在线校验器)。2. 彻底退出并重启Claude。 3. 在终端手动运行配置中的 command和args,看是否有错误输出(如Python包缺失)。 |
| 工具调用失败,提示“服务器错误”或“连接超时”。 | 1. MCP服务器进程崩溃。 2. API密钥无效或未设置。 3. 网络问题导致无法访问模型API。 | 1. 查看Claude Desktop的日志(通常可在设置中找到日志文件位置)。 2. 在服务器启动命令前直接设置环境变量并运行,测试模型API是否通: OPENAI_API_KEY=sk-xxx python -m mercury_invoicing_mcp.server。3. 检查防火墙和代理设置。 |
| 解析结果为空或明显错误。 | 1. 上传的文件不是PDF或已损坏。 2. 提示词不适合当前发票格式。 3. 使用的AI模型能力不足。 | 1. 尝试用其他PDF阅读器打开文件确认。 2. 查看项目源码中的提示词模板,尝试在对话中给AI更具体的指令。 3. 在配置中切换到更强大的模型(如从 gpt-4o-mini切换到gpt-4o)进行测试。 |
6.2 解析精度与性能优化
问题:处理速度慢
- 原因:高分辨率PDF解析耗时;调用云端LLM API有网络延迟;使用了大模型(如GPT-4)。
- 优化:
- 启用缓存:如果项目支持,确保开启缓存功能。对同一文件多次解析,第二次应直接返回缓存结果。
- 优化PDF:如果可能,在预处理阶段将PDF转换为纯文本或低分辨率版本。
- 模型降级:在批量处理或对精度要求不高的场景,使用更小、更快的模型。
- 异步处理:对于批量任务,可以考虑修改服务器代码,使用异步IO来并发处理多个文件(如果MCP客户端支持)。
问题:特定字段抽取不准(如日期格式混乱、金额识别错误)
- 原因:发票布局多样;AI模型对某些格式的泛化能力有限;提示词指导不够明确。
- 优化:
- 强化提示词:这是最有效的手段。修改
prompts/下的模板,加入更明确的指令和示例(Few-shot Learning)。例如:“日期请统一格式化为YYYY-MM-DD。金额请统一为数字,不含货币符号。” - 后处理规则:在
extractor.py的输出环节,增加针对性的后处理函数。例如,用正则表达式r'\d{4}-\d{2}-\d{2}'匹配和修正日期;将“一千五百元”这样的中文金额转换为“1500”。 - 分阶段抽取:对于极其复杂的发票,可以设计多轮工具调用。第一轮提取整体信息,第二轮针对模糊区域(如手写备注)进行专门询问。
- 强化提示词:这是最有效的手段。修改
问题:如何处理包含表格的发票?
- 策略:这取决于底层PDF解析库和提示词。
- 确保使用
pdfplumber这类能较好保留表格结构的库。 - 在提示词中明确指示:“发票中包含一个商品明细表格,请按行提取每一行的‘品名’、‘规格’、‘数量’、‘单价’、‘金额’。”
- 如果表格识别依然不好,可以考虑在调用LLM前,先用专门的表格提取库(如
camelot、tabula)将表格数据提取出来,作为结构化文本喂给LLM,让它做整理和映射。
- 确保使用
6.3 安全与成本考量
- 数据安全:发票常含敏感信息。如果你使用OpenAI/Anthropic等云端API,数据会离开你的环境。对于高度敏感数据,唯一的选择是使用本地模型(如通过Ollama)。确保你的
mercury-invoicing-mcp服务器配置为本地模型端点。 - API成本控制:
- 缓存是一切的基础:绝对不要重复解析同一份文件。
- 限制文件大小和页数:在服务器端添加预处理逻辑,拒绝处理过大的文件,或只解析前几页。
- 使用流式或细分调用:对于超长文档,是否可以只提取摘要或关键页?这需要更精细的工具设计。
- 监控用量:在代码中集成日志,记录每次调用的模型、Token使用量,便于分析和优化。
这个项目为我们展示了一条清晰的路径:如何将专业的文档处理能力,通过MCP协议,变成AI智能体触手可及的“手”和“眼”。它的价值不仅在于开箱即用的发票解析,更在于提供了一个可复用的框架。你可以借鉴其设计,将任何你希望AI掌握的复杂任务——从阅读法律合同到分析实验报告——封装成标准的MCP工具,从而极大地扩展AI在实际工作和自动化流程中的应用边界。