Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜

Avatar for Nao-RandD Nao-RandD
September 30, 2026

RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜

DroidKaigi & iOSDC After Talks Night 2026 での登壇資料です
https://yumemi.connpass.com/event/402647/

#droidkaigi_iosdc_after_26

Avatar for Nao-RandD

Nao-RandD

September 30, 2026

More Decks by Nao-RandD

Other Decks in Programming

Transcript

  1. 自己紹介 • 名前 :菅 直之(Naoyuki Kan) • 所属 :株式会社ヤプリ •

    X :Nao-RandD(ナオランド) • 趣味 :ランニング 🏃
  2. 文 RAG の全体像 Retrieve 👈 ココの一部の話 の意味からも検索できて・・・ Augment データをいい感じに LLM

    に渡せる何か・・・ データがベクトル化されてて・・・ Generate なんかセマンティック検索? みたいなのできて・・・
  3. 􂦔 􀌳 R でやってること ユーザー質問 Retrieve キーワード検索 Augment 一致した候補 セマンティック検索

    (意味検索) 意味が近い候補 関連度を評価して順位付け Generate LLMへ 属性検索 条件に合う候補 その他の手法
  4. 意味で検索する流れ 以下の流れ 質問 → Embedding model → 近い文章を探す Embedding model

    とは? 単語や文をベクトル化してそれぞれの 意味の近さを測れるようにした機械学習モデル
  5. Swift でセマンティック検索 データをベクトル化して検索できるようにする let memos = [ "明日15時からチームの打ち合わせがある", "来週月曜は顧客とのミーティング", "夕方スーパーで牛乳を買う"

    ] guard let model = NLContextualEmbedding( language: .japanese) else { return } try model.load() // 登録時:原文をベクトル化して保持する let indexed = try memos.map { text in (text: text, vector: try embed(text, using: model)) } ・・・
  6. Swift でセマンティック検索 データをベクトル化して検索できるようにする let memos = [ "明日15時からチームの打ち合わせがある", "来週月曜は顧客とのミーティング", "夕方スーパーで牛乳を買う"

    ] guard let model = NLContextualEmbedding( language: .japanese) else { return } try model.load() // 登録時:原文をベクトル化して保持する let indexed = try memos.map { text in (text: text, vector: try embed(text, using: model)) } ・・・ func embed(_ text: String, using model: NLContextualEmbedding) throws -> [Double] { // ここでAppleのモデルが単語片ごとのベクトルを作る let result = try model.embeddingResult( for: text, language: .japanese ) // 単語片のベクトルを成分ごとに平均し、文のベクトルにする ・・・
  7. Swift でセマンティック検索 検索ワードもベクトル化して検索する let query = "会議の予定" // 検索時:質問も同じモデルでベクトル化する let

    queryVector = try embed(query, using: model) // 全候補との距離を計算し、近い順に並べる let hits = try indexed.map { item in ( text: item.text, distance: try cosineDistance(queryVector, item.vector) ) }.sorted { $0.distance < $1.distance } print("質問: \(query)") for (rank, hit) in hits.enumerated() { print( "\(rank + 1)位: \(hit.text) / 距離 " + } ) String(format: "%.6f", hit.distance)
  8. Swift でセマンティック検索 検索ワードもベクトル化して検索する 質問:会議の予定 let query = "会議の予定" // 検索時:質問も同じモデルでベクトル化する

    let queryVector = try embed(query, using: model) // 全候補との距離を計算し、近い順に並べる 「会議」という単語が文になくても、 let hits = try indexed.map { item in ( text: item.text, 打ち合わせとミーティングが上位 distance: try cosineDistance(queryVector, item.vector) ) }.sorted { $0.distance < $1.distance } print("質問: \(query)") 1位:明日15時からチームの打ち合わせがある 距離* 0.383151 2位:来週月曜は顧客とのミーティング 距離 0.398008 3位:夕方スーパーで牛乳を買う 距離 0.439022 for (rank, hit) in hits.enumerated() { print( "\(rank + 1)位: \(hit.text) / 距離 " + } ) String(format: "%.6f", hit.distance) *macOS 26.6.2の実測値。距離が近いほど意味が近い( 関連度が高い)可能性がある
  9. Swift でセマンティック検索 人名などが入ると意味の近さだけでは測りづらい 質問:田中さんの予定 1位:田中さんは15時からミーティング 距離 0.391871 2位:佐藤さんは14時からミーティング 距離 0.404021

    3位:田中さんは明日の朝に歯医者へ行く 距離 0.404178 この場合、「田中さん」でキーワード検索した結果の方が 関連度が高い可能性がある
  10. 􂦔 􀌳 ユーザー質問 キーワード検索 セマンティック検索 (意味検索) 属性検索 一致した候補 意味が近い候補 条件に合う候補

    その他の手法 RAG の「R(Retrieve)」において セマンティック検索は手段のひとつ 関連度を評価して順位付け 要件に応じて組み合わせ、取りこぼしや誤候補を補う LLMへ
  11. まとめ • RAG は R(情報を探す) → A(情報を付与する) → G(生成する) を段階的に行う

    • セマンティック検索は「R(情報を探す)」で抽出するための複数手段のひとつ • iOS であれば R に必要な検索機能の多くを Core Spotlight で実現できる(iOS 18以上) Building a search interface for your app: https://developer.apple.com/documentation/corespotlight/building-a-search-interface-for-your-app