π€ μ¨λλ°μ΄μ€ AI μ±λ΄ λ§λ€κΈ°
Foundation Modelsλ₯Ό νμ©ν΄ νλΌμ΄λ²μλ₯Ό 보νΈνλ AI μ±μ λ§λλλ€. λͺ¨λ μ²λ¦¬κ° κΈ°κΈ° λ΄μμ μ΄λ£¨μ΄μ§λλ€.
β¨ Foundation Models νΉμ§
β’ νλΌμ΄λ²μ λ³΄νΈ (λ°μ΄ν°κ° κΈ°κΈ°λ₯Ό λ λμ§ μμ)
β’ μ€νλΌμΈ μ§μ (λ€νΈμν¬ λΆνμ)
β’ Swift λ€μ΄ν°λΈ async/await API
π¬ κΈ°λ³Έ μ¬μ©λ² (LanguageModelSession)
import FoundationModels // μΈμ μμ± (μμ€ν ν둬ννΈ μ€μ ) let session = LanguageModelSession( instructions: "μΉμ ν AI μ΄μμ€ν΄νΈμ λλ€" ) // μλ΅ μμ² let response = try await session.respond(to: "μλ νμΈμ") print(response.content)
π μ€νΈλ¦¬λ° μλ΅
// μ€νΈλ¦¬λ°μΌλ‘ μ€μκ° μλ΅ λ°κΈ° let stream = session.streamResponse(to: prompt) for try await partial in stream { response = partial.outputSoFar // μ§κΈκΉμ§ μμ±λ ν μ€νΈ }
π§ Tool Calling
@Tool struct WeatherTool { static let description = "νμ¬ λ μ¨λ₯Ό μ‘°νν©λλ€" @Parameter(description: "λμ μ΄λ¦") var city: String func execute() async -> String { return "\(city) λ μ¨: λ§μ, 23Β°C" } }
π¬ SwiftUI μ±λ΄ ꡬν
import SwiftUI import FoundationModels struct ChatView: View { @State private var messages: [Message] = [] @State private var inputText = "" @State private var isGenerating = false @State private var streamingText = "" // LanguageModelSession μ¬μ© @State private var session = LanguageModelSession( instructions: "μΉμ ν AI μ΄μμ€ν΄νΈμ λλ€. νκ΅μ΄λ‘ λ΅λ³νμΈμ." ) var body: some View { VStack { ScrollView { ForEach(messages) { message in MessageBubble(message: message) } // μ€νΈλ¦¬λ° μ€μΈ μλ΅ νμ if !streamingText.isEmpty { MessageBubble(message: Message(role: .assistant, content: streamingText)) } } HStack { TextField("λ©μμ§ μ λ ₯", text: $inputText) .textFieldStyle(.roundedBorder) Button("μ μ‘") { sendMessage() } .disabled(isGenerating || inputText.isEmpty) } .padding() } } func sendMessage() { let userMessage = Message(role: .user, content: inputText) messages.append(userMessage) let prompt = inputText inputText = "" isGenerating = true streamingText = "" Task { do { // μ€νΈλ¦¬λ° μλ΅ let stream = session.streamResponse(to: prompt) for try await partial in stream { streamingText = partial.outputSoFar } // μλ£ ν λ©μμ§ λ°°μ΄μ μΆκ° messages.append(Message(role: .assistant, content: streamingText)) streamingText = "" } catch { print("μ€λ₯: \(error)") } isGenerating = false } } } struct Message: Identifiable { let id = UUID() let role: MessageRole var content: String } enum MessageRole { case user, assistant }
βοΈ λͺ¨λΈ μ€μ & μλ¬ μ²λ¦¬
do { // Temperature μ‘°μ (0.0 = μΌκ΄μ±, 1.0 = μ°½μμ±) let result = try await model.generate( prompt: prompt, temperature: 0.7, maxTokens: 500 ) } catch let error as FoundationModelsError { switch error { case .modelNotAvailable: print("λͺ¨λΈμ΄ λ€μ΄λ‘λλμ§ μμμ΅λλ€") case .insufficientMemory: print("λ©λͺ¨λ¦¬κ° λΆμ‘±ν©λλ€") default: print("μ€λ₯ λ°μ: \(error)") } }
π‘ HIG κ°μ΄λλΌμΈ
AI κΈ°λ₯ μ¬μ© μ "μ¨λλ°μ΄μ€μμ μ²λ¦¬λ¨"μ λͺ
μνμΈμ. μ¬μ©μλ νλΌμ΄λ²μλ₯Ό μ€μνκ² μκ°ν©λλ€. μ²μ μ¬μ© μ AIκ° λ€μ΄λ‘λλλ λμ μ§ν μν©μ 보μ¬μ£Όλ κ²μ΄ μ’μ΅λλ€.