• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialdevelopment

output-dev-agent-class

プラグイン
outputai
ソース
GitHub で見る ↗
説明

Agent クラスを使用する場合: 複数ステップのツール処理ループ、会話履歴、処理進捗の配信(リアルタイム表示)、再利用可能なLLMエージェント(言語モデルを活用した自動実行プログラム)を必要とするとき。スキルを持つエージェントの構築、出力形式の指定、状態を保つ会話機能、またはコールバック(処理完了時に実行される関数)を通じた進捗通知が必要な場合に適しています。

原文を表示

Use the Agent class for multi-step tool loops, conversation history, streaming progress, and reusable LLM agents. Use when building agents with skills, structured output, stateful conversations, or streaming callbacks.

ユースケース
  • 複数ステップのツール処理ループが必要なとき
  • 会話履歴を保持する必要があるとき
  • 処理進捗をリアルタイム表示したいとき
  • 再利用可能なLLMエージェントを構築するとき
  • コールバックで進捗通知を行いたいとき
本文(日本語訳)

Agent クラスの使用方法

概要

Agent クラスは、AI SDK の ToolLoopAgent を拡張し、出力プロンプトファイルとスキルシステムを統合したものです。複数ステップのツール実行、会話履歴、または再利用可能なエージェントインスタンスが必要な場合に使用してください。ツールを使わない単一の LLM 呼び出しの場合は、generateText の方がシンプルです。

このスキルを使用する場合

  • ツールをループで呼び出す複数ステップのエージェントを構築する場合
  • エージェントで遅延読み込み(後処理のタイミングで機能を読み込むこと)型の指示書を使用する場合
  • aiSdk.Output.object() で構造化出力を持つエージェントを作成する場合
  • messageStore で会話状態を保持する場合
  • onChunk でエージェントの進捗をストリーミング配信する場合
  • Agent と generateText の使い分けを判断する場合

インポートパターン

import { Agent, aiSdk } from '@outputai/llm';
import type { MessageStore } from '@outputai/llm';
import { z } from '@outputai/core';

Agent は @outputai/llm からインポートしてください。構造化出力には aiSdk.Output を使用します。z は @outputai/core からインポートしてください(直接 zod からはインポートしない)。MessageStore は、プラグイン可能な getMessages / addMessages ストアの型であり、自分で実装する必要があります。

コンストラクタ

プロンプトファイルはコンストラクタ時に読み込まれてレンダリングされます。変数とツールはコンストラクタで固定されます。スキルと maxSteps はプロンプトファイルから取得されます。エージェントは generate()、generateWithStreaming()、または stream() をすぐに呼び出せる状態です。

const agent = new Agent( {
  prompt: 'writing_assistant@v1',
  variables: {
    content_type: input.contentType,
    focus: input.focus,
    content: input.content
  },
  output: aiSdk.Output.object( { schema: reviewSchema } )
} );

コンストラクタのオプション

オプション 型 デフォルト 説明
prompt string 必須 プロンプトファイル名(例:'writing_assistant@v1')
promptDir string - スタック解決されたプロンプトディレクトリをオーバーライド
variables PromptVariables - コンストラクタ時にレンダリングされるテンプレート変数
tools AI SDK tools - 呼び出し元のツール。プロンプト YAML のツールとマージ(load_skill は最後)
stopWhen 関数または関数配列 - カスタム停止条件(ツールが存在する場合、プロンプトの maxSteps をオーバーライド)
output aiSdk.Output - 構造化出力の仕様(例:aiSdk.Output.object({ schema }))
messageStore MessageStore - 複数ターンの履歴用プラグイン可能なストア

generate()

エージェントを実行して完了時に戻ります:

const result = await agent.generate();
console.log( result.text );   // 生成されたテキスト
console.log( result.output ); // 構造化出力(aiSdk.Output.object 使用時)
console.log( result.usage );  // トークン使用量

結果は generateText と同じ形式です:text、result(text のエイリアス)、output、usage、finishReason、toolCalls など。

追加メッセージの渡し方

会話を拡張してメッセージを追加します:

