View in English

  • 메뉴 열기 메뉴 닫기
  • Apple Developer
검색
검색 닫기
  • Apple Developer
  • 뉴스
  • 둘러보기
  • 디자인
  • 개발
  • 배포
  • 지원
  • 계정
페이지에서만 검색

빠른 링크

5 빠른 링크

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 주제
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • Foundation Models 프레임워크 만나보기

    Apple Intelligence에 숨겨진 온디바이스 대규모 언어 모델을 활용하는 방법을 알아보세요! 이 개요는 Swift 데이터 구조를 생성하고 반응성 경험을 스트리밍하기 위한 가이드 생성부터 맥락 관리를 위해 데이터 소스 및 세션을 통합하는 도구 호출에 이르기까지 모든 내용을 다룹니다. 이 세션에 필요한 전제 조건은 없습니다.

    챕터

    • 0:00 - 서론
    • 2:05 - 모델
    • 5:20 - 가이드 기반 생성
    • 7:45 - 스냅샷 스트리밍
    • 11:28 - 도구 호출
    • 16:11 - 스테이트풀 세션
    • 21:02 - 개발자 경험

    리소스

    • Human Interface Guidelines: Generative AI
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC25

    • 온디바이스 기반 모델에 대한 프롬프트 디자인 및 안전성 살펴보기
    • 코딩 실습: Foundation Models 프레임워크를 사용하여 앱에 온디바이스 AI 가져오기
    • Apple 플랫폼의 머신 러닝 및 AI 프레임워크 살펴보기
    • Foundation Models 프레임워크 자세히 알아보기
  • 비디오 검색…

    안녕하세요 저는 Erik입니다 저는 Yifei입니다 오늘 여러분께 새 파운데이션모델 프레임워크를 소개해 매우 기쁩니다! 파운데이션 모델프레임워크는 편리하고 강력한 Swift API를 통해 Apple Intelligence를 구동하는 기기 내 대규모 언어모델에 접근할 수 있습니다 macOS, iOS, iPadOSvisionOS에서 사용할 수 있죠 기존 앱 기능을 강화하는 데사용할 수 있으며 개인 맞춤형 검색제안을 제공할 수 있습니다 또는 여행 앱에서일정을 생성하는 것처럼 완전히 새로운 기능도온디바이스에서 만들 수 있습니다 게임 속 캐릭터의 대화를실시간으로 생성할 수도 있죠

    콘텐츠 생성, 텍스트 요약사용자 입력 분석 등 다양한 작업에 최적화되어 있습니다 이 모든 작업이 온디바이스에서 이루어지기 때문에 모델을 통과하는 모든 데이터는안전하게 보호됩니다 오프라인 상태에서도 작동한다는 뜻이죠 해당 기능은 운영체제에 있어앱 용량이 늘어나지 않습니다 올해는 중요한 해이므로 파운데이션 모델 프레임워크를최대한 활용할 수 있도록 비디오 시리즈를 준비했습니다 이번 첫 번째 비디오에서는프레임워크 전체에 대한 개요를 간단히 설명합니다 먼저 모델의 세부 사항부터 시작합니다 그다음으로 Swift에서 구조적 출력을 제공하는 가이드기반 생성 기능과 지연 시간을 즐거움으로 바꾸는 강력한스트리밍 API를 소개합니다 모델이 앱에서 정의한 코드를자율적으로 실행할 수 있는 도구 호출 기능에 대해서도 설명합니다 상태 저장 세션으로 멀티턴 대화지원을 제공하는 방법과 프레임워크를Apple 개발자 생태계에 원활하게 통합하는 방법을 설명합니다 물론, 이 프레임워크에서 가장중요한 부분은 구동 모델입니다 모델에 프롬프트를보내는 가장 좋은 방법은 Xcode에서 바로 시작하는 것이죠 다양한 프롬프트를 시험해 보며가장 적합한 방식을 찾는 것은 대규모 언어 모델을 활용해개발할 때 중요한 과정이며 Xcode의 새 Playground기능이 최적의 방법이죠 몇 줄의 코드만을 추가하여 온디바이스 모델에프롬프트를 보낼 수 있습니다 여기서는 일본 여행 제목을생성하도록 요청할 것이며 모델의 출력 결과는오른쪽 캔버스에 나타납니다 이 프롬프트가 다른 여행지에도잘 작동하는지 확인해 볼게요 #Playground에선 앱에정의된 타입에 접근할 수 있어 제 앱의 랜드마크를 반복하는for 루프를 작성하겠습니다 이제 Xcode에서 랜드마크모델의 응답을 볼 수 있습니다

    방금 사용한 온디바이스 모델은 30억 개의 매개변수를가진 대규모 언어 모델로 각 매개변수는 2비트로 양자화되어 있죠 이 모델은 운영체제에 포함된 다른 모든 모델보다 수십 배 이상 큽니다

    하지만 온디바이스 모델은 기기 규모 모델임을염두에 두는 것이 중요합니다 요약, 추출, 분류 등 다양한 용도에 최적화되어 있습니다 이 모델은 서버급 대규모언어 모델로 주로 수행하는 세계 지식이나 고급 추론작업을 위한 것은 아니죠

    기기 규모 모델은 작업 단위를더 작게 나눠 처리해야 합니다 모델을 사용하면서 강점과 약점을 자연스럽게파악할 수 있습니다

    콘텐츠 태그 지정 등일반적인 특정 사용 사례는 특수 어댑터가 제공되어 특정 도메인에서 모델의역량을 극대화합니다

    또한 시간이 지남에 따라모델을 개선해 나가게 됩니다 비디오 후반부에서모델 사용 방식을 알려주시면 중요한 방식으로 모델을개선하는 방법을 살펴보겠습니다

    이제 모델을 살펴보았으니 첫 번째로 가이드 기반생성 기능을 알아보겠습니다 가이드 기반 생성은 방금 본 기능을 구현할 수 있게해 주는 핵심 기능이며 파운데이션 모델프레임워크의 중심이죠 일반적인 문제를 살펴보고 가이드 기반 생성의해결 방법을 알아보겠습니다 기본적으로 언어 모델은비구조적 자연어를 출력합니다 사람은 읽기 쉽지만 앱의 뷰에바로 적용하기는 어렵습니다

    일반적인 해결책은 JSON이나CSV처럼 구문 분석하기 쉬운 형태를 모델에 요청하는 것입니다

    하지만 그렇게 하면 금방문제들이 계속 발생하게 됩니다 무엇을 해야 하고하지 말아야 하는지 점점 더 구체적인지침을 추가해야 합니다 종종 이 방법은 효과가 없습니다 결국 콘텐츠를 추출하고 패치를위한 해킹 방법을 쓰게 되죠 모델이 확률적이기 때문에 구조적인 오류가 발생 가능해신뢰할 수 없습니다 가이드 기반 생성은이에 대한 해결책을 제공합니다

    파운데이션 모델을 불러오면 두 가지 새 매크로 @Generable및 @Guide를 사용할 수 있죠 Generable은 모델이 생성할 타입을 설명할 수 있게 해 줍니다 또한, Guide는 속성의 자연어 설명을 제공하고 해당 속성의 생성 값을 프로그래밍 방식으로 제어할 수 있게 해줍니다

    Generable 타입을 정의하면 모델이 프롬프트에 응답해해당 인스턴스를 생성하죠 이 기능은 아주 유용합니다 이제 프롬프트에 출력 형식을따로 지정할 필요가 없습니다 프레임워크가 대신 처리해 주죠

    이제 쉽게 매핑해매력적인 뷰로 연결할 수 있는 풍부한 Swift 객체를바로 받을 수 있습니다

    Generable 타입은문자열, 정수, 실수 부동소수점, 십진수, 불리언기본형으로 구성할 수 있습니다 배열도 생성 가능합니다 Generable 타입은조합해서 사용할 수 있습니다 Generable은 재귀 타입도 지원하며 생성형 UI 같은 도메인에강력하게 적용됩니다 가이드 기반 생성에서가장 중요한 점은 제한된 복호화 기법을사용해 구조적 정확성을 근본적으로 보장한다는 점입니다 가이드 기반 생성을 사용할 때는 형식 대신 원하는 동작에 집중하고 간단한프롬프트를 사용할 수 있죠 가이드 기반 생성은모델의 정확도를 향상시킵니다 그리고 동시에 추론 속도를 높이는 최적화를 수행할 수 있습니다 이는 Apple 운영체제 개발 도구 그리고 기초 모델의 학습을 정교하게 통합한덕분에 가능해졌습니다 실행 시간에 동적스키마를 만드는 방법 등 가이드 기반 생성에 대해 아직 다룰 내용이 많으니 자세한 내용은심화 비디오에서 확인해 주세요 가이드 기반 생성은 이 정도로 마무리하겠습니다 Swift의 강력한 타입 시스템이자연어 프롬프트를 보완해 신뢰할 수 있는 구조적 출력을 지원하는 과정을 보았죠 다음 주제는 스트리밍입니다 모두 여러분이 이미익숙한 @Generable 매크로를 기반으로 합니다 대규모 언어 모델을사용해 본 경험이 있다면 텍스트가 토큰이라는 짧은 문자 단위로 생성된다는 점을아실 텐데요 스트리밍 출력 시 토큰은델타라는 형태로 전달되지만 파운데이션 모델 프레임워크는다른 방식을 사용합니다 그 이유를 설명해 볼게요

    델타가 생성될 때이를 누적하는 책임은 보통 개발자에게 있습니다 델타가 들어오면 개발자가 이를 추가합니다 그러면 그 반응은 점점 커지죠 하지만 결과에 구조가있을 때는 상황이 복잡해집니다 델타가 생성될 때마다인사 문자열을 보여주려면 누적된 결과에서구문 분석을 해야 하는데 복잡한 구조일 경우쉽지 않습니다 델타 스트리밍은구조적 출력을 다룰 때 적절한 방식이 아닙니다 아시다시피 구조적 출력은 파운데이션모델 프레임워크의 핵심입니다 그래서 우리는 다른방식을 개발했습니다 우리는 원시 델타 대신스냅샷을 스트리밍합니다

    모델에서 델타 생성 시프레임워크에서 스냅샷으로 변환하죠 스냅샷은 부분적으로생성된 응답을 나타냅니다 스냅샷의 모든 속성은 선택 사항이며 모델이 응답을 더 생성할수록속성들이 채워집니다 스냅샷은 구조적 출력을 스트리밍할 때 견고하고 편리한 표현 방식입니다

    익숙한 @Generable매크로는 부분적으로 생성된 타입의 정의가나오는 곳이기도 합니다 매크로를 확장하면 'PartiallyGenerated'타입을 생성합니다 이는 외부 구조를그대로 반영하되 모든 속성이 선택 사항인 형태입니다

    부분 생성 타입은 세션에서 'streamResponse'메서드 호출 시, 사용되죠

    스트림 응답은비동기 시퀀스를 반환합니다 해당 시퀀스의 요소는 부분생성 타입의 인스턴스입니다 시퀀스의 각 요소는업데이트된 스냅샷을 포함합니다

    SwiftUI 같은 선언형프레임워크와 잘 어울리죠 먼저 부분 생성 타입을저장할 상태를 만듭니다 그런 다음 응답 스트림을반복하며 요소를 저장하고 UI가 동적으로 변하는 모습을 지켜보세요

    스트리밍 모범 사례를살펴보겠습니다

    SwiftUI 애니메이션과전환 효과를 활용해 지연 시간을 자연스럽게 숨깁니다 기다림의 순간을 즐거움으로바꿀 수 있는 기회가 있죠 둘째 특히 배열을생성할 때 SwiftUI에서 뷰의 식별자 관리에 신경을 써야 합니다 마지막으로, 속성은 Swift구조체에 선언된 순서대로 생성된다는 점을 명심하세요 애니메이션, 모델 출력 품질모두에 영향을 줍니다 예를 들어 모델이 가장좋은 요약을 생성하려면 해당 속성이 구조체에서마지막에 올 수도 있습니다

    많은 내용을 다룰 예정이니 파운데이션 모델을SwiftUI 앱에 통합하는 비디오도 꼭 확인해 주시길 바랍니다 파운데이션 모델을활용한 스트리밍을 마무리합니다 이젠 Yifei가 도구 호출을자세히 알려드릴 예정입니다 감사합니다 Erik! 도구 호출은 우리의핵심 기능 중 하나입니다 이를 통해 모델이 앱에서정의한 코드를 실행할 수 있죠 이 기능은 모델의 성능을최대한 활용하는 데 중요한데 도구 호출이 모델에 많은추가 기능을 제공하기 때문이죠 이 기능은 모델이 작업에 추가 정보나 조치가필요할 수 있음을 인식하고 프로그래밍적으로 결정하기어려운 상황에서 어떤 도구를 언제 사용할지 자율적으로판단할 수 있게 합니다 모델에 제공하는 정보는세계 지식, 최근 사건 또는 개인 데이터일 수 있습니다 예를 들어 여행 앱에서는 MapKit을 통해 다양한위치 정보를 얻을 수 있습니다 이 기능으로 모델이 신뢰하는출처를 인용해 착오를 줄이고 모델 출력결과를 검증할 수 있죠 마지막으로, 이 기능은모델이 앱 내에서든 시스템에서든 실제 환경에서든 다양한 작업을 수행할 수 있도록 합니다 앱 내 다양한 정보출처와 통합하는 것은 매력적인 경험을 만드는필승 전략입니다 도구 호출이 유용한이유를 알아봤으니 이제 어떻게 작동하는지 살펴보겠습니다 왼쪽에는 지금까지일어난 모든 내용을 기록한 정보가 있습니다 세션에 도구를 제공했다면 해당 세션은 이 도구를지침과 함께 모델에 제시합니다 다음은 프롬프트로, 모델에게방문하려는 목적지를 알려주죠 이제 모델의 도구 호출이응답을 향상한다고 판단하면 하나 이상의 도구를 호출합니다 이 예시에서 모델은레스토랑과 호텔을 조회하는 두 개의 도구를 호출합니다 이 단계에서파운데이션 모델 프레임워크는 도구를 위해 작성한코드를 자동으로 호출합니다 그 후 도구 출력 값을 대화내역에 자동으로 삽입합니다 마지막으로 모델은도구 출력과 대화 내역의 다른 모든 내용을 함께 반영해 최종 응답을 생성합니다

    이제 도구 호출에 대한개괄적인 이해를 바탕으로 도구를 정의해 보겠습니다

    Tool 프로토콜을 따르는날씨 도구를 정의하고 있습니다 날씨 도구는 도구 호출의 사실상 'HelloWorld' 역할을 하며 시작하기에 좋은 방법입니다

    프로토콜은 먼저 도구의이름과 자연어 설명을 지정하도록 요구합니다

    프레임워크는 모델이도구를 언제 호출할지 이해할 수 있도록 해당정보를 자동으로 제공합니다

    모델에서 도구 호출 시정의한 호출 메서드가 실행되죠

    호출 메서드의 인수는 어떤Generable 타입도 될 수 있죠

    Generable이어야 하는이유는 도구 호출이 모델이 잘못된 도구 이름 또는인수를 생성하지 않도록 유도된 생성 방식을 기반으로 하기 때문입니다 인수 타입을 정의한 후에는 메서드 본문에 원하는내용을 작성할 수 있습니다 CoreLocation과WeatherKit을 사용해 특정 도시의 기온을 찾습니다 출력은 구조적 데이터를 위해GeneratedContent에서 GeneratedContent에서 생성 가능한ToolOutput 타입으로 표현됩니다 도구의 출력이 자연어일 경우문자열에서 생성할 수도 있죠 이제 도구를 정의했으므로 모델이 도구에 접근할 수있도록 해야 합니다 이를 위해 도구를 세션 초기화메서드에 전달합니다 도구는 세션 초기화 시연결되어야 하며 세션이 유지되는 동안모델이 사용할 수 있습니다

    도구를 포함한 세션을 생성한 후에는 평소처럼 모델에 프롬프트를전달하기만 하면 됩니다 도구 호출은 투명하고자율적으로 이루어지며 모델은 도구의 출력을최종 응답에 반영합니다 여기서 보여 드리는 예시는 컴파일 시 타입 안정성이보장되는 도구를 정의하는 방법을 설명하며대부분 사용 사례에 적합합니다 하지만 도구는 모든 면에서동적으로도 사용할 수 있습니다 예를 들어 동적 생성스키마를 사용해 실행 시 도구의 인수와 동작을 정의할 수 있습니다 관심이 있으시다면 자세한 내용을 알아볼 수 있는심화 비디오를 참조하세요 이것으로 도구 호출에 대한 내용을 마칩니다 도구 호출이 유용한 이유와 모델의 기능을 확장하기 위해 도구를구현하는 방법을 알아보았습니다 다음으로 상태 저장 세션에 대해 이야기 해보죠 세션이라는 단어는 이미여러 번 접했을 것입니다 파운데이션 모델 프레임워크는상태 저장 세션 개념을 기반으로 구축됩니다 기본적으로 세션을 생성하면 온디바이스 범용 모델에프롬프트를 전달하게 됩니다 그리고 맞춤형 지침을 제공할 수도 있습니다 지침은 모델에게 역할을 알려주고 응답 방식을안내할 수 있는 기회입니다 스타일이나 구체성 등을지정할 수 있죠 사용자 설정 지침제공은 선택 사항이며 지정하지 않으면 합리적인기본 지침이 사용됩니다

    사용자 지정 지침을제공하기로 결정했다면 지침과 프롬프트의 차이를이해하는 것이 중요합니다 지침은 개발자가 제공해야 하며 프롬프트는 사용자가 제공할 수 있습니다 이는 모델이 프롬프트 지시를따르도록 훈련되었기 때문입니다 이 방법은 프롬프트 인젝션공격을 어느 정도 방어하는 데 도움이 되지만 완벽한 보호책은 아닙니다 일반적으로 지침은대부분 정적이며 신뢰할 수 없는 사용자 입력을지침에서 제외하는 게 좋습니다 지침과 메시지 구성 방법의기본적인 입문서인 것이죠 더 많은 모범 사례를 알아보려면 프롬프트 디자인 및 안전비디오를 확인해 보세요 이제 세션을 초기화했으니멀티턴 상호작용을 알아보죠 앞서 이야기한 respond또는 streamResponse 메서드를 사용할 때 모델과의 각 상호작용은대화 내역에 맥락으로 저장되어 모델이 단일 세션 내에서과거의 멀티턴 내용을 참고하고 이해할 수 있습니다 예를 들어, 여기서 모델은“또 하나 작성해”라는 말이 haiku 쓰기를 재요청하는것임을 이해할 수 있습니다

    세션 객체 'transcript'속성은 이전 상호작용 확인 이를 나타내는 UI 뷰를그리는 데 사용할 수 있습니다 또는 이를 표현하기 위해 UI 뷰를 그립니다

    모델이 출력을생성하는 동안에는 'isResponding' 속성이'true'가 되죠 속성을 관찰하고 모델이 응답을완료할 때까지 다른 프롬프트를 제출하지 않도록 해야 할 수 있습니다 기본 모델 외에도 어댑터가 지원하는추가 내장 특화 사용 사례를 제공하고 있습니다 필요에 맞는 내장사용 사례를 찾으면 SystemLanguageModel의초기화 메서드에 전달할 수 있죠 어떤 내장된 사용 사례가있는지와 최적의 활용법을 이해하려면 개발자 웹사이트의 문서를 확인하시기 바랍니다 좀 더 자세히 다루고 싶은특화 어댑터 중 하나는 콘텐츠 태그 지정 어댑터입니다 콘텐츠 태그 지정 어댑터는태그 생성, 엔터티 추출 주제 감지를 기본적으로 지원합니다 기본적으로 어댑터는 학습으로주제 태그를 출력하고 가이드 기반 생성 기능과바로 통합됩니다 Generable 매크로로구조체를 간단히 정의한 다음 사용자 입력을 넘겨주제를 추출할 수 있습니다

    여기서 그치지 않습니다! 사용자 설정 지침, Generable출력 타입 지정 시 행동이나 감정 등을감지할 수 있습니다 세션을 만들기 전, 모델은Apple Intelligence 지원 기기와지원하는 지역에서만 실행되므로 사용 가능 여부를 먼저 확인해야 합니다 모델의 현재 사용가능 여부를 확인하려면 SystemLanguageModel의가용성 속성에 접근하면 됩니다

    가용성은 사용 가능 여부를나타내는 두 가지 열거형입니다 가용하지 않을 때는이유를 확인해 UI를 적절히 조정할 수 있습니다

    마지막으로, 모델을 호출할 때오류가 발생할 수 있습니다 오류로는 가드레일 위반 및지원하지 않는 언어 컨텍스트 창 초과 등이 있습니다 최상의 사용자 경험을 위해오류를 적절히 처리해야 하며 심화 비디오에서더 자세히 배울 수 있습니다 멀티턴 상태 저장 세션 설명은 여기까지입니다 세션 생성과 사용 방법 모델의 컨텍스트관리 방법을 배웠습니다 프레임워크의 기능을모두 살펴봤으니 이제 개발자 도구와경험에 대해 이야기 해보죠 먼저, 프로젝트 내Swift 파일 어디서나 새 Playground매크로로 모델에 요청할 수 있죠

    Playground는 앱을다시 빌드하고 실행하지 않고도 프롬프트를 빠르게반복할 수 있어 유용합니다 Playground에서는 이미UI를 구동하는 Generable 타입 등 프로젝트 내 모든타입에 접근 가능합니다

    대규모 언어 모델로구동되는 앱 경험을 만들 때는 내부 지연 시간을 모두 이해하는 것이 중요한데 이는 대규모 언어 모델이기존 ML 모델보다 실행 시간이 더 오래 걸리기 때문입니다 지연 시간 발생 지점 이해 시프롬프트의 상세함 조절 또는 사전 준비 같은 유용한API 호출 시점을 결정하죠

    새 Instruments 앱프로파일링 템플릿은 바로 이를 위해 만들어졌습니다 모델 요청의 지연시간을 프로파일링하고 최적화할 부분을 관찰하며개선 효과를 수치로 확인하죠

    앱을 개발하면서모델과 API 개선에 도움이 되는 피드백이있을 수 있습니다

    피드백 지원을 통해피드백을 보내주시기 바랍니다 피드백에 파일로첨부할 수 있는 인코딩 가능한 피드백 첨부 데이터구조도 제공합니다

    마지막으로, ML 전문가로서매우 특화된 사용 사례와 맞춤형 데이터세트가 있다면 어댑터 학습 툴킷으로 맞춤형어댑터를 학습시킬 수 있습니다 단, Apple이 모델을 개선할 때마다 다시 학습시켜야 하므로상당한 책임이 따릅니다 더 자세한 내용은개발자 웹사이트를 참조하세요 새 파운데이션 모델프레임워크가 제공하는 다양한 기능을 배우셨으니 여러분이 만들어 낼놀라운 결과물을 기대하겠습니다 생성형 AI의 앱 통합 방법안내된 생성 기술의 작동 원리 최적의 프롬프트 작성법 등을 더 알아볼 수 있도록 다양한 비디오와문서를 준비했습니다 오늘 함께해 주셔서 정말 감사합니다! 재미있게 작업하세요!

    • 2:28 - Playground - Trip to Japan

      import FoundationModels
      import Playgrounds
      
      #Playground {
          let session = LanguageModelSession()
          let response = try await session.respond(to: "What's a good name for a trip to Japan? Respond only with a title")
      }
    • 2:43 - Playground - Loop over landmarks

      import FoundationModels
      import Playgrounds
      
      #Playground {
          let session = LanguageModelSession()
          for landmark in ModelData.shared.landmarks {
              let response = try await session.respond(to: "What's a good name for a trip to \(landmark.name)? Respond only with a title")
          }
      }
    • 5:32 - Creating a Generable struct

      // Creating a Generable struct
      
      @Generable
      struct SearchSuggestions {
          @Guide(description: "A list of suggested search terms", .count(4))
          var searchTerms: [String]
      }
    • 5:51 - Responding with a Generable type

      // Responding with a Generable type
      
      let prompt = """
          Generate a list of suggested search terms for an app about visiting famous landmarks.
          """
      
      let response = try await session.respond(
          to: prompt,
          generating: SearchSuggestions.self
      )
      
      print(response.content)
    • 6:18 - Composing Generable types

      // Composing Generable types
      
      @Generable struct Itinerary {
          var destination: String
          var days: Int
          var budget: Float
          var rating: Double
          var requiresVisa: Bool
          var activities: [String]
          var emergencyContact: Person
          var relatedItineraries: [Itinerary]
      }
    • 9:20 - PartiallyGenerated types

      // PartiallyGenerated types
      
      @Generable struct Itinerary {
          var name: String
          var days: [Day]
      }
    • 9:40 - Streaming partial generations

      // Streaming partial generations
      
      let stream = session.streamResponse(
          to: "Craft a 3-day itinerary to Mt. Fuji.",
          generating: Itinerary.self
      )
      
      for try await partial in stream {
          print(partial)
      }
    • 10:05 - Streaming itinerary view

      struct ItineraryView: View {
          let session: LanguageModelSession
          let dayCount: Int
          let landmarkName: String
        
          @State
          private var itinerary: Itinerary.PartiallyGenerated?
        
          var body: some View {
              //...
              Button("Start") {
                  Task {
                      do {
                          let prompt = """
                              Generate a \(dayCount) itinerary \
                              to \(landmarkName).
                              """
                        
                          let stream = session.streamResponse(
                              to: prompt,
                              generating: Itinerary.self
                          )
                        
                          for try await partial in stream {
                              self.itinerary = partial
                          }
                      } catch {
                          print(error)  
                      }
                  }
              }
          }
      }
    • 11:00 - Property order matters

      @Generable struct Itinerary {
        
        @Guide(description: "Plans for each day")
        var days: [DayPlan]
        
        @Guide(description: "A brief summary of plans")
        var summary: String
      }
    • 13:42 - Defining a tool

      // Defining a tool
      import WeatherKit
      import CoreLocation
      import FoundationModels
      
      struct GetWeatherTool: Tool {
          let name = "getWeather"
          let description = "Retrieve the latest weather information for a city"
      
          @Generable
          struct Arguments {
              @Guide(description: "The city to fetch the weather for")
              var city: String
          }
      
          func call(arguments: Arguments) async throws -> ToolOutput {
              let places = try await CLGeocoder().geocodeAddressString(arguments.city)
              let weather = try await WeatherService.shared.weather(for: places.first!.location!)
              let temperature = weather.currentWeather.temperature.value
      
              let content = GeneratedContent(properties: ["temperature": temperature])
              let output = ToolOutput(content)
      
              // Or if your tool’s output is natural language:
              // let output = ToolOutput("\(arguments.city)'s temperature is \(temperature) degrees.")
      
              return output
          }
      }
    • 15:03 - Attaching tools to a session

      // Attaching tools to a session
      
      let session = LanguageModelSession(
          tools: [GetWeatherTool()],
          instructions: "Help the user with weather forecasts."
      )
      
      let response = try await session.respond(
          to: "What is the temperature in Cupertino?"
      )
      
      print(response.content)
      // It’s 71˚F in Cupertino!
    • 16:30 - Supplying custom instructions

      // Supplying custom instructions
      
      let session = LanguageModelSession(
          instructions: """
              You are a helpful assistant who always \
              responds in rhyme.
              """
      )
    • 17:46 - Multi-turn interactions

      // Multi-turn interactions
      
      let session = LanguageModelSession()
      
      let firstHaiku = try await session.respond(to: "Write a haiku about fishing")
      print(firstHaiku.content)
      // Silent waters gleam,
      // Casting lines in morning mist—
      // Hope in every cast.
      
      let secondHaiku = try await session.respond(to: "Do another one about golf")
      print(secondHaiku.content)
      // Silent morning dew,
      // Caddies guide with gentle words—
      // Paths of patience tread.
      
      print(session.transcript)
