View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • App Intents
    • Apple 智能
    • 游戏
    • 机器学习与 AI
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区主导的活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于

更多视频

  • 简介
  • 概要
  • 代码
  • 使用 Core Spotlight 进行 LLM 搜索

    使用 SpotlightSearchTool 和 LanguageModelSession,将基础搜索升级为检索增强系统。探索 Core Spotlight 集成功能、委托式数据填充模式,以及元数据质量对搜索结果的影响。了解如何使用自定 PipelineStages 执行情感分析等任务。探索相关最佳做法,以便在你的 App 中建立索引,并构建灵活又贴合情境的搜索体验。

    章节

    • 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
      • 高清视频
      • 标清视频
  • 搜索此视频…
    • 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
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • Apple 智能
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • 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 Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则