Skip to content
LlamaParse 文档版本 跟随上游 源快照 320a16a8 更新于 2026-10-16

本指南演示如何用 Split API,按内容类别把一份拼接 PDF 自动切分成逻辑上的文档小节。

使用场景

当一份大 PDF 里混着多篇彼此独立的文档或章节(例如一篇篇研究论文的合订、一批报告的合集)时,你往往需要把它们拆成独立片段。Split API 用 AI 来:

  1. 分析每一页的内容
  2. 把页面分类到用户定义的类别
  3. 判断一份文档在哪里结束、下一份从哪里开始(相邻的段可以共用同一类别)

示例文档

我们用的 PDF 拼接了三份文档:

  • Alan Turing 的文章 “Intelligent Machinery, A Heretical Theory”(一篇文章)
  • ImageNet 论文(一篇研究论文)
  • “Attention is All You Need” 论文(一篇研究论文)

我们会把它切成 essay 与 research_paper 两类段。

把示例 PDF 下载到 data/:

终端窗口

curl -fL --create-dirs -o "data/turing+imagenet+attention.pdf" https://raw.githubusercontent.com/run-llama/llama-cloud-py/main/examples/example_files/turing%2Bimagenet%2Battention.pdf

设置

安装所需的包:

  • Python
  • TypeScript
  • Go
  • Java
  • CLI

终端窗口

pip install "llama-cloud>=2.8"

配置好环境(或稍后在代码里直接传入你的 API key):

终端窗口

export LLAMA_CLOUD_API_KEY="your_api_key_here"

终端窗口

npm install @llamaindex/llama-cloud

配置好环境(或稍后在代码里直接传入你的 API key):

终端窗口

export LLAMA_CLOUD_API_KEY="your_api_key_here"

终端窗口

go get github.com/run-llama/llama-parse-go

配置好环境(或稍后在代码里直接传入你的 API key):

终端窗口

export LLAMA_CLOUD_API_KEY="your_api_key_here"
implementation("ai.llamaindex:llama-cloud:1.3.0")

配置好环境(或稍后在代码里直接传入你的 API key):

终端窗口

export LLAMA_CLOUD_API_KEY="your_api_key_here"

终端窗口

go install github.com/run-llama/llama-parse-cli/cmd/llp@latest

配置好环境(或稍后在代码里直接传入你的 API key):

终端窗口

export LLAMA_CLOUD_API_KEY="your_api_key_here"

第 1 步:上传 PDF

用 llama-cloud SDK 把这份拼接 PDF 上传到 LlamaCloud:

  • Python
  • TypeScript
  • Go
  • Java
  • CLI
from llama_cloud import LlamaCloud

client = LlamaCloud()

pdf_path = "./data/turing+imagenet+attention.pdf"

uploaded_file = client.files.create(file=pdf_path, purpose="split")

file_id = uploaded_file.id
print(f"✅ File uploaded: {uploaded_file.id}")
import fs from "fs";
import { LlamaCloud } from "@llamaindex/llama-cloud";

const client = new LlamaCloud();

const pdfPath = "./data/turing+imagenet+attention.pdf";

const uploadedFile = await client.files.create({
  file: fs.createReadStream(pdfPath),
  purpose: "split",
});

const fileId = uploadedFile.id;
console.log(`✅ File uploaded: ${uploadedFile.id}`);
package main

import (
  "context"
  "fmt"
  "log"
  "os"

  llamacloud "github.com/run-llama/llama-parse-go"
)

func main() {
  client := llamacloud.NewClient()

  f, err := os.Open("./data/turing+imagenet+attention.pdf")
  if err != nil {
    log.Fatal(err)
  }
  defer f.Close()

  uploadedFile, err := client.Files.New(context.TODO(), llamacloud.FileNewParams{
    File:    f,
    Purpose: "split",
  })
  if err != nil {
    log.Fatal(err)
  }

  fileID := uploadedFile.ID
  fmt.Printf("✅ File uploaded: %s\n", fileID)
}
import ai.llamaindex.llamacloud.client.LlamaCloudClient;
import ai.llamaindex.llamacloud.client.okhttp.LlamaCloudOkHttpClient;
import ai.llamaindex.llamacloud.models.files.FileCreateParams;
import ai.llamaindex.llamacloud.models.files.FileCreateResponse;
import java.nio.file.Paths;

LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();

FileCreateResponse uploadedFile = client.files().create(
    FileCreateParams.builder()
        .file(Paths.get("./data/turing+imagenet+attention.pdf"))
        .purpose("split")
        .build()
);

