Mastra 模板实战:从 PDF 自动生成教学闪卡(flash-cards-from-pdf 完整解析)
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
本文围绕 Mastra monorepo 中的templates/template-flash-cards-from-pdf模板展开:它是一个"上传 PDF → 自动解析 → 生成带难度分级的教学闪卡 → 可选 AI 配图"的完整 Agent 应用。读完本文,你将掌握该模板的运行与配置方式(脚手架命令、环境变量、Mastra Studio 交互流程),并能基于仓库源码理解其背后的两个核心工具——PDF 文本抽取工具与图像生成工具——的实现细节,从而把它改造成适配自己学习/培训场景的闪卡系统。
一、模板定位:它想演示什么
模板 README(README.md)开宗明义:这是一个"从 PDF 文档生成教育闪卡"的模板。用户在 Mastra Studio 中附加一个 PDF 文件,Agent 就会创建闪卡,并支持按需生成 AI 配图。
README 在 "Why we built this" 一节说明,该模板刻意展示了两个典型能力:
- 让 Agent 生成图像:通过工具调用触发图像模型,而不是让 Agent 直接"画"图;
- 构建一个解析 PDF 的工具:把二进制文件解析逻辑封装成结构化工具,供 Agent 在推理过程中按需调用。
因此这个模板的价值不仅是一个"学习卡生成器",更是一份 Mastra 中"文档解析工具 + 多模态生成工具 + 长期记忆 Agent"组合模式的参考实现。
二、运行前提与快速启动
环境前提
根据 package.json,该模板要求Node.js >= 22.13.0,并且默认依赖一个 OpenAI API key(README 指出"默认使用 OpenAI,但可以替换为任意模型")。仓库中的.env.example内容极简,只有一个占位项:
OPENAI_API_KEY=your-api-key即模板同时用 OpenAI 完成两件事:驱动对话 Agent(默认模型openai/gpt-5-mini)与生成配图(DALL-E 3),所以单个 OpenAI key 即可跑通全流程。
三步启动
按照 README 的 Quickstart:
- 克隆模板:执行
npx create-mastra@latest --template flash-cards-from-pdf在本地脚手架化项目; - 配置密钥:复制
.env.example为.env并填入 key; - 启动开发服务器:执行
npm run dev(对应 package.json 中"dev": "mastra dev"脚本),然后打开http://localhost:4111体验。
package.json中另外提供build(mastra build)与start(mastra start)脚本,用于生产构建与启动。核心依赖包括@mastra/core、@mastra/memory、@mastra/libsql、@mastra/loggers、@mastra/observability、ai(vNext AI SDK,^6.0.101)、pdf-parse(^2.4.5)与zod(^4.3.6)。
三、在 Mastra Studio 中实际操作
README 的 "Making it yours" 一节给出了完整的交互路径:
- 在 Studio 中选择Flash Card Agent;
- 使用聊天界面的附件按钮附加一个 PDF 文件(仓库内提供了 assets/example.pdf 供测试,约 128KB);
- 对 Agent 说:"Create flash cards from this PDF";
- 可选地追加一句:"Generate flash cards with images for the key concepts",此时 Agent 才会调用图像生成工具为关键概念配图。
这一步的顺序设计是有意的:图像生成在 Agent 指令中被限定为"仅在用户明确要求时才生成"(详见下文指令分析),默认只产出文字闪卡,避免不必要的图像生成开销。
README 同时说明:演示在 Mastra Studio 中运行,但同一套 workflow 可以通过 Mastra Client SDK 接入 React、Next.js 或 Vue 应用,也可以配合 AI SDK UI、CopilotKit、Assistant UI 等 agentic UI 库使用——即 Studio 只是调试入口,不是运行时绑定。
四、Agent 实现剖析:flash-card-agent.ts
Agent 定义在 flash-card-agent.ts,是一个标准的@mastra/core/agent实例:
export const flashCardAgent = new Agent({ id: 'flash-card-agent', name: 'Flash Card Generator', description: 'Generates educational flash cards from PDF documents', model: 'openai/gpt-5-mini', instructions: `You are an educational flash card generator. ...`, tools: { extractPdfText, generateImage }, memory: new Memory(), });几个关键配置点:
model: 'openai/gpt-5-mini':默认对话模型,替换成其他 provider 只需改这一行;memory: new Memory():挂载了@mastra/memory的记忆能力,配合下面的 LibSQL 存储实现多轮会话上下文;tools:注册了extractPdfText与generateImage两个工具,Agent 的"能力边界"就由这两个工具 + 指令共同决定。
instructions是整个模板的"业务规则引擎",值得逐条看(原文为英文,此处归纳要点):
- 工作流程:用户附加 PDF → Agent 收到 base64 文件内容 → 用
extract-pdf-text工具提取文本 → 分析文本生成闪卡 → 用户要求时再为关键概念调用generate-image; - 生成规则:每份 PDF 默认生成10–20 张卡(除非用户指定数量);每张卡正面是清晰的question、背面是简洁的answer;每张卡标注难度(easy / medium / hard)和分类/主题;问题类型需多样化(定义、解释、对比、应用);答案必须忠实于 PDF 原文,不得虚构;
- 输出格式:规定了一套 Markdown 结构,如
### Flash Cards: [Subject Area]标题下逐卡输出**Card N** (difficulty) — [Category]+- **Q:** .../- **A:** ...,保证下游(Studio 或自己的前端)可以稳定解析; - 图像约束:仅当用户明确要求时生成图片;每次挑选3–5 个最适合图示的概念,并在卡片输出中带上图片路径;
- 异常处理:没有 PDF 时提示用户附加;PDF 文本过少时告知用户并尽力而为。
从源码结构看,这套指令把"质量约束"(数量、难度、忠实度)与"格式约束"(Markdown 模板)都写死在 prompt 里,而不是依赖后处理脚本——这是典型的"用指令约束输出"的 Agent 工程实践。
五、工具一:PDF 文本抽取(extract-pdf-text)
实现见 extract-pdf-text.ts,使用createTool(@mastra/core/tools)定义,底层用pdf-parse的PDFParse类。
输入/输出 Schema(zod 定义,同时充当工具的"API 契约"):
| 方向 | 字段 | 说明 |
|---|---|---|
| input | pdfBase64: string | Base64 编码的 PDF 数据,可带或不带data:application/pdf;base64,前缀 |
| output | text: string | 提取出的全部文本 |
| output | pageCount: number | PDF 总页数 |
| output | title: string | PDF 元数据中的标题(无则为空串) |
执行逻辑(对应源码 L16–L40):
- 用正则
^data:application/pdf;base64,剥离可能存在的 data URI 前缀,再Buffer.from(base64Data, 'base64')还原字节; new PDFParse({ data: new Uint8Array(buffer) })创建解析器,getInfo()拿到总页数;- 逐页
parser.getText({ partial: [i] })提取第 i 页文本,trim()后非空才收集——跳过空白页; parser.destroy()释放解析器资源;- 各页文本用
\n\n拼接,连同页数、标题一起返回。
两个工程细节值得借鉴:
- 兼容带/不带 data URI 的 base64 输入:Studio 附件通常以 data URI 形式给出文件内容,工具侧统一做了前缀剥离,调用方(模型)不必关心格式差异;
- 输出 Schema 附带
pageCount与title:这让 Agent 在生成闪卡时能感知文档规模(比如配合指令中"PDF 文本过少时告知用户"的规则),而不只拿到一坨纯文本。
六、工具二:图像生成(generate-image)
实现见 generate-image.ts,是 README 所说"演示 Agent 生成图像"的核心。
输入/输出 Schema:
| 方向 | 字段 | 说明 |
|---|---|---|
| input | concept: string | 要可视化的概念 |
| input | subjectArea: string | 学科领域(如 biology、physics、history) |
| output | imagePath: string | 生成图片的本地文件路径 |
| output | revisedPrompt: string | 实际使用的提示词 |
执行逻辑(对应源码 L22–L42):
- 提示词模板化:不是把
concept直接丢给图像模型,而是套用一个固定的教学风格模板:Create a clear, educational diagram or illustration about "${concept}" in the subject of ${subjectArea}. ... Use clean visuals, labels where helpful, and no walls of text. Style: educational, clean, minimal.——保证出图风格统一为"清晰、带标注、无大段文字"的教学插画; - 调用
ai包的generateImage,模型为openai.image('dall-e-3'),尺寸固定1024x1024; - 输出目录为进程工作目录下的
output/images(mkdir时带recursive: true),文件名为randomUUID().png,避免覆盖冲突; - 把返回的 base64 写盘,返回
{ imagePath, revisedPrompt },Agent 随后把imagePath放进卡片输出,前端/Studio 即可引用该图片。
替换图像 provider 的切入点就在这里:把openai.image('dall-e-3')换成ai包支持的其他图像模型(或改为读取远端 API 的 base64),其余保存/返回逻辑可以原样保留——这也是 README 中 "Swap in a different image generation provider" 提示的具体落点。
七、服务装配:存储、日志与可观测性
Mastra 实例装配在 index.ts,把 Agent 与基础设施一次性组合:
export const mastra = new Mastra({ agents: { flashCardAgent }, storage: new LibSQLStore({ id: 'flash-cards-storage', url: 'file:./mastra.db' }), logger: new PinoLogger({ name: 'Mastra', level: 'info' }), observability: new Observability({ configs: { default: { serviceName: 'mastra', exporters: [new MastraStorageExporter(), new MastraPlatformExporter()], spanOutputProcessors: [new SensitiveDataFilter()], }, }, }), });各部分职责:
LibSQLStore(@mastra/libsql):本地文件数据库file:./mastra.db,为new Memory()提供会话/消息持久化——Agent 的对话记忆落到这个 SQLite 兼容库里,这也是多轮追问(如先出卡、再要图)能保持上下文的原因;PinoLogger:info级别的结构化日志,开发时终端可见;Observability:同时挂MastraStorageExporter(trace 落存储)与MastraPlatformExporter两个 exporter,并用SensitiveDataFilter对 span 输出做敏感数据过滤。对模板而言这是"生产级可观测性"的默认配置示范,直接改配置即可接入不同 exporter。
八、定制与集成到你自己的应用
README 给出的改造路径有三条,均对应明确代码位置:
- 换模型/换图像 provider:改 flash-card-agent.ts 的
model字段,或改 generate-image.ts 的图像模型; - 改生成规则:直接编辑 Agent 的
instructions(比如把默认 10–20 张改为 5 张、调整难度分级、变更 Markdown 输出结构),无需动任何工具代码; - 接入自己的前端:Agent 在
src/mastra/agents下,README 提示"edit it directly to fit your use case";对外暴露则通过 Mastra Client SDK 或 agentic UI 库接入 React / Next.js / Vue 应用,Studio 交互流程与 API 调用消费的是同一个 Agent。
TypeScript 配置(tsconfig.json)采用ES2022target、bundler模块解析与strict: true,include仅覆盖src/**/*,改造时保持src目录约定即可。
九、模板机制与贡献说明
Mastra 模板(templates)是一组"开箱即用的参考项目",存放在 Mastra monorepo 中,并自动同步到独立仓库以便npx create-mastra --template <name>直接克隆。
需要注意的是 CONTRIBUTING.md 的说明:该目录下的仓库是自动生成的,在此直接开 PR 会被忽略;正确贡献路径是先 Fork Mastra monorepo,在其中的templates/template-flash-cards-from-pdf目录修改,再向 monorepo 提 PR,由同步机器人把合入变更带到独立仓库。
十、小结与文件索引
该模板用一个约 150 行的 Agent 定义 + 两个不到 50 行的工具,完整演示了 Mastra 中"文档理解型 Agent"的构建范式:
| 关注点 | 参考文件 |
|---|---|
| 模板说明与快速启动 | README.md |
| Agent 与闪卡生成规则 | flash-card-agent.ts |
| PDF 解析工具(pdf-parse + 分页提取) | extract-pdf-text.ts |
| 图像生成工具(DALL-E 3 + 本地落盘) | generate-image.ts |
| 存储/日志/可观测性装配 | index.ts |
| 依赖与脚本(Node >= 22.13.0) | package.json |
| 测试用示例 PDF | assets/example.pdf |
| 环境变量模板 | .env.example |
如果你想在此基础上扩展(如把闪卡输出落库、支持多语言、或换成非 OpenAI 的文本/图像模型),所有改动点都收敛在上述少量文件中,这正是该模板作为教学样例的设计意图。
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考