// (Prompt) Write a haiku about fishing
      // (Response) Silent waters gleam...
      // (Prompt) Do another one about golf
      // (Response) Silent morning dew...
    • 18:22 - Gate on isResponding

      import SwiftUI
      import FoundationModels
      
      struct HaikuView: View {
      
          @State
          private var session = LanguageModelSession()
      
          @State
          private var haiku: String?
      
          var body: some View {
              if let haiku {
                  Text(haiku)
              }
              Button("Go!") {
                  Task {
                      haiku = try await session.respond(
                          to: "Write a haiku about something you haven't yet"
                      ).content
                  }
              }
              // Gate on `isResponding`
              .disabled(session.isResponding)
          }
      }
    • 18:39 - Using a built-in use case

      // Using a built-in use case
      
      let session = LanguageModelSession(
          model: SystemLanguageModel(useCase: .contentTagging)
      )
    • 19:19 - Content tagging use case - 1

      // Content tagging use case
      
      @Generable
      struct Result {
          let topics: [String]
      }
      
      let session = LanguageModelSession(model: SystemLanguageModel(useCase: .contentTagging))
      let response = try await session.respond(to: ..., generating: Result.self)
    • 19:35 - Content tagging use case - 2

      // Content tagging use case
      
      @Generable
      struct Top3ActionEmotionResult {
          @Guide(.maximumCount(3))
          let actions: [String]
          @Guide(.maximumCount(3))
          let emotions: [String]
      }
      
      let session = LanguageModelSession(
          model: SystemLanguageModel(useCase: .contentTagging),
          instructions: "Tag the 3 most important actions and emotions in the given input text."
      )
      let response = try await session.respond(to: ..., generating: Top3ActionEmotionResult.self)
    • 19:56 - Availability checking

      // Availability checking
      
      struct AvailabilityExample: View {
          private let model = SystemLanguageModel.default
      
          var body: some View {
              switch model.availability {
              case .available:
                  Text("Model is available").foregroundStyle(.green)
              case .unavailable(let reason):
                  Text("Model is unavailable").foregroundStyle(.red)
                  Text("Reason: \(reason)")
              }
          }
      }
    • 22:13 - Encodable feedback attachment data structure

      let feedback = LanguageModelFeedbackAttachment(
        input: [
          // ...
        ],
        output: [
          // ...
        ],
        sentiment: .negative,
        issues: [
          LanguageModelFeedbackAttachment.Issue(
            category: .incorrect,
            explanation: "..."
          )
        ],
        desiredOutputExamples: [
          [
            // ...
          ]
        ]
      )
      let data = try JSONEncoder().encode(feedback)
    • 0:00 - 서론
    • 파운데이션 모델 프레임워크는 macOS, iOS, iPadOS, visionOS용 온디바이스 대규모 언어 모델에 대한 액세스를 제공합니다. 프레임워크를 사용하면 검색 제안, 여행 일정, 게임 내 대화처럼 개인화되고 혁신적인 기능을 만들 수 있도록 지원하여 데이터가 온디바이스에 남아 오프라인에서 작동할 수 있기 때문에 사용자 개인 정보 보호를 우선시합니다. 프레임워크는 콘텐츠 생성, 텍스트 요약, 사용자 입력 분석에 최적화되어 있습니다. 개발자를 지원하기 위해 Apple에선 프레임워크의 개요, 가이드 기반 생성, 스트리밍 API, 툴 호출, 멀티턴 지원, Apple 개발자 생태계로의 원활한 통합 등을 다루는 일련의 비디오를 마련했습니다.

    • 2:05 - 모델
    • Xcode의 새로운 Playground 기능은 온디바이스 대규모 언어 모델에 대한 프롬프트와 함께 실험을 시작하기에 최적의 시작점입니다. 몇 줄의 코드만으로 프롬프트를 테스트하고 모델의 반응을 실시간으로 볼 수 있습니다. 30억 개의 매개변수를 갖춘 인상적인 온디바이스 모델은 요약, 추출, 분류와 같은 특정 작업에 최적화되어 있고 세계 지식이나 고급 추론에는 적합하지 않습니다. 효율성을 극대화하려면 작업을 작은 단위로 나누세요. FoundationModels 프레임워크의 핵심 구성 요소인 가이드 기반 생성은 모델 출력을 앱에 통합하는 과제를 해결합니다. 모델 생성에 대한 체계적인 접근 방식을 제공하여 기능을 보다 안정적으로 구축할 수 있도록 지원하여 JSON 또는 CSV와 같이 쉽게 구문 분석할 수 있는 형식을 생성하는 모델에 의존하는 데 따른 한계를 극복합니다.

    • 5:20 - 가이드 기반 생성
    • FoundationModels를 가져오면서 ‘@Generable’ 및 ‘@Guide’라는 두 개의 새로운 매크로가 도입되었습니다. ‘@Generable’은 기본형, 배열, 합성형 또는 재귀형으로 구성될 수 있는 모델 생성 인스턴스의 유형을 설명할 수 있도록 지원합니다. ‘@Guide’는 속성에 대한 자연어 설명을 제공하고 생성된 값을 제어하여 제한된 디코딩을 통해 구조적 정확성을 보장합니다. 이러한 가이드 기반 생성 접근 방식은 프롬프트를 단순화하고, 모델 정확도를 높이며, 추론 속도를 높입니다. 이 기능을 사용하면 모델에서 리치 Swift 객체를 수신하여 매력적인 뷰에 쉽게 매핑할 수 있어 프롬프트에서 출력 형식을 지정할 필요가 없습니다.

    • 7:45 - 스냅샷 스트리밍
    • FoundationModels 프레임워크는 대규모 언어 모델용 기존 토큰 기반 델타 스트리밍과 다릅니다. 대신, 구조화된 출력을 처리하는 데 더 견고하고 편리한 선택적 속성을 가지고 부분적으로 생성된 응답을 스트리밍합니다. 이러한 접근 방식은 ‘@Generable’ 매크로를 활용하여 선택적 속성이 있는 외부 구조를 미러링하는 ‘PartiallyGenerated’ 유형을 생성합니다. ‘streamResponse’ 메서드는 이처럼 부분적으로 생성된 유형의 비동기 시퀀스를 반환하여 SwiftUI와 같은 선언적 프레임워크와 원활하게 통합할 수 있습니다. 스트리밍 중 사용자 경험을 향상시키려면 SwiftUI 애니메이션과 전환을 활용하세요. 최적의 결과를 얻으려면 뷰 정체성과 속성 선언 순서를 적절히 고려하는 것도 중요합니다.

    • 11:28 - 도구 호출
    • 톨 호출을 통해 AI 모델은 앱 내에서 사용자 정의 코드를 실행하여 기능을 강화할 수 있습니다. 이 기능을 사용하면 모델은 사용자의 요청 맥락에 따라 외부 툴을 사용하여 정보를 검색하거나 레스토랑, 호텔 또는 날씨 데이터를 쿼리하는 등의 작업을 수행할 시기를 자율적으로 결정할 수 있습니다. 이 모델은 MapKit과 같은 다양한 신뢰의 원천과 통합되어 정확하고 최신 정보를 제공할 수 있습니다. 이 프로세스에는 모델이 툴 호출을 생성하는 과정이 포함되는데, 이 호출은 FoundationModels 프레임워크에서 자동으로 실행되고 그 결과는 모델이 최종 응답을 공식화하는 데 사용할 수 있도록 대화 내용에 다시 삽입됩니다.

    • 16:11 - 스테이트풀 세션
    • 파운데이션 모델 프레임워크는 온디바이스 범용 모델로 스테이트풀 세션을 활성화합니다. 선택 사항이지만 스타일과 구체성을 지정하여 모델의 응답을 안내하는 사용자 지정 지침을 제공할 수 있습니다. 사용자 프롬프트와 다른 지침을 설정하고 보안 강화를 위해 모델은 프롬프트보다 지침을 따르도록 훈련됩니다. 세션 내에서 모델은 멀티턴 상호작용에서 맥락을 유지하기 때문에 이전 프롬프트와 응답을 이해하고 참고할 수 있습니다. transcript 속성을 사용해 이러한 상호작용을 검사할 수 있습니다. 또한 프레임워크는 태그 생성, 엔터티 추출, 주제 감지를 지원하는 콘텐츠 태그 어댑터와 같은 내장 특화 사용 사례도 제공합니다. 이러한 어댑터를 특정 요구 사항에 맞게 사용자 정의하세요. 이 모델은 지원되는 지역의 Apple Intelligence 지원 기기에서만 실행될 수 있기 때문에 세션을 생성하기 전 모델의 가용성을 확인하세요. 적절한 오류 처리는 가드레일 위반, 지원되지 않는 언어 또는 초과된 맥락 창과 같은 잠재적인 문제를 관리하는 데 필수적입니다.

    • 21:02 - 개발자 경험
    • Playground를 사용하면 앱 프로젝트 내에서 대규모 언어 모델에 대한 프롬프트를 빠르게 반복할 수 있기 때문에 모든 프로젝트 유형에 액세스할 수 있습니다. 새로운 Instruments 앱 프로파일링 템플릿은 모델 요청 및 프롬프트 구체성 내 개선이 필요한 영역을 식별함으로써 대기 시간을 최적화하는 데 도움이 됩니다. 피드백 지원을 통해 피드백을 보내 주시기 바랍니다.

Developer Footer

  • 비디오
  • WWDC25
  • Foundation Models 프레임워크 만나보기
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드(영문)
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    Apple Developer 앱 받기
    Copyright © 2025 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침