
Mastra + Vercel AI SDK + 设备端 GGUF:无 API 成本的 TypeScript 移动智能体栈
TypeScript 优先的移动开发者不必使用 Python 智能体框架。Mastra 与 Vercel AI SDK 加上一个通过 llama.cpp 在设备端运行的微调 4B 模型,产出零按 token 成本的完整智能体栈。
更新于 2026-05-10——反映本指南撰写以来 5 月初登陆的 Mastra 发布。5 月 1 日的发布新增了一套新的 ChannelProvider 架构、带 OAuth 的 Slack provider、
@mastra/nestjs适配器以及 Google Drive WorkspaceFilesystem;5 月 4 日的发布新增了基于关系的 FGA 授权、调度的 cron 工作流以及用于端到端浏览器自动化的新@mastra/browser-viewer。这些都没有改变下方的设备端微调模型模式——它们扩展了周边平台。
到 2026 年大多数智能体框架讨论仍假设 Python。LangGraph、CrewAI、AutoGen、Pydantic AI——经典参考都生活在 Python 生态。对于后端工程师与 ML 实践者,这是合理的默认。对于交付 React Native、Expo 或混合 Capacitor 应用的移动开发者,这是错的语言。一个 TypeScript 代码库不应需要 Python 边车来运行智能体。
TypeScript 生态现在拥有解决这个问题的两个优秀智能体框架。Mastra 在 2026 年 1 月跨过 22,000 GitHub stars 并发布了 1.0。Vercel AI SDK 已经将近两年成为流式优先的事实工具包,如今支撑着用 TypeScript 编写的生产 LLM 应用中相当部分。两者都能干净地与自托管模型协作,两者都围绕边缘原生部署设计,两者与一个在设备端运行的微调 4B 模型搭配尤为出色。
本指南走完整条 TypeScript 原生移动智能体栈:用 Mastra 进行编排、用 Vercel AI SDK 进行推理、用一个导出为 GGUF 的 Ertas 训练 Qwen3-4B 或 Gemma 4 E4B 模型,以及用 Ertas Deployment CLI 把它部署到 React Native 应用。从端到端,该栈在最初训练步骤之后无需调用任何托管 API 即可运行。
简要介绍两个 TypeScript 框架
Mastra 是更高层的选项。它在一个电池自带的包里给你带类型的智能体定义、声明式工作流、持久化内存、评估与 RAG 原语。工具定义是带 Zod schema 的地道 TypeScript。工作流是基于步骤的 DAG,能在进程重启中存活。内存与评估无需额外胶水即可集成。当你想要一个为 JavaScript 运行时塑形的完整智能体平台时,你选 Mastra。
Vercel AI SDK 是更低层的选项。它暴露流式原语、通过 Zod 实现的结构化输出,以及一个覆盖 90 多家模型提供商的通用提供商抽象——Anthropic、OpenAI、Google、Mistral、Cohere,加上 Ollama 与 llama.cpp 等自托管运行器。Mastra 也在内部调用 SDK 进行推理。所以实际上你不必二选一:Mastra 提供编排层,Vercel AI SDK 提供推理层,而微调本地模型给你成本结构。
这种组合是 TypeScript 最接近 Python 开发者整年构建的 Pydantic AI 加 Ollama 故事的方案——但原生于移动开发者已经使用的运行时。
我们要构建什么
示例智能体是一款 React Native 健身应用的训练计划生成器。智能体读取自然语言请求,挑选正确的工具,并产出经过验证的计划。它有三个工具:
get_user_profile()返回用户的年龄、体重、训练史find_recent_workouts(limit: number)把最近 N 次训练作为结构化记录返回propose_workout(focus: string, duration_min: number, difficulty: string)产出结构化训练计划
输出是一个 WorkoutPlan Zod 对象。Mastra 根据 schema 验证每次输出。工具调用根据其输入 schema 验证。整个智能体在用户手机内运行,除可选遥测外无网络调用。
这是那种在前沿 API 上很快变贵的智能体。每天记两次训练的用户每个会话产生四到六次智能体调用,多轮、上下文非平凡。在 10,000 月活时,你花在推理上的费用比托管费还多。
第 1 步:在 Studio 中训练模型
打开 Ertas Studio 并挑一个基础模型。对于 2026 年 TypeScript 友好的移动部署,两个强力选择是 Qwen3-4B-Instruct 与 Gemma 4 E4B。两者都能舒适装进现代手机(Q4_K_M 下约 2.5 GB),两者在微调后都产出可靠的结构化输出,两者都能与 llama.cpp 的移动 FFI 协作。Qwen3 在多步骤工具调用上略占优势;Gemma 4 E4B 在指令遵循的细微差别上略占优势。任一都是良好起点。
在 Data Craft 中定义工具 schema。Studio 读取你的工具签名(以 Zod schema、JSON Schema 或 TypeScript 函数签名本身的形式粘贴),并把结构作为训练目标。对于训练计划生成器,目标是约 500 个样本,涵盖单工具调用、多工具序列与拒绝(超出范围的请求)。
用默认的工具调用 QLoRA 配置训练:rank 32,三个 epoch。验证损失通常在 epoch 2.5 左右趋平。在标准 GPU 等级上,运行不到一小时完成。Studio 的评估套件报告工具名称准确率、参数名称准确率与参数值准确率。生产就绪的模型在三项上都清过 95%。
第 2 步:导出为 GGUF 并部署
Studio 的导出流水线产出 GGUF 二进制。对于移动端 4B 模型,Q4_K_M 是合适的默认——磁盘约 2.5 GB,工作内存约 3 GB。
针对你现有的 React Native 项目运行 Ertas Deployment CLI:
ertas deploy mobile \
--project ./my-fitness-app \
--model ertas-workout-agent-4b.gguf \
--framework react-native
CLI 处理三件历史上吃掉 20 到 40 小时 llama.cpp 构建工程的事。它安装移动 FFI 绑定(iOS 上带 Metal 后端、Android 上带 OpenCL/Vulkan 后端)。它在打包器中注册 GGUF 资产,使模型与应用一起发货。它在应用进程内立起一个 本地 HTTP 风格推理端点——通常在设备本地 socket 上可达——镜像 Vercel AI SDK 已经知道如何调用的 OpenAI 兼容 API 形态。
同一个 CLI 支持 Flutter、原生 iOS Swift 与原生 Android Kotlin。这里特定的是交付物的 TypeScript 形态。
第 3 步:配置 Vercel AI SDK
Vercel AI SDK 有一个由社区维护的 Ollama 提供商,以及一个通用的兼容 OpenAI 提供商,指向任何 OpenAI 形状的端点。Ertas Deployment CLI 默认以 OpenAI 兼容形式暴露其设备端端点,所以你像对待任何其他提供商一样接线:
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
export const ertasLocal = createOpenAICompatible({
name: "ertas-on-device",
baseURL: "http://localhost:8080/v1",
apiKey: "not-needed",
});
export const workoutModel = ertasLocal("ertas-workout-agent-4b");
在开发中,你把 baseURL 指向笔记本上的 Ollama(端口 11434)。在设备端的生产中,Ertas Deployment CLI 在配置端口(默认 8080)暴露本地端点,同样的 SDK 调用形态无需修改即可工作。SDK 不会因为推理在应用内运行而非通过网络而有差异——无论哪种方式它看到的都是相同的 OpenAI 兼容响应流。
第 4 步:定义 Mastra 智能体
现在把 Mastra 接到本地模型,并定义智能体与工具:
import { Agent } from "@mastra/core/agent";
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
import { workoutModel } from "./ertas-local";
const WorkoutPlan = z.object({
focus: z.string(),
duration_min: z.number(),
difficulty: z.enum(["easy", "moderate", "hard"]),
blocks: z.array(
z.object({
name: z.string(),
sets: z.number(),
reps: z.number(),
}),
),
});
const getUserProfile = createTool({
id: "get_user_profile",
description: "Get the current user's age, weight, and training history.",
inputSchema: z.object({}),
outputSchema: z.object({
age: z.number(),
weight_kg: z.number(),
history: z.array(z.string()),
}),
execute: async () => fitnessDb.getProfile(),
});
const findRecentWorkouts = createTool({
id: "find_recent_workouts",
description: "Return the user's most recent workouts.",
inputSchema: z.object({ limit: z.number().default(5) }),
outputSchema: z.array(
z.object({ date: z.string(), name: z.string(), notes: z.string() }),
),
execute: async ({ context }) => fitnessDb.recent(context.limit),
});
const proposeWorkout = createTool({
id: "propose_workout",
description: "Produce a structured workout plan for the user.",
inputSchema: z.object({
focus: z.string(),
duration_min: z.number(),
difficulty: z.enum(["easy", "moderate", "hard"]),
}),
outputSchema: WorkoutPlan,
execute: async ({ context }) => planner.generate(context),
});
export const workoutAgent = new Agent({
name: "workout-planner",
instructions:
"You plan workouts. Use the available tools to read the user's history before proposing a plan.",
model: workoutModel,
tools: { getUserProfile, findRecentWorkouts, proposeWorkout },
});
const result = await workoutAgent.generate(
"Plan me a 45-minute moderate session focused on legs.",
{ output: WorkoutPlan },
);
console.log(result.object);
代码没明示但正在发生两件事。第一,智能体在提议计划之前读取用户的资料与最近训练,因为微调模型在建立该模式的样本上训练过。一个通用的开源权重模型常常会跳过历史查询并提议通用计划;训练好的模型按设计使用可用工具。第二,输出由 Mastra 根据 WorkoutPlan 验证。如果模型发出无效对象,验证器会拒绝它,Mastra 会浮出带类型的错误。
智能体完全在设备上运行。推理路径上没有 API 调用。用户的资料数据从不离开手机。智能体产生的唯一网络流量是你选择的任何遥测。
TypeScript 原生为何对移动端重要
交付 React Native 或 Expo 应用的移动团队,在智能体层与应用同语言时拥有有意义的生产力优势。类型定义从 Zod schema 经过 Mastra 流入 React Native UI,无需任何跨语言代码生成。智能体中抛出的错误以带类型异常的形式浮现于 React 树。Vercel AI SDK 的流式响应接入移动开发者已经使用的 useChat 风格 Hook。
基于 Python 的替代方案需要边车服务。你要么运行 React Native 应用调用的 Python 后端,要么把 CPython 嵌入到移动二进制,要么找到把工作分摊在不同运行时的某种混合。三种选项都增加部署复杂性 、包大小与崩溃面积。如果智能体层已经是 TypeScript,这些都不必。
Mastra 加 Vercel AI SDK 的组合契合移动开发者已经身处的运行时。Ertas Deployment CLI 契合同一个运行时。从端到端,你交付的是一个带模型文件的单一 TypeScript 应用。
智能体成本悬崖,再次出现
经济论据与 Python 设备端智能体所做的相同,只是按移动使用模式缩放。移动应用中的智能体调用倾向于高频且多轮——健身应用、日记应用、日历应用、规划器。前沿 API 上的每次调用成本根据上下文长度与工具深度运行约 0.01 到 0.04 美元。
在典型使用率下的代表性移动应用成本曲线:
- 1,000 MAU,每天平均 4 次调用 → 每月推理大约 120 美元
- 10,000 MAU → 大约每月 1,200 美元
- 40,000 MAU → 大约每月 4,800 美元
- 100,000 MAU → 大约每月 12,000 美元
这些数字对移动团队比对 Web 团队打击更大,因为移动变现通常通过订阅而非席位许可。你的单位经济模型在 10,000 到 40,000 MAU 区间开始破裂——恰恰是你试图投资增长而非从推理成本中后撤的区间。
设备端,成本结构是固定的。一次推理的边际成本是电费。固定成本是模 型在设备上的存储,只在安装时支付一次。从 10,000 增长到 100,000 MAU 不会移动推理线。
智能体成本悬崖一直是塑造设备端迁移的主导力量。TypeScript 移动开发者一直在等一个让他们能够回应它而又不放弃运行时的智能体栈。
你不必放弃什么
移动团队在考虑设备端迁移时通常提出三个顾虑,Mastra 加 Vercel AI SDK 加 Ertas 训练模型这一栈逐一解决。
流式。Vercel AI SDK 的流式原语面向本地 llama.cpp 端点的工作方式与面向托管 API 相同。React Native UI 中按 token 渲染不变。
结构化输出。SDK 与 Mastra 中的 Zod 验证不变运行。微调让结构化输出可靠到验证很少失败。
内存与工作流。Mastra 的内存与工作流原语不依赖模型远程运行。同样的向量存储、同样的工作流定义、同样的评估装置面向本地模型工作。
你确实放弃的是轻易切换到前沿模型的能力。一旦你微调并交付了特定模型,切换到另一个意味着再次微调。实践中,这是每个迁移到自托管模型的团队都接受的同一权衡,而对于可预测的经济性,大多数移动团队会愉快地接受这一权衡。
从原型到上线
典型流水线如下:
- 针对 API 做原型。通过 Vercel AI SDK 在 Anthropic 或 OpenAI 上构建 Mastra 智能体。把工具调对、证明价值。
- 精选数据集。从你的原型中的几百个样本,在 Data Craft 中根据你的 Zod schema 进行验证。
- 在 Studio 中微调。在数据集上迭代直至评估指标清过 95%。
- 部署到设备。针对你的 React Native 项目运行 Ertas Deployment CLI。把 Vercel AI SDK 配置中指向 API 的提供商替换为本地提供商。你的 Mastra 智能体代码不变。
- 在追踪上迭代。生产追踪成为下一轮训练数据。Studio 支持从追踪进行增量微调,因此模型在用户数据保留在设备端的同时持续改进。
前三步过去是难点。Mastra 与 Vercel AI SDK 把原型到生产的间隔从"数周的定制流式代码"压缩到"一个下午的智能体定义"。Studio 把数据集到微调的间隔从 MLE 月削减为小时。Ertas Deployment CLI 关闭了最后一道间隔——大多数 TypeScript 应用开发者从未跨越的那道,因为 llama.cpp 构建工程过于昂贵。
Mastra 加 Vercel AI SDK 加一个 Ertas 训练的设备端模型,正是 TypeScript 移动开发者一直在等的智能体栈。无 Python 边车。无按 token 账单。在 10,000 与 100,000 用户之间没有成本悬崖。
Ship AI that runs on your users' devices.
Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.
Keep reading

Pydantic AI On-Device: Fine-Tune Qwen3-4B for Type-Safe Mobile Agents
Pydantic AI brings type safety and FastAPI ergonomics to LLM agents. Combine it with a fine-tuned 4B model running on-device via llama.cpp and you get production-grade agents in mobile apps with zero API costs and validated outputs by construction.

Llama Stack on a Phone: Self-Hosted Llama Agents With a Fine-Tuned Llama 4 Model
Meta's Llama Stack is the canonical reference architecture for Llama-based agents. Combine it with a fine-tuned Llama 4 derivative and the Swift/Kotlin client SDKs and you get a complete agent stack running entirely on the user's phone.

On-Device Tool Calling 2026: Qwen3-4B vs Gemma 4 E4B vs Phi-4-Mini
We benchmarked the three best on-device tool-calling bases of 2026 — Qwen3-4B, Gemma 4 E4B, and Phi-4-Mini — across BFCL v4, real mobile latency, and post-fine-tune accuracy. Each wins a different scenario; here's how to pick.