• 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-types-file

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

types.ts ファイルを作成し、Output SDK(外部データ出力用のツール群)ワークフロー向けに Zod スキーマ(データ形式の定義・検証ツール)を設定します。 次のような場合に使用: 入出力スキーマを定義する、型定義を作成する、スキーマ関連のエラーを修正する場合。

原文を表示

Create types.ts files with Zod schemas for Output SDK workflows. Use when defining input/output schemas, creating type definitions, or fixing schema-related errors.

ユースケース
  • 入出力スキーマを定義するとき
  • 型定義を作成するとき
  • スキーマ関連のエラーを修正するとき
本文(日本語訳)

Zod スキーマを使った types.ts ファイルの作成

概要

このスキルは、Output SDK ワークフロー向けの types.ts ファイル作成方法をまとめています。このファイルに含めるのは、入出力のデータ検証を行う Zod スキーマ(スキーマとは、データの形や内容を定義するルールのこと)と、対応する TypeScript の型定義です。

このスキルを使う場合

  • 新しいワークフローの型定義を作成するとき
  • ステップ(処理の単位)用に新しいスキーマを追加するとき
  • スキーマの検証エラーを修正するとき
  • 既存の型定義をリファクタリング(整理し直し)するとき

重要なインポートのルール

z は 必ず @outputai/core からインポートしてください。zod から直接インポートしてはいけません:

// 正しい
import { z } from '@outputai/core';

// 間違い - 実行時エラーが発生
import { z } from 'zod';

関連スキル: インポートの問題をトラブルシューティングする場合は output-error-zod-import を参照してください。

基本構造

import { z } from '@outputai/core';

// 1. ワークフロー入力スキーマ
export const WorkflowInputSchema = z.object( {
  // 入力フィールドを定義
} );

// 2. ワークフロー出力型
export type WorkflowInput = z.infer<typeof WorkflowInputSchema>;
export type WorkflowOutput = /* 出力型 */;

// 3. ステップスキーマ(各ステップごと)
export const StepNameInputSchema = z.object( {
  // ステップ入力フィールド
} );

export const StepNameOutputSchema = z.object( {
  // ステップ出力フィールド
} );

// 4. 型のエクスポート
export type StepNameInput = z.infer<typeof StepNameInputSchema>;
export type StepNameOutput = z.infer<typeof StepNameOutputSchema>;

重要:LLM 出力用スキーマの制約

aiSdk.Output.object() に渡すスキーマは、LLM プロバイダー(AI サービス提供者)にツール定義として送信されます。Anthropic は Zod が生成する JSON スキーマの制約のいくつかを拒否します。これを間違えると、実行時エラーが発生します。

LLM 出力スキーマで禁止されている項目

  • 数値: z.number() の .min()、.max() は minimum/maximum を生成し、Anthropic により拒否されます。
  • 配列: z.array() の .min()、.max()、.length() は minItems/maxItems を生成し、Anthropic は minItems が 0 または 1 の場合のみサポートします。.length(3) や .min(2) などの値は拒否されます。

代わりに .describe() を使用する

.describe() は LLM 出力の品質を導く主要な仕組みです。LLM プロバイダーはスキーマのフィールド名と説明を使用して、各フィールドに何を含めるべきかを判断します。意図を明確に伝える具体的な説明を書いてください。

重要: .describe() は、サポートされていない制約とプロンプトベースの形式指示の両方に置き換わります。スキーマをプロンプトで説明してはいけません。スキーマは自動的にプロバイダーに送信され、重複するとパフォーマンスが低下し、ズレのリスクが生じます。詳細は output-dev-prompt-file を参照してください。

// LLM 出力スキーマ(aiSdk.Output.object() 経由でプロバイダーに送信)-- .describe() のみ
const llmOutputSchema = z.object( {
  score: z.number().describe( 'スコア 0-100' ),
  confidence: z.number().describe( '信頼度 0-1' ),
  predictions: z.array( predictionSchema ).describe( '予測結果ちょうど 3 つ' )
} );

// ワークフロー・ステップ検証用スキーマ(Zod のみ、LLM に送信されない)-- .min()/.max()/.length() 可
const workflowOutputSchema = z.object( {
  score: z.number().min( 0 ).max( 100 ).describe( 'スコア 0-100' ),
  confidence: z.number().min( 0 ).max( 1 ).describe( '信頼度 0-1' ),
  predictions: z.array( predictionSchema ).length( 3 ).describe( '予測結果ちょうど 3 つ' )
} );