const result = await agent.generate( {
  messages: [ { role: 'user', content: 'Focus on the introduction section.' } ]
} );

メッセージは初期プロンプトメッセージ(とメッセージストアの履歴)の後に追加されます。abortSignal と toolChoice も渡せます。

generateWithStreaming()

進捗コールバックと完全な結果が必要な場合は generateWithStreaming() を使用してください:

const result = await agent.generateWithStreaming( {
  onChunk( { chunk } ) {
    if ( chunk.type === 'text-delta' ) {
      process.stdout.write( chunk.text );
    }
  }
} );

このメソッドは内部でストリーミングを使用しながら generate() と同じように動作します。完全な応答を返し、ストリーム エラーで拒否し、設定されたメッセージストアにメッセージを自動的に追加します。generate() と同じ messages、abortSignal、toolChoice に加えて onChunk を受け付けます。Temporal ワークフロー ステップ内では、ストリーム結果への直接アクセスが必要でない限り stream() より優先してください。

stream()

textStream または fullStream の直接制御が必要な場合は stream() を使用してください。generate() と同じ messages、abortSignal、toolChoice に加えて onChunk、onFinish、onError を受け付けます:

const stream = await agent.stream();

for await ( const chunk of stream.textStream ) {
  process.stdout.write( chunk );
}

streamText と同様に、ストリーム結果は textStream と fullStream イテラブル、完了時に解決するプロミスベースのプロパティ(text、usage、finishReason)を提供します。

stream() は、finishReason が 'error' でない場合、ラップされた onFinish でメッセージストアにメッセージを追加します。詳細は output-dev-llm-streaming を参照してください。

構造化出力

aiSdk.Output.object() を使用して型付きの応答を取得してください:

const reviewSchema = z.object( {
  issues: z.array( z.string() ).describe( 'List of issues found' ),
  suggestions: z.array( z.string() ).describe( 'Actionable suggestions' ),
  score: z.number().describe( 'Quality score 0-100' ),
  summary: z.string().describe( 'Brief overall assessment' )
} );

const agent = new Agent( {
  prompt: 'writing_assistant@v1',
  variables: { content_type: 'documentation', focus: 'clarity', content: markdownContent },
  output: aiSdk.Output.object( { schema: reviewSchema } )
} );

const { output } = await agent.generate();
// output: { issues: string[], suggestions: string[], score: number, summary: string }

スキーマフィールドには .describe() を使用し、数値制約には .min()/.max() を使用しないでください。Anthropic はツール定義では minimum/maximum JSON スキーマ制約をサポートしていません。

メッセージストア

デフォルトでは Agent はステートレスです。各 generate() 呼び出しは初期プロンプトメッセージのみで最初から始まります。呼び出し全体で履歴を保持する場合は messageStore を渡してください:

import { Agent } from '@outputai/llm';
import type { MessageStore } from '@outputai/llm';

const messages: Parameters<MessageStore['addMessages']>[0] = [];
const messageStore: MessageStore = {
  getMessages: () => messages,
  addMessages: incoming => {
    messages.push( ...incoming );
  }
};

const chatbot = new Agent( {
  prompt: 'chatbot@v1',
  messageStore
} );

const r1 = await chatbot.generate( {
  messages: [ { role: 'user', content: 'Hello, tell me about Output.' } ]
} );
// r1.text: "Output is an AI framework for..."

const r2 = await chatbot.generate( {
  messages: [ { role: 'user', content: 'How does it handle retries?' } ]
} );
// r2 は r1 からの完全な履歴を確認できます

MessageStore は以下のインターフェースです:

interface MessageStore {
  getMessages(): ModelMessage[] | Promise<ModelMessage[]>;
  addMessages( messages: ModelMessage[] ): void | Promise<void>;
}

ModelMessage は AI SDK の型(aiSdk / ai)です。組み込みストアはありません。単一プロセスではインメモリで、永続的な履歴についてはデータベースで実装してください。

ワークフローステップで Agent を使用する

ワークフローステップでは、呼び出しごとに新しい Agent を構築してください。変数はステップの入力から取得されます:

import { step, z } from '@outputai/core';
import { Agent, aiSdk } from '@outputai/llm';

const reviewSchema = z.object( {
  summary: z.string().describe( 'Brief assessment' ),
  issues: z.array( z.string() ).describe( 'Problems found' ),
  suggestions: z.array( z.string() ).describe( 'Improvements' ),
  score: z.number().describe( 'Quality score 0-100' )
} );

export const reviewContent = step( {
  name: 'reviewContent',
  description: 'Review technical content using Agent with structured output',
  inputSchema: z.object( {
    content: z.string().describe( 'The content to review' ),
    content_type: z.string().describe( 'Type of content' ),
    focus: z.string().describe( 'Review focus areas' )
  } ),
  outputSchema: reviewSchema,
  fn: async input => {
    const agent = new Agent( {
      prompt: 'writing_assistant@v1',
      variables: input,
      output: aiSdk.Output.object( { schema: reviewSchema } )
    } );
    const { output } = await agent.generate();
    return output;
  }
} );

これが標準的なパターンです。各ステップ呼び出しは独立しており、Agent 構築は軽量です。

Agent とスキルの組み合わせ

プロンプトのフロントマター(ファイルの先頭メタデータ)にスキルパスを記載します。詳細は output-dev-skill-file を参照してください。

Agent と generateText の使い分け

generateText Agent
最適な用途 単一の LLM 呼び出し 複数ステップのツールループ
ツール サポート サポート
スキル サポート サポート
会話履歴 手動 messageStore で組み込み
再利用可能なインスタンス いいえ(関数呼び出し) はい(一度構築して複数回呼び出し)
構造化出力 aiSdk.Output.object() aiSdk.Output.object()

generateText から始めてください。会話状態または固定設定を持つ再利用可能なインスタンスが必要になったら Agent に移行してください。

generateText の例(比較用)

import { generateText } from '@outputai/llm';

const { result } = await generateText( {
  prompt: 'generate_summary@v1',
  variables: {
    company_name: input.name,
    website_content: input.websiteContent
  }
} );

確認チェックリスト

  • [ ] Agent を @outputai/llm からインポート(ai から直接ではない)
  • [ ] z を @outputai/core からインポート(zod からではない)
  • [ ] プロンプトファイルが prompts/ フォルダに存在する
  • [ ] 変数がプロンプト内の {{ variable }} プレースホルダと一致
  • [ ] プロンプトのフロントマターで maxSteps を設定(スキルまたはツールに 10 以外の上限が必要な場合)
  • [ ] aiSdk.Output.object({ schema }) で数値に .min()/.max() ではなく .describe() を使用
  • [ ] messageStore は複数ターンの履歴が必要な場合にのみ使用
  • [ ] ワークフローステップでは Agent をステップの fn 内で構築(モジュールレベルではない)
  • [ ] コールバックで十分な場合は stream() より generateWithStreaming() を優先

関連スキル

  • output-dev-skill-file - エージェント用スキルファイルの作成
  • output-dev-llm-streaming - ストリーミング進捗と Temporal 安全なエラー処理
  • output-dev-prompt-file - エージェントが使用する .prompt ファイルの作成
  • output-dev-step-function - ステップ関数でのエージェント使用
  • output-dev-types-file - 構造化出力用 Zod スキーマの定義
  • output-dev-workflow-function - エージェント駆動型ステップのオーケストレーション
原文(English)を表示

Using the Agent Class

Overview

The Agent class extends AI SDK's ToolLoopAgent with Output prompt files and the skills system. Use it when you need multi-step tool execution, conversation history, or a reusable agent instance. For single-shot LLM calls without tools, generateText is simpler.

When to Use This Skill

  • Building multi-step agents that call tools in a loop
  • Using skills (lazy-loaded instructions) with an agent
  • Creating agents with structured output via aiSdk.Output.object()
  • Implementing stateful conversations with messageStore
  • Streaming Agent progress with onChunk
  • Deciding between Agent and generateText

Import Pattern

import { Agent, aiSdk } from '@outputai/llm';
import type { MessageStore } from '@outputai/llm';
import { z } from '@outputai/core';

