View in English

  • Apple Developer
    • 시작하기

    시작하기 탐색

    • 개요
    • 알아보기
    • Apple Developer Program

    알림 받기

    • 최신 뉴스
    • Hello Developer
    • 플랫폼

    플랫폼 탐색

    • Apple 플랫폼
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    피처링

    • 디자인
    • 배포
    • 게임
    • 액세서리
    • 웹
    • 홈
    • CarPlay
    • 기술

    기술 탐색

    • 개요
    • Xcode
    • Swift
    • SwiftUI

    피처링

    • 손쉬운 사용
    • 앱 인텐트
    • Apple Intelligence
    • 게임
    • 머신 러닝 및 AI
    • 보안
    • Xcode Cloud
    • 커뮤니티

    커뮤니티 탐색

    • 개요
    • Apple과의 만남 이벤트
    • 커뮤니티 주도 이벤트
    • 개발자 포럼
    • 오픈 소스

    피처링

    • WWDC
    • Swift Student Challenge
    • 개발자 이야기
    • App Store 어워드
    • Apple 디자인 어워드
    • 문서

    문서 탐색

    • 문서 라이브러리
    • 기술 개요
    • 샘플 코드
    • 휴먼 인터페이스 가이드라인
    • 비디오

    릴리즈 노트

    • 피처링 업데이트
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • 다운로드

    다운로드 탐색

    • 모든 다운로드
    • 운영 체제
    • 애플리케이션
    • 디자인 리소스

    피처링

    • Xcode
    • TestFlight
    • 서체
    • SF Symbols
    • Icon Composer
    • 지원

    지원 탐색

    • 개요
    • 도움말
    • 개발자 포럼
    • 피드백 지원
    • 문의하기

    피처링

    • 계정 도움말
    • 앱 심사 지침
    • App Store Connect 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

    • 이벤트
    • 뉴스
    • 포럼
    • 샘플 코드
    • 비디오
 

비디오

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

