主题
**expand 决定一次 Parse 任务往回返回什么。**默认情况下 API 只返回任务本身(状态、ID、错误信息),不含任何解析内容。你通过增加 expand 取值来按需取用,并且之后可以针对同一个任务换一组取值再取,无需重新解析。
本页说明 expand 的用法:全部取值、多数调用方常用的模式与限制。每个返回字段里有什么,见响应形态。
速查
内联内容
这些取值会把解析出的数据直接放在响应体里,不需要再下载。
| 取值 | 你能拿到什么 | 备注 |
|---|---|---|
markdown | 逐页的 Markdown | |
markdown_full | 整份文档作为一个 markdown 字符串 | |
text | 逐页的纯文本 | |
text_full | 整份文档作为一个纯文本字符串 | |
items | 逐页的结构化 items:表格、标题、图形、列表 | |
metadata | 逐页元数据:置信度、方向、水印、演讲者备注 | |
forms | 逐页的表单树(beta) | 仅设了 processing_options.forms: "enrich" 的任务;fast 上永无 |
job_metadata | 任务执行元数据:状态迁移与耗时 | |
usage | 计费的 credit,位于 job.usage 之下 | 见单个任务计费的 credit |
下载地址
这些取值不会返回内容本身,而是在 result_content_metadata 下给出一个预签名下载地址。当结果很大、你想先看它的大小、把它流式存起来,或者要取的是 XLSX、PDF 这类文件格式时就用它们。条目形态与各自对应什么文件,见下载地址。
| 取值 | 文件 | 备注 |
|---|---|---|
markdown_content_metadata | 逐页 markdown,JSON | |
markdown_full_content_metadata | 整份文档一个 .md | |
text_content_metadata | 逐页文本,JSON | |
text_full_content_metadata | 整份文档一个 .txt | |
items_content_metadata | items 树,JSON | |
metadata_content_metadata | 页元数据,JSON | |
forms_content_metadata | 表单,JSON | 仅设了 processing_options.forms: "enrich" 的任务 |
images_content_metadata | 已保存的图片,每张各有自己的 URL | 有哪些图片取决于 output_options.images_to_save |
xlsx_content_metadata | 表格作为一个工作簿 | 仅设了 tables_as_spreadsheet.enable: true 的任务 |
output_pdf_content_metadata | 渲染出的 PDF | 仅设了 output_options.save_output_pdf: true 的任务 |
raw_words_content_metadata | 词级边界框,JSONL | 仅设了 output_options.additional_outputs: ["word_bbox"] 的任务 |
result_content_metadata.grounded_items | grounded items 边车文件,JSONL | 设了 granular_bboxes 时自动包含;expand 里无需添加任何东西 |
每个取值在所有档位上都可用,只有两点例外:forms 需要表单分析这一轮,而 fast 档不跑它;固定在 2026-06-15 之前版本的 fast 任务则完全没有 markdown 与 items。见限制。
常见模式
下面的 SDK 片段都基于这套 setup 建立的 client 与已上传的 file;安装步骤见快速上手。逐页结果里可能存在失败的页("success": false)且没有内容字段,因此循环里会先检查 success 再读取;见页数组。
先下载一份样例 PDF —— 财政服务局的 FY2024 执行摘要,存为 doc.pdf:
终端窗口
curl -fL -o doc.pdf https://fiscal.treasury.gov/system/files/files/reports-statements/financial-report/2024/executive-summary-2024.pdf- Python
- TypeScript
- Go
- Java
- CLI
from llama_cloud import LlamaCloud
client = LlamaCloud() # reads LLAMA_CLOUD_API_KEY from the environment
file = client.files.create(file="doc.pdf", purpose="parse")import LlamaCloud from "@llamaindex/llama-cloud";
import fs from "fs";
const client = new LlamaCloud(); // reads LLAMA_CLOUD_API_KEY from the environment
const file = await client.files.create({
file: fs.createReadStream("doc.pdf"),
purpose: "parse",
});package main
import (
"context"
"fmt"
"log"
"os"
"strings"
"time"
llamacloud "github.com/run-llama/llama-parse-go"
)
func main() {
ctx := context.Background()
client := llamacloud.NewClient() // reads LLAMA_CLOUD_API_KEY from the environment
f, err := os.Open("doc.pdf")
if err != nil {
log.Fatal(err)
}
defer f.Close()
file, err := client.Files.New(ctx, llamacloud.FileNewParams{
File: f,
Purpose: "parse",
})
if err != nil {
log.Fatal(err)
}
// ... a snippet below goes here, using ctx, client, and file ...
// Go rejects unused imports: drop "strings" if your snippet doesn't call it.
_ = file
}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 ai.llamaindex.llamacloud.models.parsing.ParsingCreateParams;
import ai.llamaindex.llamacloud.models.parsing.ParsingCreateResponse;
import ai.llamaindex.llamacloud.models.parsing.ParsingGetParams;
import ai.llamaindex.llamacloud.models.parsing.ParsingGetResponse;
import java.nio.file.Paths;
import java.util.stream.Collectors;
LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();
FileCreateResponse file = client.files().create(FileCreateParams.builder()
.file(Paths.get("doc.pdf"))
.purpose("parse")
.build());终端窗口
# llp reads LLAMA_CLOUD_API_KEY from the environment
FILE_ID=$(llp files create --file doc.pdf --purpose parse | jq -r '.id')只要 markdown
最简单的模式。多数 LLM 流水线只需要这个。
- Python
- TypeScript
- Go
- Java
- CLI
result = client.parsing.parse(
file_id=file.id,
tier="agentic",
version="latest",
expand=["markdown"],
)
for page in result.markdown.pages:
if page.success:
print(page.markdown)const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
expand: ["markdown"],
});
for (const page of result.markdown?.pages ?? []) {
if (page.success) {
console.log(page.markdown);
}
}// expand is a GET parameter in Go, so create the job, poll, then request markdown
job, err := client.Parsing.New(ctx, llamacloud.ParsingNewParams{
FileID: llamacloud.String(file.ID),
Tier: llamacloud.ParsingNewParamsTierAgentic,
Version: llamacloud.ParsingNewParamsVersionLatest,
})
if err != nil {
log.Fatal(err)
}
getParams := llamacloud.ParsingGetParams{Expand: []string{"markdown"}}
result, err := client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
for result.Job.Status != "COMPLETED" && result.Job.Status != "FAILED" && result.Job.Status != "CANCELLED" {
time.Sleep(2 * time.Second)
result, err = client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
}
if result.Job.Status != "COMPLETED" {
log.Fatalf("parse ended as %s", result.Job.Status)
}
for _, page := range result.Markdown.Pages {
if page.Success {
fmt.Println(page.Markdown)
}
}// expand is a query parameter in Java, so create the job, poll, then request markdown
ParsingCreateResponse job = client.parsing().create(ParsingCreateParams.builder()
.fileId(file.id())
.tier(ParsingCreateParams.Tier.AGENTIC)
.version(ParsingCreateParams.Version.LATEST)
.build());
ParsingGetParams getParams = ParsingGetParams.builder()
.jobId(job.id())
.addExpand("markdown")
.build();
ParsingGetResponse result = client.parsing().get(getParams);
while (!result.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.FAILED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.CANCELLED)) {
Thread.sleep(2000);
result = client.parsing().get(getParams);
}
if (!result.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)) {
throw new RuntimeException("parse ended as " + result.job().status());
}
for (ParsingGetResponse.Markdown.Page page : result.markdown().get().pages()) {
if (page.isMarkdownResult()) {
System.out.println(page.asMarkdownResult().markdown());
}
}终端窗口
JOB_ID=$(llp parsing create \
--file-id "$FILE_ID" \
--tier agentic \
--version latest \
| jq -r '.id')
# Poll until the job reaches a terminal status
while true; do
STATUS=$(llp parsing get --job-id "$JOB_ID" | jq -er '.job.status') || break
case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
sleep 2
done
# expand is a query parameter — request markdown when you fetch the result
llp parsing get --job-id "$JOB_ID" --expand markdown \
| jq -r 'if .job.status == "COMPLETED" then .markdown.pages[] | select(.success) | .markdown
else "Parse job failed: \(.job.error_message // .)" end'不需要逐页的 markdown?
如果你只想要整份文档的一个字符串,改用 expand=["markdown_full"]:它直接返回 result.markdown_full,省掉逐页循环。
markdown 加结构化 items 树
适合需要在程序里访问表格、标题与图形的流水线。items 里每个元素本就带一个 md 字段,所以只靠 items 也能拼出 LLM 的输入;但同时请求 markdown 能让你直接拿到现成的逐页 markdown 字符串,不必自己重组。
- Python
- TypeScript
- Go
- Java
- CLI
result = client.parsing.parse(
file_id=file.id,
tier="agentic",
version="latest",
expand=["markdown", "items"],
)
# Per-page markdown for the LLM (or use markdown_full for a single string)
llm_input = "\n\n".join(p.markdown for p in result.markdown.pages if p.success)
# Walk the items tree for tables
for page in result.items.pages:
if not page.success:
continue
for item in page.items:
if item.type == "table":
print(f"Table on page {page.page_number}: {len(item.rows)} rows")const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
expand: ["markdown", "items"],
});
// Per-page markdown for the LLM (or use markdown_full for a single string)
const llmInput = (result.markdown?.pages ?? [])
.filter((p) => p.success)
.map((p) => p.markdown)
.join("\n\n");
// Walk the items tree for tables
for (const page of result.items?.pages ?? []) {
if (!page.success) continue;
for (const item of page.items) {
if (item.type === "table") {
console.log(`Table on page ${page.page_number}: ${item.rows.length} rows`);
}
}
}job, err := client.Parsing.New(ctx, llamacloud.ParsingNewParams{
FileID: llamacloud.String(file.ID),
Tier: llamacloud.ParsingNewParamsTierAgentic,
Version: llamacloud.ParsingNewParamsVersionLatest,
})
if err != nil {
log.Fatal(err)
}
// expand is a GET parameter — request markdown and items when you fetch the result
getParams := llamacloud.ParsingGetParams{Expand: []string{"markdown", "items"}}
result, err := client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
for result.Job.Status != "COMPLETED" && result.Job.Status != "FAILED" && result.Job.Status != "CANCELLED" {
time.Sleep(2 * time.Second)
result, err = client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
}
if result.Job.Status != "COMPLETED" {
log.Fatalf("parse ended as %s", result.Job.Status)
}
// Per-page markdown for the LLM (or use markdown_full for a single string)
var pages []string
for _, page := range result.Markdown.Pages {
if page.Success {
pages = append(pages, page.Markdown)
}
}
llmInput := strings.Join(pages, "\n\n")
_ = llmInput // feed to your LLM
// Walk the items tree for tables
for _, page := range result.Items.Pages {
if !page.Success {
continue
}
for _, item := range page.Items {
if item.Type == "table" {
fmt.Printf("Table on page %d: %d rows\n", page.PageNumber, len(item.Rows))
}
}
}ParsingCreateResponse job = client.parsing().create(ParsingCreateParams.builder()
.fileId(file.id())
.tier(ParsingCreateParams.Tier.AGENTIC)
.version(ParsingCreateParams.Version.LATEST)
.build());
// expand is a query parameter — request markdown and items when you fetch the result
ParsingGetParams getParams = ParsingGetParams.builder()
.jobId(job.id())
.addExpand("markdown")
.addExpand("items")
.build();
ParsingGetResponse result = client.parsing().get(getParams);
while (!result.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.FAILED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.CANCELLED)) {
Thread.sleep(2000);
result = client.parsing().get(getParams);
}
if (!result.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)) {
throw new RuntimeException("parse ended as " + result.job().status());
}
// Per-page markdown for the LLM (or use markdown_full for a single string)
StringBuilder llmInput = new StringBuilder();
for (ParsingGetResponse.Markdown.Page page : result.markdown().get().pages()) {
if (!page.isMarkdownResult()) {
continue;
}
if (llmInput.length() > 0) {
llmInput.append("\n\n");
}
llmInput.append(page.asMarkdownResult().markdown());
}
// Walk the items tree for tables
for (ParsingGetResponse.Items.Page page : result.items().get().pages()) {
if (!page.isStructuredResult()) {
continue;
}
ParsingGetResponse.Items.Page.StructuredResultPage structured = page.asStructuredResult();
for (ParsingGetResponse.Items.Page.StructuredResultPage.Item item : structured.items()) {
if (item.isTable()) {
System.out.printf("Table on page %d: %d rows%n",
structured.pageNumber(), item.asTable().rows().size());
}
}
}终端窗口
JOB_ID=$(llp parsing create \
--file-id "$FILE_ID" \
--tier agentic \
--version latest \
| jq -r '.id')
# Poll until the job reaches a terminal status
while true; do
STATUS=$(llp parsing get --job-id "$JOB_ID" | jq -er '.job.status') || break
case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
sleep 2
done
# expand is a query parameter — request markdown and items when you fetch the result
RESULT=$(llp parsing get --job-id "$JOB_ID" --expand markdown --expand items)
if printf '%s\n' "$RESULT" | jq -e '.job.status == "COMPLETED"' >/dev/null; then
# Per-page markdown for the LLM (or use markdown_full for a single string)
printf '%s\n' "$RESULT" | jq -r '[.markdown.pages[] | select(.success) | .markdown] | join("\n\n")'
# Walk the items tree for tables
printf '%s\n' "$RESULT" | jq -r '
.items.pages[]
| select(.success)
| .page_number as $page
| .items[]
| select(.type == "table")
| "Table on page \($page): \(.rows | length) rows"'
else
printf '%s\n' "$RESULT" | jq -r '"Parse job failed: \(.job.error_message // .)"' >&2
fi完整 markdown 加预签名图片地址
适合多模态流水线 —— 要一整块 markdown,同时把各页截图作为可单独下载的图像。
- Python
- TypeScript
- Go
- Java
- CLI
result = client.parsing.parse(
file_id=file.id,
tier="agentic_plus",
version="latest",
output_options={"images_to_save": ["screenshot"]},
expand=["markdown_full", "images_content_metadata"],
)
# One big markdown blob for the LLM
print(result.markdown_full)
# Each page screenshot as a downloadable URL
for image in result.images_content_metadata.images:
print(f"{image.filename}: {image.presigned_url}")const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic_plus",
version: "latest",
output_options: { images_to_save: ["screenshot"] },
expand: ["markdown_full", "images_content_metadata"],
});
console.log(result.markdown_full);
for (const image of result.images_content_metadata?.images ?? []) {
console.log(`${image.filename}: ${image.presigned_url}`);
}job, err := client.Parsing.New(ctx, llamacloud.ParsingNewParams{
FileID: llamacloud.String(file.ID),
Tier: llamacloud.ParsingNewParamsTierAgenticPlus,
Version: llamacloud.ParsingNewParamsVersionLatest,
OutputOptions: llamacloud.ParsingNewParamsOutputOptions{
ImagesToSave: []string{"screenshot"},
},
})
if err != nil {
log.Fatal(err)
}
// Request the full markdown blob and the per-image download URLs on the result
getParams := llamacloud.ParsingGetParams{Expand: []string{"markdown_full", "images_content_metadata"}}
result, err := client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
for result.Job.Status != "COMPLETED" && result.Job.Status != "FAILED" && result.Job.Status != "CANCELLED" {
time.Sleep(2 * time.Second)
result, err = client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
}
// One big markdown blob for the LLM
fmt.Println(result.MarkdownFull)
// Each page screenshot as a downloadable URL
for _, image := range result.ImagesContentMetadata.Images {
fmt.Printf("%s: %s\n", image.Filename, image.PresignedURL)
}ParsingCreateResponse job = client.parsing().create(ParsingCreateParams.builder()
.fileId(file.id())
.tier(ParsingCreateParams.Tier.AGENTIC_PLUS)
.version(ParsingCreateParams.Version.LATEST)
.outputOptions(ParsingCreateParams.OutputOptions.builder()
.addImagesToSave(ParsingCreateParams.OutputOptions.ImagesToSave.SCREENSHOT)
.build())
.build());
// Request the full markdown blob and the per-image download URLs on the result
ParsingGetParams getParams = ParsingGetParams.builder()
.jobId(job.id())
.addExpand("markdown_full")
.addExpand("images_content_metadata")
.build();
ParsingGetResponse result = client.parsing().get(getParams);
while (!result.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.FAILED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.CANCELLED)) {
Thread.sleep(2000);
result = client.parsing().get(getParams);
}
// One big markdown blob for the LLM
System.out.println(result.markdownFull().orElse(""));
// Each page screenshot as a downloadable URL
for (ParsingGetResponse.ImagesContentMetadata.Image image : result.imagesContentMetadata().get().images()) {
System.out.println(image.filename() + ": " + image.presignedUrl().orElse(""));
}终端窗口
JOB_ID=$(llp parsing create \
--file-id "$FILE_ID" \
--tier agentic_plus \
--version latest \
--output-options.images-to-save '[screenshot]' \
| jq -r '.id')
# Poll until the job reaches a terminal status
while true; do
STATUS=$(llp parsing get --job-id "$JOB_ID" | jq -er '.job.status') || break
case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
sleep 2
done
RESULT=$(llp parsing get --job-id "$JOB_ID" \
--expand markdown_full \
--expand images_content_metadata)
if printf '%s\n' "$RESULT" | jq -e '.job.status == "COMPLETED"' >/dev/null; then
# One big markdown blob for the LLM
printf '%s\n' "$RESULT" | jq -r '.markdown_full'
# Each page screenshot as a downloadable URL
printf '%s\n' "$RESULT" | jq -r '.images_content_metadata.images[] | "\(.filename): \(.presigned_url)"'
else
printf '%s\n' "$RESULT" | jq -r '"Parse job failed: \(.job.error_message // .)"' >&2
fi按页把多种表示拼起来
每一种逐页表示都带 page_number,于是你可以把同一页的 markdown、items 与 metadata 对齐。请按页号建查找表,而不是把数组按下标 zip —— 因为失败的页仍会出现在每个数组里,只是没有内容。
- Python
- TypeScript
result = client.parsing.parse(
file_id=file.id,
tier="agentic",
version="latest",
expand=["markdown", "items", "metadata"],
)
confidence = {m.page_number: m.confidence for m in result.metadata.pages}
items_by_page = {p.page_number: p.items for p in result.items.pages if p.success}
for page in result.markdown.pages:
if not page.success:
print(f"page {page.page_number} failed: {page.error}")
continue
n_items = len(items_by_page.get(page.page_number, []))
print(page.page_number, confidence.get(page.page_number), n_items, "items")const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
expand: ["markdown", "items", "metadata"],
});
const confidence = new Map(
(result.metadata?.pages ?? []).map((m) => [m.page_number, m.confidence]),
);
const itemsByPage = new Map(
(result.items?.pages ?? []).flatMap((p) => (p.success ? [[p.page_number, p.items] as const] : [])),
);
for (const page of result.markdown?.pages ?? []) {
if (!page.success) {
console.log(`page ${page.page_number} failed: ${page.error}`);
continue;
}
const nItems = itemsByPage.get(page.page_number)?.length ?? 0;
console.log(page.page_number, confidence.get(page.page_number), nItems, "items");
}任务跑完之后再取结果
你不必在解析时就把自己可能需要的一切都要过来。可以先用一组 expand 取值跑任务,之后再用另一组取值调 get,无需重跑任务。
这正是下列场景该用的模式:
- **你还不确定要什么。**先用
expand=["markdown"]跑,后来发现还要 items 树,就针对同一个任务 ID 再用expand=["items"]取。这比重新解析便宜。 - **你在处理大文件。**先用
expand=["markdown_content_metadata"]看size_bytes,再决定要不要下载。 - **你要在早前解析过的任务上继续工作。**传入旧的任务 ID 与一份
expand列表,就能取回该任务产出的任何一种表示。
本节每个片段都会自己建 client 并上传 doc.pdf,因此不使用上面的 setup。若你跳过了 setup,请先下载这份样例 PDF:
终端窗口
curl -fL -o doc.pdf https://fiscal.treasury.gov/system/files/files/reports-statements/financial-report/2024/executive-summary-2024.pdf- Python
- TypeScript
- Go
- Java
- CLI
from llama_cloud import LlamaCloud
client = LlamaCloud() # reads LLAMA_CLOUD_API_KEY from the environment
# Step 1: run a Parse job with a minimal expand
result = client.parsing.parse(
upload_file="doc.pdf",
tier="cost_effective",
version="latest",
expand=["markdown_full"],
)
print(result.job.status)
print(result.markdown_full)
# Step 2: later, retrieve the text representation of the same job
text_result = client.parsing.get(
job_id=result.job.id,
expand=["text_full"],
)
print(text_result.text_full)import fs from "fs";
import { LlamaCloud } from "@llamaindex/llama-cloud";
const client = new LlamaCloud(); // reads LLAMA_CLOUD_API_KEY from the environment
// Step 1: run a Parse job with a minimal expand
const result = await client.parsing.parse({
upload_file: fs.createReadStream("doc.pdf"),
tier: "cost_effective",
version: "latest",
expand: ["markdown_full"],
});
console.log(result.job.status);
console.log(result.markdown_full);
// Step 2: later, retrieve the text representation of the same job
const textResult = await client.parsing.get(result.job.id, { expand: ["text_full"] });
console.log(textResult.text_full);package main
import (
"context"
"fmt"
"log"
"os"
"time"
llamacloud "github.com/run-llama/llama-parse-go"
)
func main() {
ctx := context.Background()
client := llamacloud.NewClient() // reads LLAMA_CLOUD_API_KEY from the environment
// Step 1: upload the file and run a Parse job with a minimal expand
f, err := os.Open("doc.pdf")
if err != nil {
log.Fatal(err)
}
defer f.Close()
file, err := client.Files.New(ctx, llamacloud.FileNewParams{File: f, Purpose: "parse"})
if err != nil {
log.Fatal(err)
}
job, err := client.Parsing.New(ctx, llamacloud.ParsingNewParams{
FileID: llamacloud.String(file.ID),
Tier: llamacloud.ParsingNewParamsTierCostEffective,
Version: llamacloud.ParsingNewParamsVersionLatest,
})
if err != nil {
log.Fatal(err)
}
// expand is a GET parameter — request markdown_full when you poll for the result
getParams := llamacloud.ParsingGetParams{Expand: []string{"markdown_full"}}
result, err := client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
for result.Job.Status != "COMPLETED" && result.Job.Status != "FAILED" && result.Job.Status != "CANCELLED" {
time.Sleep(2 * time.Second)
result, err = client.Parsing.Get(ctx, job.ID, getParams)
if err != nil {
log.Fatal(err)
}
}
fmt.Println(result.Job.Status)
fmt.Println(result.MarkdownFull)
// Step 2: later, retrieve the text representation of the same job
textResult, err := client.Parsing.Get(ctx, job.ID, llamacloud.ParsingGetParams{
Expand: []string{"text_full"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(textResult.TextFull)
}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 ai.llamaindex.llamacloud.models.parsing.ParsingCreateParams;
import ai.llamaindex.llamacloud.models.parsing.ParsingCreateResponse;
import ai.llamaindex.llamacloud.models.parsing.ParsingGetParams;
import ai.llamaindex.llamacloud.models.parsing.ParsingGetResponse;
import java.nio.file.Paths;
LlamaCloudClient client = LlamaCloudOkHttpClient.fromEnv();
// Step 1: upload the file and run a Parse job with a minimal expand
FileCreateResponse file = client.files().create(FileCreateParams.builder()
.file(Paths.get("doc.pdf"))
.purpose("parse")
.build());
ParsingCreateResponse job = client.parsing().create(ParsingCreateParams.builder()
.fileId(file.id())
.tier(ParsingCreateParams.Tier.COST_EFFECTIVE)
.version(ParsingCreateParams.Version.LATEST)
.build());
// expand is a query parameter — request markdown_full when you poll for the result
ParsingGetParams markdownParams = ParsingGetParams.builder()
.jobId(job.id())
.addExpand("markdown_full")
.build();
ParsingGetResponse result = client.parsing().get(markdownParams);
while (!result.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.FAILED)
&& !result.job().status().equals(ParsingGetResponse.Job.Status.CANCELLED)) {
Thread.sleep(2000);
result = client.parsing().get(markdownParams);
}
System.out.println(result.job().status());
System.out.println(result.markdownFull().orElse(""));
// Step 2: later, retrieve the text representation of the same job
ParsingGetResponse textResult = client.parsing().get(ParsingGetParams.builder()
.jobId(job.id())
.addExpand("text_full")
.build());
System.out.println(textResult.textFull().orElse(""));终端窗口
# Step 1: upload the file and run a Parse job with a minimal expand
FILE_ID=$(llp files create --file doc.pdf --purpose parse | jq -r '.id')
JOB_ID=$(llp parsing create \
--file-id "$FILE_ID" \
--tier cost_effective \
--version latest \
| jq -r '.id')
# Poll until the job reaches a terminal status
while true; do
STATUS=$(llp parsing get --job-id "$JOB_ID" | jq -er '.job.status') || break
case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
sleep 2
done
# expand is a query parameter — request markdown_full when you fetch the result
llp parsing get --job-id "$JOB_ID" --expand markdown_full | jq -r 'if .job.status == "COMPLETED" then .markdown_full
else "Parse job failed: \(.job.error_message // .)" end'
# Step 2: later, retrieve the text representation of the same job
llp parsing get --job-id "$JOB_ID" --expand text_full | jq -r 'if .job.status == "COMPLETED" then .text_full
else "Parse job failed: \(.job.error_message // .)" end'取特定图片
images_content_metadata 会返回全部已保存的图片。只想取其中一部分时,把文件名放进 image_filenames 传入;这些名字来自先前的一次完整列举,或来自 items 树里的 image 条目。REST 侧的参数是一个逗号分隔的字符串。
下面的片段会为 setup 里那个 file 保存逐页截图、列出所有已保存的图片,然后按名字取回前两张。
- Python
- TypeScript
- Go
- Java
- CLI
full = client.parsing.parse(
file_id=file.id,
tier="agentic",
version="latest",
output_options={"images_to_save": ["screenshot"]},
expand=["images_content_metadata"],
)
names = [image.filename for image in full.images_content_metadata.images]
result = client.parsing.get(
job_id=full.job.id,
expand=["images_content_metadata"],
image_filenames=",".join(names[:2]),
)
for image in result.images_content_metadata.images:
print(f"{image.filename}: {image.presigned_url}")const full = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
output_options: { images_to_save: ["screenshot"] },
expand: ["images_content_metadata"],
});
const names = (full.images_content_metadata?.images ?? []).map((image) => image.filename);
const result = await client.parsing.get(full.job.id, {
expand: ["images_content_metadata"],
image_filenames: names.slice(0, 2).join(","),
});
for (const image of result.images_content_metadata?.images ?? []) {
console.log(`${image.filename}: ${image.presigned_url}`);
}job, err := client.Parsing.New(ctx, llamacloud.ParsingNewParams{
FileID: llamacloud.String(file.ID),
Tier: llamacloud.ParsingNewParamsTierAgentic,
Version: llamacloud.ParsingNewParamsVersionLatest,
OutputOptions: llamacloud.ParsingNewParamsOutputOptions{
ImagesToSave: []string{"screenshot"},
},
})
if err != nil {
log.Fatal(err)
}
// Poll with the full image listing, then collect the file names
listParams := llamacloud.ParsingGetParams{Expand: []string{"images_content_metadata"}}
full, err := client.Parsing.Get(ctx, job.ID, listParams)
if err != nil {
log.Fatal(err)
}
for full.Job.Status != "COMPLETED" && full.Job.Status != "FAILED" && full.Job.Status != "CANCELLED" {
time.Sleep(2 * time.Second)
full, err = client.Parsing.Get(ctx, job.ID, listParams)
if err != nil {
log.Fatal(err)
}
}
if full.Job.Status != "COMPLETED" {
log.Fatalf("parse ended as %s", full.Job.Status)
}
var names []string
for _, image := range full.ImagesContentMetadata.Images {
names = append(names, image.Filename)
}
result, err := client.Parsing.Get(ctx, job.ID, llamacloud.ParsingGetParams{
Expand: []string{"images_content_metadata"},
ImageFilenames: llamacloud.String(strings.Join(names[:min(2, len(names))], ",")),
})
if err != nil {
log.Fatal(err)
}
for _, image := range result.ImagesContentMetadata.Images {
fmt.Printf("%s: %s\n", image.Filename, image.PresignedURL)
}ParsingCreateResponse job = client.parsing().create(ParsingCreateParams.builder()
.fileId(file.id())
.tier(ParsingCreateParams.Tier.AGENTIC)
.version(ParsingCreateParams.Version.LATEST)
.outputOptions(ParsingCreateParams.OutputOptions.builder()
.addImagesToSave(ParsingCreateParams.OutputOptions.ImagesToSave.SCREENSHOT)
.build())
.build());
// Poll with the full image listing, then join the first two file names
ParsingGetParams listParams = ParsingGetParams.builder()
.jobId(job.id())
.addExpand("images_content_metadata")
.build();
ParsingGetResponse full = client.parsing().get(listParams);
while (!full.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)
&& !full.job().status().equals(ParsingGetResponse.Job.Status.FAILED)
&& !full.job().status().equals(ParsingGetResponse.Job.Status.CANCELLED)) {
Thread.sleep(2000);
full = client.parsing().get(listParams);
}
if (!full.job().status().equals(ParsingGetResponse.Job.Status.COMPLETED)) {
throw new RuntimeException("parse ended as " + full.job().status());
}
String names = full.imagesContentMetadata().get().images().stream()
.limit(2)
.map(ParsingGetResponse.ImagesContentMetadata.Image::filename)
.collect(Collectors.joining(","));
ParsingGetResponse result = client.parsing().get(ParsingGetParams.builder()
.jobId(job.id())
.addExpand("images_content_metadata")
.imageFilenames(names)
.build());
for (ParsingGetResponse.ImagesContentMetadata.Image image : result.imagesContentMetadata().get().images()) {
System.out.println(image.filename() + ": " + image.presignedUrl().orElse(""));
}终端窗口
JOB_ID=$(llp parsing create \
--file-id "$FILE_ID" \
--tier agentic \
--version latest \
--output-options.images-to-save '[screenshot]' \
| jq -r '.id')
# Poll until the job reaches a terminal status; stop if the lookup itself fails
while true; do
STATUS=$(llp parsing get --job-id "$JOB_ID" | jq -er '.job.status') || break
case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
sleep 2
done
if [ "$STATUS" = COMPLETED ]; then
# List every saved image and keep the first two file names
NAMES=$(llp parsing get --job-id "$JOB_ID" --expand images_content_metadata \
| jq -r '[.images_content_metadata.images[:2][].filename] | join(",")')
llp parsing get --job-id "$JOB_ID" \
--expand images_content_metadata \
--image-filenames "$NAMES" \
| jq -r '.images_content_metadata.images[] | "\(.filename): \(.presigned_url)"'
else
llp parsing get --job-id "$JOB_ID" | jq -r '"Parse job failed: \(.job.error_message // .)"' >&2
fi单个任务计费的额度
expand=usage 返回某个 Parse 任务计费的 credit,位置在 job.usage 而不是顶层。它可以和内容类取值组合:expand=markdown,usage 两者都返回。
下面的片段会在 setup 的那个 file 上跑一个任务,然后取回它的 credit。
- Python
- TypeScript
- CLI
import time
result = client.parsing.parse(
file_id=file.id,
tier="agentic",
version="latest",
expand=["usage"],
)
# Billing can trail completion, so fetch again until credits are recorded
for _ in range(10):
if result.job.usage and result.job.usage.credits is not None:
break
time.sleep(3)
result = client.parsing.get(job_id=result.job.id, expand=["usage"])
print(result.job.usage.credits if result.job.usage else None)let result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
expand: ["usage"],
});
// Billing can trail completion, so fetch again until credits are recorded
for (let attempt = 0; attempt < 10 && result.job.usage?.credits == null; attempt++) {
await new Promise((resolve) => setTimeout(resolve, 3000));
result = await client.parsing.get(result.job.id, { expand: ["usage"] });
}
console.log(result.job.usage?.credits);终端窗口
JOB_ID=$(llp parsing create \
--file-id "$FILE_ID" \
--tier agentic \
--version latest \
| jq -r '.id')
# Poll until the job reaches a terminal status; stop if the lookup itself fails
while true; do
STATUS=$(llp parsing get --job-id "$JOB_ID" | jq -er '.job.status') || break
case "$STATUS" in COMPLETED|FAILED|CANCELLED) break ;; esac
sleep 2
done
if [ "$STATUS" = COMPLETED ]; then
# Billing can trail completion, so fetch again until credits are recorded
for _ in 1 2 3 4 5 6 7 8 9 10; do
CREDITS=$(llp parsing get --job-id "$JOB_ID" --expand usage | jq -e '.job.usage.credits') && break
sleep 3
done
echo "$CREDITS"
else
llp parsing get --job-id "$JOB_ID" | jq -r '"Parse job failed: \(.job.error_message // .)"' >&2
fi{
"job": {
"id": "JOB_ID",
"status": "COMPLETED",
"usage": {
"credits": 30.0
}
}
}注意
计费可能滞后于任务完成一小段时间。credits: null 表示还没记录下来,此时请再次拉取,而不是把它当作零。
限制
Fast 档
当前的 fast 版本和其他档位一样会返回 markdown 与 items。只有固定在 2026-06-15 之前版本的 fast 任务是纯文本的:对那种任务 expand=markdown 会被拒绝并返回 400,提示信息形如 "Markdown expansion is not available for FAST tier jobs on version ...",而 items 会返回 null。把 version: "latest" 或当前的 fast 版本固定下来即可避免。
fast 档不跑表单分析。在 fast 档任务上请求 processing_options.forms: "enrich" 会返回校验错误,因此 forms 与 forms_content_metadata 只存在于 cost_effective 及以上档位的任务里。各档产出什么的完整清单见档位。
预签名地址的有效期
预签名 URL 会在有限时间后失效。请在取到后尽快下载,或者用同样的 expand 再调一次 get 以换取新地址。