Agent comes from @outputai/llm. Use aiSdk.Output for structured output. Import z from @outputai/core (never from zod directly). MessageStore is the type for a pluggable getMessages / addMessages store; implement it yourself.

Construction

The prompt file is loaded and rendered at construction time. Variables and tools are fixed at construction. Skills and maxSteps come from the prompt file. The agent is ready to call generate(), generateWithStreaming(), or stream() immediately.

const agent = new Agent( {
  prompt: 'writing_assistant@v1',
  variables: {
    content_type: input.contentType,
    focus: input.focus,
    content: input.content
  },
  output: aiSdk.Output.object( { schema: reviewSchema } )
} );

Constructor Options

Option Type Default Description
prompt string (required) Prompt file name (e.g. 'writing_assistant@v1')
promptDir string - Override the stack-resolved prompt directory
variables PromptVariables - Template variables rendered at construction
tools AI SDK tools - Caller tools; merged with prompt YAML tools (load_skill last)
stopWhen function or function[] - Custom stop condition (overrides prompt maxSteps when tools exist)
output aiSdk.Output - Structured output spec (e.g. aiSdk.Output.object({ schema }))
messageStore MessageStore - Pluggable store for multi-turn history

generate()

Run the agent and return when complete:

const result = await agent.generate();
console.log( result.text );   // Generated text
console.log( result.output ); // Structured output (when using aiSdk.Output.object)
console.log( result.usage );  // Token counts

The result has the same shape as generateText: text, result (alias for text), output, usage, finishReason, toolCalls, etc.

Passing Additional Messages

Extend the conversation with extra messages:

const result = await agent.generate( {
  messages: [ { role: 'user', content: 'Focus on the introduction section.' } ]
} );

Messages are appended after the initial prompt messages (and any message-store history). You can also pass abortSignal and toolChoice.

generateWithStreaming()

Use generateWithStreaming() when you need progress callbacks and a complete result:

const result = await agent.generateWithStreaming( {
  onChunk( { chunk } ) {
    if ( chunk.type === 'text-delta' ) {
      process.stdout.write( chunk.text );
    }
  }
} );

The method behaves like generate() while using streaming internally. It returns the complete response, rejects on stream errors, and automatically appends messages to the configured message store. It accepts the same messages, abortSignal, and toolChoice as generate(), plus onChunk. Prefer it over stream() in Temporal activity steps unless direct access to the stream result is required.

stream()

Use stream() when direct control over textStream or fullStream is required. It accepts the same messages, abortSignal, and toolChoice as generate(), plus onChunk, onFinish, and onError:

const stream = await agent.stream();

for await ( const chunk of stream.textStream ) {
  process.stdout.write( chunk );
}

Like streamText, the stream result provides textStream and fullStream iterables, plus promise-based properties (text, usage, finishReason) that resolve on completion.

stream() appends messages to the message store in its wrapped onFinish when finishReason is not 'error'. See output-dev-llm-streaming for streaming and error-handling guidance.

Structured Output

Use aiSdk.Output.object() to get typed responses:

const reviewSchema = z.object( {
  issues: z.array( z.string() ).describe( 'List of issues found' ),
  suggestions: z.array( z.string() ).describe( 'Actionable suggestions' ),
  score: z.number().describe( 'Quality score 0-100' ),
  summary: z.string().describe( 'Brief overall assessment' )
} );

const agent = new Agent( {
  prompt: 'writing_assistant@v1',
  variables: { content_type: 'documentation', focus: 'clarity', content: markdownContent },
  output: aiSdk.Output.object( { schema: reviewSchema } )
} );

const { output } = await agent.generate();
// output: { issues: string[], suggestions: string[], score: number, summary: string }

Use .describe() on schema fields instead of .min()/.max() for number constraints. Anthropic does not support minimum/maximum JSON Schema constraints in tool definitions.

Message Store

By default, Agent is stateless. Each generate() call starts fresh with only the initial prompt messages. Pass a messageStore to maintain history across calls:

import { Agent } from '@outputai/llm';
import type { MessageStore } from '@outputai/llm';