더 많은 비디오

  • 소개
  • 요약
  • 코드
  • Core Spotlight를 사용한 LLM 검색

    SpotlightSearchTool과 LanguageModelSession을 사용하여 기본 검색을 RA(Retrieval-Augmented) 시스템으로 레벨업하세요. Core Spotlight 통합, 위임 기반 하이드레이션 패턴, 그리고 메타데이터 품질이 검색 결과에 영향을 미치는 방식을 살펴보세요. 감성 분석과 같은 작업을 위해 맞춤형 PipelineStage를 사용하는 방법을 알아보세요. 앱에서 유연하고 컨텍스트가 풍부한 검색 경험을 인덱싱 및 빌드하는 모범 사례를 살펴보세요.

    챕터

    • 0:00 - Introduction
    • 1:41 - Grounding answers with Spotlight tool-calling
    • 4:00 - Configure and add SpotlightSearchTool
    • 6:44 - Displaying results and partial replies
    • 6:46 - Provide full items with an index delegate
    • 8:12 - Customizing with guidance profiles
    • 11:02 - Reference resolution with a contact resolver
    • 11:24 - Custom pipeline stages
    • 12:47 - Evaluating response quality
    • 15:53 - Next steps

    리소스

    • Spotlight search tool
    • Making your indexed content available to Foundation Models
      • HD 비디오
      • SD 비디오
  • 비디오 검색…
    • 0:59 - Ask the model with a Foundation Models session

      let response = try await session.respond(to: "What are some nice hikes near water?")
    • 4:20 - Set up SpotlightSearchTool

      // Set up SpotlightSearchTool
        import CoreSpotlight
        import FoundationModels
      
        // In one line, the tool is ready to search your app's Core Spotlight index
        let tool = SpotlightSearchTool()
      
        // Or provide a custom configuration — e.g. search file paths in your app's sandbox
        let fileTool = SpotlightSearchTool(
            configuration: .init(
                sources: [
                    .files
                ]
            )
        )
    • 4:50 - Add SpotlightSearchTool to a session

      // Add SpotlightSearchTool to a session
        import CoreSpotlight
        import FoundationModels
        
        let tool = SpotlightSearchTool()
      
        let session = LanguageModelSession(model: model, tools: [tool], instructions: instructions)
      
        let response = try await session.respond(to: "What hikes have I gone on?")
    • 6:24 - Implement an index delegate

      // Implement an index delegate
        import CoreSpotlight
      
        class IndexDelegate: NSObject, CSSearchableIndexDelegate {
      
            // Called when the index requests searchable items for the provided identifiers
            func searchableItems(forIdentifiers identifiers: [String]) async -> [CSSearchableItem] {
                let entries = await mystore.fetchEntries(ids: identifiers)
                return entries.map { makeSearchableItem(from: $0) }
            }
        }
    • 7:37 - Track the query token for refresh

      // Track the query token for refresh
        import CoreSpotlight
        import FoundationModels
      
        let tool = SpotlightSearchTool()
      
        for await reply in tool.searchResults {
        
            if reply.queryToken != currentToken {
                // New query — start a new display section
                currentToken = reply.queryToken
            }
      
            switch reply.content {
            case .items(let searchItems):
            }
        }
    • 8:42 - Set a dynamic guidance profile

      // Set a dynamic guidance profile
        import CoreSpotlight
        import FoundationModels
      
        let profile = SpotlightSearchTool.GuidanceProfile(
            textMatch: true,
            dates: true,
            people: false,
            attributes: [.title, .altitude, .completionDate]
        )
      
        let tool = SpotlightSearchTool(
            configuration: .init(
                guide: .init(level: .dynamic(profile))
            )
        )
      
        // On-device models have smaller context — prefer focused guidance
        let focusedTool = SpotlightSearchTool(
            configuration: .init(
                guide: .init(level: .focused(.items))
            )
        )
    • 9:32 - Implement a ContactResolver

      // Implement a ContactResolver
        import CoreSpotlight
        import FoundationModels
      
        struct MyContactResolver: ContactResolver {
        
            func userIdentity() -> ResolvedContact {
                // Pull from whatever identity source your app has —
                // account profile, Contacts framework, sign-in session, etc.
                var contact = ResolvedContact(displayName: "Jane Doe")
                contact.emailAddresses = ["jane@example.com", "jdoe@work.com"]
                contact.names = ["Jane", "JD"]
                return contact
            }
        }
        
        tool.contactResolver = MyContactResolver()
    • 11:34 - Define a custom stage

      // Define a custom stage
        import CoreSpotlight
        import FoundationModels
      
        @Generable
        struct HappinessStage: CustomStage {
            static var name = "happiness"
            static var description = "Scores hike by how happy the author was"
            static var inputTypes: [SearchPipelineDataType] = [.items]
            static var outputTypes: [SearchPipelineDataType] = [.scoredItems]
      
            @Guide(description: "Minimum happiness score (0.0-1.0) to include in results")
            var threshold: Double?
      
            func execute(on input: SearchPipelineData) async throws -> SearchPipelineData {
                return SearchPipelineData(payload: .scoredItems(sorted))
            }
        }
      
        // Register the stage by adding it to the tool's configuration
        let tool = SpotlightSearchTool(configuration: .init(
            customStages: [.happinessBoost(threshold: 0.5)])
        )
    • 12:10 - Handle a reply data types

      // Handle a reply data types
        import CoreSpotlight
        import FoundationModels
      
        for await reply in tool.searchResults {
      
            let label = reply.label
            case .items(let searchItems):
            case .scoredItems(let scored):
            case .groupedItems(let groups):
            case .count(let count):
            case .table(let table):
            case .statistic(let statistic):
            case .text(let text):
                continue
            }   
        }
    • 13:47 - Define an evaluation dataset with ModelSampleProtocol

      // Evaluations
        import Evaluations
        
        struct TrailRequest: ModelSampleProtocol {
        
            typealias ExpectedValue = String                    // sample response
            typealias Expectation   = TrajectoryExpectation     
            
            var input:  ModelSampleInput
            var output: ModelSampleOutput<String, TrajectoryExpectation>
            
            var expectedIdentifiers: [String]
        }
    • 15:06 - Define the trajectory expectation

      // Evaluations
        import Evaluations
        
        TrajectoryExpectation(
            unordered: [
                ToolExpectation("searchSpotlight", arguments: [.keyOnly(argumentName: "query")])
            ]   
        )
    • 15:17 - Run the evaluation test —

      @Test("Trail search evaluation meets quality thresholds")
        func trailSearchEval() async throws {
        
            let items = try Self.loadItems()
            let samples = try Self.loadSamples()
            
            try await Self.indexDelegate.indexSearchableItems(items)
            let tool = Self.makeSearchTool()
            
            let evaluation = TrailSearchEvaluation(
                tool: tool,
                dataset: ArrayLoader(samples: samples)
            )   
            
            let result = try await evaluation.run()
            let coverageMean = result.aggregateValue(.mean(of: Metric("ResultCoverage")))
            #expect(coverageMean >= 0.5, "Result coverage should be at least 50% across queries")
        }
    • 0:00 - Introduction
    • Build conversational search by making app content available to a language model. Sets up the running example: a hiking trails app that browses state parks and trails and stores personal notes on completed hikes.

    • 1:41 - Grounding answers with Spotlight tool-calling
    • A LanguageModelSession answers broad questions from world knowledge, but to answer only about the app's hikes you ground it in the Core Spotlight index via the Foundation Models Tool protocol. Introduces SpotlightSearchTool (iOS, iPadOS, macOS, visionOS) and the prerequisite of donating searchable content.

    • 4:00 - Configure and add SpotlightSearchTool
    • Import CoreSpotlight and FoundationModels, create the tool (optionally with a custom configuration like a FileSource), choose a model (SystemLanguageModel or a Model Provider), and add the tool to a session. Walks the tool-call trajectory from query to grounded response.

    • 6:44 - Displaying results and partial replies
    • The session response suits an assistant-style UI, while the tool's searchable items suit a list UI. Search replies arrive as an async sequence of batched results; use the query token to know when to refresh, since the model may call the tool multiple times per response.

    • 6:46 - Provide full items with an index delegate
    • Some donated metadata is stored compactly and isn't readable by the model. Implement searchableItemsForIdentifiers on the CSSearchableIndexDelegate to recover the full CSSearchableItem on demand and attach extra attributes for the model to reason over.

    • 8:12 - Customizing with guidance profiles
    • SpotlightSearchTool exposes its full search capabilities for guided generation; a GuidanceProfile scopes that guidance to only what the app needs (such as specific attributes or a dynamic guide level), which matters for the smaller context of on-device models.

    • 11:02 - Reference resolution with a contact resolver
    • When a query references a person ("Who did I go hiking with?"), supply a ContactResolver that returns contact information matching the user's identity, so the tool can disambiguate and filter to the right results.

    • 11:24 - Custom pipeline stages
    • For complex requests the model can run a pipeline of search plus computation stages instead of a simple query. Register your own @Generable stages (such as a happiness-score stage over notes); the model generates stages on demand and may return computed data back to the app for display.

    • 12:47 - Evaluating response quality
    • Use the Evaluations framework to measure tool-calling and response quality. Define a dataset via ModelSampleProtocol with expected item identifiers and trajectory, expand seed samples with the Sample Generation APIs, and assert metrics like result coverage in a test.

    • 15:53 - Next steps
    • Download the hiking trails sample, add your own custom functionality and evaluation suite, and lean into the deep-dive sessions. The takeaway: stop writing search queries, provide the content and let intelligence do the rest.

Developer Footer

  • 비디오
  • WWDC26
  • Core Spotlight를 사용한 LLM 검색
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • Apple Intelligence
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • Mini Apps Partner 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 © 2026 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침