Agent Skills by ALSEL
Anthropic ClaudeLLM・AI開発⭐ リポ 337品質スコア 85/100

foundation-models

AppleのFoundation Modelsフレームワークを使用したデバイス上でのLLM統合です。AI によるテキスト生成、構造化された出力、またはツール呼び出しを実装する際に活用できます。

description の原文を見る

On-device LLM integration using Apple's Foundation Models framework. Use when implementing AI text generation, structured output, or tool calling.

SKILL.md 本文

Foundation Models

Appleのオンデバイス LLMをアプリに統合して、プライバシーを保護するAI機能を実現します。

このスキルが有効になるケース

  • ユーザーがAIテキスト生成機能を希望している
  • ユーザーが自然言語から構造化データを必要としている
  • ユーザーがプロンプトまたはLLM統合について質問している
  • ユーザーがAIアシスタントの実装を希望している
  • ユーザーがコンテンツの要約または抽出を必要としている

クイックスタート

1. 利用可能性を確認する

import FoundationModels

struct IntelligentView: View {
    private var model = SystemLanguageModel.default

    var body: some View {
        switch model.availability {
        case .available:
            ContentView()
        case .unavailable(.deviceNotEligible):
            UnsupportedDeviceView()
        case .unavailable(.appleIntelligenceNotEnabled):
            EnableIntelligenceView()
        case .unavailable(.modelNotReady):
            ModelDownloadingView()
        case .unavailable(let reason):
            ErrorView(reason: reason)
        }
    }
}

2. セッションを作成する

// シンプルなセッション
let session = LanguageModelSession()

// インストラクション付きセッション
let session = LanguageModelSession(instructions: """
    You are a helpful cooking assistant.
    Provide concise, practical advice for home cooks.
    """)

3. レスポンスを生成する

let response = try await session.respond(to: "What's a quick dinner idea?")
print(response.content)

プロンプトエンジニアリングのベストプラクティス

インストラクション公式

インストラクションはモデルのペルソナと制約を設定します。プロンプトよりも優先されます。

[Role] + [Task] + [Style] + [Safety]

例:

let instructions = """
    You are a fitness coach specializing in home workouts.
    Help users create exercise routines based on their equipment and goals.
    Keep responses under 100 words and use bullet points for exercises.
    Decline requests for medical advice and suggest consulting a doctor.
    """

インストラクション構成要素

構成要素目的
Roleペルソナを定義「You are a travel expert」
Task実行内容「Help plan itineraries」
Style出力形式「Use bullet points, be concise」
Safety境界線「Don't provide medical advice」

効果的なプロンプト

プロンプトはユーザー入力です。以下の特性を持つようにします:

原則悪い例良い例
具体的「Help with cooking」「Suggest a 30-minute vegetarian dinner」
制約付き「Tell me about dogs」「Describe Golden Retrievers in 3 sentences」
焦点を絞った「I need help with many things」「What ingredients substitute for eggs in baking?」

プロンプトパターン

質問パターン:

let prompt = "What are three ways to reduce food waste at home?"

コマンドパターン:

let prompt = "Create a weekly meal plan for a family of four, budget-friendly."

抽出パターン:

let prompt = """
    Extract the following from this email:
    - Sender name
    - Meeting date
    - Action items

    Email: \(emailContent)
    """

変換パターン:

let prompt = "Rewrite this text to be more formal: \(casualText)"

@Generableで構造化出力を取得

生の文字列の代わりに、型付きSwiftデータを取得します。

生成可能な型を定義

@Generable(description: "A recipe suggestion")
struct Recipe {
    var name: String

    @Guide(description: "Cooking time in minutes", .range(5...180))
    var cookingTime: Int

    @Guide(description: "Difficulty level", .options(["Easy", "Medium", "Hard"]))
    var difficulty: String

    @Guide(description: "List of ingredients", .count(3...15))
    var ingredients: [String]

    @Guide(description: "Step-by-step instructions")
    var instructions: [String]
}

@Guide制約

制約ユースケース
.range(min...max)数値の範囲.range(1...100)
.options([...])列挙型のような選択肢.options(["Low", "Medium", "High"])
.count(n)配列の正確な長さ.count(5)
.count(min...max)配列の長さの範囲.count(3...10)

構造化データを生成

let session = LanguageModelSession(instructions: """
    You are a recipe assistant. Generate practical, home-cook friendly recipes.
    """)

let recipe = try await session.respond(
    to: "Suggest a quick pasta dish",
    generating: Recipe.self
)

print("Recipe: \(recipe.content.name)")
print("Time: \(recipe.content.cookingTime) minutes")
print("Ingredients: \(recipe.content.ingredients.joined(separator: ", "))")

複雑なネストされた構造

@Generable(description: "A travel itinerary")
struct Itinerary {
    var destination: String

    @Guide(description: "Daily activities for the trip")
    var days: [DayPlan]
}

@Generable(description: "Activities for one day")
struct DayPlan {
    var dayNumber: Int

    @Guide(description: "Morning activity")
    var morning: String

    @Guide(description: "Afternoon activity")
    var afternoon: String