const messages: Parameters<MessageStore['addMessages']>[0] = [];
const messageStore: MessageStore = {
  getMessages: () => messages,
  addMessages: incoming => {
    messages.push( ...incoming );
  }
};

const chatbot = new Agent( {
  prompt: 'chatbot@v1',
  messageStore
} );

const r1 = await chatbot.generate( {
  messages: [ { role: 'user', content: 'Hello, tell me about Output.' } ]
} );
// r1.text: "Output is an AI framework for..."

const r2 = await chatbot.generate( {
  messages: [ { role: 'user', content: 'How does it handle retries?' } ]
} );
// r2 sees the full history from r1

MessageStore is:

interface MessageStore {
  getMessages(): ModelMessage[] | Promise<ModelMessage[]>;
  addMessages( messages: ModelMessage[] ): void | Promise<void>;
}

ModelMessage is an AI SDK type (aiSdk / ai). There is no built-in store. Implement the interface in memory for a single process, or with your database for durable history.

Using Agent in Workflow Steps

In workflow steps, construct a new Agent per invocation. Variables come from the step input:

import { step, z } from '@outputai/core';
import { Agent, aiSdk } from '@outputai/llm';

const reviewSchema = z.object( {
  summary: z.string().describe( 'Brief assessment' ),
  issues: z.array( z.string() ).describe( 'Problems found' ),
  suggestions: z.array( z.string() ).describe( 'Improvements' ),
  score: z.number().describe( 'Quality score 0-100' )
} );

export const reviewContent = step( {
  name: 'reviewContent',
  description: 'Review technical content using Agent with structured output',
  inputSchema: z.object( {
    content: z.string().describe( 'The content to review' ),
    content_type: z.string().describe( 'Type of content' ),
    focus: z.string().describe( 'Review focus areas' )
  } ),
  outputSchema: reviewSchema,
  fn: async input => {
    const agent = new Agent( {
      prompt: 'writing_assistant@v1',
      variables: input,
      output: aiSdk.Output.object( { schema: reviewSchema } )
    } );
    const { output } = await agent.generate();
    return output;
  }
} );

This is the standard pattern. Each step invocation is independent, and Agent construction is cheap.

Using Agent with Skills

List skill paths in the prompt frontmatter. See output-dev-skill-file for the full skills guide.

When to Use Agent vs generateText

generateText Agent
Best for Single-shot LLM calls Multi-step tool loops
Tools Supported Supported
Skills Supported Supported
Conversation history Manual Built-in with messageStore
Reusable instance No (function call) Yes (construct once, call many)
Structured output aiSdk.Output.object() aiSdk.Output.object()

Start with generateText. Move to Agent when you need conversation state or a reusable instance with a fixed configuration.

generateText Example (for comparison)

import { generateText } from '@outputai/llm';

const { result } = await generateText( {
  prompt: 'generate_summary@v1',
  variables: {
    company_name: input.name,
    website_content: input.websiteContent
  }
} );

Verification Checklist

  • [ ] Import Agent from @outputai/llm (not from ai directly)
  • [ ] Import z from @outputai/core (never from zod)
  • [ ] Prompt file exists in prompts/ folder
  • [ ] Variables match {{ variable }} placeholders in the prompt
  • [ ] Prompt frontmatter sets maxSteps when skills or tools need a ceiling other than 10
  • [ ] aiSdk.Output.object({ schema }) uses .describe() not .min()/.max() on numbers
  • [ ] messageStore is only used when multi-turn history is needed
  • [ ] Agent is constructed inside the step fn (not at module level) for workflow steps
  • [ ] Prefer generateWithStreaming() when callbacks are sufficient

Related Skills

  • output-dev-skill-file - Creating skill files for agents
  • output-dev-llm-streaming - Streaming progress and Temporal-safe error handling
  • output-dev-prompt-file - Creating .prompt files used by agents
  • output-dev-step-function - Using agents in step functions
  • output-dev-types-file - Defining Zod schemas for structured output
  • output-dev-workflow-function - Orchestrating agent-powered steps

原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。