主题
本教程演示如何在一个 Node.js 的 TypeScript 脚本里用 Parse 解析 PDF —— 安装 SDK、设置 API key、跑解析、遍历 markdown 输出。它是快速上手:解析 PDF 并理解输出 那份 Python 教程的 TypeScript 对应版本,也是你在 Node 里做服务端或 CLI 式集成时推荐的起点。
什么时候用 TypeScript
Parse 的 SDK 在 Python 与 TypeScript 里行为一致 —— 同样的档位体系、同样的选项分组、同样的响应形态。在这些情况下选 TypeScript:
- 你要把 Parse 集成进 Node.js 或 Bun 服务、Edge 函数,或一个要作为包分发的 CLI 工具
- 你的团队已经在用 TS,希望全栈只用一种语言
- 你要把 Parse 接到 Next.js、Astro 或其他以 JS 为先的框架里
如果你只是在 notebook 里做原型,Python 教程 是更快的路径。到了要交付的时候,这些模式可以干净地平移过去。
1. 建好项目
初始化一个新项目(已有就跳过):
终端窗口
mkdir parse-tutorial && cd parse-tutorial
npm init -y安装 SDK 与 tsx(一个 TypeScript 运行器,支持包括顶层 await 在内的现代 ESM 语法):
终端窗口
npm install @llamaindex/llama-cloud
npm install --save-dev tsx typescript @types/node把 Parse 的 API key 设成环境变量,SDK 会自动读取:
终端窗口
export LLAMA_CLOUD_API_KEY="llx-..."还没有 key 的话,到 LlamaCloud 控制台去取一把 API key。
2. 下载一份样例 PDF
本教程要解析的是 LLaMA 论文 —— 一份公开的研究论文,它的多栏版式、表格与插图正好能体现 Parse 的强项。
终端窗口
curl -fL -o llama.pdf https://arxiv.org/pdf/2302.13971.pdf用任何 PDF 都行 —— 把下面脚本里的路径换掉即可。
3. 写解析脚本
新建 parse.ts,只写最小必要的部分:上传、解析、把 markdown 打出来。
import LlamaCloud from "@llamaindex/llama-cloud";
import fs from "fs";
const client = new LlamaCloud(); // reads LLAMA_CLOUD_API_KEY from the environment
console.log("Uploading file...");
const file = await client.files.create({
file: fs.createReadStream("./llama.pdf"),
purpose: "parse",
});
console.log(`Uploaded file ${file.id}, parsing...`);
const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
expand: ["markdown"],
});
console.log(`Job status: ${result.job.status}`);
console.log(`Total pages: ${result.markdown.pages.length}`);
console.log("\n--- First page markdown ---\n");
console.log(result.markdown.pages[0].markdown);有几点值得注意:
new LlamaCloud()会从环境里读LLAMA_CLOUD_API_KEY—— 你不必显式传入。真想传的话,用new LlamaCloud({ apiKey: "llx-..." })。client.parsing.parse()会阻塞到任务结束并返回完整结果。 SDK 替你处理了轮询。若你直连原始 REST API,就得自己轮询 —— 见快速上手里的 REST API 标签页。- 顶层
await在这里能用,是因为tsx把文件当 ES 模块跑。若你的目标是 CommonJS(package.json里写"type": "commonjs"),把主体包进一个async function main()再调用main()。
4. 运行它
终端窗口
npx tsx parse.ts你应当能看到上传、解析任务运行,以及 LLaMA 论文第一页被打印成 markdown —— 标题、作者栏、摘要、章节标题,全都作为规范的 markdown 结构保留了下来。
5. 遍历每一页
上面那个极简脚本只打印第一页。要处理整份文档,就遍历 result.markdown.pages:
for (const page of result.markdown.pages) {
console.log(`\n=== Page ${page.page_number} ===\n`);
console.log(page.markdown);
}或者把整份文档拼成一个 markdown 字符串,直接送进 LLM 提示词:
const fullDocument = result.markdown.pages
.map((p) => p.markdown)
.join("\n\n---\n\n");
console.log(`Full document is ${fullDocument.length} characters.`);
// fullDocument is now ready to feed into your LLM6. 不止要 markdown
expand 数组决定响应里返回什么。想要结构化树(表格、标题、图形)就要 items,想要逐页纯文本就要 text,想要置信度与逐页元数据就要 metadata:
const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
expand: ["markdown", "items", "metadata"],
});
// Walk the items tree to find tables
for (const page of result.items.pages) {
for (const item of page.items) {
if (item.type === "table") {
console.log(
`Table on page ${page.page_number}: ${item.rows.length} rows`,
);
}
}
}
// Inspect per-page confidence
for (const page of result.metadata.pages) {
console.log(`Page ${page.page_number}: confidence ${page.confidence}`);
}所有合法的 expand 取值及其返回内容,见取回结果。
7. 加上自定义提示词
通过 agentic_options.custom_prompt 用自然语言指示引导解析器:
const result = await client.parsing.parse({
file_id: file.id,
tier: "agentic",
version: "latest",
agentic_options: {
custom_prompt:
"This is a scientific research paper. Preserve all mathematical equations in LaTeX. Keep inline citations like (Smith 2024) intact in the flowing text. Do not flatten the multi-column layout into a single column.",
},
expand: ["markdown"],
});自定义提示词只在 cost_effective、agentic 与 agentic_plus 档位上有效(fast 不行)。完整的提示词工程指引见自定义提示词。
8. 把结果落盘
解析之后最常见的做法是把 markdown 写进一个文件:
import { writeFileSync } from "fs";
const fullDocument = result.markdown.pages
.map((p) => p.markdown)
.join("\n\n---\n\n");
writeFileSync("./llama-parsed.md", fullDocument);
console.log("Wrote llama-parsed.md");或者每页写一个文件,方便下游切块:
for (const page of result.markdown.pages) {
writeFileSync(`./pages/page-${page.page_number}.md`, page.markdown);
}常见的坑
tsx跑不了顶层await? 检查你的package.json里有没有"type": "module"(或显式用tsx的 ESM 模式)。被困在 CommonJS 里时,把脚本包成async function main() { ... } main()。- 认证报错? 确认
LLAMA_CLOUD_API_KEY就设在你运行tsx的那个 shell 会话里。echo $LLAMA_CLOUD_API_KEY应当打印出你的 key,而不是空。 fs.createReadStream出问题? 路径是相对于当前工作目录的,不是相对脚本文件。从别的目录运行时,用path.resolve(__dirname, "llama.pdf")给出绝对路径。- 解析任务卡住了? 它不该卡 ——
client.parsing.parse()会随任务耗时一直阻塞,但 SDK 内置了超时。单个任务跑了几分钟还没完,就检查一下文档:极长的文档(1000 页以上)在agentic_plus上确实要花好几分钟。
另请参阅
- 快速上手 → TypeScript 标签页 —— 范围更小、更纯粹的初次解析配置
- 快速上手:解析 PDF 并理解输出 —— 本教程的 Python 对应版,对每种输出视图的解读更深
- 档位 —— 为你的文档挑对档位
- 配置模型 —— 每个选项在请求结构里的位置
- 取回结果 —— 所有合法的
expand取值 - 自定义提示词 —— 用自然语言引导智能体式解析器