どちらを使うべき場合

文脈 .min()/.max()/.length() .describe()
aiSdk.Output.object() に渡すスキーマ 不可(数値または配列) 推奨
ステップの inputSchema / outputSchema 可 任意
ワークフローの inputSchema / outputSchema 可 任意
評価関数の outputSchema 可 任意

LLM スキーマは types.ts に置く必要があります

aiSdk.Output.object() で使用するすべてのスキーマを types.ts で定義し、ステップ関数内でインポートしてください。インラインで定義してはいけません。重複が発生し、上記の制約に従っているか検証しづらくなります。

よくあるスキーマパターン

基本的な型

import { z } from '@outputai/core';

// 文字列
const stringField = z.string();
const optionalString = z.string().optional();
const stringWithDefault = z.string().default( 'デフォルト値' );
const describedString = z.string().describe( 'フィールドの説明' );

// 数値
const numberField = z.number();
const integerField = z.number().int();
const rangedNumber = z.number().min( 1 ).max( 100 ); // 実行時のみ — aiSdk.Output.object() スキーマでは非推奨

// 真偽値
const booleanField = z.boolean();
const defaultBoolean = z.boolean().default( false );

// 列挙型(決まった複数の値から選ぶ型)
const enumField = z.enum( [ 'option1', 'option2', 'option3' ] );
const enumWithDefault = z.enum( [ 'small', 'medium', 'large' ] ).default( 'medium' );

複合型

import { z } from '@outputai/core';

// 配列
const stringArray = z.array( z.string() );
const objectArray = z.array( z.object( { id: z.string(), name: z.string() } ) );

// オブジェクト
const nestedObject = z.object( {
  user: z.object( {
    id: z.string(),
    email: z.string().email()
  } ),
  settings: z.object( {
    notifications: z.boolean()
  } )
} );

// 合併型(複数の型のどれか)
const flexibleInput = z.union( [
  z.string(),
  z.array( z.string() )
] );

// キーと値のペア
const keyValueMap = z.record( z.string(), z.number() );

検証パターン

import { z } from '@outputai/core';

// 文字列の検証
const emailField = z.string().email();
const urlField = z.string().url();
const uuidField = z.string().uuid();
const minLengthString = z.string().min( 1 );
const maxLengthString = z.string().max( 1000 );

// 数値の検証
const positiveNumber = z.number().positive();
const nonNegativeNumber = z.number().nonnegative();
const percentageNumber = z.number().min( 0 ).max( 100 );

// 配列の検証(実行時のみ — aiSdk.Output.object() スキーマでは非推奨)
const nonEmptyArray = z.array( z.string() ).min( 1 );
const limitedArray = z.array( z.string() ).max( 10 );
const fixedLengthArray = z.array( z.string() ).length( 3 );

完全な例

実際のワークフロー(image_infographic_nano)に基づいています:

import { z } from '@outputai/core';

// ============================================
// ワークフロースキーマ
// ============================================

export const WorkflowInputSchema = z.object( {
  content: z.string().describe( '画像アイデア生成の元となるテキスト' ),
  mode: z.enum( [ 'infographic' ] ).default( 'infographic' ).describe( '生成する画像のタイプ' ),
  colorPalette: z.string().optional().describe( '画像の色合いに関する希望' ),
  artDirection: z.string().optional().describe( 'アート方向やスタイルの希望' ),
  numberOfIdeas: z.number().min( 1 ).max( 10 ).default( 1 ).describe( '生成する画像コンセプト数' ),
  referenceImageUrls: z.union( [
    z.string(),
    z.array( z.string() )
  ] ).optional().describe( 'スタイル参考用の画像 URL(最大 14 個)' ),
  aspectRatio: z.enum( [ '1:1', '16:9', '9:16', '4:3', '3:4' ] ).default( '1:1' ).describe( '生成画像のアスペクト比' ),
  resolution: z.enum( [ '1K', '2K', '4K' ] ).default( '1K' ).describe( '生成画像の解像度' ),
  numberOfGenerations: z.number().min( 1 ).max( 10 ).default( 1 ).describe( 'コンセプトあたりの生成画像数' ),
  storageNamespace: z.string().optional().describe( '画像保存先の S3 フォルダパス' )
} );

export type WorkflowInput = z.infer<typeof WorkflowInputSchema>;
export type WorkflowOutput = string[];

// ============================================
// ステップスキーマ
// ============================================

export const ValidateReferenceImagesInputSchema = z.object( {
  referenceImageUrls: z.array( z.string() ).optional()
} );