String fileId = uploadedFile.id();
System.out.println("✅ File uploaded: " + uploadedFile.id());

终端窗口

FILE_ID=$(llp files create \
  --file ./data/turing+imagenet+attention.pdf \
  --purpose split | jq -r '.id')
echo "✅ File uploaded: $FILE_ID"

第 2 步:创建 Split 任务

用类别定义创建一个 split 任务。每个类别需要一个 name 与一段 description,用来帮 AI 理解哪些内容属于这个类别:

  • Python
  • TypeScript
  • Go
  • Java
  • CLI
job = client.beta.split.create(
    document_input={
        "type": "file_id",
        "value": file_id,
    },
    configuration={
        "categories": [
            {
                "name": "essay",
                "description": "A philosophical or reflective piece of writing that presents personal viewpoints, arguments, or thoughts on a topic without strict formal structure",
            },
            {
                "name": "research_paper",
                "description": "A formal academic document presenting original research, methodology, experiments, results, and conclusions with citations and references",
            },
        ],
    },
)

print(f"✅ Split job created: {job.id}")
print(f"   Status: {job.status}")
const job = await client.beta.split.create({
  document_input: {
    type: "file_id",
    value: fileId,
  },
  configuration: {
    categories: [
      {
        name: "essay",
        description:
          "A philosophical or reflective piece of writing that presents personal viewpoints, arguments, or thoughts on a topic without strict formal structure",
      },
      {
        name: "research_paper",
        description:
          "A formal academic document presenting original research, methodology, experiments, results, and conclusions with citations and references",
      },
    ],
  },
});

console.log(`✅ Split job created: ${job.id}`);
console.log(`   Status: ${job.status}`);
job, err := client.Beta.Split.New(context.TODO(), llamacloud.BetaSplitNewParams{
  DocumentInput: llamacloud.SplitDocumentInputParam{
    Type:  "file_id",
    Value: fileID,
  },
  Configuration: llamacloud.BetaSplitNewParamsConfiguration{
    Categories: []llamacloud.SplitCategoryParam{
      {
        Name:        "essay",
        Description: llamacloud.String("A philosophical or reflective piece of writing that presents personal viewpoints, arguments, or thoughts on a topic without strict formal structure"),
      },
      {
        Name:        "research_paper",
        Description: llamacloud.String("A formal academic document presenting original research, methodology, experiments, results, and conclusions with citations and references"),
      },
    },
  },
})
if err != nil {
  log.Fatal(err)
}

fmt.Printf("✅ Split job created: %s\n", job.ID)
fmt.Printf("   Status: %s\n", job.Status)
import ai.llamaindex.llamacloud.models.beta.split.SplitCategory;
import ai.llamaindex.llamacloud.models.beta.split.SplitCreateParams;
import ai.llamaindex.llamacloud.models.beta.split.SplitCreateResponse;
import ai.llamaindex.llamacloud.models.beta.split.SplitDocumentInput;

SplitCreateResponse job = client.beta().split().create(
    SplitCreateParams.builder()
        .documentInput(
            SplitDocumentInput.builder()
                .type("file_id")
                .value(fileId)
                .build())
        .configuration(
            SplitCreateParams.Configuration.builder()
                .addCategory(
                    SplitCategory.builder()
                        .name("essay")
                        .description("A philosophical or reflective piece of writing that presents personal viewpoints, arguments, or thoughts on a topic without strict formal structure")
                        .build())
                .addCategory(
                    SplitCategory.builder()
                        .name("research_paper")
                        .description("A formal academic document presenting original research, methodology, experiments, results, and conclusions with citations and references")
                        .build())
                .build())
        .build()
);

System.out.println("✅ Split job created: " + job.id());
System.out.println("   Status: " + job.status());

终端窗口

JOB_ID=$(llp beta:split create \
  --document-input "{type: file_id, value: $FILE_ID}" \
  --configuration '{categories: [{name: essay, description: "A philosophical or reflective piece of writing that presents personal viewpoints, arguments, or thoughts on a topic without strict formal structure"}, {name: research_paper, description: "A formal academic document presenting original research, methodology, experiments, results, and conclusions with citations and references"}]}' | jq -r '.id')
echo "✅ Split job created: $JOB_ID"

第 3 步:轮询直到完成

split 任务是异步运行的。轮询直到它完成:

  • Python
  • TypeScript
  • Go
  • Java
  • CLI
