返回市场
流程调度器

流程调度器

作者:Traves-Theberge3 星标更新:2025-11-22

项目介绍

PDFlow Logo

PDFlow

使用AI驱动的提取功能将PDF转换为结构化数据。

PDFlow是一款现代的、全栈式的PDF提取工具,利用多模态AI智能地从PDF文档中提取并结构化内容。无论你需要的是Markdown格式的文档、JSON格式的数据还是HTML格式的报告,PDFlow都能通过Web UI、CLI以及AI代理集成提供准确的提取。

📚 查看完整文档 | 🚀 快速开始 | 🔌 API参考

功能

核心功能

  • PDF上传:直观的拖放式PDF上传界面
  • CLI支持:通过命令行接口进行无头PDF处理以实现自动化
  • 图像转换:使用pdftocairo将PDF页面转换为WebP图像
  • AI提取:使用Google Gemini 2.0 Flash多模态AI进行智能提取
  • 多种格式:导出结果到Markdown、MDX、JSON、XML、YAML、HTML或CSV
  • 视觉进度:四步视觉追踪器(上传→转换→提取→完成),实时更新
  • 丰富的预览:带有语法高亮和格式化的渲染Markdown预览
  • 线程输出:实时流式查看已完成的结果
  • 暗模式:持久存储的美观暗模式支持
  • 极简设计:受shadcn/ui启发的干净黑白灰美学
  • 响应式设计:使用TailwindCSS 4的移动友好界面
  • 类型安全:完整的TypeScript实现与Zod验证
  • 会话存储API密钥:在浏览器会话存储中安全管理API密钥

新增:部署及AI集成

  • 🐳 Docker支持:多阶段构建,生产就绪容器
  • 🤖 MCP服务器:AI代理(Claude等)的模型上下文协议集成
  • 📡 REST API:用于自定义集成的完整API
  • 🔐 安全特性:文件验证、命令注入防护、容器化
  • 📚 完整文档站点:交互式文档,包含全面指南和示例
  • 📋 全面日志记录:具有文件持久性、Docker集成和高级过滤的双输出日志系统

技术栈

层级技术
前端Next.js 16.0.1, React 19, TailwindCSS 4, Framer Motion
渲染React Markdown, Rehype Highlight
状态Zustand
验证Zod
模板Handlebars
AI模型Google Gemini 2.0 Flash Exp (多模态)
AI SDKVercel AI SDK
后端TypeScript + Next.js API 路由
PDF处理pdftocairo (poppler-utils)
存储本地文件系统(上传、输出)

预备条件

  • Node.js 20+(Next.js 16所需)
  • npm 或 yarn
  • pdftocairo (poppler-utils)
  • Google Gemini API密钥

安装pdftocairo

Ubuntu/Debian:

sudo apt-get install poppler-utils

macOS:

brew install poppler

Windows: 下载并安装适用于Windows的poppler,并将其添加到PATH中。

设置

选项1:Docker(推荐)

# 设置你的API密钥
export GEMINI_API_KEY="your-api-key-here"

# 使用Docker Compose构建并启动(包括正确的用户权限)
USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose build
USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose up -d

# 访问 http://localhost:3535

注意: 使用USER_IDGROUP_ID构建确保容器用户与主机用户匹配,防止挂载卷时出现权限问题。

📦 完整的Docker文档,请参阅Docker部署指南

选项2:本地开发

  1. 克隆仓库并安装依赖项:
git clone https://github.com/traves-theberge/pdflow.git
cd pdflow
npm install
  1. 运行开发服务器:
npm run dev
  1. 打开应用程序:
    • 导航至http://localhost:3001
    • 点击右上角的设置齿轮图标
    • 输入你的Google Gemini API密钥
    • 点击“保存API密钥”

你的API密钥被安全地存储在浏览器的会话存储中,并且仅发送给Google的Gemini API服务器。

使用

Web界面

  1. 配置API密钥:在设置中输入Gemini API密钥(仅首次需要)
  2. 选择输出格式:从Markdown、MDX、JSON、XML、YAML、HTML或CSV中选择
  3. 上传PDF:拖放或点击选择PDF文件
  4. 处理:应用自动将PDF转换为WebP图像并使用AI提取数据
  5. 查看结果:实时查看已完成页面的提取内容
  6. 导出:导出单个页面或下载所有页面合并后的文件

