前言¶
用 create-voltagent 或 npm create voltagent-app@latest 能把 TypeScript Agent 项目搭起来,但真正动手写业务时,编程助手仍会反复问同一组问题:这件事该用 Agent 还是 Workflow?src/ 怎么切?内存挂在入口还是挂在单个对象上?Node 进程和 Cloudflare Worker 该选哪套服务器?观测数据怎么接到 VoltOps?
这些问题在官方文档里都有答案,只是散落在 Agent、Workflow、Memory、Server、Observability 几章。模型每次临场发挥,项目就会慢慢长出一套「能跑、但对不上框架约定」的结构。
voltagent-best-practices 把这些约定收成一份 Agent Skill。它来自 VoltAgent 官方维护的 VoltAgent/skills 仓库,正文在 skills/voltagent-best-practices/SKILL.md,许可证 MIT。同一份 SKILL.md 按 Agent Skills 通用格式编写,Cursor、Codex CLI、Claude Code 等能读 Skill 的工具都可以加载。
和「跑一条脚手架命令」不同,这份文件承载的是框架级架构知识:什么时候用 Agent、什么时候用 Workflow、目录怎么放、内存和服务器怎么选。它不替代 voltagent.dev/docs,而是让编程助手在写代码前先对齐官方约定。
这是什么¶
一句话定位:VoltAgent 架构模式与约定的速查手册,覆盖 Agent 与 Workflow 的取舍、项目布局、内存默认值、服务器提供方,以及可观测性接入。
官方 frontmatter:
- name:
voltagent-best-practices - description:VoltAgent architectural patterns and conventions. Covers agents vs workflows, project layout, memory, servers, and observability.
- author:VoltAgent
- version:
1.0.0 - license:MIT
- repository:https://github.com/VoltAgent/skills
VoltAgent 是开源 TypeScript Agent 工程平台:运行时在 @voltagent/core(Agent、Tool、Memory、Workflow 等),观测与运维侧是 VoltOps。VoltAgent 这个类本身是应用入口,负责把 Agent / Workflow 注册到一起、套上全局默认值,并按需启动 HTTP 或 serverless 提供方。官方文档入口是 voltagent.dev/docs。
同仓库里还有三份配套 Skill,职责不要混:
create-voltagent:从零创建项目(CLI 或手动脚手架)voltagent-core-reference:VoltAgent类选项与生命周期参考voltagent-docs-bundle:查阅与当前@voltagent/core版本匹配的内嵌文档
voltagent-best-practices 的边界是「已经决定用 VoltAgent 之后,按官方约定写结构」。新建仓库仍应先走 create-voltagent。
officialskills.sh 对它的概括和 SKILL.md 一致:把约定放在一处,就不必每次开工都去翻 VoltAgent 单仓,找正确的 import、内存模式或服务器选项。
核心功能与亮点¶
Skill 正文不长,分成几块速查。下面按官方 SKILL.md 展开,并用 VoltAgent 文档交叉核对过的细节补全优先级和包名。
先分清 Agent 和 Workflow¶
Skill 给的判断标准只有两行,但足够当默认规则:
| 用 | 什么时候 |
|---|---|
| Agent | 开放式任务,需要选工具、做自适应推理 |
| Workflow | 多步流水线,控制流明确,并且要 suspend / resume |
官方 Workflow 文档把 Workflow 写成用 .andThen()、.andAgent()、.andWhen() 等方法串起来的步骤链;HTTP API 里也有对应的挂起 / 恢复接口:POST /workflows/:id/executions/:executionId/suspend 和 .../resume。脚手架里的报销审批示例就是这条路:金额超过阈值就 suspend,等人用 resumeData 恢复。
反过来,客服问答、带工具的研究助手这类「下一步取决于模型判断」的任务,Skill 要求用 Agent。官方 API Overview 也把 Agent 端点(/agents/:id/text、stream、object)和 Workflow 端点分开,两边不是同一套执行模型。
一个实用推论:步骤顺序事先知道、中间可能等人或等外部事件,用 Workflow;路径要靠模型当场选工具,用 Agent。两者可以组合——Workflow 的某一步里再调用 Agent——但入口类型要先选对。
推荐的 src/ 布局¶
Skill 给出的目录是:
src/
|-- index.ts
|-- agents/
|-- tools/
`-- workflows/
create-voltagent 脚手架默认生成的是 src/index.ts、src/tools/、src/workflows/,Agent 往往直接写在入口文件里。voltagent-best-practices 额外要求把 Agent 收到 src/agents/。两者不冲突:CLI 给最小可运行形状,这份 Skill 给后续往上长时的切分方式。
入口文件负责 new VoltAgent({ agents, workflows, server })。具体 Agent、Tool、Workflow 各自放目录,避免全部堆进 index.ts。
内存:共享默认值,需要时再拆开¶
Skill 对内存只写了两条:
- 用
memory作为 Agent 和 Workflow 的共享默认 - 两边默认值需要不同时,改用
agentMemory或workflowMemory
官方 VoltAgent Instance 和 Memory Overview 把优先级写得更完整:
- Agent:实例上的
memory> 入口的agentMemory> 入口的memory> 内置内存 - Workflow:实例上的
memory> 入口的workflowMemory> 入口的memory> 内置内存
省略 memory 并不会关掉记忆,仍会落到上面的默认值(或内置 in-memory)。要在某个 Agent 上彻底关掉,官方写法是显式 memory: false。
还有一层容易混的区别:Workflow 上的 memory 存的是执行历史(每一步的输入输出、状态、耗时),和 Agent 上的对话记忆不是同一件事。官方 Workflow 文档专门标了这条。Skill 让你在入口一次性配好默认存储;具体用 InMemory、LibSQL、Postgres 还是 Managed Memory,要去 Memory 文档选适配器,这份 Skill 不展开各适配器。
服务器:Node 用 Hono/Elysia,fetch 运行时用 serverless¶
Skill 的服务器选项:
- Node HTTP:
@voltagent/server-hono - Node 备选:
@voltagent/server-elysia - Cloudflare、Netlify 这类 fetch 运行时:用
serverless提供方
官方 API Overview 把 Hono 标成推荐实现,Elysia 是另一套高性能实现;两者都通过 new VoltAgent({ server: honoServer() }) 或 elysiaServer() 挂上。默认端口在文档和 Quick Start 里是 3141,Swagger UI 在 /ui。
serverless 侧,官方部署文档给出的具体包是 @voltagent/serverless-hono,入口写法是 serverless: serverlessHono(),再导出 toCloudflareWorker() 或 Netlify handler。Skill 只写「serverless provider」,写代码时以部署文档里的包名为准。
可观测性:环境变量就能接上 VoltOps¶
Skill 写了两条:
- 用
VoltOpsClient或createVoltAgentObservability做 tracing - 若设置了
VOLTAGENT_PUBLIC_KEY和VOLTAGENT_SECRET_KEY,VoltAgent 会自动配置 VoltOps
官方 Observability Setup 与此一致:两把钥匙放进环境变量后,基础路径不需要再写观测代码。钥匙从 console.voltagent.dev 的项目设置里取,格式是 pk_xxxx 和 sk_live_xxxx。需要服务名、采样率时,再用 createVoltAgentObservability({ serviceName, voltOpsSync: { sampling: ... } });需要把客户端显式传给 VoltAgent 时,用 voltOpsClient: new VoltOpsClient({ publicKey, secretKey })。
内嵌 recipes,以及一个仓库内的坑¶
Skill 把更短的实践食谱指到 VoltAgent 单仓里的内嵌文档:
packages/core/docs/recipes/
检索命令是:
rg -n "keyword" packages/core/docs/recipes -g"*.md"
这些路径相对于 voltagent/voltagent 仓库(以及安装后的 @voltagent/core/docs),不是 VoltAgent/skills 仓库本身。需要按当前 core 版本查内嵌文档时,同仓库的 voltagent-docs-bundle 更对口。
最后一条 Footguns:在 VoltAgent 的包内部不要用 JSON.stringify,改用 @voltagent/internal 的 safeStringify。这是给改框架源码、给 VoltAgent 提 PR 的约定(官方仓库的 coding guideline 也是同一句),不是要求业务项目把所有序列化都换掉。Agent 对象、循环引用的工具结果上,JSON.stringify 容易直接抛错,所以框架内部换成了 safeStringify。
安装与启用¶
该 Skill 收录在 VoltAgent/skills 仓库。官方 README 与 Docs for AI Assistants 都以 npx skills add 为准;这条命令会装上仓库里的整套 Skill,不只是 voltagent-best-practices。
官方推荐(支持 add-skill 的 Agent)¶
npx skills add VoltAgent/skills
officialskills.sh 与 skills.sh 上若只装这一份,命令是:
npx skills add https://github.com/VoltAgent/skills --skill voltagent-best-practices
官方文档把 Local Skills 和 MCP 文档服务分成两条线:Skill 适合能读本地文件的助手;若要在 Cursor / VS Code 里按需查文档、示例和 changelog,可以用 @voltagent/docs-mcp。后者不是这份 Skill 本身,但和「让 AI 按官方约定写 VoltAgent 代码」是同一套工具链。
手动克隆¶
git clone https://github.com/VoltAgent/skills.git
然后把 skills/voltagent-best-practices/ 放到各工具会扫描的 Skill 目录。SKILL.md 是通用格式。按 Cursor 文档,项目级会从 .agents/skills/、.cursor/skills/ 自动发现;用户级对应 ~/.agents/skills/、~/.cursor/skills/。兼容目录还包括 .claude/skills/、.codex/skills/ 以及对应的用户级路径。手动放置时目录应类似:
.cursor/skills/voltagent-best-practices/SKILL.md
或:
.agents/skills/voltagent-best-practices/SKILL.md
Claude Code 项目级为 .claude/skills/voltagent-best-practices/SKILL.md,用户级为 ~/.claude/skills/voltagent-best-practices/SKILL.md。Codex CLI 扫描 $CODEX_HOME/skills(默认 ~/.codex/skills)以及项目内的 .codex/skills/。
启用后,在对话里输入 / 搜索 voltagent-best-practices 可手动调用。用户说「按 VoltAgent 约定组织项目」「这个该用 Agent 还是 Workflow」「怎么接 VoltOps」时,Agent 也应按 description 自动选用。
典型用法示例¶
下面的代码均来自官方 SKILL.md,并与 VoltAgent Instance、Workflow Overview 中的写法一致。
让助手按约定做架构选择¶
Skill 装好后,可以直接把判断标准交给它:
请按 voltagent-best-practices 设计这个 VoltAgent 服务:
用户上传一份长文档,先抽取文本,再生成摘要,最后写入数据库。
步骤固定,中间可能等人审核。请决定用 Agent 还是 Workflow,
并按推荐的 src/ 布局给出文件划分。
按 Skill 的表,这条应落成 Workflow(多步、控制流明确、可能 suspend/resume),而不是一个大 Agent 把三步都「想」出来。文件上则应出现 src/workflows/,而不是把流水线写进 src/agents/。
另一类提示更适合 Agent:
请按 voltagent-best-practices 加一个助手:用户提问后由模型决定
要不要查天气、搜知识库或直接回答。放到推荐目录里,模型用 openai/gpt-4o-mini。
Basic Agent¶
Skill 的最小 Agent:
import { Agent } from "@voltagent/core";
const agent = new Agent({
name: "assistant",
instructions: "You are helpful.",
model: "openai/gpt-4o-mini",
});
模型字符串格式是 provider/model。Skill 给的例子是 openai/gpt-4o-mini 和 anthropic/claude-3-5-sonnet。官方文档说明:用这种字符串时不必再单独引入提供商 SDK,把对应 API Key 写进环境变量即可。文档和仓库 README 里也有 openai("gpt-4o-mini") 这种 Vercel AI SDK 写法,两种都出现在官方材料中;这份 Skill 用的是字符串形式。
Basic Workflow¶
Skill 的最小 Workflow 用 createWorkflowChain + Zod 声明输入输出,再用 .andThen() 接一步:
import { createWorkflowChain } from "@voltagent/core";
import { z } from "zod";
const workflow = createWorkflowChain({
id: "example",
input: z.object({ text: z.string() }),
result: z.object({ summary: z.string() }),
}).andThen({
id: "summarize",
execute: async ({ data }) => ({ summary: data.text }),
});
这只是结构示例:execute 原样把 text 放进 summary,用来演示链式 API,不是真正的摘要模型。需要模型参与某一步时,官方 Workflow 文档用 .andAgent(),或在 .andThen() 里直接调用 agent.generateText() / streamText()。
入口:把 Agent、Workflow 和服务器注册在一起¶
import { VoltAgent } from "@voltagent/core";
import { honoServer } from "@voltagent/server-hono";
new VoltAgent({
agents: { agent },
workflows: { workflow },
server: honoServer(),
});
这是 Skill 的 Bootstrap 片段。官方 Instance 文档在同一位置还可以传入 agentMemory / workflowMemory、voltOpsClient、observability、logger。换 Elysia 时把 import 改成 @voltagent/server-elysia 的 elysiaServer;上 Cloudflare / Netlify 时不要再用 server: honoServer(),改走 serverless: serverlessHono()。
内存默认值怎么写在入口¶
官方 Instance 文档给出的拆分写法和 Skill 的 agentMemory / workflowMemory 对应:
import { Memory, VoltAgent } from "@voltagent/core";
import { LibSQLMemoryAdapter } from "@voltagent/libsql";
const agentMemory = new Memory({
storage: new LibSQLMemoryAdapter({ url: "file:./.voltagent/agent.db" }),
});
const workflowMemory = new Memory({
storage: new LibSQLMemoryAdapter({ url: "file:./.voltagent/workflows.db" }),
});
new VoltAgent({
agentMemory,
workflowMemory,
// memory: sharedFallbackMemory,
});
两边可以共用一个 memory;只有存储策略确实不同时才拆成两个。适配器种类以 Memory 文档为准,上面的 LibSQL 只是官方示例之一。
接 VoltOps¶
最小路径是环境变量,不必改代码:
VOLTAGENT_PUBLIC_KEY=pk_xxxx
VOLTAGENT_SECRET_KEY=sk_live_xxxx
需要显式传入客户端时,官方 Setup 文档的写法是:
import { VoltAgent, VoltOpsClient } from "@voltagent/core";
new VoltAgent({
agents: { agent },
voltOpsClient: new VoltOpsClient({
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
}),
});
跑一条请求后,到 console.voltagent.dev 看 trace。官方排障顺序是:确认两把钥匙属于同一项目、改环境变量后重启、查运行时日志里的鉴权 / 导出错误。
适用场景与注意事项¶
适合
- 已经用 VoltAgent(或刚用
create-voltagent建好仓库),接下来要决定 Agent / Workflow、目录、内存和服务器 - 希望 Cursor / Claude Code / Codex 在加功能时复用同一套约定,而不是每次重新发明 import 和入口参数
- 要把 VoltOps tracing 接上,或按运行时在 Hono、Elysia、serverless 之间做选择
- 给 VoltAgent 本身提 PR,需要避开
JSON.stringify这条仓库内约定
使用时要注意
- 这是架构速查,不是脚手架。 从零创建项目应走
create-voltagent/npm create voltagent-app@latest。这份 Skill 不生成package.json,也不替你选模型提供商。 - 判断表很短,细节在文档里。 Skill 不展开
.andWhen()/.andAll()/.andRace()等步骤类型,也不展开 Memory 适配器清单。写复杂流水线或生产存储时,仍要打开 Workflow Overview 和 Memory Overview。 src/agents/是约定,不是 CLI 默认产物。 脚手架可能把 Agent 放在index.ts。按这份 Skill 往上加功能时,再拆到agents/即可,不必认为官方 CLI 漏目录。- Workflow 的 memory 不是对话历史。 它存执行痕迹;对话上下文配在 Agent 上。入口的
workflowMemory和agentMemory拆开,就是为了这两类数据可以不同库。 - serverless 的具体包名以部署文档为准。 Skill 只写 provider 类型。Cloudflare / Netlify 官方示例用
@voltagent/serverless-hono的serverlessHono()。部分观测文档里出现过从@voltagent/core引入serverlessHono的片段,与 Instance / 部署文档不一致,写代码时以后者为准。 safeStringify针对 VoltAgent 包内部。 业务项目序列化普通 JSON 不必强行替换;在框架仓库里改 TypeScript 则不要用JSON.stringify。- Skill 目录里目前主要是
SKILL.md。 没有附带评测集或可执行脚本。效果取决于模型是否先按表选择 Agent/Workflow、是否沿用官方 snippet,而不是跳过约定直接编一套目录。
小结¶
voltagent-best-practices 把 VoltAgent 已经拍板的工程约定收成一份可移植 Skill:Agent 对开放式工具选择,Workflow 对可挂起的多步流水线;src/ 按 agents/、tools/、workflows/ 切开;内存用入口默认值,需要时再拆 agentMemory / workflowMemory;Node 走 Hono 或 Elysia,fetch 运行时走 serverless;VoltOps 用环境变量或 VoltOpsClient 接上。
它不教你从零 npm init,但能避免编程助手在框架已经有约定的地方临时发明结构。和 create-voltagent 搭配时,一个负责开工,一个负责按官方形状往下写。
官方地址:
https://github.com/voltagent/skills/tree/main/skills/voltagent-best-practices
目录页:
https://officialskills.sh/voltagent/skills/voltagent-best-practices
框架文档:
https://voltagent.dev/docs