completed_job = client.beta.split.wait_for_completion(job.id, polling_interval=2.0)
const completedJob = await client.beta.split.waitForCompletion(job.id, { pollingInterval: 2.0 });

Go SDK 没有等待辅助函数,因此要轮询 Get 直到任务进入终态:

completedJob, err := client.Beta.Split.Get(context.TODO(), job.ID, llamacloud.BetaSplitGetParams{})
if err != nil {
  log.Fatal(err)
}
for completedJob.Status != "completed" &&
  completedJob.Status != "failed" &&
  completedJob.Status != "cancelled" {
  time.Sleep(2 * time.Second)
  completedJob, err = client.Beta.Split.Get(context.TODO(), job.ID, llamacloud.BetaSplitGetParams{})
  if err != nil {
    log.Fatal(err)
  }
}

Java SDK 没有等待辅助函数,因此要轮询 get 直到任务进入终态:

import ai.llamaindex.llamacloud.models.beta.split.SplitGetResponse;

SplitGetResponse completedJob = client.beta().split().get(job.id());
while (!completedJob.status().equals("completed")
    && !completedJob.status().equals("failed")
    && !completedJob.status().equals("cancelled")) {
    Thread.sleep(2000);
    completedJob = client.beta().split().get(job.id());
}

CLI 没有等待辅助函数,因此要轮询 get 直到任务进入终态:

终端窗口

while true; do
  STATUS=$(llp beta:split get "$JOB_ID" | jq -er '.status') || break
  case "$STATUS" in
    completed|failed|cancelled) break ;;
  esac
  sleep 2
done

第 4 步:分析结果

查看切分结果:

  • Python
  • TypeScript
  • Go
  • Java
  • CLI
segments = completed_job.result.segments if completed_job.result else []

print(f"📊 Total segments found: {len(segments)}")

for i, segment in enumerate(segments, 1):
    category = segment.category
    pages = segment.pages
    confidence = segment.confidence_category

    if len(pages) == 1:
        page_range = f"Page {pages[0]}"
    else:
        page_range = f"Pages {min(pages)}-{max(pages)}"

    print(f"\nSegment {i}:")
    print(f"   Category: {category}")
    print(f"   {page_range} ({len(pages)} pages)")
    print(f"   Confidence: {confidence}")
const segments = completedJob.result?.segments || [];

console.log(`📊 Total segments found: ${segments.length}`);

segments.forEach((segment, index) => {
  const category = segment.category;
  const pages = segment.pages;
  const confidence = segment.confidence_category;

  const pageRange =
    pages.length === 1
      ? `Page ${pages[0]}`
      : `Pages ${Math.min(...pages)}-${Math.max(...pages)}`;

  console.log(`\nSegment ${index + 1}:`);
  console.log(`   Category: ${category}`);
  console.log(`   ${pageRange} (${pages.length} pages)`);
  console.log(`   Confidence: ${confidence}`);
});
segments := completedJob.Result.Segments

fmt.Printf("📊 Total segments found: %d\n", len(segments))

for i, segment := range segments {
  pages := segment.Pages

  var pageRange string
  if len(pages) == 1 {
    pageRange = fmt.Sprintf("Page %d", pages[0])
  } else if len(pages) > 0 {
    pageRange = fmt.Sprintf("Pages %d-%d", pages[0], pages[len(pages)-1])
  }

  fmt.Printf("\nSegment %d:\n", i+1)
  fmt.Printf("   Category: %s\n", segment.Category)
  fmt.Printf("   %s (%d pages)\n", pageRange, len(pages))
  fmt.Printf("   Confidence: %s\n", segment.ConfidenceCategory)
}
import ai.llamaindex.llamacloud.models.beta.split.SplitResultResponse;
import ai.llamaindex.llamacloud.models.beta.split.SplitSegmentResponse;
import java.util.Collections;
import java.util.List;

List<SplitSegmentResponse> segments = completedJob.result()
    .map(SplitResultResponse::segments)
    .orElse(Collections.emptyList());

System.out.println("📊 Total segments found: " + segments.size());

for (int i = 0; i < segments.size(); i++) {
    SplitSegmentResponse segment = segments.get(i);
    List<Long> pages = segment.pages();

    String pageRange = pages.size() == 1
        ? "Page " + pages.get(0)
        : !pages.isEmpty()
            ? "Pages " + pages.get(0) + "-" + pages.get(pages.size() - 1)
            : "";

    System.out.println("\nSegment " + (i + 1) + ":");
    System.out.println("   Category: " + segment.category());
    System.out.println("   " + pageRange + " (" + pages.size() + " pages)");
    System.out.println("   Confidence: " + segment.confidenceCategory());
}

