PDFlow
通过人工智能提取将PDF转换为结构化数据。
PDFlow是一个现代化的全栈PDF提取工具,它利用多模态AI从PDF文档中智能提取和构建内容。无论您需要Markdown格式的文档、JSON格式的数据还是HTML格式的报告,PDFlow都能通过web UI、CLI和AI代理集成提供准确的提取。
特性
核心功能
- PDF上传:直观的拖放式PDF上传界面
- CLI支持:通过命令行界面进行无头PDF处理,实现自动化
- 图像转换:使用pdftocairo将PDF页面转换为WebP图像
- AI提取:使用Google Gemini 2.0 Flash多模式AI进行智能提取
- 多种格式:以Markdown、MDX、JSON、XML、YAML、HTML或CSV格式导出结果
- 视觉进度:4步视觉跟踪器(上传→ 转换→ 提取→ 完成),实时更新
- 丰富的预览:带有语法高亮显示和格式设置的渲染Markdown预览
- 线程输出:通过实时流媒体查看结果
- 深色模式:具有本地存储持久性的漂亮暗模式支持
- 最小设计:灵感来自shadcn/ui的干净黑/白/灰色美学
- 响应式设计:采用TailwindCSS 4的移动友好界面
- 类型安全:带Zod验证的完整TypeScript实现
- 会话存储API密钥:浏览器会话存储中安全的API密钥管理
新增:部署和AI集成
- 🐳 Docker支持:使用生产就绪容器的多阶段构建
- 🤖 MCP服务器:AI代理的模型上下文协议集成(Claude等)
- 📡 REST API:用于自定义集成的完整API
- 🔐 安全特性:文件验证、命令注入预防、容器化
- 📚 完整文档网站:互动文档,包括全面的指南和示例
- 📋 综合录井:具有文件持久性、Docker集成和高级过滤的双输出日志记录系统
技术栈
| 层 | 技术 |
|---|---|
| 前端 | Next.js 16.0.1,React 19,TailwindCSS 4,Framer Motion |
| 渲染 | React Markdown,重新键入高亮显示 |
| 状态 | 状态 |
| 验证 | Zod |
| 模板 | 把手 |
| 人工智能模型 | 谷歌Gemini 2.0 Flash Exp(多模式) |
| AI SDK | Vercel AI SDK |
| 后端 | TypeScript+Next.js API路由 |
| PDF处理 | pdftocairo(poppler-utils) |
| 存储 | 本地文件系统(上传、输出) |
先决条件
- Node.js 20+(Next.js 16需要)
- npm或纱线
- pdftocairo(poppler-utils)
- Google Gemini API密钥
安装pdftocairo
Ubuntu/Debian:
sudo apt-get install poppler-utilsmacOS:
brew install poppler窗户: 下载并安装 Windows版poppler 并添加到PATH中。
设置
选项1:Docker(推荐)
# Set your API key
export GEMINI_API_KEY="your-api-key-here"
# Build and start with Docker Compose (includes proper user permissions)
USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose build
USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose up -d
# Access at http://localhost:3535注: 建筑与 USER_ID 和 GROUP_ID 确保容器用户与主机用户匹配,防止装载卷的权限问题。
📦 有关完整的Docker文档,请参阅
方案2:地方发展
- 克隆存储库并安装依赖项:
git clone https://github.com/traves-theberge/pdflow.git
cd pdflow
npm install- 运行开发服务器:
npm run dev- 打开应用程序:
- 引导到 http://localhost:3001 - 点击右上角的设置齿轮图标 - 输入您的Google Gemini API密钥 - 点击“保存API密钥”
您的API密钥安全地存储在浏览器的会话存储中,并且不会发送到除Google的Gemini API之外的任何服务器。
用法
网络界面
- 配置API密钥:在“设置”中输入Gemini API密钥(仅限第一次)
- 选择输出格式:从Markdown、MDX、JSON、XML、YAML、HTML或CSV中选择
- 上传PDF:拖放或单击以选择PDF文件
- 处理:该应用程序自动将PDF转换为WebP图像,并使用AI提取数据
- 查看结果:在页面完成时实时查看提取的内容
- 下载:导出单个页面或合并下载所有页面
📚 有关完整的web界面指南,请参阅 Web使用文档
CLI(无头模式)
PDFlow包含一个命令行界面,用于在没有web UI的情况下进行无头PDF处理。
将PDF提取为结构化数据:
npm run pdflow -- extract
[options]选项:
-f, --format:输出格式(markdown|json|xml|yaml|html|mdx|csv)\[默认:markdown\]-o, --output:输出目录\[默认:./outputs\]-k, --api-key:Gemini API密钥(或设置Gemini_API_key env var)-a, --aggregate:将所有页面聚合到一个文件中-v, --verbose:显示详细输出
示例:
# Extract PDF to markdown
npm run pdflow -- extract document.pdf -f markdown -o ./results
# Extract to JSON with aggregation
npm run pdflow -- extract document.pdf -f json -a
# Extract with custom API key
npm run pdflow -- extract document.pdf -k YOUR_API_KEY
# Extract with verbose output
npm run pdflow -- extract document.pdf -v验证Gemini API密钥:
npm run pdflow -- validate-key
# or
npm run pdflow -- validate-key -k YOUR_API_KEY生成MCP配置:
# Generate config for VS Code
npm run pdflow -- mcp-config --tool vscode
# Generate for Claude Desktop
npm run pdflow -- mcp-config --tool claude-desktop
# Generate for Cursor
npm run pdflow -- mcp-config --tool cursor
# Generate for Claude Code
npm run pdflow -- mcp-config --tool claude-code
# Use development server (port 3001)
npm run pdflow -- mcp-config --dev
# Use custom URL (e.g., Tailscale)
npm run pdflow -- mcp-config --url http://100.64.0.2:3535CLI输出: CLI在输出文件夹中创建一个会话目录,其中包含:
- 单个页面文件(例如。,
page-1.md,page-2.md) - 元数据文件(例如。,
page-1.meta.json) - 聚合文件(如果
-a使用标志。,full.markdown)
📚 有关完整的CLI文档,请参阅 CLI使用指南
项目结构
/src
/app
/api
/upload
route.ts # PDF upload endpoint
/process
route.ts # Processing endpoint with progress
/outputs/[sessionId]/[filename]
route.ts # Output file serving
/settings
/validate-key
route.ts # API key validation
/components
UploadForm.tsx # File upload component
ProgressBar.tsx # Progress tracking with polling
EnhancedOutputViewer.tsx # Real-time threaded output display
Settings.tsx # Settings modal with API key management
/utils
gemini-extractor.ts # Gemini AI extraction logic
aggregator.ts # Output aggregation
prompt-builder.ts # Dynamic prompt generation
/store
useAppStore.ts # Zustand state management
page.tsx # Main page with dark mode
layout.tsx # Root layout
globals.css # Global styles
/cli
pdflow.ts # CLI entry point
pdf-processor.ts # Headless PDF processing logic
/templates
/formats
markdown_format.hbs # Markdown extraction template
mdx_format.hbs # MDX extraction template
json_format.hbs # JSON extraction template
xml_format.hbs # XML extraction template
yaml_format.hbs # YAML extraction template
html_format.hbs # HTML extraction template
csv_format.hbs # CSV extraction template
/scripts
convert-to-webp.sh # PDF to WebP conversion script
/docs
CLI_USAGE.md # Complete CLI documentation
/public
PDFlow_Logo.png # Logo (icon only)
PDFlow_Logo_W_Text.png # Logo with text
/uploads # Temporary upload storage (gitignored)
/outputs # Processed output files (gitignored)
/test-cli-outputs # CLI test outputs (gitignored)API终点
POST/api/上传
上传PDF文件并将其转换为WebP图像。
请求: multipart/form-data
file:PDF文件
答复:
{
"success": true,
"sessionId": "session_1234567890_abc123",
"pageCount": 5,
"message": "Successfully uploaded and converted PDF to 5 pages"
}POST/api/进程
开始处理会话或聚合结果。
请求:
{
"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/进程?会话ID=
获取会话的处理进度。
答复:
{
"sessionId": "session_1234567890_abc123",
"status": "processing",
"totalPages": 5,
"processedPages": 3,
"processingTime": "15.23s"
}环境变量
| 变量 | 描述 | 必填 |
|---|---|---|
GEMINI_API_KEY | Google Gemini API密钥(可通过UI设置) | 可选\* |
PORT | 服务器端口(默认为3000) | 否 |
NODE_ENV | 节点环境 | 否 |
\*API键可以通过设置在应用程序UI中设置。如果已设置 .env.local,它将被用作后备方案。
发展
可用脚本
npm run dev-启动开发服务器npm run build-为生产而建npm run start-启动生产服务器npm run lint-运行ESLint
添加新功能
- 新的输出格式:添加到
aggregator.ts并更新格式选择器 - 自定义处理:修改
gemini-extractor.ts用于不同的提取提示 - UI组件:添加到
/src/app/components并进口page.tsx
部署
维塞尔
- 推送到GitHub
- 将存储库连接到Vercel
- 添加
GEMINI_API_KEY作为环境变量 - 部署
码头工人
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+包括用于调试和监控的全面日志记录:
查看日志
# Watch logs in real-time
./scripts/view-logs.sh --follow
# Show only errors
./scripts/view-logs.sh --errors
# Filter by session ID
./scripts/view-logs.sh --session session_123
# View Docker logs
docker logs -f pdflow日志文件
日志存储在:
- 主机:
./logs/pdflow-YYYY-MM-DD.log - 容器:
/app/logs/pdflow-YYYY-MM-DD.log - 码头工人:
docker logs pdflow
配置
通过环境变量控制日志记录:
LOG_LEVEL=info # debug|info|warn|error|critical
ENABLE_FILE_LOGGING=true # Enable file-based logs
LOG_RETENTION_DAYS=7 # Days to keep logs📋 有关完整的日志记录文档,请参阅 docs/LOGGING.md
故障排除
常见问题
- “未找到pdftocairo”
- 安装poppler-utils(请参阅先决条件)
- “未找到Gemini API密钥”
- 检查 .env.local 文件存在并且包含有效的API密钥
- “PDF转换失败”
- 确保PDF不受密码保护 - 检查文件大小限制 - 检查日志: ./scripts/view-logs.sh --errors
- “处理停留在0%”
- 检查浏览器控制台是否有错误 - 验证API终结点是否响应 - 审核日志: ./scripts/view-logs.sh --follow
- “脚本已退出,代码为1”
- 检查详细的错误日志: grep "Script failed" logs/pdflow-*.log - 验证是否安装了ImageMagick和poppler-utils - 查看日志中的stderr输出以了解特定错误消息
使用日志进行调试
# Find errors in today's logs
./scripts/view-logs.sh --today --errors
# Search for specific errors
grep "ERROR" logs/pdflow-*.log
# View session timeline
grep "session_YOUR_SESSION_ID" logs/pdflow-*.log
# Check Docker logs
docker logs --tail 100 pdflow许可证
MIT许可证-有关详细信息,请参阅许可证文件。
贡献
- 分叉存储库
- 创建要素分支
- 进行更改
- 如果适用,添加测试
- 提交拉取请求
支持
对于问题和疑问:
- 在GitHub上打开一个问题
- 检查上面的故障排除部分
