Output Dev Agent Class

作者 growthxaia4f6bd40ab0e無授權條款440 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫今天更新

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.

AI 產生的概覽

說明如何使用 Output 的 Agent 類別實現多步驟工具迴圈、結構化輸出、訊息歷史與串流進度。

功能
本技能介紹 Output LLM 套件中的 Agent 類別,涵蓋建構選項、提示檔案、變數、工具與結構化輸出結構描述。它示範如何透過 generate、generateWithStreaming 與 stream 執行代理,以及如何接上可插拔的訊息存放區以保留多輪歷史。它也將 Agent 與 generateText 做比較,並提供在工作流程步驟中使用代理的檢查清單。
適用情境
適用於建構在迴圈中呼叫工具的多步驟代理、需要對話歷史,或需要可重複使用代理實例的情境。也適用於為代理加入結構化輸出、串流進度回呼或技能時。
執行需求
需要 Output 框架套件 @outputai/llm 與 @outputai/core、提示檔案,以及 AI SDK 模型供應者。不包含指令碼,僅為說明文件。

Using the Agent Class

Overview

The Agent class uses an internal AI SDK ToolLoopAgent through composition with Output prompt files and the skills system. It does not inherit from ToolLoopAgent. 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

typescript
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.

typescript
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

OptionTypeDefaultDescription
promptstring(required)Prompt file name (e.g. 'writing_assistant@v1')
promptDirstring-Override the stack-resolved prompt directory
variablesPromptVariables-Template variables rendered at construction
toolsAI SDK tools-Caller tools; merged with prompt YAML tools (load_skill last)
stopWhenfunction or function[]-Custom stop condition (overrides prompt maxSteps when tools exist)
outputaiSdk.Output-Structured output spec (e.g. aiSdk.Output.object({ schema }))
messageStoreMessageStore-Pluggable store for multi-turn history

generate()

Run the agent and return when complete:

typescript
const result = await agent.generate();console.log( result.text );   // Generated textconsole.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:

typescript
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:

typescript
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 stream is required. It accepts the same messages, abortSignal, and toolChoice as generate(), plus onChunk, onEnd, and onError:

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

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

stream() appends messages to the message store in its wrapped onEnd 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:

typescript
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:

typescript
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:

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

ModelMessage is an AI SDK type available through the aiSdk namespace or as an import from 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:

typescript
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

generateTextAgent
Best forSingle-shot LLM callsMulti-step tool loops
ToolsSupportedSupported
SkillsSupportedSupported
Conversation historyManualBuilt-in with messageStore
Reusable instanceNo (function call)Yes (construct once, call many)
Structured outputaiSdk.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)

typescript
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

來源與署名

來源:growthxai/output位於coding_assistants/claude/plugins/outputai/skills/output-dev-agent-class提交a4f6bd4

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架