终端窗口

llp beta:split get "$JOB_ID" \
  | jq -r 'if .status == "completed" then .result.segments[] | "Category: \(.category) | Pages: \(.pages | join(",")) | Confidence: \(.confidence_category)"
    else "Split job failed: \(.error_message // .)" end'

预期输出

📊 Total segments found: 3

Segment 1:
   Category: essay
   Pages 1-4 (4 pages)
   Confidence: high

Segment 2:
   Category: research_paper
   Pages 5-13 (9 pages)
   Confidence: high

Segment 3:
   Category: research_paper
   Pages 14-24 (11 pages)
   Confidence: high

Split API 正确识别出了:

  • 1 个 essay 段:Alan Turing 的 “Intelligent Machinery, A Heretical Theory”
  • 2 个 research paper 段:ImageNet 论文与 “Attention is All You Need”

控制未分类页

默认情况下,没有命中任何已定义类别的页会被归为 uncategorized。你可以用 allow_uncategorized 控制:

  • "include"(默认)—— 未命中任何类别的页会被归为 uncategorized 并包含在结果里
  • "forbid" —— 所有页都必须被分到已定义的类别中
  • "omit" —— 未命中任何类别的页不会出现在结果里
  • Python
  • TypeScript
  • Go
  • Java
  • CLI
# Exclude uncategorized pages from results
job = client.beta.split.create(
    ...,
    configuration={"categories": [...], "splitting_strategy": {"allow_uncategorized": "omit"}},
)

# Force all pages into defined categories
job = client.beta.split.create(
    ...,
    configuration={"categories": [...], "splitting_strategy": {"allow_uncategorized": "forbid"}},
)
// Exclude uncategorized pages from results
const job = await client.beta.split.create({
  ...,
  configuration: { categories: [...], splitting_strategy: { allow_uncategorized: "omit" } },
});

// Force all pages into defined categories
const job = await client.beta.split.create({
  ...,
  configuration: { categories: [...], splitting_strategy: { allow_uncategorized: "forbid" } },
});
// Exclude uncategorized pages from results
omitJob, err := client.Beta.Split.New(context.TODO(), llamacloud.BetaSplitNewParams{
  // ...
  Configuration: llamacloud.BetaSplitNewParamsConfiguration{
    // ...
    SplittingStrategy: llamacloud.BetaSplitNewParamsConfigurationSplittingStrategy{
      AllowUncategorized: "omit",
    },
  },
})

// Force all pages into defined categories
forbidJob, err := client.Beta.Split.New(context.TODO(), llamacloud.BetaSplitNewParams{
  // ...
  Configuration: llamacloud.BetaSplitNewParamsConfiguration{
    // ...
    SplittingStrategy: llamacloud.BetaSplitNewParamsConfigurationSplittingStrategy{
      AllowUncategorized: "forbid",
    },
  },
})
// Exclude uncategorized pages from results
SplitCreateResponse omitJob = client.beta().split().create(
    SplitCreateParams.builder()
        // ...
        .configuration(
            SplitCreateParams.Configuration.builder()
                // ...
                .splittingStrategy(
                    SplitCreateParams.Configuration.SplittingStrategy.builder()
                        .allowUncategorized(
                            SplitCreateParams.Configuration.SplittingStrategy.AllowUncategorized.OMIT)
                        .build())
                .build())
        .build()
);

// Force all pages into defined categories
SplitCreateResponse forbidJob = client.beta().split().create(
    SplitCreateParams.builder()
        // ...
        .configuration(
            SplitCreateParams.Configuration.builder()
                // ...
                .splittingStrategy(
                    SplitCreateParams.Configuration.SplittingStrategy.builder()
                        .allowUncategorized(
                            SplitCreateParams.Configuration.SplittingStrategy.AllowUncategorized.FORBID)
                        .build())
                .build())
        .build()
);

终端窗口

# Exclude uncategorized pages from results
llp beta:split create \
  --document-input "{type: file_id, value: $FILE_ID}" \
  --configuration '{categories: [...], splitting_strategy: {allow_uncategorized: omit}}'

# Force all pages into defined categories
llp beta:split create \
  --document-input "{type: file_id, value: $FILE_ID}" \
  --configuration '{categories: [...], splitting_strategy: {allow_uncategorized: forbid}}'

下一步

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。