export const GenerateImageIdeasInputSchema = z.object( {
  content: z.string(),
  numberOfIdeas: z.number(),
  colorPalette: z.string().optional(),
  artDirection: z.string().optional()
} );

export const GenerateImagesInputSchema = z.object( {
  input: z.object( {
    referenceImageUrls: z.union( [ z.string(), z.array( z.string() ) ] ).optional(),
    aspectRatio: z.enum( [ '1:1', '16:9', '9:16', '4:3', '3:4' ] ),
    resolution: z.enum( [ '1K', '2K', '4K' ] ),
    numberOfGenerations: z.number(),
    storageNamespace: z.string().optional()
  } ),
  prompt: z.string()
} );

// LLM レスポンス検証用スキーマ
export const ImageIdeasSchema = z.object( {
  ideas: z.array( z.string() ).describe( 'Gemini 用の詳細な画像プロンプト配列' )
} );

// ============================================
// 型のエクスポート
// ============================================

export type ValidateReferenceImagesInput = z.infer<typeof ValidateReferenceImagesInputSchema>;
export type GenerateImageIdeasInput = z.infer<typeof GenerateImageIdeasInputSchema>;
export type GenerateImagesInput = z.infer<typeof GenerateImagesInputSchema>;
export type ImageIdeas = z.infer<typeof ImageIdeasSchema>;

ベストプラクティス

1. 分かりやすいフィールド説明を使う

// 良い例 - ドキュメントとエラーメッセージに役立つ
z.string().describe( 'お知らせ用のユーザーメールアドレス' )

// 避けるべき例 - コンテキストがない
z.string()

2. 適切なデフォルト値を指定する

// 良い例 - オプショナルフィールドなしでワークフローが動作
numberOfIdeas: z.number().min( 1 ).max( 10 ).default( 1 )

// 避けるべき例 - ユーザーがすべてのフィールドを指定する必要がある
numberOfIdeas: z.number().min( 1 ).max( 10 )

3. ワークフロースキーマとステップスキーマを分ける

// ワークフロー入力スキーマ(ユーザーが指定するもの)
export const WorkflowInputSchema = z.object( { ... } );

// ステップスキーマ(内部でのデータ形式)
export const StepNameInputSchema = z.object( { ... } );

4. スキーマと型の両方をエクスポートする

// 実行時の検証用にスキーマをエクスポート
export const UserSchema = z.object( { ... } );

// TypeScript の型チェック用に型をエクスポート
export type User = z.infer<typeof UserSchema>;

チェックリスト

  • [ ] z が @outputai/core からインポートされている
  • [ ] WorkflowInputSchema が定義・エクスポートされている
  • [ ] WorkflowInput 型がエクスポートされている
  • [ ] WorkflowOutput 型が定義されている
  • [ ] 各ステップに対応する入出力スキーマがある
  • [ ] 重要なフィールドすべてに .describe() がある
  • [ ] オプショナルフィールド
原文(English)を表示

Creating types.ts Files with Zod Schemas

Overview

This skill documents how to create types.ts files for Output SDK workflows. These files contain Zod schemas for input/output validation and their corresponding TypeScript types.

When to Use This Skill

  • Creating a new workflow's type definitions
  • Adding new schemas for steps
  • Fixing schema validation errors
  • Refactoring existing type definitions

Critical Import Rule

ALWAYS import z from @outputai/core, NEVER from zod directly:

// CORRECT
import { z } from '@outputai/core';

// WRONG - will cause runtime errors
import { z } from 'zod';

Related Skill: output-error-zod-import for troubleshooting import issues

Basic Structure

import { z } from '@outputai/core';

// 1. Workflow Input Schema
export const WorkflowInputSchema = z.object( {
  // Define input fields
} );

// 2. Workflow Output Type
export type WorkflowInput = z.infer<typeof WorkflowInputSchema>;
export type WorkflowOutput = /* output type */;

// 3. Step Schemas (for each step)
export const StepNameInputSchema = z.object( {
  // Step input fields
} );

export const StepNameOutputSchema = z.object( {
  // Step output fields
} );

// 4. Type Exports
export type StepNameInput = z.infer<typeof StepNameInputSchema>;
export type StepNameOutput = z.infer<typeof StepNameOutputSchema>;

CRITICAL: Schema Constraints for LLM Output

Schemas passed to aiSdk.Output.object() are sent to LLM providers as tool definitions. Anthropic rejects several JSON Schema constraints that Zod methods produce. Getting this wrong causes runtime errors.