📚 完整的Web界面指南,请参阅Web使用文档

CLI(无头模式)

PDFlow包含一个命令行接口,用于无头PDF处理,无需Web UI。

提取PDF为结构化数据:

npm run pdflow -- extract <pdf-file> [options]

选项:

  • -f, --format <format>:输出格式(markdown|json|xml|yaml|html|mdx|csv)[默认:markdown]
  • -o, --output <directory>:输出目录 [默认:./outputs]
  • -k, --api-key <key>:Gemini API密钥(或设置GEMINI_API_KEY环境变量)
  • -a, --aggregate:将所有页面合并为一个文件
  • -v, --verbose:显示详细输出

示例:

# 提取PDF为Markdown
npm run pdflow -- extract document.pdf -f markdown -o ./results

# 提取为JSON并合并
npm run pdflow -- extract document.pdf -f json -a

# 使用自定义API密钥提取
npm run pdflow -- extract document.pdf -k YOUR_API_KEY

# 提取并显示详细输出
npm run pdflow -- extract document.pdf -v

验证Gemini API密钥:

npm run pdflow -- validate-key
# 或
npm run pdflow -- validate-key -k YOUR_API_KEY

生成MCP配置:

# 为VS Code生成配置
npm run pdflow -- mcp-config --tool vscode

# 为Claude Desktop生成配置
npm run pdflow -- mcp-config --tool claude-desktop

# 为Cursor生成配置
npm run pdflow -- mcp-config --tool cursor

# 为Claude Code生成配置
npm run pdflow -- mcp-config --tool claude-code

# 使用开发服务器(端口3001)
npm run pdflow -- mcp-config --dev

# 使用自定义URL(例如,Tailscale)
npm run pdflow -- mcp-config --url http://100.64.0.2:3535

