需在Dify中通过本地PaddleOCR HTTP服务实现证件信息提取:先部署Flask版OCR API(指定模型路径、禁用localhost调用),再以MCP协议接入Dify插件,最后用Prompt+JSON Schema驱动LLM结构化解析OCR文本。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

要在Dify中实现身份证、银行卡等证件信息的自动提取,必须让Dify能调用本地部署的PaddleOCR引擎完成图像到结构化文本的转换,而非依赖第三方云API——这关系到数据不出域、字段可控、响应低延迟等刚性要求。
准备PaddleOCR服务端(HTTP API模式)
这一步不是在Dify里装PaddleOCR,而是在同一内网另起一个独立服务进程,专供Dify调用。推荐使用PaddleOCR自带的`tools/infer/predict_system.py`改造为Flask接口,避免Dify插件层直接加载模型引发内存冲突。
进入PaddleOCR项目根目录,创建app_ocr_api.py:
复制以下代码并保存:
from flask import Flask, request, jsonify
import cv2
import numpy as np
from paddleocr import PaddleOCR
app = Flask(__name__)
# 初始化OCR实例,仅启动一次
ocr = PaddleOCR(use_angle_cls=True, lang='ch', use_gpu=True, det_model_dir='./inference/ch_PP-OCRv4_det_slim_infer/', rec_model_dir='./inference/ch_PP-OCRv4_rec_slim_infer/', cls_model_dir='./inference/ch_ppocr_mobile_v2.0_cls_slim_infer/')
@app.route('/ocr', methods=['POST'])
def ocr_endpoint():
file = request.files.get('image')
if not file:
return jsonify({'error': 'missing image'}), 400
img_bytes = file.read()
nparr = np.frombuffer(img_bytes, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
return jsonify({'error': 'invalid image format'}), 400
result = ocr.ocr(img, cls=True)
# 提取纯文本行,忽略坐标和置信度
texts = [line[1][0] for line in result[0]] if result and result[0] else []
return jsonify({'texts': texts})
if __name__ == '__main__':
app.run(host='0.0.0.0:8080', threaded=True)
注意:【det_model_dir、rec_model_dir、cls_model_dir路径必须指向你已下载好的PP-OCRv4 Slim模型目录,不能用默认相对路径】。若未下载,运行paddleocr --download-model ch后去~/.paddleocr/找对应子目录并拷贝到当前./inference/下。
安装依赖并启动服务:
pip install flask opencv-python paddleocr==2.7.0.3 paddlepaddle-gpu==2.4.2.post116
python app_ocr_api.py
此时访问http://localhost:8080/ocr(POST,带image文件)应返回JSON格式的识别文本列表。
在Dify中配置OCR插件(MCP协议方式)
MCP是Dify 1.10+官方推荐的工具接入协议,比旧版Function Calling更安全、可发现、可热插拔。它不要求OCR服务改造成LLM函数,只需暴露标准HTTP接口并提供YAML描述文件。
第一步:在Dify管理后台 → 插件 → 新建插件 → 选择“MCP HTTP”类型。
第二步:填写基础信息:
名称:PaddleOCR-ID-Card
描述:用于身份证、银行卡等证件图像的文字提取与字段定位
Base URL:http://192.168.1.100:8080(填你PaddleOCR服务所在机器的真实内网IP,【绝不能写localhost或127.0.0.1】)
第三步:上传MCP描述文件paddle_ocr_mcp.yaml:
```yaml
version: "0.1"
name: "paddle_ocr"
description: "Extract text from ID card or bank card images"
tools:
- name: "extract_id_text"
description: "Perform OCR on uploaded ID/bank card image and return plain text lines"
input_schema:
type: "object"
properties:
image_url:
type: "string"
description: "Publicly accessible URL of the image (e.g., from Dify's file storage)"
output_schema:
type: "object"
properties:
texts:
type: "array"
items:
type: "string"
```
第四步:启用插件并测试。点击“测试工具”,输入一个Dify内已上传的身份证图片URL(必须是Dify对象存储生成的公开可读链接),点击执行。若返回非空text数组,说明链路通了。
构建证件字段解析工作流
单纯OCR返回一堆文本行没有业务价值,必须让Dify用大模型从中抽取出身份证号、姓名、出生日期等结构化字段。这一步靠Prompt工程驱动,不写代码。
① 在Dify应用中新建一个“文本提取”工作流节点,类型选“LLM”。
② 输入提示词(System Prompt):
你是一名专业证件信息提取员。用户将提供一段从身份证正面OCR识别出的原始文本行列表,请严格按以下规则处理:
- 只输出JSON,无任何额外说明或markdown标记
- 字段名固定为:name、id_number、birthday、address、sex、nationality
- birthday格式为YYYY-MM-DD,从“出生”后文字中提取;id_number必须是18位连续数字+字母
- 若某字段未出现,对应值填null
- 忽略所有非中文字符开头的行(如页眉页脚、条形码)
③ 工作流输入变量设为{{tools.paddle_ocr.extract_id_text.texts}},即上一步OCR插件的输出结果。
④ 启用JSON Schema约束输出,填写:
{
"type": "object",
"properties": {
"name": {"type": ["string", "null"]},
"id_number": {"type": ["string", "null"]},
"birthday": {"type": ["string", "null"]},
"address": {"type": ["string", "null"]},
"sex": {"type": ["string", "null"]},
"nationality": {"type": ["string", "null"]}
}
}
⑤ 保存并发布该工作流。后续用户上传身份证图片时,即可自动触发OCR→清洗→结构化三步,最终得到标准JSON。