    @Guide(description: "Evening activity")
    var evening: String
}

ツール呼び出し

モデルにコードを呼び出させて、データにアクセスしたりアクションを実行します。

ツールを定義

struct WeatherTool: Tool {
    let name = "getWeather"
    let description = "Get current weather for a location"

    struct Arguments: Codable {
        var location: String
    }

    func call(arguments: Arguments) async throws -> ToolOutput {
        let weather = await WeatherService.shared.fetch(for: arguments.location)
        return .string("Temperature: \(weather.temp)°F, Conditions: \(weather.conditions)")
    }
}

セッションでツールを使用

let weatherTool = WeatherTool()
let session = LanguageModelSession(
    instructions: "You help users plan outdoor activities based on weather.",
    tools: [weatherTool]
)

// モデルは必要に応じて自動的にツールを呼び出します
let response = try await session.respond(
    to: "Should I go hiking in San Francisco today?"
)

ツールエラーハンドリング

do {
    let response = try await session.respond(to: prompt)
} catch let error as LanguageModelSession.ToolCallError {
    print("Tool '\(error.tool.name)' failed: \(error.underlyingError)")
} catch {
    print("Generation error: \(error)")
}

スナップショットストリーミング

生成中のレスポンスを表示して、より良いUXを実現します。

SwiftUIにストリーミング

@Generable
struct StoryIdea {
    var title: String

    @Guide(description: "A brief plot summary")
    var plot: String

    @Guide(description: "Main characters", .count(2...4))
    var characters: [String]
}

struct StreamingView: View {
    @State private var partial: StoryIdea.PartiallyGenerated?
    @State private var isGenerating = false

    var body: some View {
        VStack(alignment: .leading) {
            if let partial {
                if let title = partial.title {
                    Text(title).font(.headline)
                }
                if let plot = partial.plot {
                    Text(plot)
                }
                if let characters = partial.characters {
                    ForEach(characters, id: \.self) { char in
                        Text("• \(char)")
                    }
                }
            }

            Button("Generate Story Idea") {
                Task { await generateStory() }
            }
            .disabled(isGenerating)
        }
    }

    func generateStory() async {
        isGenerating = true
        defer { isGenerating = false }

        let session = LanguageModelSession()
        let stream = session.streamResponse(
            to: "Create a sci-fi story idea",
            generating: StoryIdea.self
        )

        for try await snapshot in stream {
            partial = snapshot
        }
    }
}

複数ターンの会話

セッションを再利用してコンテキストを保持します。

@Observable
final class ChatViewModel {
    private var session: LanguageModelSession?
    var messages: [ChatMessage] = []

    func startConversation() {
        session = LanguageModelSession(instructions: """
            You are a helpful assistant. Remember context from earlier in our conversation.
            """)
    }

    func send(_ message: String) async throws {
        guard let session else { return }

        messages.append(ChatMessage(role: .user, content: message))

        let response = try await session.respond(to: message)

        messages.append(ChatMessage(role: .assistant, content: response.content))
    }
}

エラーハンドリング

do {
    let response = try await session.respond(to: prompt)
} catch LanguageModelSession.GenerationError.exceededContextWindowSize {
    // コンテキストが大きすぎます (>4,096トークン)
    // 解決策: 新しいセッションを開始するか、小さいリクエストに分割します
} catch LanguageModelSession.GenerationError.cancelled {
    // リクエストがキャンセルされました
} catch {
    print("Unexpected error: \(error)")
}

コンテキストウィンドウ管理

コンテキストサイズをプログラム的に取得

4096 をハードコードしないでください — 実行時にモデルにクエリします:

let model = SystemLanguageModel.default
let contextSize = try await model.contextSize
print("Context size: \(contextSize)") // 4096 (current limit)

contextSize には @backDeployed(before: iOS 26.4, macOS 26.4, visionOS 26.4) がマークされています。

実行時のトークン使用量を測定

推測の代わりに tokenUsage(for:) を使用して、各構成要素の正確なトークンコストを測定します:

let model = SystemLanguageModel.default

// インストラクションコストを測定
let instructions = Instructions("You're a helpful assistant that generates haiku.")
let instructionTokens = try await model.tokenUsage(for: instructions)
print(instructionTokens.tokenCount) // 16

// インストラクション+ツールを組み合わせて測定
let tools = [MoodTool()]
let combinedTokens = try await model.tokenUsage(for: instructions, tools: tools)
print(combinedTokens.tokenCount) // 79 — tools add significant overhead!

// プロンプトを測定
let prompt = Prompt("Generate a haiku about Swift")
let promptTokens = try await model.tokenUsage(for: prompt)
print(promptTokens.tokenCount) // 14

// マルチターンセッションで累積使用量を追跡
let session = LanguageModelSession(model: model, tools: tools, instructions: instructions)
let response = try await session.respond(to: prompt)
let transcriptTokens = try await model.tokenUsage(for: session.transcript)
print(transcriptTokens.tokenCount)

⚠️ ツールはトークン消費を増加させます

