Skip to content

OpenRouter 支持将 PDF 发送给任意模型处理,使用 /api/v1/chat/completions 接口的 file 内容类型。支持 URL(公开文档)和 base64(本地文件)两种传入方式。提供三种解析引擎:cloudflare-ai(免费)、mistral-ocr(扫描件首选,$2/千页)、native(模型原生支持时最优)。重复发送同一文档时,可通过复用 annotations 跳过重复解析,节省时间和费用。

选择解析引擎

通过请求中的 plugins 参数指定引擎:

json
{
  "plugins": [
    {
      "id": "file-parser",
      "pdf": {
        "engine": "cloudflare-ai"
      }
    }
  ]
}
引擎费用适用场景
native按 input token 计模型本身支持文件输入时最优
cloudflare-ai免费普通文字 PDF,快速解析
mistral-ocr$2/千页扫描件或含图片的 PDF

不指定引擎时,优先用模型原生能力,不支持则自动用 mistral-ocr

pdf-text 引擎已废弃,请求会自动重定向到 cloudflare-ai,旧代码仍可正常工作。

发送 PDF URL

公开可访问的 PDF 可以直接传 URL,无需下载或编码:

typescript
import { OpenRouter } from '@openrouter/sdk';

const openRouter = new OpenRouter({ apiKey: '<OPENROUTER_API_KEY>' });

const result = await openRouter.chat.send({
  model: 'google/gemini-2.5-flash',
  messages: [
    {
      role: 'user',
      content: [
        { type: 'text', text: 'What are the main points in this document?' },
        {
          type: 'file',
          file: {
            filename: 'document.pdf',
            fileData: 'https://bitcoin.org/bitcoin.pdf',
          },
        },
      ],
    },
  ],
  plugins: [{ id: 'file-parser', pdf: { engine: 'mistral-ocr' } }],
  stream: false,
});

发送 Base64 编码 PDF

本地 PDF 文件需要先 base64 编码:

python
import requests, json, base64

def encode_pdf_to_base64(pdf_path):
    with open(pdf_path, "rb") as f:
        return base64.b64encode(f.read()).decode('utf-8')

base64_pdf = encode_pdf_to_base64("path/to/document.pdf")
data_url = f"data:application/pdf;base64,{base64_pdf}"

payload = {
    "model": "google/gemma-3-27b-it",
    "messages": [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What are the main points?"},
                {"type": "file", "file": {"filename": "document.pdf", "file_data": data_url}}
            ]
        }
    ],
    "plugins": [{"id": "file-parser", "pdf": {"engine": "cloudflare-ai"}}]
}

response = requests.post(
    "https://openrouter.ai/api/v1/chat/completions",
    headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
    json=payload
)
print(response.json())

复用文件注解节省费用

首次解析 PDF 后,响应的 choices[0].message.annotations 中会包含结构化的解析结果。将这个 annotations 附在后续请求的 assistant 消息中,OpenRouter 会直接复用缓存,跳过重复解析:

python
# 第一次请求后,保存注解
file_annotations = response_data["choices"][0]["message"].get("annotations")

# 后续请求中附上注解(无需再传 PDF 文件)
follow_up_messages = [
    {"role": "user", "content": [{"type": "file", "file": {...}}]},
    {"role": "assistant", "content": "...", "annotations": file_annotations},
    {"role": "user", "content": "Can you elaborate on the second point?"}
]

这对大型文档或使用 mistral-ocr 引擎(按页收费)的场景尤其划算。

文件注解格式

typescript
type FileAnnotation = {
  type: 'file';
  file: {
    hash: string;      // 解析文件的唯一标识
    name?: string;     // 原始文件名(可选)
    content: ContentPart[];  // 解析后的内容
  };
};

type ContentPart =
  | { type: 'text'; text: string }
  | { type: 'image_url'; image_url: { url: string } };

常见问题

Q: 不指定 engine 时默认用哪个?

A: 优先用模型原生文件处理能力;不支持时自动切换到 mistral-ocr

Q: 扫描件和普通 PDF 用哪个引擎?

A: 扫描件或含图片的 PDF 用 mistral-ocr(付费但准确);纯文字 PDF 用 cloudflare-ai(免费)即可。

Q: 一次请求能发几个 PDF?

A: 可以同时发送多个 PDF 和其他类型文件,具体上限取决于模型。