🤖output-dev-agent-class
- プラグイン
- outputai
- ソース
- GitHub で見る ↗
説明
次のような場合に使用: マルチステップのツールループ、会話履歴、および再利用可能なLLM Agentを構築する際には、Agent クラスを使用してください。 スキルを持つAgentの構築、構造化された出力、またはステートフルな会話を実装する場合に適しています。
原文を表示
Use the Agent class for multi-step tool loops, conversation history, and reusable LLM agents. Use when building agents with skills, structured output, or stateful conversations.
ユースケース
- ✓マルチステップのツールループを構築するとき
- ✓会話履歴を管理するとき
- ✓再利用可能なLLM Agentを構築するとき
- ✓スキルを持つAgentを構築するとき
- ✓ステートフルな会話を実装するとき
本文(日本語訳)
Agentクラスの使い方
概要
Agentクラスは、AI SDKのToolLoopAgentをOutputプロンプトファイルおよびskillsシステムで拡張したものです。
次のような場合に使用:
複数ステップにわたるツール実行、会話履歴の管理、または再利用可能なagentインスタンスが必要なとき。
ツールを使わない単発のLLM呼び出しであれば、generateTextの方がシンプルです。
このSkillを使う場面
- ツールをループで呼び出す複数ステップのagentを構築する
- agentでskill(遅延ロードされるインストラクション)を利用する
Output.object()による構造化出力を持つagentを作成するconversationStoreでステートフルな会話を実装するAgentとgenerateTextのどちらを使うか判断する
インポートパターン
import { Agent, createMemoryConversationStore, skill, Output } from '@outputai/llm';
import { z } from '@outputai/core';
Agent、createMemoryConversationStore、skill、Outputはすべて@outputai/llmからインポートします。
zは@outputai/coreからインポートしてください(zodから直接インポートしないこと)。
コンストラクション
プロンプトファイルはコンストラクション時にロード・レンダリングされます。
変数・skill・ツールはコンストラクション時に固定され、agentはすぐにgenerate()またはstream()を呼び出せる状態になります。
const agent = new Agent( {
prompt: 'writing_assistant@v1',
variables: {
content_type: input.contentType,
focus: input.focus,
content: input.content
},
skills: [ audienceSkill ],
output: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
コンストラクターオプション
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
prompt |
string |
(必須) | プロンプトファイル名(例: 'writing_assistant@v1') |
variables |
Record<string, unknown> |
{} |
コンストラクション時にレンダリングされるテンプレート変数 |
skills |
Skill[] |
[] |
LLM向けのskillパッケージ(output-dev-skill-file参照) |
tools |
ToolSet |
{} |
ループ中に利用可能なAI SDKツール |
maxSteps |
number |
10 |
ツールループの最大イテレーション数 |
stopWhen |
StopCondition |
- | カスタム停止条件(maxStepsを上書き) |
output |
Output |
- | 構造化出力の仕様(例: Output.object({ schema })) |
conversationStore |
ConversationStore |
- | 複数ターンの履歴を管理するプラガブルストア |
temperature |
number |
- | プロンプトファイルのtemperatureを上書き |
onStepFinish |
Function |
- | ツールループの各ステップ完了後に呼ばれるコールバック |
prepareStep |
Function |
- | 各ステップを実行前にカスタマイズする |
generate()
agentを実行し、完了まで待機して結果を返します:
const result = await agent.generate();
console.log( result.text ); // 生成されたテキスト
console.log( result.output ); // 構造化出力(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.' } ]
} );
メッセージは、初期プロンプトメッセージ(およびconversation storeの履歴)の後に追加されます。
stream()
agentのレスポンスをストリーミングします:
const stream = await agent.stream();
for await ( const chunk of stream.textStream ) {
process.stdout.write( chunk );
}
streamTextと同様に、ストリーム結果はtextStreamおよびfullStreamのイテラブルを提供し、完了時に解決されるPromiseベースのプロパティ(text、usage、finishReason)も利用できます。
重要: stream()はconversation storeへのメッセージの自動追加を行いません。
ストリーミングをconversation storeと併用する場合は、メッセージを手動で永続化してください。
構造化出力
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: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
const { output } = await agent.generate();
// output: { issues: string[], suggestions: string[], score: number, summary: string }
スキーマフィールドには.min()/.max()ではなく.describe()を使用してください。
Anthropicはツール定義におけるminimum/maximum JSON Schemaの制約をサポートしていません。
Conversation Store
デフォルトでは、Agentはステートレスです。
各generate()呼び出しは、初期プロンプトメッセージのみでゼロから開始されます。
conversationStoreを渡すことで、呼び出しをまたいだ履歴の保持が可能になります:
import { Agent, createMemoryConversationStore } from '@outputai/llm';
const store = createMemoryConversationStore();
const chatbot = new Agent( {
prompt: 'chatbot@v1',
conversationStore: store
} );
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からの全会話履歴が参照される
カスタムストア
本番環境での利用では、ConversationStoreインターフェースをデータベースで実装してください:
interface ConversationStore {
getMessages(): ModelMessage[] | Promise<ModelMessage[]>;
addMessages(messages: ModelMessage[]): void | Promise<void>;
}
createMemoryConversationStore()は組み込みのインメモリ実装です。
ワークフローステップでのAgentの使い方
ワークフローステップでは、呼び出しごとに新しいAgentを生成してください。 変数はステップの入力から取得します:
import { step, z } from '@outputai/core';
import { Agent, Output } 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: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
const { output } = await agent.generate();
return output;
}
} );
これが標準パターンです。各ステップの呼び出しは独立しており、Agentのコンストラクションは低コストです。
インラインSkillを使ったAgentの利用
インラインskillとAgentを組み合わせることで、動的な専門知識を付与できます:
import { Agent, skill, Output } from '@outputai/llm';
const audienceSkill = skill( {
name: 'audience_adaptation',
description: 'Tailor feedback for the specified expertise level',
instructions: `# Audience Adaptation
When the target audience is specified, adjust your feedback:
**Beginner**: Flag jargon as high-priority issues.
**Expert**: Focus on accuracy and completeness.
Always mention the audience level in your summary.`
} );
const agent = new Agent( {
prompt: 'writing_assistant@v1',
variables: input,
skills: [ audienceSkill ],
output: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
const { output } = await agent.generate();
インラインskillは、プロンプトと同じディレクトリのskills/フォルダやフロントマターパスに配置されたファイルベースのskillとマージされます。
skillの詳細なガイドはoutput-dev-skill-fileを参照してください。
AgentとgenerateTextの使い分け
generateText |
Agent |
|
|---|---|---|
| 最適な用途 | 単発のLLM呼び出し | 複数ステップのツールループ |
| ツール | 対応 | 対応 |
| Skill | 対応 | 対応 |
| 会話履歴 | 手動管理 | conversationStoreで組み込み対応 |
| 再利用可能なインスタンス | 不可(関数呼び出し) | 可能(一度構築して何度も呼び出せる) |
| 構造化出力 | Output.object() |
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 }}プレースホルダーと一致している - [ ] skillまたはツール使用時に
maxStepsが設定されている(デフォルト: 10) - [ ]
Output.object({ schema })で数値の制約に.min()/.max()ではなく.describe()を使用している - [ ] conversation storeは複数ターンの履歴が必要な場合のみ使用している
- [ ] ワークフローステップでは、Agentをモジュールレベルではなくステップの
fn内でコンストラクトしている
関連Skill
output-dev-skill-file- agent向けskillファイルの作成output-dev-prompt-file- agentが使用する.promptファイルの作成output-dev-step-function- ステップ関数でのagentの利用output-dev-types-file- 構造化出力のためのZodスキーマ定義output-dev-workflow-function- agent活用ステップのオーケストレーション
原文(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
Output.object() - Implementing stateful conversations with
conversationStore - Deciding between
AgentandgenerateText
Import Pattern
import { Agent, createMemoryConversationStore, skill, Output } from '@outputai/llm';
import { z } from '@outputai/core';
Agent, createMemoryConversationStore, skill, and Output all come from @outputai/llm. Import z from @outputai/core (never from zod directly).
Construction
The prompt file is loaded and rendered at construction time. Variables, skills, and tools are fixed at construction. The agent is ready to call generate() or stream() immediately.
const agent = new Agent( {
prompt: 'writing_assistant@v1',
variables: {
content_type: input.contentType,
focus: input.focus,
content: input.content
},
skills: [ audienceSkill ],
output: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
Constructor Options
| Option | Type | Default | Description |
|---|---|---|---|
prompt |
string |
(required) | Prompt file name (e.g. 'writing_assistant@v1') |
variables |
Record<string, unknown> |
{} |
Template variables rendered at construction |
skills |
Skill[] |
[] |
Skill packages for the LLM (see output-dev-skill-file) |
tools |
ToolSet |
{} |
AI SDK tools available during the loop |
maxSteps |
number |
10 |
Maximum tool-loop iterations |
stopWhen |
StopCondition |
- | Custom stop condition (overrides maxSteps) |
output |
Output |
- | Structured output spec (e.g. Output.object({ schema })) |
conversationStore |
ConversationStore |
- | Pluggable store for multi-turn history |
temperature |
number |
- | Override prompt file temperature |
onStepFinish |
Function |
- | Callback after each tool-loop step |
prepareStep |
Function |
- | Customize each step before execution |
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 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 conversation store history).
stream()
Stream the agent's response:
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.
Important: stream() does not automatically append messages to the conversation store. If you use streaming with a conversation store, persist messages manually.
Structured Output
Use 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: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
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.
Conversation Store
By default, Agent is stateless. Each generate() call starts fresh with only the initial prompt messages. Pass a conversationStore to maintain history across calls:
import { Agent, createMemoryConversationStore } from '@outputai/llm';
const store = createMemoryConversationStore();
const chatbot = new Agent( {
prompt: 'chatbot@v1',
conversationStore: store
} );
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 conversation history from r1
Custom Store
For production use, implement the ConversationStore interface with your database:
interface ConversationStore {
getMessages(): ModelMessage[] | Promise<ModelMessage[]>;
addMessages(messages: ModelMessage[]): void | Promise<void>;
}
createMemoryConversationStore() is the built-in in-memory implementation.
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, Output } 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: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
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 Inline Skills
Combine inline skills with Agent for dynamic expertise:
import { Agent, skill, Output } from '@outputai/llm';
const audienceSkill = skill( {
name: 'audience_adaptation',
description: 'Tailor feedback for the specified expertise level',
instructions: `# Audience Adaptation
When the target audience is specified, adjust your feedback:
**Beginner**: Flag jargon as high-priority issues.
**Expert**: Focus on accuracy and completeness.
Always mention the audience level in your summary.`
} );
const agent = new Agent( {
prompt: 'writing_assistant@v1',
variables: input,
skills: [ audienceSkill ],
output: Output.object( { schema: reviewSchema } ),
maxSteps: 5
} );
const { output } = await agent.generate();
Inline skills are merged with any file-based skills from the prompt's colocated skills/ directory or frontmatter paths. 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 conversationStore |
| Reusable instance | No (function call) | Yes (construct once, call many) |
| Structured output | Output.object() |
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
Agentfrom@outputai/llm(not fromaidirectly) - [ ] Import
zfrom@outputai/core(never fromzod) - [ ] Prompt file exists in
prompts/folder - [ ] Variables match
{{ variable }}placeholders in the prompt - [ ]
maxStepsis set when using skills or tools (default 10) - [ ]
Output.object({ schema })uses.describe()not.min()/.max()on numbers - [ ] Conversation store is only used when multi-turn history is needed
- [ ] Agent is constructed inside the step
fn(not at module level) for workflow steps
Related Skills
output-dev-skill-file- Creating skill files for agentsoutput-dev-prompt-file- Creating .prompt files used by agentsoutput-dev-step-function- Using agents in step functionsoutput-dev-types-file- Defining Zod schemas for structured outputoutput-dev-workflow-function- Orchestrating agent-powered steps
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。