What Is NOT Allowed in LLM Output Schemas

  • Numbers: .min(), .max() on z.number() produce minimum/maximum -- rejected by Anthropic.
  • Arrays: .min(), .max(), .length() on z.array() produce minItems/maxItems -- Anthropic only supports minItems of 0 or 1. Values like .length( 3 ) or .min( 2 ) will be rejected.

Use .describe() Instead

.describe() is the primary mechanism for guiding LLM output quality. LLM providers use field names and descriptions from the schema to understand what each field should contain. Write clear, specific descriptions that communicate your intent.

Important: .describe() replaces both unsupported constraints AND prompt-based format instructions. Do not also describe the schema in the prompt -- the schema is sent to the provider automatically, and duplicating it reduces performance and creates drift risk. See output-dev-prompt-file for details.

// LLM output schema (sent to provider via aiSdk.Output.object()) -- .describe() ONLY
const llmOutputSchema = z.object( {
  score: z.number().describe( 'Quality score 0-100' ),
  confidence: z.number().describe( 'Confidence 0-1' ),
  predictions: z.array( predictionSchema ).describe( 'Exactly 3 predictions' )
} );

// Workflow/step validation schema (Zod-only, NOT sent to LLM) -- .min()/.max()/.length() OK
const workflowOutputSchema = z.object( {
  score: z.number().min( 0 ).max( 100 ).describe( 'Quality score 0-100' ),
  confidence: z.number().min( 0 ).max( 1 ).describe( 'Confidence 0-1' ),
  predictions: z.array( predictionSchema ).length( 3 ).describe( 'Exactly 3 predictions' )
} );

When to Use Which

Context .min()/.max()/.length() .describe()
Schema passed to aiSdk.Output.object() No (numbers or arrays) Yes
inputSchema / outputSchema on steps OK Optional
inputSchema / outputSchema on workflows OK Optional
outputSchema on evaluators OK Optional

LLM Schemas Must Live in types.ts

Define all schemas used in aiSdk.Output.object() in types.ts and import them in step functions. Never define them inline -- this causes duplication and makes it harder to verify they follow the constraints above.

Common Schema Patterns

Basic Types

import { z } from '@outputai/core';

// Strings
const stringField = z.string();
const optionalString = z.string().optional();
const stringWithDefault = z.string().default( 'default value' );
const describedString = z.string().describe( 'Field description' );

// Numbers
const numberField = z.number();
const integerField = z.number().int();
const rangedNumber = z.number().min( 1 ).max( 100 ); // runtime only — NOT safe for aiSdk.Output.object() schemas

// Booleans
const booleanField = z.boolean();
const defaultBoolean = z.boolean().default( false );

// Enums
const enumField = z.enum( [ 'option1', 'option2', 'option3' ] );
const enumWithDefault = z.enum( [ 'small', 'medium', 'large' ] ).default( 'medium' );

Complex Types

import { z } from '@outputai/core';

// Arrays
const stringArray = z.array( z.string() );
const objectArray = z.array( z.object( { id: z.string(), name: z.string() } ) );

// Objects
const nestedObject = z.object( {
  user: z.object( {
    id: z.string(),
    email: z.string().email()
  } ),
  settings: z.object( {
    notifications: z.boolean()
  } )
} );

// Union Types
const flexibleInput = z.union( [
  z.string(),
  z.array( z.string() )
] );

// Records
const keyValueMap = z.record( z.string(), z.number() );

Validation Patterns

import { z } from '@outputai/core';

// String Validations
const emailField = z.string().email();
const urlField = z.string().url();
const uuidField = z.string().uuid();
const minLengthString = z.string().min( 1 );
const maxLengthString = z.string().max( 1000 );

// Number Validations
const positiveNumber = z.number().positive();
const nonNegativeNumber = z.number().nonnegative();
const percentageNumber = z.number().min( 0 ).max( 100 );

// Array Validations (runtime only — NOT safe for aiSdk.Output.object() schemas)
const nonEmptyArray = z.array( z.string() ).min( 1 );
const limitedArray = z.array( z.string() ).max( 10 );
const fixedLengthArray = z.array( z.string() ).length( 3 );

Complete Example

Based on a real workflow (image_infographic_nano):

import { z } from '@outputai/core';

// ============================================
// Workflow Schemas
// ============================================

