axiom-foundation-models-diag について
Apple Foundation Modelsを使う開発者向けの診断ガイドです。利用可否、コンテキスト制限、ガードレール、出力品質、パフォーマンスを扱い、確認手順と対処方法を示します。
主な機能
- 01モデルの利用可否を確認
- 02コンテキストウィンドウ超過を診断
- 03ガードレールと言語エラーに対応
- 04出力品質の問題を調査
- 05生成遅延とUI応答性を改善
活用シーン
- 01デバイスでモデルが利用できない原因を調査
- 02長い会話によるコンテキストエラーに対処
- 03不正確または不正な形式の出力を調査
- 04生成待ち時間とUIのフリーズを軽減
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-foundation-models-diagインストール後、Claude Code で/axiom-foundation-models-diagを入力して読み込まれたか確認します。
詳細
Foundation Models の診断
概要
Foundation Models の問題は、コンテキストウィンドウ超過エラー、ガードレール違反、生成の遅延、利用可否の問題、予期しない出力として現れます。基本原則 Foundation Models の問題の 80%は、モデルの能力(世界知識を持つモデルではなく、デバイス向けの 3B パラメーターのモデル)、コンテキストの上限(4096 トークン)、または利用要件を誤解していることが原因であり、フレームワークのバグではありません。
危険信号 — Foundation Models の問題を疑う
次のいずれかが見られる場合は、フレームワークの不具合ではなく、Foundation Models に関する誤解を疑ってください。
- 生成に 5 秒以上かかる
- エラー:
exceededContextWindowSize - エラー:
guardrailViolation - エラー:
unsupportedLanguageOrLocale - モデルが幻覚や誤った出力を返す
- 生成中に UI がフリーズする
- シミュレーターでは機能するが、デバイスでは機能しない
- ❌ 禁止 「Foundation Models は壊れている。別の AI が必要だ」
- Foundation Models は、何百万台ものデバイスで Apple Intelligence を支えています
- 出力が誤っているのは、ユースケースが適切でないためです(世界知識ではなく要約に使うべきです)
- 問題を正当化して片付けず、原因を診断してください
重要な区別 Foundation Models は、要約、抽出、分類に最適化されたデバイス向けモデル(3B パラメーター)であり、世界知識や複雑な推論を行うモデルではありません。誤ったタスクに使用すれば、必ず結果が悪くなります。
必須の最初の手順
コードを変更する前に、必ず最初に次を実行してください。
// 1. Check availability
let availability = SystemLanguageModel.default.availability
switch availability {
case .available:
print("✅ Available")
case .unavailable(let reason):
print("❌ Unavailable: \(reason)")
// Possible reasons:
// - Device not Apple Intelligence-capable
// - Region not supported
// - User not opted in
}
// Record: "Available? Yes/no, reason if not"
// 2. Check supported languages
let supported = SystemLanguageModel.default.supportedLanguages
print("Supported languages: \(supported)")
print("Current locale: \(Locale.current.language)")
if !supported.contains(Locale.current.language) {
print("⚠️ Current language not supported!")
}
// Record: "Language supported? Yes/no"
// 3. Check context usage
let session = LanguageModelSession()
// After some interactions:
print("Transcript entries: \(session.transcript.entries.count)")
// Rough estimation (not exact):
let transcriptText = session.transcript.entries
.map { $0.content }
.joined()
print("Approximate chars: \(transcriptText.count)")
print("Rough token estimate: \(transcriptText.count / 3)")
// 4096 token limit ≈ 12,000 characters
// Record: "Approaching context limit? Yes/no"
// 4. Profile with Instruments
// Run with Foundation Models Instrument template
// Check:
// - Initial model load time
// - Token counts (input/output)
// - Generation time per request
// - Areas for optimization
// Record: "Latency profile: [numbers from Instruments]"
// 5. Inspect transcript for debugging
print("Full transcript:")
for entry in session.transcript.entries {
print("Entry: \(entry.content.prefix(100))...")
}
// Record: "Any unusual entries? Repeated content?"
ここから分かること
- 利用不可 → パターン 1a/1b/1c に進みます(利用可否の問題)
- コンテキスト超過 → パターン 2a に進みます(トークンの上限)
- ガードレールエラー → パターン 2b に進みます(コンテンツポリシー)
- 言語エラー → パターン 2c に進みます(未対応の言語)
- 誤った出力 → パターン 3a/3b/3c に進みます(出力品質)
- 生成が遅い → パターン 4a/4b/4c/4d に進みます(パフォーマンス)
- UI がフリーズ → パターン 5a に進みます(メインスレッドのブロック)
必須の解釈
コードを変更する前に、必ず次のいずれかを特定してください。
availability = .unavailableの場合 → デバイス/地域/オプトインの問題です(コードのバグではありません)- エラーが
exceededContextWindowSizeの場合 → トークンが多すぎます(会話の記録を簡潔にしてください) - エラーが
guardrailViolationの場合 → コンテンツポリシーが適用されました(モデルの障害ではありません) - エラーが
unsupportedLanguageOrLocaleの場合 → 言語がサポートされていません(サポート対象の一覧を確認してください) - 出力に幻覚が含まれる場合 → ユースケースが適切ではありません(世界知識ではなく抽出に使うべきです)
- 生成に 5 秒以上かかる場合 → ストリーミングされていないか、最適化が必要です
- UI がフリーズする場合 → メインスレッドで呼び出しています(Task {} を使用してください)
診断結果に矛盾がある場合、または不明瞭な場合
- いったん停止してください。まだパターンに進まないでください
- すべての
respond()呼び出しに詳細なログを追加してください - Instruments の Foundation Models テンプレートを使って実行してください
- ベースラインを確立してください。実際に起きていることと、想定していたことを確認します
判断ツリー
Foundation Models problem?
│
├─ Won't start?
│ ├─ .unavailable → Availability issue
│ │ ├─ Device not capable? → Pattern 1a (device requirement)
│ │ ├─ Region restriction? → Pattern 1b (regional availability)
│ │ └─ User not opted in? → Pattern 1c (Settings check)
│ │
├─ Generation fails?
│ ├─ exceededContextWindowSize → Context limit
│ │ └─ Long conversation or verbose prompts? → Pattern 2a (condense)
│ │
│ ├─ guardrailViolation → Content policy
│ │ └─ Sensitive or inappropriate content? → Pattern 2b (handle gracefully)
│ │
│ ├─ unsupportedLanguageOrLocale → Language issue
│ │ └─ Non-English or unsupported language? → Pattern 2c (language check)
│ │
│ └─ Other error → General error handling
│ └─ Unknown error type? → Pattern 2d (catch-all)
│
├─ Output wrong?
│ ├─ Hallucinated facts → Wrong model use
│ │ └─ Asking for world knowledge? → Pattern 3a (use case mismatch)
│ │
│ ├─ Wrong structure → Parsing issue
│ │ └─ Manual JSON parsing? → Pattern 3b (use @Generable)
│ │
│ ├─ Missing data → Tool needed
│ │ └─ Need external information? → Pattern 3c (tool calling)
│ │
│ └─ Inconsistent output → Sampling issue
│ └─ Different results each time? → Pattern 3d (temperature/greedy)
│
├─ Too slow?
│ ├─ Initial delay (1-2s) → Model loading
│ │ └─ First request slow? → Pattern 4a (prewarm)
│ │
│ ├─ Long wait for results → Not streaming
│ │ └─ User waits 3-5s? → Pattern 4b (streaming)
│ │
│ ├─ Verbose schema → Token overhead
│ │ └─ Large @Generable type? → Pattern 4c (includeSchemaInPrompt)
│ │
│ └─ Complex prompt → Too much processing
│ └─ Massive prompt or task? → Pattern 4d (break down)
│
└─ UI frozen?
└─ Main thread blocked → Async issue
└─ App unresponsive during generation? → Pattern 5a (Task {})
診断パターン
パターン 1a:デバイスが対応していない
症状:
SystemLanguageModel.default.availability = .unavailable- 理由:デバイスが Apple Intelligence に対応していない
診断:
let availability = SystemLanguageModel.default.availability
switch availability {
case .available:
print("✅ Available")
case .unavailable(let reason):
print("❌ Reason: \(reason)")
// Check if device-related
}
修正方法:
// ❌ BAD - No availability UI
let session = LanguageModelSession() // Crashes on unsupported devices
// ✅ GOOD - Graceful UI
struct AIFeatureView: View {
@State private var availability = SystemLanguageModel.default.availability
var body: some View {
switch availability {
case .available:
AIContentView()
case .unavailable:
VStack {
Image(systemName: "cpu")
Text("AI features require Apple Intelligence")
.font(.headline)
Text("Available on iPhone 15 Pro and later")
.font(.caption)
.foregroundColor(.secondary)
}
}
}
}
所要時間:UI の追加に 5~10 分
パターン 1b:地域での利用可否
症状:
- 一部のユーザーには機能するが、ほかのユーザーには機能しない
- 地域制限により .unavailable になる
診断: Foundation Models の要件:
- サポート対象の地域(例:初期段階では米国、英国、オーストラリア)
- 対象地域は今後拡大する可能性があります
修正方法:
// ✅ GOOD - Clear messaging
switch SystemLanguageModel.default.availability {
case .available:
// proceed
case .unavailable(let reason):
// Show region-specific message
Text("AI features not yet available in your region")
Text("Check Settings → Apple Intelligence for availability")
}
所要時間:5 分
パターン 1c:ユーザーがオプトインしていない
症状:
- デバイスは対応しており、地域もサポート対象
- それでも .unavailable になる
診断: ユーザーは「設定」で Apple Intelligence をオプトインする必要があります
修正方法:
// ✅ GOOD - Direct user to settings
switch SystemLanguageModel.default.availability {
case .available:
// proceed
case .unavailable:
VStack {
Text("Enable Apple Intelligence")
Text("Settings → Apple Intelligence → Enable")
Button("Open Settings") {
if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url)
}
}
}
}
所要時間:10 分
パターン 2a:コンテキストウィンドウ超過
症状:
Error: LanguageModelSession.GenerationError.exceededContextWindowSize
診断:
- 4096 トークンの上限(入力+出力)
- 長い会話ではトークンが蓄積します
- 冗長なプロンプトが上限を圧迫します
修正方法:
// ❌ BAD - Unhandled error
let response = try await session.respond(to: prompt)
// Crashes after ~10-15 turns
// ✅ GOOD - Condense transcript
var session = LanguageModelSession()
do {
let response = try await session.respond(to: prompt)
} catch LanguageModelSession.GenerationError.exceededContextWindowSize {
// Condense and continue
session = condensedSession(from: session)
let response = try await session.respond(to: prompt)
}
func condensedSession(from previous: LanguageModelSession) -> LanguageModelSession {
let entries = previous.transcript.entries
guard entries.count > 2 else {
return LanguageModelSession(transcript: previous.transcript)
}
// Keep: first (instructions) + last (recent context)
var condensed = [entries.first!, entries.last!]
let transcript = Transcript(entries: condensed)
return LanguageModelSession(transcript: transcript)
}
所要時間:簡潔化処理の実装に 15~20 分
パターン 2b:ガードレール違反
症状:
Error: LanguageModelSession.GenerationError.guardrailViolation
診断:
- ユーザー入力がコンテンツポリシーに抵触しました
- 暴力、ヘイトスピーチ、違法行為
- モデルが生成を拒否します
対処法:
// ✅ GOOD - Graceful handling
do {
let response = try await session.respond(to: userInput)
print(response.content)
} catch LanguageModelSession.GenerationError.guardrailViolation {
// Show user-friendly message
print("I can't help with that request")
// Log for review (but don't show user input to avoid storing harmful content)
}
所要時間:5~10 分
パターン 2c:未対応の言語
症状:
Error: LanguageModelSession.GenerationError.unsupportedLanguageOrLocale
診断: ユーザー入力の言語がモデルでサポートされていません
対処法:
// ❌ BAD - No language check
let response = try await session.respond(to: userInput)
// Crashes if unsupported language
// ✅ GOOD - Check first
let supported = SystemLanguageModel.default.supportedLanguages
guard supported.contains(Locale.current.language) else {
// Show disclaimer
print("Language not supported. Currently supports: \(supported)")
return
}
// Also handle errors
do {
let response = try await session.respond(to: userInput)
} catch LanguageModelSession.GenerationError.unsupportedLanguageOrLocale {
print("Please use English or another supported language")
}
所要時間:10 分
パターン 2d:一般的なエラー処理
症状: 不明なエラーの種類
対処法:
// ✅ GOOD - Comprehensive error handling
do {
let response = try await session.respond(to: prompt)
print(response.content)
} catch LanguageModelSession.GenerationError.exceededContextWindowSize {
// Handle context overflow
session = condensedSession(from: session)
} catch LanguageModelSession.GenerationError.guardrailViolation {
// Handle content policy
showMessage("Cannot generate that content")
} catch LanguageModelSession.GenerationError.unsupportedLanguageOrLocale {
// Handle language issue
showMessage("Language not supported")
} catch {
// Catch-all for unexpected errors
print("Unexpected error: \(error)")
showMessage("Something went wrong. Please try again.")
}
所要時間:10~15 分
パターン 3a:ハルシネーション出力(ユースケースの誤り)
症状:
- モデルが事実と異なる回答をします
- 情報をでっち上げます
診断: モデルを世界知識に使用しています(ユースケースの誤り)
対処法:
// ❌ BAD - Wrong use case
let prompt = "Who is the president of France?"
let response = try await session.respond(to: prompt)
// Will hallucinate or give outdated info
// ✅ GOOD - Use server LLM for world knowledge
// Foundation Models is for:
// - Summarization
// - Extraction
// - Classification
// - Content generation
// OR: Use Tool calling with external data source
struct GetFactTool: Tool {
let name = "getFact"
let description = "Fetch factual information from verified source"
@Generable
struct Arguments {
let query: String
}
func call(arguments: Arguments) async throws -> ToolOutput {
// Fetch from Wikipedia API, news API, etc.
let fact = await fetchFactFromAPI(arguments.query)
return ToolOutput(fact)
}
}
所要時間:ツールの実装または適切な AI への切り替えに 20~30 分
パターン 3b:構造の誤り(@Generable を使用していない)
症状:
- 解析エラー
- 無効な JSON
- キーの誤り
診断: @Generable の代わりに手動で JSON を解析しています
対処法:
// ❌ BAD - Manual parsing
let prompt = "Generate person as JSON"
let response = try await session.respond(to: prompt)
let data = response.content.data(using: .utf8)!
let person = try JSONDecoder().decode(Person.self, from: data) // CRASHES
// ✅ GOOD - @Generable
@Generable
struct Person {
let name: String
let age: Int
}
let response = try await session.respond(
to: "Generate a person",
generating: Person.self
)
// response.content is type-safe Person, guaranteed structure
所要時間:@Generable への変換に 10 分
パターン 3c:データ不足(ツールが必要)
症状:
- モデルに必要な情報がありません
- 出力が曖昧、または一般的すぎます
診断: 外部データ(天気、場所、連絡先)が必要です
対処法:
// ❌ BAD - No external data
let response = try await session.respond(
to: "What's the weather in Tokyo?"
)
// Will make up weather data
// ✅ GOOD - Tool calling
import WeatherKit
struct GetWeatherTool: Tool {
let name = "getWeather"
let description = "Get current weather for a city"
@Generable
struct Arguments {
let city: String
}
func call(arguments: Arguments) async throws -> ToolOutput {
// Fetch real weather
let weather = await WeatherService.shared.weather(for: arguments.city)
return ToolOutput("Temperature: \(weather.temperature)°F")
}
}
let session = LanguageModelSession(tools: [GetWeatherTool()])
let response = try await session.respond(to: "What's the weather in Tokyo?")
// Uses real weather data
所要時間:ツールの実装に 20~30 分
パターン 3d:出力の不一致(サンプリング)
症状:
- 同じプロンプトでも毎回異なる出力になります
- テストで一貫した結果が必要です
診断: ランダムサンプリング(デフォルトの動作)
対処法:
// Default: Random sampling
let response1 = try await session.respond(to: "Write a haiku")
let response2 = try await session.respond(to: "Write a haiku")
// Different every time
// ✅ For deterministic output (testing/demos)
let response = try await session.respond(
to: "Write a haiku",
options: GenerationOptions(sampling: .greedy)
)
// Same output for same prompt (given same model version)
// ✅ For low variance
let response = try await session.respond(
to: "Classify this article",
options: GenerationOptions(temperature: 0.5)
)
// Slightly varied but focused
// ✅ For high creativity
let response = try await session.respond(
to: "Write a creative story",
options: GenerationOptions(temperature: 2.0)
)
// Very diverse output
所要時間:2~5 分
パターン 4a:初回の遅延(事前ウォームアップ)
症状:
- 初回の生成開始までに 1~2 秒かかります
- 2 回目以降のリクエストは高速です
診断: モデルの読み込み時間
対処法:
// ❌ BAD - Load on user interaction
Button("Generate") {
Task {
let session = LanguageModelSession() // 1-2s delay here
let response = try await session.respond(to: prompt)
}
}
// ✅ GOOD - Prewarm on init
class ViewModel: ObservableObject {
private var session: LanguageModelSession?
init() {
// Prewarm before user interaction
Task {
self.session = LanguageModelSession(instructions: "...")
}
}
func generate(prompt: String) async throws -> String {
guard let session = session else {
// Fallback if not ready
self.session = LanguageModelSession()
return try await self.session!.respond(to: prompt).content
}
return try await session.respond(to: prompt).content
}
}
所要時間:10 分 短縮される遅延:初回のリクエストで 1~2 秒
パターン 4b:生成時間が長い(ストリーミング)
症状:
- ユーザーは何も表示されないまま 3~5 秒待ちます
- その後、結果全体が一度に表示されます
診断: 時間のかかる生成をストリーミングしていません
対処法:
// ❌ BAD - No streaming
let response = try await session.respond(
to: "Generate 5-day itinerary",
generating: Itinerary.self
)
// User waits 4 seconds seeing nothing
// ✅ GOOD - Streaming
@Generable
struct Itinerary {
var destination: String
var days: [DayPlan]
}
let stream = session.streamResponse(
to: "Generate 5-day itinerary to Tokyo",
generating: Itinerary.self
)
for try await partial in stream {
// Update UI incrementally
self.itinerary = partial
}
// User sees destination in 0.5s, then days progressively
所要時間:15~20 分 体感遅延:0.5 秒対 4 秒
パターン 4c:大きなスキーマによるオーバーヘッド
症状:
- 同じ @Generable 型を使った 2 回目以降のリクエストが遅くなります
診断: 毎回スキーマがプロンプトに再挿入されています
対処法:
// First request - schema inserted automatically
let first = try await session.respond(
to: "Generate first person",
generating: Person.self
)
// ✅ Subsequent requests - skip schema insertion
let second = try await session.respond(
to: "Generate another person",
generating: Person.self,
options: GenerationOptions(includeSchemaInPrompt: false)
)
所要時間:2 分 短縮される遅延:リクエストごとに 10~20%
パターン 4d:複雑なプロンプト(分割する)
症状:
- 生成に 5 秒以上かかります
- 結果の品質が低いです
診断: 1 回の生成に対してプロンプトが複雑すぎます
対処法:
// ❌ BAD - One massive prompt
let prompt = """
Generate complete 7-day itinerary with hotels, restaurants,
activities, transportation, budget, tips, and local customs
"""
// 5-8 seconds, poor quality
// ✅ GOOD - Break into steps
let overview = try await session.respond(
to: "Generate high-level 7-day plan for Tokyo"
)
var dayDetails: [DayPlan] = []
for day in 1...7 {
let detail = try await session.respond(
to: "Detail activities and restaurants for day \(day) in Tokyo",
generating: DayPlan.self
)
dayDetails.append(detail.content)
}
// Total time similar, but better quality and progressive results
所要時間:20~30 分 品質の向上:大幅に改善
パターン 5a:UI のフリーズ(メインスレッドのブロック)
症状:
- 生成中にアプリが応答しなくなります
- UI が数秒間フリーズします
診断:
メインスレッドで respond() を同期的に呼び出しています
対処法:
// ❌ BAD - Blocking main thread
Button("Generate") {
let response = try await session.respond(to: prompt)
// UI frozen for 2-5 seconds!
}
// ✅ GOOD - Async task
Button("Generate") {
Task {
do {
let response = try await session.respond(to: prompt)
// Update UI on main thread
await MainActor.run {
self.result = response.content
}
} catch {
print("Error: \(error)")
}
}
}
所要時間:5 分 UX の改善:非常に大きい(UI がフリーズしなくなります)
本番環境での危機的状況
状況
状況:Foundation Models を使った AI 機能をリリースしたところです。2 時間以内に次の状況が発生しました:
- ユーザーの 20% が「AI 機能が動作しない」と報告
- App Store のレビューが低下:「新しい AI が壊れている」
- プロダクト担当 VP からのメール:「修正の ETA は?」
- エンジニアリングマネージャー:「ロールバックすべきでしょうか?」
プレッシャーの兆候:
- 🚨 収益への影響:この機能はアプリの新バージョンの重要なセールスポイントです
- ⏰ 時間的プレッシャー:「今すぐ直して」
- 👔 経営陣の注目:VP が状況を見ています
- 📉 公の評価:App Store のレビューは誰でも見られます
合理化の落とし穴
絶対に次の落とし穴にはまらないでください。
-
「機能を無効にする」
- 製品の差別化が失われます
- 敗北を認めることになります
- 何が問題だったのか学べません
-
「以前のバージョンにロールバックする」
- 数週間分の作業が無駄になります
- 根本原因は解決しません
- ユーザーの不満は解消されません
-
「こちらでは動きます」
- シミュレーター ≠ 実機
- 自分のデバイス ≠ すべてのデバイス
- 実際の問題を無視しています
-
「ChatGPT APIに切り替える」
- プライバシーを侵害します
- 大規模になるとコストがかかります
- 可用性の問題は解決しません
必須プロトコル
フェーズ 1:特定(5 分)
// Check error distribution
// What percentage seeing what error?
// Run this on test devices:
let availability = SystemLanguageModel.default.availability
switch availability {
case .available:
print("✅ Available")
case .unavailable(let reason):
print("❌ Unavailable: \(reason)")
}
// Hypothesis:
// - If 20% unavailable → Availability issue (device/region/opt-in)
// - If 20% getting errors → Code bug
// - If 20% seeing wrong results → Use case mismatch
結果:ユーザーの 20% は Apple Intelligence に対応していないデバイスを使っていることが判明します。
フェーズ 2:確認(5 分)
// Check which devices affected
// iPhone 15 Pro+ = ✅ Available
// iPhone 15 = ❌ Unavailable
// iPhone 14 = ❌ Unavailable
// Conclusion: Availability issue, not code bug
根本原因:この機能は、すべてのユーザーが Apple Intelligence を利用できることを前提としています。利用できないユーザーが 20% います。
フェーズ 3:デバイス要件(5 分)
次の点を確認します。
- Apple Intelligence には iPhone 15 Pro 以降が必要です
- または M1 以降のチップを搭載した iPad が必要です
- または Apple シリコンを搭載した Mac が必要です
ユーザーベースの 20% が旧型デバイスを使用
フェーズ 4:修正を実装(15 分)
// ✅ Add availability check + graceful UI
struct AIFeatureView: View {
@State private var availability = SystemLanguageModel.default.availability
var body: some View {
switch availability {
case .available:
// Show AI feature
AIContentView()
case .unavailable:
// Graceful fallback
VStack {
Image(systemName: "sparkles")
.font(.largeTitle)
.foregroundColor(.secondary)
Text("AI-Powered Features")
.font(.headline)
Text("Available on iPhone 15 Pro and later")
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
// Offer alternative
Button("Use Standard Mode") {
// Show non-AI fallback
}
}
}
}
}
フェーズ 5:デプロイ(20 分)
-
複数のデバイスでテストします(15 分)
- iPhone 15 Pro:✅ AI 機能を表示します
- iPhone 14:✅ 適切なメッセージを表示します
- iPad Pro M1:✅ AI 機能を表示します
-
ホットフィックスビルドを提出します(5 分)
コミュニケーションテンプレート
プロダクト担当副社長へ(直ちに):
Root cause identified:
The AI feature requires Apple Intelligence (iPhone 15 Pro+).
20% of our users have older devices. We didn't check availability.
Fix: Added availability check with graceful fallback UI.
Timeline:
- Hotfix ready: Now
- TestFlight: 10 minutes
- App Store submission: 30 minutes
- Review: 24-48 hours (requesting expedited)
Impact mitigation:
- 80% of users see working AI feature
- 20% see clear message + standard mode fallback
- No functionality lost, just graceful degradation
エンジニアリングチームへ:
Post-mortem items:
1. Add availability check to launch checklist
2. Test on non-Apple-Intelligence devices
3. Document device requirements clearly
4. Add analytics for availability status
削減できる時間
- パニック対応(無効化/ロールバック):会議に 2 時間+作業の損失
- 適切な診断:根本原因の特定から修正、デプロイまで 45 分
学んだこと
- セッションを作成する前に、必ず利用可否を確認する
- デバイスの世代をまたいで、実機でテストする
- 機能を削除するより、適切に機能を縮退させる
- 要件をユーザーに明確に伝える
クイックリファレンステーブル
| 症状 | 原因 | 確認項目 | パターン | 時間 |
|---|---|---|---|---|
| 起動しない | .unavailable | SystemLanguageModel.default.availability | 1a | 5 分 |
| 地域の問題 | サポート対象外の地域 | サポート対象地域を確認 | 1b | 5 分 |
| オプトインしていない | Apple Intelligence が無効 | 設定を確認 | 1c | 10 分 |
| コンテキスト超過 | >4096 トークン | トランスクリプトの長さ | 2a | 15 分 |
| ガードレールエラー | コンテンツポリシー | ユーザー入力の種類 | 2b | 10 分 |
| 言語エラー | サポート対象外の言語 | supportedLanguages | 2c | 10 分 |
| ハルシネーション出力 | ユースケースの誤り | タスクの種類を確認 | 3a | 20 分 |
| 構造が誤っている | @Generable がない | 手動で解析しているか | 3b | 10 分 |
| データが不足している | ツールがない | 外部データが必要か | 3c | 30 分 |
| 一貫性がない | ランダムサンプリング | 決定論的な出力が必要か | 3d | 5 分 |
| 初回の遅延 | モデルの読み込み | 最初のリクエストが遅いか | 4a | 10 分 |
| 待ち時間が長い | ストリーミングがない | 生成に 1 秒以上かかるか | 4b | 20 分 |
| スキーマのオーバーヘッド | スキーマを再挿入している | 後続のリクエストか | 4c | 2 分 |
| 複雑なプロンプト | 一度に指示しすぎている | 生成に 5 秒以上かかるか | 4d | 30 分 |
| UI がフリーズする | メインスレッド | スレッドを確認 | 5a | 5 分 |
相互参照
関連する Axiom スキル:
axiom-foundation-models— アンチパターン、適切な使用パターン、プレッシャー下のシナリオに関する規律スキルaxiom-foundation-models-ref— WWDC 2025 のすべてのコード例を含む完全な API リファレンス
Apple のリソース:
- Foundation Models Framework のドキュメント
- WWDC 2025-286:Foundation Models フレームワークについて
- WWDC 2025-301:Foundation Models フレームワークの詳細
- Instruments の Foundation Models テンプレート
最終更新日:2025-12-03 バージョン:1.0.0 スキルタイプ:診断