VoltAgent のエージェントは、指示、ツール、メモリとその他の機能で言語モデルをラッピングします。ユーザはエージェント・インスタンスを作成してから、そのメソッドを呼び出してレスポンスを生成したり出力をストリーミングします。
VoltAgent : エージェント – 概要
作成 : クラスキャット・セールスインフォメーション
作成日時 : 12/22/2025
バージョン : @voltagent/core@1.5.0
* 本記事は voltagent.dev/docs の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

VoltAgent : エージェント – 概要
VoltAgent のエージェントは、指示、ツール、メモリとその他の機能で言語モデルをラッピングします。ユーザはエージェント・インスタンスを作成してから、そのメソッドを呼び出してレスポンスを生成したり出力をストリーミングします。
VoltAgent でエージェントを使用するには 2 つの方法があります :
- 直接的なメソッド呼び出し – アプリケーションのコードからエージェントのメソッド (generateText, streamText, generateObject, streamObject) を呼び出します。
- REST API – VoltAgent の HTTP サーバを使用してエージェントを REST エンドポイントとして公開します。
このドキュメントは、基本から始めて、両方のアプローチをカバーします。
エージェントの作成
エージェントは 3 つのプロパティ: name, instructions と model が必要です。
import { Agent } from "@voltagent/core";
import { openai } from "@ai-sdk/openai";
const agent = new Agent({
name: "Assistant",
instructions: "Answer questions clearly and concisely.",
model: openai("gpt-4o"),
});
instructions プロパティはエージェントの動作を定義します。model は ai-sdk から取得され、サポートされる任意のプロバイダー (OpenAI, Anthropic, Google 等) でかまいません。
エージェントの使用: 直接メソッド呼び出し
エージェントはレスポンスを生成するための 4 つのコアメソッドを持ちます :
テキスト生成
テキストレスポンスが必要な場合、これらのメソッドを使用します。
generateText – 完全なテキストレスポンスを一度に返します。
const result = await agent.generateText("What is TypeScript?");
console.log(result.text);
streamText – テキストチャンクを生成されると同時にストリーミングします (リアルタイム UI 用)。
const stream = await agent.streamText("Explain async/await");
for await (const chunk of stream.textStream) {
process.stdout.write(chunk);
}
ストリーミング機能
streamText や streamObject を使用すると、詳細なイベントと最終的な値にアクセスできます。
詳細なイベント用の fullStream
fullStream を使用して、ツール呼び出し、推論ステップ、完了ステータスのような詳細なストリーミング・イベントを受け取ることができます。
const response = await agent.streamText("Write a story");
for await (const chunk of response.fullStream) {
switch (chunk.type) {
case "text-delta":
process.stdout.write(chunk.textDelta);
break;
case "tool-call":
console.log(`\nUsing tool: ${chunk.toolName}`);
break;
case "tool-result":
console.log(`Tool completed: ${chunk.toolName}`);
break;
case "finish":
console.log(`\nDone! Tokens: ${chunk.usage?.totalTokens}`);
break;
}
}
※ 訳注: 上述のコードはそのままでは動かないので、以下のように書き換えました。おそらくは ai-sdk v5.0 の仕様変更にドキュメントが追随していないのでしょう :
const response = await agent.streamText("Write a short horror story");
for await (const chunk of response.fullStream) {
switch (chunk.type) {
case "text-delta":
// text プロパティを使用
const text = (chunk as any).text;
if (text) {
process.stdout.write(text);
}
break;
case "tool-call":
console.log(`\nUsing tool: ${chunk.toolName}`);
break;
case "tool-result":
console.log(`Tool completed: ${chunk.toolName}`);
break;
case "finish":
const usage = (chunk as any).totalUsage;
console.log(`\nDone! Tokens: ${usage?.totalTokens} (input: ${usage?.inputTokens}, output: ${usage?.outputTokens})`);
break;
}
}
出力例
深夜の静かな村には、一つの古い伝説があった。村の奥に立つ廃屋には、「影の女」が住んでいると言われていた。 ある晩、若者のタケシは好奇心からその廃屋に足を踏み入れた。月明かりに照らされた部屋の中は、時間に忘れ去られたかのようだった。埃に覆われた家具が点在し、壁には奇妙な絵が描かれていた。 部屋の奥から小さなすすり泣きが聞こえ、タケシは思わず声の方へ歩み寄った。古い鏡に手をかざすと、そこには自分の姿の隣にぼんやりとした影が映っていた。その影がゆっくりと、しかし確かにタケシに手を伸ばした。 瞬間、部屋は不気味な冷気に包まれ、影の女が耳元でささやく。「あなたもここで私と一緒に…」 その後、タケシを見た者はいなかった。しかし村人たちは知っていた。新たな影が廃屋の中に増えていることを。 Done! Tokens: 319 (input: 28, output: 291)
Promise ベースのプロパティ
ストリーミングが完了したときに解決される Promise として最終的な値にアクセスできます。
const response = await agent.streamText("Explain async/await");
// Process stream
(async () => {
for await (const chunk of response.textStream) {
process.stdout.write(chunk);
}
})();
// Access final values (resolve when stream completes)
const [fullText, usage, finishReason] = await Promise.all([
response.text, // Promise
response.usage, // Promise
response.finishReason, // Promise
]);
console.log(`\nTotal: ${fullText.length} chars, ${usage?.totalTokens} tokens`);
出力例
async/awaitは非同期処理を簡潔に書くためのJavaScriptの構文です。
- **async関数**: 関数に`async`を付けることで、その関数が非同期関数になります。この関数は自動的にPromiseを返します。
- **await**: `await`キーワードは、Promiseの完了を待つために使います。`await`の後にPromiseが来ると、そのPromiseが解決または拒否されるまで処理が一時停止します。非同期処理が終了すると、結果が返されます。
具体的な例:
```javascript
async function fetchData() {
try {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
} catch (error) {
console.error('エラー:', error);
}
}
```
このように、`async`と`await`を使うことで、コールバックや`.then()`チェーンを避けつつ、同期的な記述が可能になります。
Total: 560 chars, 266 tokens
構造化データ生成
エージェントから構造化データを取得するには 2 つのアプローチがあります :
オプション 1: generateObject / streamObject (Schema-Only)
これらのメソッドは出力をスキーマに照らして検証しますが、ツール呼び出しはサポートしていません。これらはツールなしの単純なデータ抽出のために使用してください。
generateObject – 完全な検証済オブジェクトを返します。
import { z } from "zod";
const schema = z.object({
name: z.string(),
age: z.number(),
skills: z.array(z.string()),
});
const result = await agent.generateObject("Create a developer profile for Alex", schema);
console.log(result.object); // { name: "Alex", age: 28, skills: [...] }
出力例
{
name: 'Alex Johnson',
age: 30,
skills: [
'Python',
'JavaScript',
'React',
'Node.js',
'Django',
'REST APIs',
'SQL',
'Git',
'Docker',
'Agile methodologies'
]
}
streamObject – 部分的なオブジェクトを構築されるときにストリーミングします。
const stream = await agent.streamObject("Create a profile for Jamie", schema);
for await (const partial of stream.partialObjectStream) {
console.log(partial); // { name: "Jamie" } -> { name: "Jamie", age: 25 } -> ...
}
出力例
{}
{ name: '' }
{ name: 'Jamie' }
{ name: 'Jamie', age: 29 }
{ name: 'Jamie', age: 29, skills: [ '' ] }
{ name: 'Jamie', age: 29, skills: [ 'program' ] }
{ name: 'Jamie', age: 29, skills: [ 'programming' ] }
{ name: 'Jamie', age: 29, skills: [ 'programming', '' ] }
{ name: 'Jamie', age: 29, skills: [ 'programming', 'graphic' ] }
{ name: 'Jamie', age: 29, skills: [ 'programming', 'graphic design' ] }
{
name: 'Jamie',
age: 29,
skills: [ 'programming', 'graphic design', '' ]
}
{
name: 'Jamie',
age: 29,
skills: [ 'programming', 'graphic design', 'project' ]
}
{
name: 'Jamie',
age: 29,
skills: [ 'programming', 'graphic design', 'project management' ]
}
オプション 2: experimental_output (Schema + Agent 機能)
experimental_output を generateText/streamText とともに使用して、ツールとすべてのエージェント機能を使用しながら構造化データを取得できます。
import { Output } from "ai";
const recipeSchema = z.object({
name: z.string(),
ingredients: z.array(z.string()),
steps: z.array(z.string()),
prepTime: z.number(),
});
// With generateText - supports tool calling
const result = await agent.generateText("Create a pasta recipe", {
experimental_output: Output.object({ schema: recipeSchema }),
});
console.log(result.experimental_output); // { name: "...", ingredients: [...], ... }
// With streamText - stream partial objects while using tools
const stream = await agent.streamText("Create a detailed recipe", {
experimental_output: Output.object({ schema: recipeSchema }),
});
for await (const partial of stream.experimental_partialOutputStream ?? []) {
console.log(partial); // Incrementally built object
}
// Constrained text generation
const haiku = await agent.generateText("Write a haiku about coding", {
experimental_output: Output.text({
maxLength: 100,
description: "A traditional haiku poem",
}),
});
console.log(haiku.experimental_output);
When to use which :
- ツール呼び出しなしで単純なスキーマ検証を行う場合は、generateObject/streamObject を使用します
- 構造化出力とツール呼び出しを必要とする場合は、experimental_output を使用します
入力タイプ
すべてのメソッドは文字列またはメッセージの配列を受け取ります。
// String input
await agent.generateText("Hello");
// Message array (for multimodal or conversation history)
await agent.generateText([{ role: "user", content: "What's in this image?" }]);
エージェント: REST API の使用
VoltAgent はエージェントを HTTP エンドポイントを通して公開できます。これは任意のクライアント (web, mobile 等) からエージェントを呼び出すことを可能にします。
サーバセットアップ
サーバプロバイダーを使用して VoltAgent インスタンスを作成します :
import { VoltAgent, Agent } from "@voltagent/core";
import { honoServer } from "@voltagent/server-hono";
import { openai } from "@ai-sdk/openai";
const agent = new Agent({
name: "assistant",
instructions: "Answer questions clearly.",
model: openai("gpt-4o"),
});
new VoltAgent({
agents: { assistant: agent },
server: honoServer(), // Starts on port 3141 by default
});
利用可能なエンドポイント
サーバは以下の REST エンドポイントを公開します :
テキスト生成
- POST /agents/:id/text – 完全なテキストレスポンスを生成します (同期)
- POST /agents/:id/stream – fullStream イベントの生データをストリーミングします (SSE)
- POST /agents/:id/chat – useChat フック用の UI メッセージをストリーミングします (SSE)
構造化データ
- POST /agents/:id/object – 構造化オブジェクトの生成 (同期)
- POST /agents/:id/stream-object – ストリーミング・オブジェクトの生成 (SSE)
エンドポイントの比較
| エンドポイント | メソッド | レスポンス型 | ユースケース |
|---|---|---|---|
| /text | POST | JSON | すぐにテキスト・レスポンスを完了する |
| /stream | POST | SSE | Raw ストリームイベント (テキスト差分, ツール呼び出し, ツール結果, 終了) |
| /chat | POST | SSE | ai-sdk の useChat フック用の UI メッセージストリーム |
| /object | POST | JSON | すぐに構造化オブジェクトを完了する |
| /stream-object | POST | SSE | 部分オブジェクトをストリーミング |
HTTP 経由の構造化出力
テキストエンドポイントで experimental_output (/text, /stream, /chat) を使用すると、ツール呼び出し機能を維持しながら構造化データを取得できます。リクエストの options オブジェクトに experimental_output フィールドを追加します :
const response = await fetch("http://localhost:3141/agents/assistant/text", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
input: "Create a recipe",
options: {
experimental_output: {
type: "object",
schema: {
type: "object",
properties: {
name: { type: "string" },
ingredients: { type: "array", items: { type: "string" } },
},
required: ["name"],
},
},
},
}),
});
const data = await response.json();
console.log(data.data.experimental_output); // Structured object
For detailed API reference and examples, see Agent Endpoints – experimental_output.
Next.js API ルートからの呼び出し
SDK を使用した Next.js API ルートの例 (直接の REST 呼び出しではありません) :
// app/api/chat/route.ts
import { agent } from "@/voltagent";
export async function POST(req: Request) {
const { messages, conversationId, userId } = await req.json();
const result = await agent.streamText(messages, {
conversationId,
userId,
});
return result.toUIMessageStreamResponse();
}
クライアントから REST API を直接呼び出すには :
// Client-side code
const response = await fetch("http://localhost:3141/agents/assistant/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [{ role: "user", content: "Hello" }],
}),
});
// Stream response (SSE)
const reader = response.body.getReader();
// ... process stream chunks
コンストラクタ・オプション
追加のオプションでエージェントを構成設定できます :
const agent = new Agent({
// 必須
name: "MyAgent", // エージェント識別子
instructions: "You are a helpful assistant", // 動作ガイドライン
model: openai("gpt-4o"), // 使用する AI モデル (ai-sdk)
// オプション
id: "custom-id", // Unique ID (提供されない場合自動生成)
purpose: "Customer support agent", // スーパーバイザーコンテキスト用のエージェントの目的
tools: [weatherTool, searchTool], // 利用可能なツール
memory: memoryStorage, // メモリ・インスタンス (or false to disable)
context: new Map([
// Default context for all operations
["environment", "production"],
]),
maxSteps: 10, // Maximum tool-use iterations
temperature: 0.7, // Default creativity (overridable per call)
maxOutputTokens: 512, // Default token limit (overridable per call)
subAgents: [researchAgent], // Sub-agents for delegation
supervisorConfig: {
// Supervisor behavior config
systemMessage: "Custom supervisor instructions",
includeAgentsMemory: true,
},
// 追加のコンストラクタ・パラメータ
hooks: createHooks({ onStart, onEnd }), // Lifecycle event handlers
retriever: new PineconeRetriever(), // RAG retriever
voice: new ElevenLabsVoice(), // Voice configuration
markdown: true, // Enable markdown formatting
voltOpsClient: new VoltOpsClient({
// Observability & prompt management
publicKey: "...",
secretKey: "...",
}),
maxHistoryEntries: 1000, // Max history entries to store
});
以上