export const WorkflowInputSchema = z.object( {
  content: z.string().describe( 'Text content to generate image ideas from' ),
  mode: z.enum( [ 'infographic' ] ).default( 'infographic' ).describe( 'Type of image to generate' ),
  colorPalette: z.string().optional().describe( 'Color palette preference for the images' ),
  artDirection: z.string().optional().describe( 'Art direction or style preference' ),
  numberOfIdeas: z.number().min( 1 ).max( 10 ).default( 1 ).describe( 'Number of image concepts to generate' ),
  referenceImageUrls: z.union( [
    z.string(),
    z.array( z.string() )
  ] ).optional().describe( 'Reference image URLs for style guidance (max 14)' ),
  aspectRatio: z.enum( [ '1:1', '16:9', '9:16', '4:3', '3:4' ] ).default( '1:1' ).describe( 'Aspect ratio for generated images' ),
  resolution: z.enum( [ '1K', '2K', '4K' ] ).default( '1K' ).describe( 'Resolution for generated images' ),
  numberOfGenerations: z.number().min( 1 ).max( 10 ).default( 1 ).describe( 'Number of images to generate per concept' ),
  storageNamespace: z.string().optional().describe( 'S3 folder path for storing images' )
} );

export type WorkflowInput = z.infer<typeof WorkflowInputSchema>;
export type WorkflowOutput = string[];

// ============================================
// Step Schemas
// ============================================

export const ValidateReferenceImagesInputSchema = z.object( {
  referenceImageUrls: z.array( z.string() ).optional()
} );

export const GenerateImageIdeasInputSchema = z.object( {
  content: z.string(),
  numberOfIdeas: z.number(),
  colorPalette: z.string().optional(),
  artDirection: z.string().optional()
} );

export const GenerateImagesInputSchema = z.object( {
  input: z.object( {
    referenceImageUrls: z.union( [ z.string(), z.array( z.string() ) ] ).optional(),
    aspectRatio: z.enum( [ '1:1', '16:9', '9:16', '4:3', '3:4' ] ),
    resolution: z.enum( [ '1K', '2K', '4K' ] ),
    numberOfGenerations: z.number(),
    storageNamespace: z.string().optional()
  } ),
  prompt: z.string()
} );

// Schema for LLM response validation
export const ImageIdeasSchema = z.object( {
  ideas: z.array( z.string() ).describe( 'Array of detailed image prompts for Gemini' )
} );

// ============================================
// Type Exports
// ============================================

export type ValidateReferenceImagesInput = z.infer<typeof ValidateReferenceImagesInputSchema>;
export type GenerateImageIdeasInput = z.infer<typeof GenerateImageIdeasInputSchema>;
export type GenerateImagesInput = z.infer<typeof GenerateImagesInputSchema>;
export type ImageIdeas = z.infer<typeof ImageIdeasSchema>;

Best Practices

1. Use Descriptive Field Descriptions

// Good - helps with documentation and error messages
z.string().describe( 'User email address for notifications' )

// Avoid - no context for errors
z.string()

2. Provide Sensible Defaults

// Good - workflow works without optional fields
numberOfIdeas: z.number().min( 1 ).max( 10 ).default( 1 )

// Avoid - forces users to provide every field
numberOfIdeas: z.number().min( 1 ).max( 10 )

3. Separate Workflow and Step Schemas

// Workflow input schema (what the user provides)
export const WorkflowInputSchema = z.object( { ... } );

// Step schemas (internal data shapes)
export const StepNameInputSchema = z.object( { ... } );

4. Export Both Schemas and Types

// Export schema for runtime validation
export const UserSchema = z.object( { ... } );

// Export type for TypeScript type checking
export type User = z.infer<typeof UserSchema>;

Verification Checklist

  • [ ] z is imported from @outputai/core
  • [ ] WorkflowInputSchema is defined and exported
  • [ ] WorkflowInput type is exported
  • [ ] WorkflowOutput type is defined
  • [ ] Each step has corresponding input/output schemas
  • [ ] All schemas have .describe() for important fields
  • [ ] Optional fields use .optional() or .default()
  • [ ] Numeric fields have appropriate constraints (.min()/.max() for runtime schemas, .describe() for aiSdk.Output.object() schemas)
  • [ ] Code follows style conventions (see output-dev-code-style)

Related Skills

  • output-dev-workflow-function - Using schemas in workflow definitions
  • output-dev-step-function - Using schemas in step definitions
  • output-dev-evaluator-function - Using schemas in evaluator definitions
  • output-dev-folder-structure - Where types.ts belongs in the project
  • output-error-zod-import - Troubleshooting schema import issues
  • output-dev-code-style - Code style conventions

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