CLI输出: CLI会在输出文件夹中创建一个会话目录,其中包含:

  • 单个页面文件(如page-1.mdpage-2.md
  • 元数据文件(如page-1.meta.json
  • 合并文件(如果使用了-a标志,如full.markdown

📚 完整的CLI文档,请参阅CLI使用指南

项目结构

/src
  /app
    /api
      /upload
        route.ts                      # PDF上传端点
      /process
        route.ts                      # 处理端点,带进度
      /outputs/[sessionId]/[filename]
        route.ts                      # 输出文件服务
      /settings
        /validate-key
          route.ts                    # API密钥验证
    /components
      UploadForm.tsx                  # 文件上传组件
      ProgressBar.tsx                 # 进度跟踪,带轮询
      EnhancedOutputViewer.tsx        # 实时线程输出显示
      Settings.tsx                    # 设置模态框,含API密钥管理
    /utils
      gemini-extractor.ts             # Gemini AI提取逻辑
      aggregator.ts                   # 输出聚合
      prompt-builder.ts               # 动态提示生成
    /store
      useAppStore.ts                  # Zustand状态管理
    page.tsx                          # 主页,含暗模式
    layout.tsx                        # 根布局
    globals.css                       # 全局样式
  /cli
    pdflow.ts                         # CLI入口点
    pdf-processor.ts                  # 无头PDF处理逻辑
/templates
  /formats
    markdown_format.hbs               # Markdown提取模板
    mdx_format.hbs                    # MDX提取模板
    json_format.hbs                   # JSON提取模板
    xml_format.hbs                    # XML提取模板
    yaml_format.hbs                   # YAML提取模板
    html_format.hbs                   # HTML提取模板
    csv_format.hbs                    # CSV提取模板
/scripts
  convert-to-webp.sh                  # PDF转WebP脚本
/docs
  CLI_USAGE.md                        # 完整CLI文档
/public
  PDFlow_Logo.png                     # 图标(仅图标)
  PDFlow_Logo_W_Text.png              # 图标带文字
/uploads                              # 临时上传存储(已忽略)
/outputs                              # 已处理输出文件(已忽略)
/test-cli-outputs                     # CLI测试输出(已忽略)

API端点

POST /api/upload

上传PDF文件并将其转换为WebP图像。

请求: multipart/form-data

  • file:PDF文件

响应:

{
  "success": true,
  "sessionId": "session_1234567890_abc123",
  "pageCount": 5,
  "message": "成功上传并转换PDF为5页"
}

POST /api/process

开始处理会话或聚合结果。

请求:

{
  "sessionId": "session_1234567890_abc123",
  "format": "markdown",
  "aggregate": true
}

响应:

{
  "sessionId": "session_1234567890_abc123",
  "status": "completed",
  "totalPages": 5,
  "processedPages": 5,
  "aggregate": {
    "format": "markdown",
    "totalPages": 5,
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}

GET /api/process?sessionId=<id>

获取会话的处理进度。

响应:

{
  "sessionId": "session_1234567890_abc123",
  "status": "processing",
  "totalPages": 5,
  "processedPages": 3,
  "processingTime": "15.23s"
}

环境变量

变量描述必需
GEMINI_API_KEYGoogle Gemini API密钥(可通过UI设置)可选*
PORT服务器端口(默认为3000)
NODE_ENVNode环境

*API密钥可以在应用UI中的设置中设置。如果在.env.local中设置,则作为后备使用。

开发

可用脚本

  • npm run dev - 启动开发服务器
  • npm run build - 构建生产版本
  • npm run start - 启动生产服务器
  • npm run lint - 运行ESLint

添加新功能

  1. 新的输出格式:添加到aggregator.ts并更新格式选择器
  2. 自定义处理:修改gemini-extractor.ts以使用不同的提取提示
  3. UI组件:添加到/src/app/components并在page.tsx中导入

部署

Vercel

  1. 推送到GitHub
  2. 将仓库连接到Vercel
  3. 添加GEMINI_API_KEY作为环境变量
  4. 部署

Docker

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]

日志记录与监控

PDFlow v0.5.0+ 包含全面的日志记录,用于调试和监控:

查看日志

# 实时查看日志
./scripts/view-logs.sh --follow

# 显示错误
./scripts/view-logs.sh --errors

# 按会话ID筛选
./scripts/view-logs.sh --session session_123

# 查看Docker日志
docker logs -f pdflow

日志文件

日志存储在:

  • 主机./logs/pdflow-YYYY-MM-DD.log
  • 容器/app/logs/pdflow-YYYY-MM-DD.log
  • Dockerdocker logs pdflow

配置

通过环境变量控制日志记录:

LOG_LEVEL=info              # debug|info|warn|error|critical
ENABLE_FILE_LOGGING=true    # 启用基于文件的日志记录
LOG_RETENTION_DAYS=7        # 保留日志天数

📋 完整的日志记录文档,请参阅docs/LOGGING.md

故障排除

常见问题

  1. "pdftocairo未找到"

    • 安装poppler-utils(参阅预备条件)
  2. "Gemini API密钥未找到"

    • 检查.env.local文件是否存在并包含有效的API密钥
  3. "PDF转换失败"

    • 确保PDF没有密码保护
    • 检查文件大小限制
    • 查看日志:./scripts/view-logs.sh --errors
  4. "处理卡在0%"

    • 检查浏览器控制台是否有错误
    • 验证API端点是否响应
    • 查看日志:./scripts/view-logs.sh --follow
  5. "脚本退出代码1"

    • 查看详细的错误日志:grep "Script failed" logs/pdflow-*.log
    • 验证ImageMagick和poppler-utils是否已安装
    • 查看日志中的stderr输出以获取具体的错误信息

使用日志进行调试

# 在今天的日志中查找错误
./scripts/view-logs.sh --today --errors

# 搜索特定错误
grep "ERROR" logs/pdflow-*.log

# 查看会话时间线
grep "session_YOUR_SESSION_ID" logs/pdflow-*.log

# 查看Docker日志
docker logs --tail 100 pdflow

许可证

MIT许可证 - 详情见LICENSE文件。

贡献

  1. 分叉仓库
  2. 创建功能分支
  3. 进行更改
  4. 如适用,添加测试
  5. 提交拉取请求

支持

对于问题和疑问:

  • 在GitHub上打开问题
  • 查看上面的故障排除部分