ツール定義はJSONスキーマとしてシリアル化され、トークン使用量が大幅に増加します。上の例では、単一のツールを追加すると、インストラクションが 16 → 79トークン に跳ね上がりました (約5倍)。ツールを追加する前に必ず測定し、特定のセッションで本当に必要かどうかを検討してください。

トークン予算モニタリング

コンテキスト使用量をパーセンテージで追跡して、オーバーフロー防止します:

extension SystemLanguageModel.TokenUsage {
    func percent(ofContextSize contextSize: Int) -> Float {
        guard contextSize > 0 else { return 0 }
        return Float(tokenCount) / Float(contextSize)
    }

    func formattedPercent(ofContextSize contextSize: Int) -> String {
        percent(ofContextSize: contextSize)
            .formatted(.percent.precision(.fractionLength(0)).rounded(rule: .down))
    }
}

// 使用方法
let contextSize = try await model.contextSize
print(instructionTokens.formattedPercent(ofContextSize: contextSize)) // "0%"
print(combinedTokens.formattedPercent(ofContextSize: contextSize))    // "1%"

プリフライトトークン予算チェック

exceededContextWindowSize エラー防止のため、送信前にプロンプトが収まるかを確認します:

func canFit(prompt: Prompt, in session: LanguageModelSession, model: SystemLanguageModel) async throws -> Bool {
    let contextSize = try await model.contextSize
    let transcriptTokens = try await model.tokenUsage(for: session.transcript)
    let promptTokens = try await model.tokenUsage(for: prompt)
    let totalNeeded = transcriptTokens.tokenCount + promptTokens.tokenCount
    return totalNeeded < contextSize
}

TranscriptDebugMenuでデバッグ

開発中は、SwiftUIビューの階層に TranscriptDebugMenu をドロップして、会話トランスクリプト全体とトークン消費をリアルタイムで視覚的に検査します。

大規模コンテンツの戦略

// コンテンツをチャンクに分割
func processLargeDocument(_ document: String) async throws -> [Summary] {
    let chunks = document.split(every: 10000) // ~2500トークン/チャンク
    var summaries: [Summary] = []

    for chunk in chunks {
        let session = LanguageModelSession() // チャンクごとに新規セッション
        let summary = try await session.respond(
            to: "Summarize this section: \(chunk)",
            generating: Summary.self
        )
        summaries.append(summary.content)
    }

    return summaries
}

生成オプション

let options = GenerationOptions(
    temperature: 0.7  // 0.0 = deterministic, 2.0 = creative
)

let response = try await session.respond(
    to: prompt,
    options: options
)
温度ユースケース
0.0-0.3事実抽出、データ処理
0.5-0.7創造性と精度のバランス
1.0-2.0クリエイティブライティング、ブレインストーミング

一般的なパターン

コンテンツ抽出

@Generable
struct EventDetails {
    var title: String
    var date: String?
    var time: String?
    var location: String?
    var attendees: [String]
}

let session = LanguageModelSession(instructions: """
    Extract event details from text. Use nil for missing information.
    """)

let event = try await session.respond(
    to: "Extract: Team lunch next Friday at noon in Conference Room B with John and Sarah",
    generating: EventDetails.self
)

要約

let session = LanguageModelSession(instructions: """
    Summarize text concisely. Focus on key points and actionable items.
    Maximum 3 bullet points.
    """)

let response = try await session.respond(
    to: "Summarize this email: \(longEmail)"
)

分類

@Generable
struct Classification {
    @Guide(description: "Category", .options(["Bug", "Feature", "Question", "Other"]))
    var category: String

    @Guide(description: "Priority", .options(["Low", "Medium", "High"]))
    var priority: String

    @Guide(description: "Brief summary")
    var summary: String
}

let result = try await session.respond(
    to: "Classify this support ticket: \(ticketText)",
    generating: Classification.self
)

チェックリスト

リリース前に確認:

  • AI機能を表示する前にモデルの利用可能性を確認する
  • サポートされていないデバイスのフォールバックUIを提供する
  • すべてのエラーケースをグレースフルに処理する
  • さまざまなプロンプト長でテストする
  • コンテキストウィンドウの制限を超えていないことを確認する
  • 構造化出力には @Generable を使用する
  • 生成に対して適切なローディング状態を追加する
  • ストリーミングUXがレスポンシブに感じることをテストする
  • インストラクションが明確で具体的であることを確認する
  • インストラクションに安全性の境界線を含める

参照

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
rshankras
リポジトリ
rshankras/claude-code-apple-skills
ライセンス
MIT
最終更新
2026/4/20

Source: https://github.com/rshankras/claude-code-apple-skills / ライセンス: MIT

関連スキル

OpenAILLM・AI開発⭐ リポ 6,054

agent-browser

AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。

by JimmyLv
汎用LLM・AI開発⭐ リポ 1,982

anyskill

AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 1,982

engram

AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 21,584

skyvern

AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。

by Skyvern-AI
汎用LLM・AI開発⭐ リポ 1,149

pinchbench

PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。

by pinchbench
汎用LLM・AI開発⭐ リポ 4,693

openui

OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。

by thesysdev
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: rshankras · rshankras/claude-code-apple-skills · ライセンス: MIT