Section 2/151 menit

2. Masalah yang Dipecahkan

2. Masalah yang Dipecahkan

Masalah 1: Integrasi AI Memerlukan Server Eksternal

Sebelum Foundation Models, menambahkan AI generatif ke aplikasi iOS berarti mengandalkan API pihak ketiga — dengan implikasi privasi dan latensi.

swift
// ❌ TANPA Foundation Models: bergantung ke server eksternal
func summarizeText(_ text: String) async throws -> String {
    var request = URLRequest(url: URL(string: "https://api.openai.com/v1/chat/completions")!)
    request.httpMethod = "POST"
    request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    let body: [String: Any] = [
        "model": "gpt-4",
        "messages": [["role": "user", "content": "Summarize: \(text)"]]
    ]
    request.httpBody = try JSONSerialization.data(withJSONObject: body)
    
    // Data pengguna keluar dari perangkat ↑
    // Memerlukan koneksi internet ↑
    // API key tersimpan di app ↑
    let (data, _) = try await URLSession.shared.data(for: request)
    // ... parsing manual JSON
}
swift
// ✓ DENGAN Foundation Models: sepenuhnya on-device
func summarizeText(_ text: String) async throws -> String {
    let session = LanguageModelSession()
    let response = try await session.respond(to: "Rangkum teks ini: \(text)")
    return response.content
    // Data tidak meninggalkan perangkat ↑
    // Bekerja tanpa internet ↑
    // Tidak perlu API key ↑
}

Masalah 2: Output AI Tidak Terstruktur, Perlu Parsing Manual

Meminta LLM mengembalikan JSON lalu mem-parsing-nya secara manual rentan error dan tidak type-safe.

swift
// ❌ TANPA @Generable: parsing JSON dari string yang tidak terjamin
func analyzeReview(_ text: String) async throws -> (rating: Int, summary: String) {
    let prompt = """
    Analyze this review and return JSON:
    {"rating": <1-5>, "summary": "<brief summary>"}
    Review: \(text)
    """
    // Model mungkin mengembalikan format berbeda, extra text, atau JSON malformed
    let rawResponse = try await fetchFromAPI(prompt)
    
    guard let data = rawResponse.data(using: .utf8),
          let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
          let rating = json["rating"] as? Int,
          let summary = json["summary"] as? String else {
        throw AnalysisError.invalidResponse
    }
    return (rating, summary)
}
swift
// ✓ DENGAN @Generable: output terstruktur, type-safe, terjamin formatnya
@Generable
struct ReviewAnalysis {
    @Guide(description: "Rating dari 1 hingga 5")
    var rating: Int

    @Guide(description: "Ringkasan singkat review dalam satu kalimat")
    var summary: String
}

func analyzeReview(_ text: String) async throws -> ReviewAnalysis {
    let session = LanguageModelSession()
    return try await session.respond(
        to: "Analisis review ini: \(text)",
        generating: ReviewAnalysis.self
    ).content
    // Compiler menjamin tipe output ↑
    // Tidak perlu parsing manual ↑
}

Masalah 3: Konteks Multi-Turn Sulit Dikelola

Mempertahankan riwayat percakapan dengan API eksternal memerlukan manajemen array messages secara manual.

swift
// ❌ TANPA Foundation Models: kelola history secara manual
class ChatViewModel {
    var messages: [[String: String]] = []

    func sendMessage(_ text: String) async throws -> String {
        messages.append(["role": "user", "content": "text"])
        let body = ["model": "...", "messages": messages] as [String: Any]
        // ... serialize, send, parse response
        let reply = try await sendToAPI(body)
        messages.append(["role": "assistant", "content": reply])
        return reply
    }
}
swift
// ✓ DENGAN Foundation Models: session mengelola konteks otomatis
class ChatViewModel {
    let session = LanguageModelSession()

    func sendMessage(_ text: String) async throws -> String {
        // Session menyimpan riwayat percakapan secara otomatis
        let response = try await session.respond(to: text)
        return response.content
    }
}