voltagent-best-practices:把 VoltAgent 架構約定寫進 Agent Skill

前言

create-voltagentnpm create voltagent-app@latest 能把 TypeScript Agent 項目搭起來,但真正動手寫業務時,編程助手仍會反覆問同一組問題:這件事該用 Agent 還是 Workflowsrc/ 怎麼切?內存掛在入口還是掛在單個對象上?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.mdAgent Skills 通用格式編寫,Cursor、Codex CLI、Claude Code 等能讀 Skill 的工具都可以加載。

和「跑一條腳手架命令」不同,這份文件承載的是框架級架構知識:什麼時候用 Agent、什麼時候用 Workflow、目錄怎麼放、內存和服務器怎麼選。它不替代 voltagent.dev/docs,而是讓編程助手在寫代碼前先對齊官方約定。

這是什麼

一句話定位:VoltAgent 架構模式與約定的速查手冊,覆蓋 Agent 與 Workflow 的取捨、項目佈局、內存默認值、服務器提供方,以及可觀測性接入。

官方 frontmatter:

  • namevoltagent-best-practices
  • description:VoltAgent architectural patterns and conventions. Covers agents vs workflows, project layout, memory, servers, and observability.
  • author:VoltAgent
  • version1.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,職責不要混:

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.tssrc/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 的共享默認
  • 兩邊默認值需要不同時,改用 agentMemoryworkflowMemory

官方 VoltAgent InstanceMemory 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 寫了兩條:

  • VoltOpsClientcreateVoltAgentObservability 做 tracing
  • 若設置了 VOLTAGENT_PUBLIC_KEYVOLTAGENT_SECRET_KEY,VoltAgent 會自動配置 VoltOps

官方 Observability Setup 與此一致:兩把鑰匙放進環境變量後,基礎路徑不需要再寫觀測代碼。鑰匙從 console.voltagent.dev 的項目設置裏取,格式是 pk_xxxxsk_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/internalsafeStringify。這是給改框架源碼、給 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.shskills.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 InstanceWorkflow 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-minianthropic/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 / workflowMemoryvoltOpsClientobservabilitylogger。換 Elysia 時把 import 改成 @voltagent/server-elysiaelysiaServer;上 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 這條倉庫內約定

使用時要注意

  1. 這是架構速查,不是腳手架。 從零創建項目應走 create-voltagent / npm create voltagent-app@latest。這份 Skill 不生成 package.json,也不替你選模型提供商。
  2. 判斷表很短,細節在文檔裏。 Skill 不展開 .andWhen() / .andAll() / .andRace() 等步驟類型,也不展開 Memory 適配器清單。寫複雜流水線或生產存儲時,仍要打開 Workflow OverviewMemory Overview
  3. src/agents/ 是約定,不是 CLI 默認產物。 腳手架可能把 Agent 放在 index.ts。按這份 Skill 往上加功能時,再拆到 agents/ 即可,不必認爲官方 CLI 漏目錄。
  4. Workflow 的 memory 不是對話歷史。 它存執行痕跡;對話上下文配在 Agent 上。入口的 workflowMemoryagentMemory 拆開,就是爲了這兩類數據可以不同庫。
  5. serverless 的具體包名以部署文檔爲準。 Skill 只寫 provider 類型。Cloudflare / Netlify 官方示例用 @voltagent/serverless-honoserverlessHono()。部分觀測文檔裏出現過從 @voltagent/core 引入 serverlessHono 的片段,與 Instance / 部署文檔不一致,寫代碼時以後者爲準。
  6. safeStringify 針對 VoltAgent 包內部。 業務項目序列化普通 JSON 不必強行替換;在框架倉庫裏改 TypeScript 則不要用 JSON.stringify
  7. 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

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