VoltAgent : エージェント – 概要

VoltAgent のエージェントは、指示、ツール、メモリとその他の機能で言語モデルをラッピングします。ユーザはエージェント・インスタンスを作成してから、そのメソッドを呼び出してレスポンスを生成したり出力をストリーミングします。

VoltAgent : エージェント – 概要

作成 : クラスキャット・セールスインフォメーション
作成日時 : 12/22/2025
バージョン : @voltagent/core@1.5.0

* 本記事は voltagent.dev/docs の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

 

VoltAgent : エージェント – 概要

VoltAgent のエージェントは、指示、ツール、メモリとその他の機能で言語モデルをラッピングします。ユーザはエージェント・インスタンスを作成してから、そのメソッドを呼び出してレスポンスを生成したり出力をストリーミングします。

VoltAgent でエージェントを使用するには 2 つの方法があります :

  1. 直接的なメソッド呼び出し – アプリケーションのコードからエージェントのメソッド (generateText, streamText, generateObject, streamObject) を呼び出します。

  2. 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
});

 

以上